跳到主要内容

Git 版本控制核心概念

Git 记录文件的版本,方便比较改动、在分支上工作,以及找回已保存的内容。它采用分布式版本控制:普通的完整克隆会把项目历史带到本地,之后不联网也能提交和比较版本。不过,浅克隆会省略较早的历史,部分克隆也可能推迟下载某些对象。

GitHub、GitLab 等平台提供 Git 仓库托管,并增加 Pull Request、Issue 跟踪、权限控制和自动化功能。Git 本身不依赖这些平台。Pro Git 的入门部分介绍了两者的区别。

本地三个核心状态

在支持 Bash 语法的终端里新建一个练习目录。以下提交命令假设你已经在 Git 中配置了作者姓名和邮箱。

mkdir git-color-practice
cd git-color-practice
git init
printf 'blue\n' > color.txt
git add color.txt
git commit -m "Save blue"
printf 'green\n' > color.txt
git add color.txt
printf 'red\n' > color.txt

先停在这里。同一个文件现在有三个版本:

位置color.txt 的内容含义
最近一次提交(HEADblue已保存的快照,带有父提交指针和元数据
暂存区(index/staging area)green准备交给下一次提交的快照
工作区(working tree)red磁盘上当前的文件

git add 把执行时的文件内容放进暂存区。后来把文件改成 red,暂存区并不会跟着变化。此时直接运行 git commit,会保存哪种颜色?git diffgit diff --staged 又分别比较哪两个版本?

查看答案和差异片段

提交会保存 green,不是 red。git diff 比较工作区与暂存区:

@@ -1 +1 @@
-green
+red

git diff --staged 比较暂存区与 HEAD

@@ -1 +1 @@
-blue
+green

git status --short 会显示 MM color.txt:第一个 M 表示有已暂存的修改,第二个表示有未暂存的修改。

现在直接提交,不要再运行 git add

git commit -m "Save green"
git show HEAD:color.txt
cat color.txt

git show 输出 greencat 仍输出 red。提交保存了暂存区,工作区中后来的修改留在原处。若要在之后的提交里保存 red,需要重新暂存这个文件。

日常操作可以按下面的顺序进行:

git status
git diff
git add path/to/file
git diff --staged
git commit -m "Explain the change"

第一次查看差异,是看有哪些内容可以暂存;第二次则是看提交会保存什么。两处都看一眼,也有助于发现误入的生成文件、密钥或无关改动。

分支与远程仓库

分支是指向某个提交、可以移动的名称。远程仓库是另一个仓库的命名 URL,常用名称为 origin。上面的练习仓库还没有配置远程仓库;下面涉及远程的命令假设 origin 已配置,且你有推送权限。

git switch -c feature/name
git fetch origin
git log --oneline --decorate --graph --all
git push -u origin feature/name

git fetch 下载远程历史,并更新 origin/main 这类远程跟踪引用,不改动工作区,也不把变更整合进当前分支。git pull 则在 fetch 之后,按选项和配置执行合并或变基。拉取前要先确定采用哪种整合方式。

如何正确撤销操作

命令改动哪里
git restore path默认用暂存区内容覆盖工作区文件;可用 --source 指定其他提交。该路径未暂存的修改会被丢弃。
git restore --staged path默认把暂存区条目恢复为 HEAD 中的版本,取消暂存,但保留工作区修改。
git revert COMMIT新建一个提交来抵消先前提交的变更,通常是处理已共享历史最稳妥的方式。
git reset指定提交的用法会移动当前分支,也可改变暂存区或工作区。--hard 可能丢失未提交的内容,执行前先看状态和历史。

在高风险历史操作前,临时分支或标签能保留当前提交,却不会保存已暂存或未暂存的修改。这些内容要另行提交或放进 stash;若还要保留未跟踪文件,需明确把它们纳入。Git 的 reflog 能帮助找回许多本地提交的旧位置,不能恢复任意未保存的文件内容。各命令的选项见 Git reference

仓库基础规范

一个实用的仓库通常包含 README、适用的许可证、.gitignore 和明确的默认分支。仓库可见性、代码审查要求和部署规则由托管平台及仓库策略决定,不由 Git 决定。

参考资源

探索关联打开关联网络