繁体   English   中英

如何将更改的文件添加到 Git 中的旧(不是最后)提交

[英]How to add a changed file to an older (not last) commit in Git

在过去的一个小时里,我改变了几件事并一步一步地提交,但我才意识到我忘记在一些提交前添加一个更改的文件。

日志看起来像这样:

GIT TidyUpRequests u:1 d:0> git log 
commit fc6734b6351f6c36a587dba6dbd9d5efa30c09ce 
Author: David Klein <> 
Date:   Tue Apr 27 09:43:55 2010 +0200

    The Main program now tests both Webservices at once

commit 8a2c6014c2b035e37aebd310a6393a1ecb39f463 
Author: David Klein <>
Date:   Tue Apr 27 09:43:27 2010 +0200

    ISBNDBQueryHandler now uses the XPath functions from XPath.fs too

commit 06a504e277fd98d97eed4dad22dfa5933d81451f 
Author: David Klein <> 
Date:   Tue Apr 27 09:30:34 2010 +0200

    AmazonQueryHandler now uses the XPath Helper functions defined in XPath.fs

commit a0865e28be35a3011d0b6091819ec32922dd2dd8 <--- changed file should go here
Author: David Klein <> 
Date:   Tue Apr 27 09:29:53 2010 +0200

    Factored out some common XPath Operations

有任何想法吗?

使用git rebase 具体来说:

  1. 使用git stash存储您要添加的更改。
  2. 使用git rebase -i HEAD~10 (或者你想看到多少回提交)。
  3. 通过将行开头的单词pick更改为 edit 来标记有问题的提交 ( a0865... ) 以进行edit 不要删除其他行,因为这会删除提交。[^vimnote]
  4. 保存 rebase 文件,git 将返回到 shell 并等待您修复该提交。
  5. 使用git stash pop
  6. 使用git add <file>
  7. 使用git commit --amend --no-edit
  8. 执行git rebase --continue这将针对新提交重写其余提交。
  9. 如果您标记了多个提交进行编辑,则从第 2 步开始重复。

[^vimnote]: 如果您使用的是vim则必须按Insert键进行编辑,然后按 Esc并输入:wq以保存文件、退出编辑器并应用更改。 或者,您可以使用git config --global core.editor "nano" 配置用户友好的 git commit 编辑器

用一个小的更改“修复”旧提交,而不更改旧提交的提交消息,其中OLDCOMMIT类似于091b73a

git add <my fixed files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^

您还可以使用git commit --squash=OLDCOMMIT在变基期间编辑旧的提交消息。

请参阅git commitgit rebase 的文档。 与往常一样,在重写 git history 时,您应该只修复或压缩尚未发布给其他任何人(包括随机 Internet 用户和构建服务器)的提交。


详细说明

  • git commit --fixup=OLDCOMMIT复制OLDCOMMIT提交消息并自动为fixup!前缀fixup! 所以它可以在交互式 rebase 期间按正确的顺序排列。 --squash=OLDCOMMIT做同样的--squash=OLDCOMMIT ,但前缀squash! 。)
  • git rebase --interactive会调出一个文本编辑器( 可以配置)来确认(或编辑) rebase 指令序列 文件中有关于rebase 指令更改的信息; 只需保存并退出编辑器( vim :wq )即可继续 rebase。
  • --autosquash将自动以正确的顺序放置任何--fixup=OLDCOMMIT提交。 请注意,-- --autosquash仅在使用--interactive选项时有效。
  • ^OLDCOMMIT^意味着它是一个参考之前提交OLDCOMMIT OLDCOMMIT^OLDCOMMIT^的第一个父OLDCOMMIT 。)

可选自动化

上述步骤适用于验证和/或修改rebase 指令序列,但也可以通过以下方式跳过/自动化交互式 rebase 文本编辑器:

使用 git 1.7,使用git rebase有一个非常简单的方法:

暂存您的文件:

git add $files

创建一个新的提交并重用“损坏的”提交的提交消息

git commit -c master~4

预先fixup! 在主题行(或squash!如果你想编辑提交(消息)):

fixup! Factored out some common XPath Operations

使用git rebase -i --autosquashgit rebase -i --autosquash你的提交

您可以尝试rebase --interactive会话来修改您的旧提交(前提是您尚未将这些提交送到另一个存储库)。

有时在 b.2 中固定的东西。 不能修改为它修复的不太完美的提交,因为该提交深埋在补丁系列中
这正是交互式 rebase 的用途:在大量“a”和“b”之后使用它,通过重新排列和编辑提交,并将多个提交压缩为一个。

从您要按原样保留的最后一次提交开始:

git rebase -i <after-this-commit>

编辑器将在您当前分支中的所有提交(忽略合并提交)中启动,这些提交在给定提交之后。
您可以将此列表中的提交重新排序为您满意的内容,也可以删除它们。 该列表或多或少是这样的:

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

单行描述纯粹是为了您的乐趣; git rebase 不会查看它们,而是查看提交名称(在此示例中为“deadbee”和“fa1afe1”),因此不要删除或编辑名称。

通过将命令“pick”替换为“edit”命令,您可以告诉 git rebase 在应用该提交后停止,以便您可以编辑文件和/或提交消息、修改提交并继续 rebase

这是一个实现@Greg 答案的函数:

function gitamendoldcommit() {
    printf "\n\nPress any key if you have no changes other than those you want to add to $1."
    printf "(You can commit your unwanted changes and undo later.):\n\n"
    read foo
    printf "\n\nChange 'pick' to 'edit' in front of $1 (top one), save, close the editor & press any key..."
    printf "Resolve any possible conflicts, if any. then: git add .; git rebase --continue\n\n"
    git rebase -i $1^

    git stash pop
    git add .
    git commit --amend --no-edit
    git rebase --continue
}

用法:(虽然在暂存中只有预期的更改) gitamendoldcommit $OLDCOMMIT

另外,如果您使用git rebase -i并且想要转到当前分支的第一次提交,您可以使用git rebase -i --root 现在您可以轻松修改您的第一次提交。

2023 年有工具可以做到这一点:特别是git 吸收 这是一个很棒的工具,有可能改变很多尘封的 git 工作流程。

暂无
暂无

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

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