git创建合并冲突
其中我们将展示合并冲突如何出现的模拟。
mkdir test-dir cd test-dir git init . echo "some content" > example.txt git add example.txt git commit -am "initial commit" [master (root-commit) a45c22d] initial commit 1 file changed, 1 insertion(+) create mode 100524 example.txt
在给定的示例中,我们创建了一个 test-dir 新目录。
接下来,我们创建包含一些内容的 example.txt 文本文件并将其添加到存储库并提交。
结果,我们有了一个包含一个 master 分支和 example.txt 文件的新存储库。
下一步是创建另一个分支以用作冲突合并。
git checkout -b branch_to_merge echo "completely different content to merge later" > example.txt git commit -am "edit the content of example.txt to make a conflict" [branch_to_merge 4221135] edit the content of example.txt to make a conflict 1 file changed, 1 insertion(+), 1 deletion(-)
在上面的例子中,我们创建并签出 branch_to_merge 分支。
创建后,我们覆盖 example.txt 文件中的内容并提交新内容。
完成所有这些之后,提交会覆盖 example.txt 的内容:
git checkout master Switched to branch 'master' echo "content to add" >> example.txt git commit -am "added content to example.txt" [master 11ab34b] added content to example.txt 1 file changed, 1 insertion(+)
这一系列命令检查 master 分支,将内容添加到 example.txt 并提交。
因此,我们的存储库处于这样的状态:我们在 master 分支中有一个提交,在 branch_to_merge 分支中有一个提交。
最后一步是执行 git merge 命令,之后就会发生冲突:
git merge branch_to_merge Auto-merging example.txt CONFLICT (content): Merge conflict in example.txt Automatic merge failed; fix conflicts and then commit the result.
当多个作者编辑相同的内容或者一个开发人员删除文件而另一位开发人员正在对其进行更改时,就会发生合并冲突。
为了解决这个问题,开发人员在孤立的分支中工作。
git merge 命令负责合并孤立的分支并解决冲突的编辑。
与大多数版本控制系统不同,Git 使合并过程更容易。
Git 甚至可以自动集成新的更改。
但是在发生冲突的情况下,Git 无法自动确定哪个版本是正确的。
它将文件标记为冲突并停止合并过程。
合并冲突的类型
冲突可能出现在两个点:合并过程开始时或者合并过程中。
开始时合并失败
Git 无法启动合并,因为项目的工作目录或者暂存区中的待处理更改应该被合并的提交覆盖。
这是因为待处理的本地更改而发生的。
为了控制本地状态,使用了 git stash、git checkout、git commit 和 git reset 命令。
启动时发生错误时将显示以下消息:
error: Entry '<fileName>' not uptodate. Cannot merge. (Changes in working directory)
合并失败
合并时失败说明当前本地分支与正在合并的分支之间存在冲突。
合并时发生错误时将显示以下消息:
error: Entry '<fileName>' would be overwritten by merge. Cannot merge. (Changes in staging area)
识别合并冲突
正如我们已经看到的,Git 显示的输出表明出现了冲突。
执行 git status 命令查看未合并的路径:
git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: example.txt
example.txt 文件显示为修改后的状态。
执行 cat 命令将 example.txt 文件的内容放出。
我们可以看到这些视觉标记:
<<<<<<< HEAD ======= >>>>>>> branch_to_merge
======== 标记是冲突的中心。
center 和 HEAD 行之间的内容是 HEAD 引用指向的当前分支 master 中存在的内容。
在 git merge 页面上阅读更多关于视觉标记的信息。
git解决合并冲突
要解决合并冲突,我们应该编辑冲突的文件。
在编辑器中打开 example.txt 文件并删除所有标记。
更改后的文件具有以下外观:
some content to mess with content to add completely different content to merge later
执行 git add 命令来暂存新的合并内容。
接下来,创建一个新的提交来完成合并:
git commit -m "the conflict in example.txt is merged and resolved"
常用工具 | |
---|---|
git status | 有助于查找冲突文件。 |
git log --merge | 使用合并分支之间具有冲突的提交列表创建日志。 |
git diff | 在存储库或者文件的状态下找到差异。执行Git Diff可以预测和防止合并冲突。 |
Tools to resolve failure on start | |
git checkout | 撤消对文件的更改并更改分支。 |
git reset --mixed | 撤消对工作目录和暂存区域的更改。 |
Tools to resolve failure during merge | |
git merge --abort | 从合并过程中退出并在开始之前将分支返回到状态。 |
git reset | 将冲突文件重置为已知的良好状态。 |