乐闻世界logo
搜索文章和话题

Git 如何修改特定的提交

9 个月前提问
5 个月前修改
浏览次数84

6个答案

1
2
3
4
5
6

当您想要修改特定的提交时,Git 提供了一些工具来帮助您实现这个目的。以下是几种常见的方法:

1. git commit --amend

如果您刚刚做了一个提交,并且想要修改它(例如,修复一个打字错误、忘记添加一个文件、或者想要更改提交信息),您可以使用 git commit --amend 命令。这将打开一个编辑器,让您可以修改当前提交的信息,或者添加忘记的更改。

例子:

bash
git commit --amend -m "新的提交信息"

2. git rebase -i

对于较早的提交,如果需要修改,您可以使用交互式变基(git rebase -i)。这会打开一个TODO列表,让您可以选择需要修改的提交。

例子:

bash
git rebase -i HEAD~3 # 查看最近三个提交并选择编辑

在打开的编辑器中,将您想要修改的提交前面的 pick 改为 edit,然后保存退出。Git 将会停在您选择的那个提交,允许您做出修改。

bash
# 修改文件并将它们添加到暂存区 git add . # 使用 --amend 选项来修改提交 git commit --amend # 继续变基过程 git rebase --continue

3. git filter-branch

如果需要修改很早以前的提交,或者做一些复杂的历史修改,可以使用 git filter-branch 命令。这是一个强大但复杂的工具,可以对历史中的多个提交进行修改。

例子:

bash
git filter-branch --env-filter ' OLD_EMAIL="your-old-email@example.com" CORRECT_NAME="Your Correct Name" CORRECT_EMAIL="your-correct-email@example.com" if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ] then export GIT_COMMITTER_NAME="$CORRECT_NAME" export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL" fi if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ] then export GIT_AUTHOR_NAME="$CORRECT_NAME" export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL" fi ' --tag-name-filter cat -- --branches --tags

警告

修改已经提交到公共仓库的历史是一个危险的操作,因为它会改变历史中的提交ID(SHA-1哈希)。如果其他人已经基于这些提交做了工作,他们将不得不处理合并冲突或重新基于新的历史。因此,在修改公共仓库的历史之前,请确保这是必要的,并且您已经通知了所有相关的合作伙伴。

在每一种情况下,都要确保您对 Git 有足够的了解,以避免数据丢失。在执行任何修改历史的操作之前,最好是先备份您的仓库。

2024年6月29日 12:07 回复

使用git rebase。例如,要修改 commit bbc643cd,请运行:

shell
git rebase --interactive bbc643cd~

~请注意命令末尾的波形符,因为您需要在上一次提交的基础上重新应用提交bbc643cd(即bbc643cd~)。

在默认编辑器中,在提到 的行中修改pick为。edit``bbc643cd

保存文件并退出。git 会解释并自动执行文件中的命令。您会发现自己处于刚刚创建 commit 的先前情况bbc643cd

此时,bbc643cd这是您的最后一次提交,您可以轻松修改它。进行更改,然后使用以下命令提交它们:

shell
git commit --all --amend --no-edit

之后,使用以下命令返回到之前的 HEAD 提交:

shell
git rebase --continue

警告:请注意,这将更改该提交****以及所有子提交的 SHA-1——换句话说,这将重写从该点开始的历史记录。如果使用命令进行推送,则可以中断存储库执行此操作git push --force

2024年6月29日 12:07 回复

使用很棒的交互式变基:

shell
git rebase -i # Show your commits in a text editor

找到所需的提交,更改picke( edit),然后保存并关闭文件。Git 将回退到该提交,允许您:

  • 用于git commit --amend进行更改,或
  • 用于git reset @~放弃最后一次提交,但不放弃对文件的更改(即带您到编辑文件但尚未提交时所在的位置)。

后者对于执行更复杂的操作(例如拆分为多个提交)很有用。

然后,运行git rebase --continue,Git 将在修改后的提交之上重播后续更改。可能会要求您修复一些合并冲突。

注意:@是 的简写HEAD~是指定提交之前的提交。

在 Git 文档中阅读有关重写历史的更多信息。

不要害怕重新建立基础

专业提示™:不要害怕尝试重写历史记录的“危险”命令* — 默认情况下,Git 在 90 天内不会删除您的提交;你可以在转发日志中找到它们:

shell
$ git reset @~3 # go back 3 commits $ git reflog c4f708b HEAD@{0}: reset: moving to @~3 2c52489 HEAD@{1}: commit: more changes 4a5246d HEAD@{2}: commit: make important changes e8571e4 HEAD@{3}: commit: make some changes ... earlier commits ... $ git reset 2c52489 ... and you're back where you started

*注意诸如--hard--force等选项 - 它们可能会丢弃数据。
* 另外,不要重写您正在协作的任何分支上的历史记录。


