我想从线性提交树中删除选定的提交日志项,这样这些项就不会显示在提交日志中。

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

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 awesome -ness [Git rebase——interactive]包含了一个例子。

不要在公共(远程)提交上使用git-rebase。 确保您的工作目录是干净的(提交或保存当前的更改)。 执行上述命令。它会启动你的$编辑器。 将C和D之前的pick替换为squash。它会将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-rebase(1)正是这样做的。

$ git rebase -i HEAD~5

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

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

如果你迷路了,输入:

$ git rebase --abort  

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

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

或象征性的,

git rebase --onto A C HEAD

注意,B和C的变化不会出现在D中;他们会走的。

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