这是一个例子:
>git status # On branch master nothing to commit (working directory clean) >git checkout -b test-branch >vi test.c >git add test.c >git commit -m "modified test.c" >vi README >git add README >git commit -m "modified README"
现在我想做一个' git rebase -i
',这将让我为这个分支重新提交所有提交.有没有像' git rebase -i HEAD~MASTER
'或类似的东西.我想我可以做' git rebase -i HEAD~2
',但我真的不想计算已经提交了多少次提交.我也可以这样做git rebase -i sha1
但我不想通过git log来查找第一个提交sha1.有任何想法吗?
好吧,我认为分支被称为"特征",它从"主"分支.
有一个叫做merge-base的小git命令.它需要两次提交,并为您提供这两者的第一个共同祖先.所以...
git merge-base feature master
...将为您提供这两个提交的第一个共同祖先.猜猜当你将这个提交传递给git rebase -i时会发生什么,比如......
git rebase -i `git merge-base feature master`
来自master和feature分支的第一个共同祖先的交互式rebase.利润!;)
所有提供的解决方案的问题是,它们不允许您从第一次提交时进行rebase.如果第一个提交哈希值是XYZ,那么您执行以下操作:
git rebase -i XYZ
您只从第二次提交开始重新绑定.
如果你想从第一次提交改变:
git rebase -i --root
你试过了git rebase -i master
吗?
在其他平台上使用gitk(*nix)或gitx(OS X)或类似的东西,并查看哪个提交是您的分支的根目录.然后运行:
git rebase -i
例如,我有一个我使用gitx检查的存储库:
现在我知道根哈希我可以运行这个:
git rebase -i 38965ed29d89a4136e47b688ca10b522b6bc335f
我的编辑弹出这个,我可以重新排列/挤压/随心所欲.
pick 50b2cff File 1 changes. pick 345df08 File 2 changes. pick 9894931 File 3 changes. pick 9a62b92 File 4 changes. pick 640b1f8 File 5 changes. pick 1c437f7 File 6 changes. pick b014597 File 7 changes. pick b1f52bc File 8 changes. pick 40ae0fc File 9 changes. # Rebase 38965ed..40ae0fc onto 38965ed # # Commands: # pick = use commit # edit = use commit, but stop for amending # squash = use commit, but meld into previous commit # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
我确信有一些神奇的方法来说服git自动找出树的根,但我不知道它是什么.
编辑:这就是魔术:
git log master..other_feature | cat
这将显示该分支上的所有提交,并且对cat的管道将禁用寻呼机,以便您立即看到第一个提交.
编辑:结合上面提供了一个完全自动化的解决方案:
git rebase -i `git log master..other_feature --pretty=format:"%h" | tail -n 1`~
从不同的分支重新定位的问题
问题git rebase -i master
在于您可能存在目前不一定要处理的合并冲突,或者您可能在一次提交中修复冲突,只在rebase过程中再次在另一次提交中修复它.
从已知提交重新定位的问题
这里的整个问题是你必须知道你要引用哪个提交,无论是通过它的SHA,还是HEAD~x等.这只是一个小麻烦,但这是一个烦恼.
更好的方法
如果您想要重新绑定当前分支中的所有提交,因为它与其父分支共享的最新提交,您可以将以下别名添加到.gitconfig:
rbi = !sh -c \"git rebase -i `git merge-base $1 HEAD`\" -
用法
git rbi parentBranch
这个怎么运作
这个别名只是一个shell脚本,它使用一个引用父分支的参数.传入该参数是git merge-base
为了确定该分支与当前分支之间的最新共享提交.