Git 实战系列(八)Git 解决冲突

如果工作目录的本地代码做了修改但尚未提交,pull 拉取远程仓库的新提交时,往往会提示冲突:

1
2
3
4
$ git pull
error: Your local changes to the following files would be overwritten by merge:
/there/is/a/conflict/file
Please, commit your changes or stash them before you can merge.

如上所示,有 commitstash 两种处理方法。针对本地代码的完成情况我们需要作出选择。

代码已完成

如果确认本地代码已经完成无误,可以先将本地代码 commit 到本地仓库。再次 pull 拉取远程仓库时,如无冲突,Git 会自动产生一次“合并”提交:

1
2
3
4
5
6
7
$ git lg
* e6f4e18 - Merge branch 'master' of origin (1 minutes ago)
|\
* | abfa93b - 本地仓库的提交 (2 minutes ago)
| * 1f1c21d - 远程仓库的提交 (3 minutes ago)
|/
* 17ef24c - 基准版本 (4 minutes ago)

这是因为 pull 的默认策略是“fetch + merge”。如果本地仓库的提交一直不 push 到远程仓库,极端情况下每一次 pull 都可能会产生一次“合并”提交,这会造成祖先图谱(graph)无谓的复杂。此时推荐使用 rebase 避免本地仓库无谓的合并节点:

1
$ git pull --rebase

代码未完成

但如果本地代码仍未完成,此时推荐使用 stash 命令暂存修改,避免将未完成的功能代码 commit 到本地仓库,污染仓库。

暂存当前修改

第一步,stash 暂存当前修改:

1
2
$ git stash save "填写你的备注"
Saved working directory and index state ......
1
2
3
$ git status
On branch master
nothing to commit, working directory clean

可以看到暂存后工作目录一干二净。这是因为 stash 命令可以将“修改过的被追踪的文件(modified tracked files)”和“暂存的变更(staged changes)”暂存到临时堆栈中,并将工作目录还原干净,以便后续的操作。

Stashing takes the dirty state of your working directory – that is, your modified tracked files and staged changes – and saves it on a stack of unfinished changes that you can reapply at any time.

拉取远程仓库

第二步,继续 pull 拉取远程仓库并进行自动合并:

1
$ git pull

重新还原暂存

第三步,stash pop 重新还原暂存修改:

1
$ git stash pop

处理冲突

最后一步,如果还原后产生冲突,需要手工或使用 mergetool 进行处理。处理完毕后,使用 add 标明冲突已解决:

1
$ git add .

参考

Git-工具-储藏(Stashing)