directory search
Guides gitattributes giteveryday gitglossary gitignore gitmodules gitrevisions gittutorial gitworkflows Administration git archive git bundle git clean git filter-branch git fsck git gc git instaweb git reflog Basic Snapshotting git add git commit git diff git mv git reset git rm git status Branching and Merging git branch git checkout git log git merge git mergetool git stash git tag Debugging git bisect git blame git grep Email git am git format-patch git request-pull git send-email External Systems git fast-import git svn Getting and Creating Projects git clone git init Git git annotate git archimport git bisect-lk2009 git check-attr git check-mailmap git check-ref-format git checkout-index git cherry git citool git column git credential git credential-cache git credential-store git cvsexportcommit git cvsimport git cvsserver git diff-files git diff-tree git difftool git fast-export git fetch-pack git fmt-merge-msg git get-tar-commit-id git gui git http-backend git http-fetch git http-push git imap-send git index-pack git interpret-trailers git ls-remote git ls-tree git mailinfo git mailsplit git merge-file git merge-index git merge-one-file git merge-tree git mktag git mktree git name-rev git notes git p4 git pack-objects git pack-redundant git pack-refs git parse-remote git patch-id git prune git prune-packed git quiltimport git receive-pack git remote-ext git remote-fd git remote-testgit git repack git replace git rerere git send-pack git sh-i18n git sh-setup git shell git show-branch git show-index git stripspace git unpack-file git unpack-objects git upload-archive git upload-pack git var git verify-commit git verify-tag git whatchanged git worktree Inspection and Comparison git describe git shortlog git show Miscellaneous api credentials api index gitcli gitcore tutorial gitcredentials gitcvs migration gitdiffcore githooks gitk gitnamespaces gitremote helpers gitrepository layout gitsubmodules gittutorial 2 gitweb gitweb.conf pack format User Manual Patching git apply git cherry-pick git rebase git revert Plumbing Commands git cat-file git check-ignore git commit-tree git count-objects git diff-index git for-each-ref git hash-object git ls-files git merge-base git read-tree git rev-list git rev-parse git show-ref git symbolic-ref git update-index git update-ref git verify-pack git write-tree Server Admin git daemon git update-server-info Setup and Config git git config git help Sharing and Updating Projects git fetch git pull git push git remote git submodule
characters

名称

git-rerere  - 重复使用冲突合并的记录分辨率

概要

git rerere [clear|forget <pathspec>|diff|remaining|status|gc]

描述

在采用相对较长时间的主题分支的工作流中,开发人员有时需要一遍又一遍地解决相同的冲突,直到主题分支完成(合并到“release”分支,或发送并接受上游)。

此命令通过在初始手动合并时记录冲突的自动合并结果和相应的手动分析结果,并将先前记录的手动分辨率应用于其相应的自动合并结果,来帮助开发人员处理此过程。

注意

您需要设置配置变量rerere.enabled才能启用此命令。

命令

通常,git rerere运行时没有参数或用户干预。但是,它有几个允许它与其工作状态交互的命令。

clear

如果要中止合并分辨率,请重置rerere使用的元数据。调用git am [--skip|--abort]git rebase [--skip|--abort]将自动调用此命令。

forget <pathspec>

在<pathspec>中重置针对当前冲突记录的冲突解决方案。

diff

显示分辨率当前状态的差异。跟踪用户解决冲突时更改的内容很有用。其他参数直接传递给diff安装在PATH中的系统命令。

status

具有合并分辨率将会记录的冲突的打印路径。

remaining

打印具有尚未由rerere自动解决的冲突的路径。这包括其分辨率无法通过rerere进行跟踪的路径,例如冲突的子模块。

gc

Prune记录很久以前发生的冲突合并。默认情况下,将修剪超过15天的未解决的冲突并修复60天以上的已解决冲突。这些默认值分别通过gc.rerereUnresolvedgc.rerereResolved配置变量进行控制。

讨论

