繁体   English   中英

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

[英]How to remove selected commit log entries from a Git repository while keeping their changes?

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

我的提交树看起来像:

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之前的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

这是一种仅知道您要删除的提交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

您可以移动行以更改提交的顺序,也可以删除行以删除该提交。 或者,您可以添加命令以将两个提交合并(压缩)为单个提交(先前的提交是上述提交),编辑提交(已更改的内容)或重新编写提交消息。

我认为选择只是意味着您想不考虑该承诺。

(示例从这里开始

您可以使用以下示例非交互式地删除 B和C:

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

或象征性地

git rebase --onto A C HEAD

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

还有一种方法

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

选择要用作基础的哈希,上面的命令应该使其具有交互性,以便可以压缩所有顶部消息(您需要保留最旧的消息)

通过从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 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)

然后屏幕将如下所示:

选择0c2236d添加了新行。

将2a1cd65..0c2236d重新设置为2a1cd65(1个命令)

命令:

p,选择=使用提交

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

e,编辑=使用提交,但停止进行修改

s,squash =使用提交,但可以合并到先前的提交中

f,fixup =类似于“ squash”,但丢弃此提交的日志消息

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

d,drop =删除提交

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

如果您在此处删除一行,那将丢失。

但是,如果删除所有内容,则重新定位将中止。

注意,空的提交被注释掉了~~









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

接着

git推

如果显示问题,则需要将更改强制推送到远程(非常重要:如果您在团队中工作,请不要强制推送)

git push -f起源

您可以为此使用git cherry-pick。 'chery-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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM