18

是否可以使用 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

有没有办法解决它,或者我是否坚持在新的重新提交提交上重新创建分支?

4

4 回答 4

5

根据 git 的对象模型,如果您只更改提交的元数据(即提交消息)而不更改其中包含的底层数据(“树”),那么它的树哈希将保持不变。

除了编辑提交消息之外,您还执行了变基,这将更改历史记录中每个提交的树哈希,因为从中提取的任何更改origin/master都会影响您重写历史记录中的文件:这意味着一些文件 ( blobs),您的提交指向已更改。

所以没有万无一失的方法来做你想做的事。

也就是说,编辑提交rebase -i通常不会更改提交的时间戳和作者,因此您可以使用它来唯一地标识您在变基操作之前和之后的提交。

在进行变基之前,您必须编写一个脚本,根据这些“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属于两个分支!

于 2010-06-16T13:11:01.947 回答
2

我不确定您是如何到达那里的,但是:

git branch -f (same changeset as featureA-finished)

应该足以featureA-finished用正确的历史记录重置您的分支。

于 2010-04-28T17:53:48.180 回答
2

看起来这个功能正在慢慢进入 git。rebase将获得--rebase-refs完全按照我最初的回答所要求的选项。对于建议的补丁系列,请参见 gmane 上的线程rebase: command "ref" 和 options --rewrite-{refs,heads,tags}

于 2011-06-27T07:39:42.070 回答
1

我的建议是先重新featureA-finished定位origin/master。然后执行改写步骤。之后,重新定位masterfeatureA-finished. 这将为您提供您想要的最终结果。

请注意,您需要在两个变基上都使用,并且可能必须在第二个变基中-i删除原始的所有提交。featureA-finshed如果您愿意,您可以编写一个脚本,通过保存中间分支并将其用作--onto重新设置新版本的基础来消除这种情况。如果你写得对,它甚至可以处理一系列这样的“子分支”。如果您需要帮助,我可以尝试解决问题。

于 2010-06-15T17:31:29.783 回答