如何在保持更改的同时从Git存储库中删除选定的提交日志条目?

时间:2009-01-30 12:23:01

标签: git commit

我想从线性提交树中删除选定的提交日志条目,以便条目不会显示在提交日志中。

我的提交树看起来像:

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

这可能吗?如果有,怎么样?

这是一个相当新的项目,所以目前没有分支,因此也没有合并。

9 个答案:

答案 0 :(得分:267)

git-rebase(1)正是如此。

$ git rebase -i HEAD~5

git awsome-ness [git rebase --interactive]包含一个示例。

  1. 不要在公共(远程)提交上使用git-rebase
  2. 确保您的工作目录干净(commitstash您当前的更改。
  3. 运行以上命令。它会启动您的$EDITOR
  4. pick替换为C,将D替换为squash。它将C和D合并为B.如果要删除提交,则只需删除它的行。
  5. 如果您迷路了,请输入:

    $ 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 rebase删除任何提交

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”,但丢弃此提交的日志消息

     使用shell

x,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。