当您的主题分支修改主分支(或上游)在主题分支从其分支后触及的重叠区域时,即使在主题分支已准备好向上游推送之前,也可能需要使用最新的主分支进行测试:

              o---*---o topic             /
    o---o---o---*---o---o master

对于这样的测试,您需要以某种方式合并主题和主题。一种方法是将主人拉入主题分支:

        $ git checkout topic
        $ git merge master

              o---*---o---+ topic             /           /
    o---o---o---*---o---o master

标记的提交*触摸同一文件中的同一区域; 您需要在创建标记为的提交时解决冲突+。然后,您可以测试结果,以确保您的工作进行中仍然适用于最新的master。

在这次测试合并之后,有两种方法可以继续您关于该主题的工作。最简单的方法是在测试合并提交的基础上构建+,当主题分支中的工作终于准备就绪后,将主题分支拉入主内容中,和/或请求上游从您那里撤出。然而到那时,主测试或上游测试合并后可能已经进阶+,在这种情况下,最终提交图如下所示:

        $ git checkout topic
        $ git merge master
        $ ... work on both topic and master branches
        $ git checkout master
        $ git merge topic

              o---*---o---+---o---o topic             /           /         \
    o---o---o---*---o---o---o---o---+ master

然而,当你的主题分支是长期存在的时候,你的主题分支最终会有很多这样的“Merge from master”提交,这会不必要地混淆发展历史。Linux内核邮件列表的读者可能还记得,当一个子系统维护者要求从一个充满“useless merges”的分支中拉出时,Linus抱怨这种频繁的测试合并。

作为替代方案,为了保持主题分支不受测试合并的干扰,您可以放弃测试合并,并在测试合并之前继续构建在提示之上:

        $ git checkout topic
        $ git merge master
        $ git reset --hard HEAD^ ;# rewind the test merge
        $ ... work on both topic and master branches
        $ git checkout master
        $ git merge topic

              o---*---o-------o---o topic             /                     \
    o---o---o---*---o---o---o---o---+ master

当您的主题分支最终准备就绪并合并到主分支时,这将只剩下一个合并提交。此合并将要求您解决标记为的提交引入的冲突*。但是,这种冲突通常与您在创建测试合并时所解决的冲突相同。git rerere使用您早先解决的问题中的信息帮助您解决最终冲突的合并问题。

运行git rerere一个冲突automerge后,立即命令记录冲突工作树中的文件,与通常的冲突标志<<<<<<<=======以及>>>>>>>在其中。稍后,在解决冲突之后,git rerere再次运行将记录这些文件的已解决状态。假设您在创建主控测试合并到主题分支时执行了此操作。

下一次,在看到相同的冲突automerge之后,运行git rerere将执行早先冲突的automerge,早期的手动分辨率和当前冲突的automerge之间的三方合并。如果这个三路合并干净地解决,结果写出到您的工作树文件,因此您不必手动解决它。请注意,git rerere单独保留索引文件,因此您仍然需要使用git diff(或git diff -c)进行最终的完整性检查,并且git add当您满意时。

作为一种便利措施,git merge自动调用git rerere退出时失败的自动合并,git rerere并在新的冲突时记录手的解决方案,或者在不是时重新使用先前的手解决方案。在提交合并结果时git commit也会调用git rerere。这意味着你不需要做任何特别的事情(除了启用rerere.enabled配置变量)。

在我们的示例中,当您进行测试合并时,手动解析会被记录下来,并且只要记录的分辨率仍然适用,稍后使用更新的主控和主题分支进行实际合并时,它将被重用。

信息git rerere记录也在运行时使用git rebase。在主题分支上淘汰测试合并并继续开发之后:

              o---*---o-------o---o topic             /
    o---o---o---*---o---o---o---o   master

        $ git rebase master topic

                                  o---*---o-------o---o topic                                 /
    o---o---o---*---o---o---o---o   master

您可以运行git rebase master topic,在您的主题准备好向上游发送之前让自己保持最新状态。这会导致回退到三路合并,并且与您之前解决的测试合并相同。git rerere将通过运行git rebase来帮助你解决这个冲突。

Previous article: Next article: