假设我有一个 git 存储库并且我一直在做 master,我可以追溯创建一个分支吗?例如:
A - B - C - A1 - D - A2 - E
我想让它看起来像这样:
A - A1 - A2
\ \
B - C - D - E
具体的用例是当我将一堆提交挑选到旧版本分支中并且它需要进入多个旧版本并且我不想在所有这些修订上重复挑选时。
从本质上讲,它本来可以作为一个特性或主题分支,但不是这样创建的。
如果您希望修订 XXX 之后的所有提交都发生在分支中,我发现这比其他建议的方法容易得多。
$ git branch fixes # copies master to new branch
$ git reset --hard XXX # resets master to XXX
提交现在仅在“修复”分支中。
此过程在 git 的帮助页面中的reset
“撤消提交,使其成为主题分支”下进行了描述。
当然可以。(使用 Git 没有什么是你做不到的。:)
git checkout -b new-branch hash-of-A
git cherry-pick hash-of-A1
git cherry-pick hash-of-A2
这将创建一个新分支,从 commit 开始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 所说的仍然有效:提交的哈希值会发生变化,所以只有在尚未发布更改的情况下才应该这样做。
你不能透明地做到这一点,因为哈希必须改变,但你基本上只需要分支 HEAD 和 rebase -i 两个分支来删除相应的更改。
你要做的是真正改写历史。提交的标识符会改变,在某些情况下,提交给出的变更集也会改变。因此,如果有人可能基于您想要更改的旧版本分支的工作,最好不要这样做。但是,如果您没有发布此分支,请随意。
假设我们要更改的分支名为“master”,并且我们要开始新分支的点名为“A”(在给定的示例中,您可以使用的名称之一是“master~6”)。
首先,让我们从提交“A”创建新分支,我们将其命名为“修复”
$ git checkout -b fixes A
这也将使分支“修复”成为当前的。因为只有少数提交是我们想要 un-cherry-pick 的,所以我们可以在分支 'fixes' 上挑选它们:
$ 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”的行,保存更改,关闭编辑器(或以其他方式将更改发送到无效的变基),git 将重新应用所有提交,除了那些您已删除的提交。
然后你可以完成
$ git merge fixes
(git-rebase 将我们留在了重写的分支“master”上)。
忘记所有的樱桃采摘。只需 rebase -i 两次忽略更改,每次创建一个新分支,然后合并 2.