Pay*_*ian 9 git rebase git-rebase
我有两个分支:master和test-branch(分支master).我的工作看起来如下:
git checkout mastergit checkout -b test-branchgit checkout mastergit pull - >其他人已经做出改变大师git checkout test-branchgit rebase -i masterpick将交互式控制台中的第一个更改为s我想做的是在重新定位test-branch之前压缩所有提交,这样我只需要解决一次合并冲突.这可能吗?如果是这样,怎么样?
有可能,甚至很容易.Git就是这样,有很多不同的方法可以做到.
从字面上做你最初的建议:
...在变基之前压缩测试分支上的所有提交
如果你在分支上运行之前这样做是最简单的.(我知道你没有作为命令列出,但你确实在第6步中运行:git mergemastergit mergegit merge
git pull- >其他人已经做出改变大师
因为git pull只是git fetch紧随其后git merge.)但是之后仍然很容易做到; 我们只需要定位正确的commit-ID.
让我们绘制您在步骤4中提交的提交图:
...<- o <- * <-- master, origin/master
\
A <- B <-- HEAD=test-branch
Run Code Online (Sandbox Code Playgroud)
该图显示的是有两个标签1指向我标记的提交*,即master和origin/master.提交*点返回提交o指向更多提交:这是分支的历史master.
您创建的分支的标签(现在是,因此是HEAD=部分)指向提交B.B然后提交指向提交A,指向提交*.那是分支的历史test-branch:你在at时创建它*,然后添加A,然后添加B.
这里有两种方法可以轻松压缩提交A,B此时:
git rebase -i master
这为您提供了一个交互式编辑会话,您可以在其中"选择"第一个提交然后"压缩"第二个提交,它将收集两个提交消息并让您以通常的方式编辑结果.然后它进行(单个)新提交,其树是提交的B.
git reset --soft master; git commit
这并没有打开底垫的交互式编辑会话:它只是让临时区域和树的承诺B(这是--soft部分git reset --soft),移动标签test-branch回点提交*直接(这是git reset一部分git reset --soft),并且使像往常一样新的提交(git commit).
缺点是您必须编写新的提交消息,但您可以从提交A或B以任何方式恢复提交消息.例如,您可以使用-c或-C标记git commit(您必须标识提交,A或者B,例如,使用@{1}或@{1}^或@{yesterday}或其他一些reflog说明符).或者,在执行此操作之前git reset --soft,您可以使用git log日志消息并将其保存在文件中,或者其他任何内容.
(第二种方法闪耀时,而不是只有两次提交壁球,你有42左右.)
这两种方法都做了同样的事情:它们添加了一个新的提交(让我们称之为AB),离开A和B后面以及有点灰色,我无法正确绘制:
AB <-- HEAD=test-branch
/
...<- o <- * <-- master, origin/master
\
A <- B [ghost version of test-branch]
Run Code Online (Sandbox Code Playgroud)
您的分支的幽灵版本对于大多数正常使用是不可见的,并且最终(默认情况下在30天左右之后)被垃圾收集掉.(在那之前它仍然在你的存储库中,并在你的reflog中,这样你就可以找到原始提交A,B以防万一你需要它们.)
如果你已经完成了第6步怎么办?在这种情况下,您仍必须识别提交*.你可以像我写这篇文章时那样按照jsexpert建议的方式来做,或者你可以通过以下方式找到它git merge-base:
$ mergebase=$(git merge-base HEAD master)
# then pick just ONE of the next two
$ git rebase -i $mergebase
$ git reset --soft $mergebase; git commit
Run Code Online (Sandbox Code Playgroud)
这是如何工作的.之后git checkout master; git fetch; git merge; git checkout test-branch(步骤5和6,或多或少),您的提交图现在看起来更像是:
...<- o <- * <- o <-- master, origin/master
\
A <- B <-- HEAD=test-branch
Run Code Online (Sandbox Code Playgroud)
那个并且指向它的新o提交- 或者它可能是整个提交链 - 是"在路上",但是(现在你在哪里)的"合并基础" 并且是提交:在两个之前最近的共享提交分支发散.masterorigin/mastertest-branchmaster*
然后我们简单地定位rebase或reset --soft在那个提交.当我们完成并有一个新的AB提交时,它看起来像这样:
AB <-- HEAD=test-branch
/
...<- o <- * <- o <-- master, origin/master
\
A <- B [ghost version of test-branch]
Run Code Online (Sandbox Code Playgroud)
一旦你的压扁AB提交,然后你可以git rebase说在master通常的方式.
请注意,另一个答案是做同样的事情,它只是*通过计算提交来识别提交.如果您知道提示test-branch和"有趣"提交之间有两个提交*,则HEAD~2标识相同的提交$(git merge-base HEAD master).使用git merge-base只是让你避免计数.
1 "引用"是实际的一般git术语.在这种情况下,它们是分支名称,我使用"label"一词将它们与此提交图形成的分支历史区分开来.git中的"branch"一词用来指代至少这两个不同的东西,它会让人感到困惑.
| 归档时间: |
|
| 查看次数: |
4021 次 |
| 最近记录: |