git 是否可以追溯地将一组提交变成一个分支?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/364925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to retroactively turn a set of commits into a branch?
提问by Otto
Say I have a git repository and I've been working on master, can I retroactively create a branch. For example:
假设我有一个 git 存储库并且我一直在研究 master,我可以追溯创建一个分支。例如:
A - B - C - A1 - D - A2 - E
A - B - C - A1 - D - A2 - E
I want to make it look like this:
我想让它看起来像这样:
A - A1 - A2
\ \
B - C - D - E
The specific use case is when I've cherry-picked a bunch of commits into an old version branch and it needs to go into multiple older versions and I don't want to repeat the cherry-pick on all those revision.
具体用例是当我将一堆提交挑选到一个旧版本分支时,它需要进入多个旧版本,我不想在所有这些修订版上重复挑选。
Essentially it's something that would have been good as a feature or topic branch in the first place but wasn't created like that.
从本质上讲,它本来可以作为功能或主题分支放在首位,但不是这样创建的。
采纳答案by Bombe
Of course you can. (With Git there isn't much than you can't do anyway. :)
当然可以。(使用 Git,您无能为力。:)
git checkout -b new-branch hash-of-A
git cherry-pick hash-of-A1
git cherry-pick hash-of-A2
This will create a new branch, starting from the commit A. Afterwards you go back to the same commit again, creating another branch:
这将从 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
Now you simply have to merge new-branchand new-branch2to get the structure you want and drop your old branch.
现在您只需合并new-branch并new-branch2获得所需的结构并删除旧分支。
Of course what Dustin said still holds: the hashes of the commits will change so you should only do that if you haven't published your changes yet.
当然,Dustin 所说的仍然成立:提交的哈希值会发生变化,因此只有在您尚未发布更改时才应该这样做。
回答by alltom
If you want all the commits after revision XXX to have happened in a branch, I find this a lot easier than the other proposed methods.
如果您希望修订 XXX 之后的所有提交都发生在一个分支中,我发现这比其他建议的方法容易得多。
$ git branch fixes # copies master to new branch
$ git reset --hard XXX # resets master to XXX
This is described in git's help page for resetunder "Undo a commit, making it a topic branch".
这在 git 的帮助页面中的reset“撤消提交,使其成为主题分支”下进行了描述。
回答by Dustin
You can't do that transparently because the hashes will have to change, but you basically just need to branch HEAD and rebase -i both branches to drop the respective changes.
你不能透明地这样做,因为散列必须改变,但你基本上只需要分支 HEAD 和 rebase -i 两个分支来删除相应的更改。
回答by Jakub Nar?bski
What you want to do is to actually rewritehistory. The identifiers of commits would change, and in some cases the changeset given by commits would change. So if there is a chance that somebody could have based work on old version of the branch you want to change, better to not do this. But if you didn't publish this branch, feel free.
你要做的是真正改写历史。提交的标识符会改变,在某些情况下,提交给出的变更集会改变。因此,如果有人可能基于您想要更改的旧版本分支进行工作,最好不要这样做。但是如果你没有发布这个分支,请随意。
Let us assume that a branch we want to change is named 'master', and that the point where we want to start new branch is named 'A' (in given example one of names you can use is 'master~6').
让我们假设我们要更改的分支名为“master”,并且我们要开始新分支的点名为“A”(在给定的示例中,您可以使用的名称之一是“master~6”)。
First, lets create new branch from commit 'A', let's name it 'fixes'
首先,让我们从提交“A”创建新分支,让我们将其命名为“修复”
$ git checkout -b fixes A
This would also make branch 'fixes' current. Because there are only a few commits that we want to un-cherry-pick, we can cherry pick them on branch 'fixes':
这也将使分支“修复”成为当前。因为只有少数提交我们想要取消樱桃挑选,我们可以在分支“修复”上挑选它们:
$ git cherry-pick A1
$ git cherry-pick A2
Then we want to remove commits 'A1' and 'A2' from branch 'master'. Because there are only a few commits we want to remove, and possibly many more we want to keep, we eould use 'git rebase --interactive' for that:
然后我们想从分支“master”中删除提交“A1”和“A2”。因为只有少数提交我们想要删除,而且可能还有更多我们想要保留,所以我们可以使用 'git rebase --interactive' :
$ git rebase -i fixes master
An editor will be fired up with all the commits in 'master' after commit 'A' (which is common commit i.e. merge base of branch 'master' and branch 'fixes'). The list would look like this:
在提交“A”(这是常见提交,即分支“master”和分支“fixes”的合并基础)之后,编辑器将被“master”中的所有提交启动。该列表将如下所示:
pick deadbee B
pick fa1afe1 C
pick a98d4ba A1
...
Remove lines with commits 'A1' and 'A2', save changes, close editor (or otherwise send changes to inetractive rebase) and git would reapply all commits except those that you have deleted.
删除提交“A1”和“A2”的行,保存更改,关闭编辑器(或以其他方式将更改发送到 intractive rebase)和 git 将重新应用所有提交,除了您已删除的提交。
Then you can finalize with
然后你可以完成
$ git merge fixes
(git-rebase left us on rewritten branch 'master').
(git-rebase 将我们留在重写的分支“master”上)。
回答by Adam Dymitruk
Forget all that cherry-picking. Just rebase -i twice omitting the changes, making a new branch each time and then merging the 2.
忘记所有的樱桃采摘。只需 rebase -i 两次忽略更改,每次创建一个新分支,然后合并 2.

