原文:The Ultimate Guide to Git Merge and Git Rebase

欢迎阅读 git mergegit rebase 命令使用指南。本教程将教你如何使用 Git 处理多个分支。

Git Merge

git merge 命令会将在单独分支上对代码库所做的任何更改合并到当前分支作为新的提交。

命令语法如下:

git merge BRANCH-NAME

例如,如果你当前在名为 dev 的分支中工作,并且想要合并在名为 new-features 的分支中所做的任何新更改,你将输入以下命令:

git merge new-features

注意:如果当前分支上有任何未提交的更改,Git 将不允许你合并,直到当前分支中的所有更改都已提交。要处理这些更改,你可以——

创建一个新分支并提交更改

git checkout -b new-branch-name
git add .
git commit -m "<your commit message>"

将它储存起来

git stash               # add them to the stash
git merge new-features  # do your merge
git stash pop           # get the changes back into your working tree

放弃所有更改

git reset --hard        # removes all pending changes

Git Rebase

git rebase 是一种将整个分支移动到树中另一个点的方法。最简单的例子是在树中向上移动一个分支。假设我们有一个分支在 A 点与主分支不同:

        /o-----o---o--o-----o--------- branch
--o-o--A--o---o---o---o----o--o-o-o--- master

当你做 rebase 时,你可以像这样移动它:

                                   /o-----o---o--o-----o------ branch
--o-o--A--o---o---o---o----o--o-o-o master

要执行 rebase,请确保你在主分支的 rebase 中具有所需的所有提交。检查你想要 rebase 的分支并输入 git rebase master(其中 master 是你想要 rebase 的分支)。

也可以在不同的分支上 rebase,例如,基于另一个分支的分支(我们称之为 feature)在 master 上 rebase:

                            /---o-o branch
           /---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master

git rebase master branchgit rebase master 签出分支后,你将得到:

           /---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master
                                  \---o-o branch

控制台中的 Git Rebase 交互

要在控制台中使用带有提交(commits)列表的 git rebase,你可以选择、编辑或放入 rebase:

  • 输入 git rebase -i HEAD~5,最后一个数字是你要查看的最近向后提交的任意数量。
  • 在 vim 中,按 esc,然后按 i 开始编辑测试。
  • 在左侧,你可以使用以下命令之一覆盖 pick。如果要将提交压缩到前一个提交并丢弃提交消息,请输入 f 代替 pick 的提交。
  • 保存并退出你的文本编辑器。
  • 当 rebase 停止时,进行必要的调整,然后使用 git rebase --continue 直到 rebase 成功。
  • 如果它成功 rebase,那么你需要使用 git push -f 强制推送你的更改,以将 rebase 版本添加到你的远程仓库。
  • 如果存在合并冲突,有多种方法可以解决此问题,包括遵循这份指南中的建议。一种方法是在文本编辑器中打开文件并删除不需要的代码部分。然后使用 git add  后跟 git rebase --continue。你可以通过输入 git rebase --skip 跳过冲突的提交,通过在控制台中运行 git rebase --abort 来停止 rebase。
pick 452b159 <message for this commit>
pick 7fd4192 <message for this commit>
pick c1af3e5 <message for this commit>
pick 5f5e8d3 <message for this commit>
pick 5186a9f <message for this commit>

# Rebase 0617e63..5186a9f onto 0617e63 (30 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but stop to edit the commit message.
# e, edit = use commit, but stop to amend or add commit.
# s, squash = use commit, meld into previous commit and stop to edit the commit message.
# f, fixup = like "squash", but discard this commit's log message thus doesn't stop.
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom. 
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

合并冲突

合并冲突是指你在不同的分支上提交对同一行的更改,产生了冲突。如果发生这种情况,Git 将不知道要保留哪个版本的文件,并显示类似于以下内容的错误消息:

CONFLICT (content): Merge conflict in resumé.txt Automatic merge failed; fix conflicts and then commit the result.

如果你在代码编辑器中查看 resumé.txt 文件,你可以看到发生冲突的位置:

<<<<<<< HEAD
Address: 808 South Street
=======
Address: 505 North Street
>>>>>>> updated_address

Git 在文件中添加了一些额外的行:

  • <<<<<<< HEAD
  • =======
  • >>>>>>> updated_address

======= 视为冲突的分界线。<<<<<<< HEAD======= 之间的所有内容都是 HEAD ref 指向的当前分支的内容。另一方面,=======>>>>>>> updated_address 之间的所有内容都是要合并的分支中的内容,updated_address

Git Merge vs Git Rebase

git mergegit rebase 都是非常有用的命令。你和你的团队应该考虑这两个命令之间的一些非常重要的区别。

每当运行 git merge 时,都会创建一个额外的合并提交。每当你在本地仓库中工作时,合并提交过多会使提交历史看起来很混乱。避免合并提交的一种方法是改用 git rebase

git rebase 是一个非常强大的功能,但是如果没有以正确的方式使用它也是有风险的。 git rebase 会更改提交历史记录,因此请谨慎使用。如果 rebase 是在远程仓库中完成的,那么当其他开发人员尝试从远程仓库中提取最新的代码更改时,可能会产生很多问题。请记住仅在本地仓库中运行 git rebase

以上就是你需要了解的关于 git mergegit rebase 的知识。