在许多系统上,git rebase -i会默认打开 Vim。Vim 的工作方式与大多数现代文本编辑器不同,因此请了解如何使用 Vim 进行变基。如果您想使用其他编辑器,请将其更改为git config --global core.editor your-favorite-text-editor.

2024年6月29日 12:07 回复

当我需要更深入地修复历史记录中的先前提交时,我经常使用交互式变基--autosquash它本质上加速了 ZelluX 的答案所说明的过程,并且当您需要编辑多个提交时特别方便。

从文档中:

--autosquash

当提交日志消息以“squash!…​”(或“fixup!…​”)开头,并且存在标题以相同…​开头的提交时,自动修改rebase -i的todo列表,以便该提交标记为压缩发生在要修改的提交之后

假设您有这样的历史记录:

shell
$ git log --graph --oneline * b42d293 Commit3 * e8adec4 Commit2 * faaf19f Commit1

并且您有想要修改为 Commit2 的更改,然后使用以下命令提交更改

shell
$ git commit -m "fixup! Commit2"

或者,您可以使用 commit-sha 代替提交消息,甚至"fixup! e8adec4只是提交消息的前缀。

然后在之前的提交上启动交互式变基

shell
$ git rebase e8adec4^ -i --autosquash

您的编辑器将打开并显示已正确排序的提交

shell
pick e8adec4 Commit2 fixup 54e1a99 fixup! Commit2 pick b42d293 Commit3

您所需要做的就是保存并退出

2024年6月29日 12:07 回复

基于文档

修改较旧的消息或多个提交消息

shell
git rebase -i HEAD~3

上面显示了当前分支上最近 3 次提交的列表,如果需要更多,请将 3 更改为其他内容。该列表将类似于以下内容:

shell
pick e499d89 Delete CNAME pick 0c39034 Better README pick f7fde4a Change the commit message but push the same commit.

在要更改的每个提交消息之前将pick替换为**reword 。**假设您更改列表中的第二个提交,您的文件将如下所示:

shell
pick e499d89 Delete CNAME reword 0c39034 Better README pick f7fde4a Change the commit message but push the same commit.

保存并关闭提交列表文件,这将弹出一个新的编辑器供您更改提交消息,更改提交消息并保存。

最后,强制推送修改后的提交。

shell
git push --force
2024年6月29日 12:07 回复

修改特定提交的步骤

  1. 定位提交: 首先,我们需要找到要修改的提交。可以通过 git log命令查看提交历史,确定要修改的提交的哈希值。
  2. 交互式变基: 使用 git rebase -i命令进行交互式变基。该命令将打开一个文本编辑器,列出待选的提交列表。这需要指定基底提交的哈希值或使用 HEAD的相对引用,例如 HEAD~3表示当前分支最后三个提交。
  3. 挑选提交: 在交互式变基的列表中,找到要修改的提交,并将该行前的命令从 pick改为 edit。然后保存并退出编辑器,Git将暂停在那个提交上,允许你进行更改。
  4. 修改提交: 在此步骤中,可以进行所需的文件更改。完成后,使用 git add命令将这些更改加入暂存区。
  5. 应用修改: 使用 git commit --amend命令来修改那个提交。可以在此时修改提交信息,或者保留原始提交信息。
  6. 继续变基操作: 更改完成并提交后,使用 git rebase --continue来继续之前的变基操作。Git将应用剩余的提交。
  7. 处理冲突: 如果在变基过程中遇到冲突,需要手动解决冲突,然后使用 git add命令标记为已解决。之后再次使用 git rebase --continue
  8. 完成变基: 一旦所有的冲突都解决了,且所有的提交都被顺利地应用,变基操作就完成了。

注意事项

  • 不要在公共分支上修改历史:修改已经推送到远程且被他人使用的分支的提交历史是非常危险的做法,因为它会改变历史,需要其他人进行强制拉取(git pull --force)。
  • 备份分支:在进行变基之前,建议创建一个备份分支,以便发生错误时可以恢复到原始状态。

实战示例

假如我在工作中修复了一个bug,并提交了这个更改。但之后我发现提交消息写错了,或者我忘记了把一些重要的改动加入到提交中,我就需要对这个提交进行修改。以下是我具体操作的一个例子:

shell
# 查看提交历史,找到要修改的提交的哈希值 git log # 假设要修改的提交是3个提交前的那个 git rebase -i HEAD~3 # 这会打开一个文本编辑器,我会将要修改的提交行前的指令从'pick'改为'edit' # 保存退出编辑器之后,Git会停在那个提交上 # 做必要的文件修改 # ... # 把更改添加到暂存区 git add . # 修改提交信息或者保留原来的提交信息 git commit --amend # 继续变基过程 git rebase --continue # 解决可能出现的任何冲突,并继续 # ... # 变基完成

通过这样的步骤,我可以修改特定的提交,并确保项目的历史保持清晰和有序。

2024年6月29日 12:07 回复

你的答案