我想从线性提交树中删除选定的提交日志条目,以便条目不会显示在提交日志中。
我的提交树看起来像:
R--A--B--C--D--E--HEAD
我想删除B和C条目,以便它们不会在提交日志中显示,但应保留从A到D的更改。也许通过引入一个提交,使B和C成为BC并且树看起来像。
R--A--BC--D--E--HEAD
或者,理想情况下,A直接来自D. D'表示从A到B,B到C和C到D的变化。
R--A--D'--E--HEAD
这可能吗?如果有,怎么样?
这是一个相当新的项目,所以目前没有分支,因此也没有合并。
答案 0 :(得分:267)
git-rebase(1)正是如此。
$ git rebase -i HEAD~5
git awsome-ness [git rebase --interactive]包含一个示例。
git-rebase
。commit
或stash
您当前的更改。$EDITOR
。pick
替换为C
,将D
替换为squash
。它将C和D合并为B.如果要删除提交,则只需删除它的行。如果您迷路了,请输入:
$ git rebase --abort
答案 1 :(得分:72)
# detach head and move to D commit
git checkout <SHA1-for-D>
# move HEAD to A, but leave the index and working tree as for D
git reset --soft <SHA1-for-A>
# Redo the D commit re-using the commit message, but now on top of A
git commit -C <SHA1-for-D>
# Re-apply everything from the old D onwards onto this new place
git rebase --onto HEAD <SHA1-for-D> master
答案 2 :(得分:39)
这是一种删除特定提交ID的方法,只知道您要删除的提交ID。
git rebase --onto commit-id^ commit-id
请注意,这实际上删除了提交引入的更改。
答案 3 :(得分:19)
扩展J.F. Sebastian的回答:
您可以使用git-rebase轻松对提交历史记录进行各种更改。
运行git rebase --interactive之后,你在$ EDITOR中得到以下内容:
pick 366eca1 This has a huge file
pick d975b30 delete foo
pick 121802a delete bar
# Rebase 57d0b28..121802a onto 57d0b28
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
您可以移动行来更改提交顺序并删除行以删除该提交。或者您可以添加一个命令将两个提交组合(压缩)到一个提交(先前的提交是上面的提交),编辑提交(更改的内容)或重写提交消息。
我认为选择只是意味着您想单独留下该提交。
(示例来自here)
答案 4 :(得分:14)
您可以通过以下方式非交互式删除 B和C:
git rebase --onto HEAD~5 HEAD~3 HEAD
或象征性地
git rebase --onto A C HEAD
请注意,B和C的变化不在D中;他们将消失。
答案 5 :(得分:3)
还有一种方式,
git rebase -i ad0389efc1a79b1f9c4dd6061dca6edc1d5bb78a (C's hash)
and
git push origin master -f
选择你想用它作为基础的哈希,上面的命令应该使它具有交互性,这样你就可以压缩所有顶部消息(你需要留下最旧的)
答案 6 :(得分:2)
通过从A的SHA1创建另一个分支并挑选所需的更改,我发现这个过程更安全,更容易理解,因此我可以确保我对这个新分支的外观感到满意。之后,很容易删除旧分支并重命名新分支。
git checkout <SHA1 of A>
git log #verify looks good
git checkout -b rework
git cherry-pick <SHA1 of D>
....
git log #verify looks good
git branch -D <oldbranch>
git branch -m rework <oldbranch>
答案 7 :(得分:0)
刚刚收集了所有人的答案:(我是git plz的新手,仅供参考)
git log
-first check from which commit you want to rebase
git rebase -i HEAD~1
-Here i want to rebase on the second last commit- commit count starts from '1')
-this will open the command line editor (called vim editor i guess)
然后屏幕看起来像这样:
选择0c2236d添加新行。
Rebase 2a1cd65..0c2236d到2a1cd65(1个命令)
#
命令:
p,pick = use commit
r,reword =使用提交,但编辑提交消息
e,edit =使用提交,但停止修改
s,squash =使用提交,但融入先前的提交
f,fixup = like“squash”,但丢弃此提交的日志消息
使用shellx,exec = run命令(行的其余部分)
d,drop =删除提交
#
这些行可以重新排序;它们是从上到下执行的。
#
如果你在这里删除一行,那么COMMIT将会丢失。
#
但是,如果删除所有内容,则将终止rebase。
#
请注意,空提交已注释掉~~
〜
〜
〜
〜
〜
〜
〜
〜
〜
根据您的需要更改第一行(使用上面列出的命令,即'drop'删除提交等) 完成编辑后按':x'保存并退出编辑器(这仅适用于vim编辑器)
然后
git push
如果显示问题,那么你需要强行将更改推送到远程(非常关键:如果你在团队中工作,不要强行推送)
git push -f origin
答案 8 :(得分:-1)
你可以使用git cherry-pick。 'cherry-pick'会将提交应用到您现在的分支上。
然后做
git rebase --hard <SHA1 of A>
然后应用D和E提交。
git cherry-pick <SHA1 of D>
git cherry-pick <SHA1 of E>
这将跳过B和C提交。已经说过,如果没有B,可能无法将D提交应用于分支,所以YMMV。