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

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

我的提交树看起来像这样:

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 

这可能吗? 如果是的话,怎么样?

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

git-rebase(1)就是这么做的。

 $ git rebase -i HEAD~5 

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

  1. 公共(远程)提交不要使用git-rebase
  2. 确保你的工作目录是干净的( commitstash你当前的改变)。
  3. 运行上面的命令。 它启动你的$EDITOR
  4. CD之前用squashreplace。 它将把C和D融合到B中。如果你想删除一个提交,那么就删除它的行。

如果你输了,input:

 $ git rebase --abort 
 # 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 

这是一个方法来删除特定的提交ID只知道你想删除的提交ID。

 git rebase --onto commit-id^ commit-id 

请注意,这实际上删除了提交引入的更改。

为了扩展JF塞巴斯蒂安的答案:

您可以使用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 

您可以移动行来更改提交的顺序并删除行以删除该提交。 或者你可以添加一个命令来合并(挤压)两个提交到一个提交(以前的提交是上面的提交),编辑提交(改变了什么)或reword提交消息。

我认为,只是意味着你想单独提交。

(例子来自这里 )

你可以非交互式地移除你的例子中的 B和C:

 git rebase --onto HEAD~5 HEAD~3 HEAD 

或象征性地,

 git rebase --onto AC HEAD 

请注意,B和C中的更改不会在D中; 他们将会消失

通过从A的SHA1创build另一个分支并挑选所需的更改,我发现这个过程更安全,更容易理解,所以我可以确保我对这个新分支的外观感到满意。 之后,很容易删除旧的分支并重命名新分支。

 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> 

还有一种方法,

 git rebase -i ad0389efc1a79b1f9c4dd6061dca6edc1d5bb78a (C's hash) and git push origin master -f 

select你想用它作为基础的散列,上面的命令应该使它交互,所以你可以挤压所有的顶部消息(你需要离开最古老的)

你可以使用git樱桃select这个。 “樱桃select”将现在应用到分支上。

然后做

 git rebase --hard <SHA1 of A> 

然后应用D和E提交。

 git cherry-pick <SHA1 of D> git cherry-pick <SHA1 of E> 

这将跳过B和C提交。 话虽如此,可能不可能将D提交应用于没有B的分支,所以YMMV。

刚刚收集了所有人的答案:( m新的git plz使用它仅供参考)

git rebase删除任何提交

git日志

 -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) 

然后屏幕会看起来像这样:

select0c2236d添加新行。

将2a1cd65..0c2236d重新映射到2a1cd65(1个命令)

命令:

p,pick =使用提交

r,reword =使用提交,但编辑提交消息

e,edit =使用提交,但停止修改

s,squash =使用提交,但融入到以前的提交

f,fixup = like“squash”,但放弃这个提交的日志消息

x,exec =运行命令(该行的其余部分)使用shell

d,drop =删除提交

这些线可以重新sorting; 他们是从上到下执行的。

如果你在这里删除一行,那么这个COMMIT将会丢失。

但是,如果您删除了所有内容,那么rebase将被中止。

注意空提交被注释掉了〜〜









这里根据你的需要改变第一行(使用上面列出的命令,即'drop'删除提交等)。完成编辑后按':x'保存并退出编辑器(这仅适用于vim编辑器)

接着

混帐推

如果它显示的问题,那么你需要强制推动变化远程(其非常关键:如果你在团队工作,不要强迫推)

git push -f原点