如何从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

这可能吗?如果是,怎么做?

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

220367 次浏览

git-rebase (1)正是这样做的。

$ git rebase -i HEAD~5

Git awesome -ness [Git rebase -interactive]包含一个例子。

  1. 不要在公共(远程)提交上使用git-rebase
  2. 确保您的工作目录是干净的(commitstash您当前的更改)。
  3. 执行上述命令。它会启动你的$EDITOR
  4. squash替换pick之前的CD。它会将C和D合并为b。如果你想删除一个提交,那么只需删除它的行。

如果你迷路了,输入:

$ 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

你可以使用git进行选择。'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。

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

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

或象征性的,

git rebase --onto A C HEAD

注意,B和C中的变化将放在D中;它们将是走了

进一步解释一下J.F.塞巴斯蒂安的回答:

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

您可以移动行来更改提交的顺序,也可以删除行来删除提交。或者您可以添加一个命令将两个提交合并(压缩)为一个提交(以前的提交就是上面的提交)、编辑提交(更改的内容)或改写提交消息。

我认为选择只是意味着你不想去做承诺。

(示例来自在这里)

下面是一种删除特定提交id的方法,只知道您想删除的提交id。

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

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

我发现这个过程更安全,更容易理解,从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>

还有一种方法,

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

选择你想要使用它作为基础的哈希,上面的命令应该使它具有交互性,这样你就可以压缩所有消息(你需要留下最古老的)

刚刚收集了所有人的答案:(我是git的新手,请仅供参考)

Git重基删除任何提交

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)

然后屏幕看起来会是这样的:

新增一行。

变基2 a1cd65 . .0c2236d onto 2a1cd65(1个命令)

命令:

P,选择=使用提交

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

E,编辑=使用提交,但停止修改

S, squash =使用提交,但合并到以前的提交

F, fixup = like "squash",但丢弃此提交的日志消息

X, exec = run命令(其余的行)使用shell

D, drop =删除提交

这些线路可以重新排序;它们从上到下执行。

如果你在这里删除一行,提交将会丢失。

但是,如果您删除了所有内容,则重基操作将会中止。

注意,空提交会被注释掉~ ~

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

然后

git推

如果它的显示问题,那么你需要强行将更改推到远程(非常关键:如果你是团队工作,不要强行推)

Git push -f origin