我知道编辑这个网站吗?

Git 主题分支

通常,你想尝试一些新想法,或开发一些新功能,而不是干扰主分支。这就是主题分支的用武之地。你可以轻松地在分支之间来回切换,这样你就不需要通过一次大的“怪物”提交来贡献新功能。

如果你想尝试一些可能行不通的事情,并且你不想让任何人知道这种情况,你可以将主题分支保留在本地。

#创建主题分支

您可以从任意起点创建主题分支,如下所示:

$ git checkout -b new-branch branch-point

参数 branch-point 可以是任何提交或标签。如果你想从当前 HEAD 分支,则根本不需要提交参数:

$ git checkout -b topic1

注意:如果您想从远程(默认跟踪)分支启动新分支,此命令发送设置默认合并为来自该远程分支与该分支:

$ git checkout -b fake2 origin/fake2  
...  
$ git pull

分支分支 fake2origin 拉入当前 (fake2) 分支。

分支间切换

要从当前分支切换到另一个分支,首先确保您已提交(或隐藏)所有内容,然后调用

$ git checkout 其他分支

这将切换到另一个分支(现在成为您的 HEAD),并更新工作目录。注意:只有跟踪的文件才会更新;未跟踪的文件将保持不变。

择优提交

如果您希望在当前分支中拥有另一个分支上的单个提交,请使用

$ gitcherry-pick 其他分支~2

在此示例中,引用了其他分支提示的倒数第三次提交(第二顺序祖先)。

如果您修复主题分支中的某些内容也需要在主分支中进行修复,那么择优挑选即可派上使用场:

# current branch: topic234  
... fix bug ...  
# git commit -s <file>  
$ git checkout main  
$ git cherry-pick topic234  
$ git checkout topic234

在此示例中,修复错误并提交错误修复后,您切换到分支 main,选择分支 topic234 上的最新提交,然后切换回分支 topic234

解决冲突

注意:当轮询提交时,可能会出现冲突。它们标记有冲突标记(“«<”…“===”…»»”)。

您必须编辑文件,选择想要的更改(第一部分是您当前分支中的版本,部分是预选的提交想要导入的内容)。有关如何解决合并冲突的第二详细信息,请参阅Git Conflicts

编辑文件后,将它们暂存在以进行提交和提交,使用

$ git add <file>...  
$ git commit

如果cherry-pick/rebase失败,这将为您带来合适的提交消息。

合并/变基主题分支

如果您完成了一个主题,并且想要更改分支分支 main,只需切换到该分支并合并主题分支:

$ git checkout main  
$ git merge topic234

与cherry-pick一样,混音可能会造成冲突和失败。详情请参阅Resolving conflicts

您可能不想合并,但是希望在当前主分支的基础上重新建立主题分支。要了解合并和变基之间的区别,请考虑以下历史记录(左边比右边更旧):

- A - B - C - D - main  
    \  
      E - F - G - topic234

合并后:

- A - B - C - D - main^ - main  
    \                      /  
      E - F - G - topic234

变基后:

  • A - B - C - D - 主要 - E’ - F’ - G’ - topic234

那么,topic234 中的所有提交都被重写,就要求它们在 main 分支的当前提示之上创建的一样。

如您所见,分支 topic234 被重写,并且与 topic234 分支的前一个提示没有共享任何有趣的历史记录。(您可以通过 topic234@{1} 访问前一个提示,请参阅Git_reflogs。)

因此,要通过变基将您的主题分支合并到 main 分支中,您需要执行以下操作:

# current branch is topic234  
$ git rebase main  
$ git checkout main  
# this will fast-forward, i.e. not create a merge commit, but just move main's tip to topic234's tip.  
$ git merge topic234

通常情况下,合并应该优先于变基,因为合并可以更好地显示历史记录:变基之后,分支的尖端基本上没有测试,因为您只在变基之前测试了提交。

然而,变基有时会非常方便,特别是如果您想重写提交历史记录,如下所述。

高级主题分支编辑(又名药物变基)

通常,主题分支会成为良好提交和修复提交的集合,也许还有一些需要的提交。在这种情况下,您可能需要稍微清理一下提交历史记录。这就是“交互式”变基的用武之地。

考虑一下这样的历史(第一个“单词”是缩写的提交名称):

0470894... Untrack generated files  
e0acf90... Add Fake, a specialized yet simple substitute for 'make'  
047ad28... Fake: implement up-to-date test and use it in make()  
deadbee... fixup! Add Fake, a specialized yet simple substitute for 'make'

其中0470894main分支的尖端,而deadbee修复了提交e0acf90中的一些严重问题,这些问题不应该按原样提交。

Note that the *fixup!* commit can be made easily by calling `git commit --fixup <commit-to-fixup>`.

To reorder the commits and merge the two commits (*squash* in Git terminology, as *merge* already means to merge branches), call

$ git rebase -i –autosquash main

这将启动一个编辑器,其中包含要在 main 之上应用的提交列表:

pick e0acf90 Add Fake, a specialized yet simple substitute for 'make'  
fixup deadbee fixup! Add Fake, a specialized yet simple substitute for 'make'  
pick 047ad28 Fake: implement up-to-date test and use it in make()

请注意,autosquash 模式解释了修复提交的特殊提交消息,移动了最后一行放置命令“pick”(如“cherry-pick”中的)替换为“fixup”。

保存并退出编辑器。将启动变基并使用修复提交修改第一个提交。

Note: If you want to default to the *autosquash* mode, you can tell Git so: `git config --global rebase.autosquash true` (you only need to do this once).

Note: as with cherry-picking and merging, conflicts can arise. You will [have to resolve them](/develop/git/conflicts), `git add` the resolved files, but you do not need to commit; calling

$ git rebase –继续

将接受更改,应用正确的提交作者和消息,并启动编辑器提供您验证内容。和以前一样,保存并退出,rebase 将继续。

中止交互式变基

Sometimes you realize by the sheer size of the list of commits that you made a mistake, and do not want to rebase after all. As with `git commit`, just delete the *complete* list, and the interactive rebase will be aborted.

Even at later stages, e.g. when you have a huge conflict and would prefer to go back and merge instead of rebase, you can abort the rebase. Just call

$ git rebase --abort

Git 将您带回到开始变基之前的位置。

Reflog 和 rebase

变基将在分离的 HEAD 上工作。既然,rebase 进行时,不会更新任何分支,而是会增长一个临时分支,只有当rebase 成功完成后,才会更新当前的分支。

这意味着您可以通过 branch-name@{1} 引用变基之前的状态(参见Git_reflogs)。

注意:对于 HEAD@{1} 来说情况并非如此:“HEAD”的引用日志遵循存储库中当前某个阶段的每个单独修订。