说我有一个git存储库,我一直在做master,我可以追溯创建一个分支。例如:
A - B - C - A1 - D - A2 - E
我想让它看起来像这样:
A - A1 - A2
\ \
B - C - D - E
具体的用例是当我在旧版本分支中挑选了一堆提交时,它需要进入多个旧版本,并且我不想重复所有这些版本的樱桃选择。
基本上,它首先作为一个功能或主题分支是好的,但不是那样创建的。
答案 0 :(得分:100)
如果您希望修订版XXX之后的所有提交都发生在分支中,我发现这比其他提议的方法容易得多。
$ git branch fixes # copies master to new branch
$ git reset --hard XXX # resets master to XXX
在git的“{撤消提交,使其成为主题分支”下的reset
帮助页面中对此进行了描述。
答案 1 :(得分:19)
当然可以。 (对于Git,没有什么比你不能做的更多。:)
git checkout -b new-branch hash-of-A
git cherry-pick hash-of-A1
git cherry-pick hash-of-A2
这将从提交A
开始创建一个新分支。然后再次返回相同的提交,创建另一个分支:
git checkout -b new-branch2 hash-of-A
git cherry-pick hash-of-B
git cherry-pick hash-of-C
git cherry-pick hash-of-D
git cherry-pick hash-of-E
git merge new-branch
现在您只需合并new-branch
和new-branch2
即可获得所需的结构并删除旧分支。
当然Dustin所说的仍然存在:提交的哈希值会发生变化,所以如果你还没有公布你的更改,你应该这样做。
答案 2 :(得分:6)
你不能透明地做到这一点,因为哈希必须改变,但你基本上只需要分支HEAD和rebase -i两个分支来删除相应的变化。
答案 3 :(得分:1)
您要做的是实际重写历史记录。提交的标识符会发生变化,在某些情况下,提交给出的变更集会发生变化。因此,如果某个人有可能根据您想要更改的旧版本分支进行工作,那么最好不要这样做。但如果你没有发布这个分支,请随意。
让我们假设我们想要改变的分支被命名为'master',并且我们想要开始新分支的点被命名为'A'(在给定的示例中,您可以使用的名称之一是'master~6 “)。
首先,让我们从提交'A'创建新分支,让它命名为'fixes'
$ git checkout -b fixes A
这也会使分支'修复'成为现实。因为只有少数提交我们想要取消选择,我们可以在分支'修复'上挑选它们:
$ git cherry-pick A1
$ git cherry-pick A2
然后我们要从分支'master'中删除提交'A1'和'A2'。因为我们想删除的提交只有少数,而且我们想要保留的更多,我们可以使用'git rebase --interactive'来实现:
$ git rebase -i fixes master
在提交'A'之后,编辑器将被'master'中的所有提交激活(这是常见提交,即分支'master'和分支'fixes'的合并基础)。列表看起来像这样:
pick deadbee B
pick fa1afe1 C
pick a98d4ba A1
...
删除提交'A1'和'A2'的行,保存更改,关闭编辑器(或以其他方式发送更改为inetractive rebase),git将重新应用除已删除的提交之外的所有提交。
然后你可以用
完成$ git merge fixes
(git-rebase让我们重写了分支'master')。
答案 4 :(得分:0)
忘记挑选所有的樱桃。只需重新定义-i两次省略更改,每次创建一个新分支然后合并2。