我们的一些开发人员已经在主服务器上提交了非工作提交。我想清理它,以便主服务器上的每个提交都是一个工作版本。
假设我们有以下提交:
A - B - C - D - E - F
如何将一个或多个提交提取到另一个分支:
A - B E - F
\ /
C - D
编辑:
答案 0 :(得分:2)
执行:
git rebase -i B
然后您可以从B中引入的提交中进行选择。
-i
标志代表交互式,这意味着编辑器将显示(默认情况下为vi
,就像编辑提交消息时一样)提交每一行。您可以删除一行以跳过提交,替换提交顺序,甚至将两个或多个提交合并为一个提交。
更多信息可以在官方git文档的第Rewriting History章中找到。
答案 1 :(得分:1)
由于您似乎能够容忍重写master
分支的历史记录,尽管它是公开的(并且可能被许多开发人员使用),您可以考虑以下策略:
git cherry-pick
C
和D
按顺序提交到新分支git rebase --interactive
master
分支删除C
和D
提交首先选择C
和D
提交到新分支:
git checkout new_branch
git cherry-pick dk8cnj2
git cherry-pick dn52bd6
这里,cherry-pick
之后看起来很滑稽的字符串实际上是C
和D
提交的SHA-1哈希,q.v。下面。这就是你告诉Git引用实际提交的方法。
现在您已经抢救了C
和D
提交,您可以启动交互式rebase以将其从master
分支中删除:
git rebase -i HEAD~4
这应该会显示一个编辑器,按照从最旧到最新的顺序显示最近4次提交的列表(参见HEAD~4
),如下所示:
pick dk8cnj2 Commit C
pick dn52bd6 Commit D
pick 9m38b2f Commit E
pick ldkj093 Commit F
删除(即删除)提交C
和D
的行,在编辑器中留下以下内容:
pick 9m38b2f Commit E
pick ldkj093 Commit F
然后保存文件,关闭它,继续rebase。在此之后,您将有效地从C
分支拼接出D
和master
次提交。现在,既然你在本地做了这个,并且因为你也重写了master
的历史,你将不得不强制将其推送到存储库:
git push --force origin
请记住,这将重写 master
分支的历史记录,可能会导致与该分支机构合作的其他任何人产生混淆。解决这个问题的一种方法是告诉每个人在一天结束时冻结master
上的工作,然后完成交互式rebase。第二天早上,每个人都删除了他们当地的master
并结帐了新的副本。
答案 2 :(得分:0)
TMG给出的交互式rebase的另一个解决方案是在master上创建一个临时分支,重置master来提交B,并挑选你需要保留的所有提交。
它给你这些命令。警告:确保没有当前更改或存储它们。
// Starting point
git checkout master
// Create a new branch to avoid loosing some commit
git branch tmp
// Change master HEAD
git reset --hard master commit_B
// Get the commits you want
git cherry-pick commit_E
git cherry-pick commit_F
// DONE, you can clean up tmp branch if you don't need commit C and D (you will loose them)
git branch -D tmp