是否可以使用git中的所有子分支来重新分支分支?
我经常使用分支作为快速/可变标记来标记某些提交。
* master
*
* featureA-finished
*
* origin/master
现在我想rebase -i
master
到origin/master
,更改/重新提交提交featureA-finished^
在git rebase -i --onto origin/master origin/master master
之后,我基本上希望历史记录为:
* master
*
* featureA-finished
* (changed/reworded)
* origin/master
但我得到的是:
* master
*
* (same changeset as featureA-finished)
* (changed/reworded)
| * featureA-finished
|.* (original commit i wanted to edit)
* origin/master
有没有办法绕过它,或者我是否仍然坚持在新的重新提交的作品上重新创建分支?
答案 0 :(得分:5)
根据git的Object Model,如果你只改变提交的元数据(即提交消息)但不包含其中包含的底层数据(“树”),那么它的树形散列将保持不变
除了编辑提交消息之外,您还执行了一个rebase,它将更改历史记录中每个提交的Tree哈希值,因为从origin/master
拉出的任何更改都会影响重写历史记录中的文件:这意味着您的提交指向的某些文件(blob)已更改。
所以没有防弹方法可以做你想做的事。
也就是说,使用rebase -i
编辑提交通常不会改变提交的时间戳和作者,因此您可以使用它来唯一地标识在rebase操作之前和之后的提交。
在执行rebase之前,您必须编写一个脚本来记录针对这些“timestamp:author”标识符的所有分支起始点,然后找到具有相同“timestamp:author”ID的重写提交并重新分支该分支在它上面。
可悲的是,我现在没有时间尝试自己编写这个脚本,所以我只能祝你好运!
修改:您可以使用以下方式获取作者电子邮件地址和时间戳:
$ git log --graph --all --pretty=format:"%h %ae:%ci"
* 53ca31a robert.meerman@gmail.com:2010-06-16 13:50:12 +0100
* 03dda75 robert.meerman@gmail.com:2010-06-16 13:50:11 +0100
| * a8bb03a robert.meerman@gmail.com:2010-06-16 13:49:46 +0100
| * b93e59d robert.meerman@gmail.com:2010-06-16 13:49:44 +0100
|/
* d4214a2 robert.meerman@gmail.com:2010-06-16 13:49:41 +0100
您可以根据提交哈希值获取每个分支的列表:
$ git branch --contains 03dda75
* testbranch
每次提交时注意多个分支,共同的祖先d4214a2
属于两个分支!
答案 1 :(得分:2)
我不确定你到底是怎么回事,但是:
git branch -f (same changeset as featureA-finished)
应足以重置具有正确历史记录的featureA-finished
分支。
答案 2 :(得分:2)
看起来这个功能正慢慢进入git。 rebase
将获得--rebase-refs
选项,该选项将完全按我原来的答案提出。对于拟议的补丁系列,请参阅gmane上的线程rebase: command "ref" and options --rewrite-{refs,heads,tags}。
答案 3 :(得分:1)
我建议首先将featureA-finished
重新加入origin/master
。然后进行重新编写步骤。之后,将master
变为featureA-finished
。这将为您提供您想要的最终结果。
请注意,您需要在两个rebase上使用-i
,并且可能必须删除第二个rebase中原始featureA-finshed
向下的所有提交。如果您愿意,您可以编写一个脚本,通过保存中间分支并将其用作新版本的基础--onto
来消除此问题。如果你写得正确,它甚至可以处理一系列这样的“子分支”。如果你需要帮助,我可以尝试敲打一个。