如何修改旧的 Git 提交? [复制]
Posted
技术标签:
【中文标题】如何修改旧的 Git 提交? [复制]【英文标题】:How to amend older Git commit? [duplicate] 【发布时间】:2012-02-08 03:29:20 【问题描述】:我做了 3 次 git 提交,但没有被推送。 如何修改不是最新的旧的 (ddc6859af44) 和 (47175e84c)?
$git log
commit f4074f289b8a49250b15a4f25ca4b46017454781
Date: Tue Jan 10 10:57:27 2012 -0800
commit ddc6859af448b8fd2e86dd0437c47b6014380a7f
Date: Mon Jan 9 16:29:30 2012 -0800
commit 47175e84c2cb7e47520f7dde824718eae3624550
Date: Mon Jan 9 13:13:22 2012 -0800
【问题讨论】:
请说明您是否想将这 2 个提交合并为 1 个提交,或者您是否想通过进一步的更改来修改每个提交。 我已经为此目的创建了一个 Bash 脚本:github.com/colinodell/git-amend-old 安装后,您可以像这样使用它:git amend-old abcd123
,其中abcd123
是您想要通过分阶段更改修改的旧提交。希望有人觉得它有用!
【参考方案1】:
您可以使用git rebase
重写提交历史。这可能会对您的更改造成潜在破坏,因此请谨慎使用。
首先将您的“修改”更改作为正常提交提交。然后从最旧提交的父级开始进行交互式变基
git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^
这将通过所有提交启动您的编辑器。重新排序它们,以便您的“修改”提交低于您要修改的提交。然后用 s
将行中的第一个单词替换为“修改”提交,这会将 (s quash) 与之前的提交结合起来。保存并退出编辑器并按照说明进行操作。
【讨论】:
他不想压缩或重新排序提交。 @AdamDymitruk:他在哪里说的?顺便说一句,您的回答还建议改写历史。 @AdamDymitruk:修改是提交和压缩最后两个提交的简写。两者都更改了提交 SHA1(“重写历史记录”)。如果我有错误的心理图片,请教育我。 我已对请求 OP 澄清的问题添加了评论。正如它现在所读的那样,我将其解释为他想要更改这 2 个提交而不是压缩或重新排序它们。 amend 添加到最后一次提交 - 无论您是否在变基中。 Squash 需要 2 个现有提交并将它们变成 1 个。我错过了什么?【参考方案2】:您可以使用git rebase --interactive
,在要修改的提交上使用edit
命令。
【讨论】:
【参考方案3】:git rebase -i HEAD^^^
现在用edit
或e
标记您要修改的那些(替换pick
)。现在保存并退出。
现在进行更改,然后
git add .
git rebase --continue
如果您想添加额外的删除,请从 commit 命令中删除选项。如果要调整消息,请仅省略 --no-edit
选项。
【讨论】:
使用git stash
或 git stash [-p|--patch]
(交互式)在 rebase 期间轻松地将更改应用到较旧的提交可能会很方便。
注意 - 你不必在 git add -A 之后 git commit,只需 git rebase --continue 会保留你的更改。
no matches found: HEAD^^^
@kleinfreund 两年后你可能已经解决了这个问题,但是对于其他任何人(比如我)来说,有这个问题:一些 shell(比如 zsh)将 ^
解析为一个模式。在这种情况下,您可以改用~
。
@DarkFranX "HEAD^^^" 表示“头部前 3 次提交”【参考方案4】:
如果 OP 想要将指定的 2 个提交压缩为 1 个,这里是另一种无需变基的替代方法
git checkout HEAD^ # go to the first commit you want squashed
git reset --soft HEAD^ # go to the second one but keep the tree and index the same
git commit --amend -C HEAD@1 # use the message from first commit (omit this to change)
git checkout HEAD@3 -- . # get the tree from the commit you did not want to touch
git add -A # add everything
git commit -C HEAD@3 # commit again using the message from that commit
@N)
语法很容易知道,因为它可以让您引用您的引用所在的历史记录。在这种情况下,它是 HEAD 代表您当前的提交。
【讨论】:
【参考方案5】:我准备了我的提交,我想用一个旧的进行修改,并且惊讶地看到变基 - 我抱怨我有未提交的更改。但是我不想再次指定旧提交的编辑选项进行更改。所以解决方案非常简单明了:
-
准备更新到旧提交,添加并提交
git rebase -i <commit you want to amend>^
- 请注意 ^
,以便您在文本编辑器中看到上述提交
你会得到这样的东西:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
pick e23d23a fix indentation of jgroups.xml
现在将 e23d23a 与 8c83e24 结合起来,您可以更改线路顺序并像这样使用壁球:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
squash e23d23a fix indentation of jgroups.xml
pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
写入并退出文件,您将看到一个编辑器来合并提交消息。这样做并保存/退出文本文档
您已完成,您的提交已修改归功于:http://git-scm.com/book/en/Git-Tools-Rewriting-History 还有其他有用的演示 git 魔法。
【讨论】:
我没有意识到我可以重新排序变基文件中的行。很棒的提示! 如果有人不熟悉在终端编辑文件的vi命令,这个页面是一个很好的参考cs.colostate.edu/helpdocs/vi.html @DanBechard 重新排序行时要小心:如果您不小心剪切并忘记粘贴:该提交已消失!【参考方案6】:我用过另一种方式好几次了。事实上,它是一本手册 git rebase -i
,当您想要重新排列多个提交(包括压缩或拆分其中一些)时,它很有用。主要优点是您不必一次决定每个提交的命运。在此过程中,您还将拥有所有可用的 Git 功能,这与变基期间不同。例如,您可以随时显示原始历史和重写历史的日志,甚至可以进行另一个 rebase!
我将通过以下方式引用提交,因此它易于阅读:
C # good commit after a bad one
B # bad commit
A # good commit before a bad one
一开始你的历史是这样的:
x - A - B - C
| |
| master
|
origin/master
我们将以这种方式重新创建它:
x - A - B*- C'
| |
| master
|
origin/master
程序
git checkout B # get working-tree to the state of commit B
git reset --soft A # tell Git that we are working before commit B
git checkout -b rewrite-history # switch to a new branch for alternative history
现在使用git add
(git add -i
、git stash
等)改进您的旧提交。您甚至可以将旧的提交拆分为两个或更多。
git commit # recreate commit B (result = B*)
git cherry-pick C # copy C to our new branch (result = C')
中间结果:
x - A - B - C
| \ |
| \ master
| \
| B*- C'
| |
| rewrite-history
|
origin/master
让我们结束吧:
git checkout master
git reset --hard rewrite-history # make this branch master
或者只使用一个命令:
git branch -f master # make this place the new tip of the master branch
就是这样,你现在可以push
你的进度了。
最后的任务是删除临时分支:
git branch -d rewrite-history
【讨论】:
以上是关于如何修改旧的 Git 提交? [复制]的主要内容,如果未能解决你的问题,请参考以下文章