如何在Git中将修改过的文件添加到旧的(不是最后一次)提交中

1mrurvl1  于 2023-01-07  发布在  Git
关注(0)|答案(7)|浏览(546)

在过去的一个小时里,我修改了一些东西,并一步一步地提交了它们,但我刚刚意识到我忘记在几次提交之前添加一个修改过的文件。
日志如下所示:

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

有什么想法吗?

vawmfj5a

vawmfj5a1#

使用git rebase。具体来说:
1.使用git stash存储要添加的更改。
1.使用git rebase -i HEAD~10(或者你想看到多少次提交)。
1.将有问题的提交(a0865...)标记为编辑,方法是将该行开头的单词pick更改为edit。不要删除其他行,因为这样会删除提交。[^vimnote]
1.保存rebase文件,git会回到shell并等待你修改提交。
1.使用git stash pop弹出隐藏的内容
1.使用git add <file>添加文件。
1.使用git commit --amend --no-edit修改提交。
1.执行一个git rebase --continue,它将根据新的提交重写其余的提交。
1.如果您标记了多个提交进行编辑,请从步骤2开始重复。
[^vimnote]:如果你使用的是vim,那么你需要按Insert键来编辑,然后按Esc键并输入:wq来保存文件,退出编辑器,然后应用修改。或者,你可以用git config --global core.editor "nano"来编辑configure a user-friendly git commit editor

8yoxcaq7

8yoxcaq72#

通过一个小的修改来“修复”一个旧的提交,而不改变旧提交的提交信息,其中OLDCOMMIT类似于091b73a

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

您还可以使用git commit --squash=OLDCOMMIT在变基期间编辑旧的提交消息。
请参阅git commitgit rebase的文档。与往常一样,当rewriting git history时,您应该只修复或压缩您尚未发布给任何其他人的提交(包括随机的Internet用户和构建服务器)。

详细说明

  • X1 M3 N1 X复制X1 M4 N1 X提交消息并自动地为X1 M5 N1 X加前缀,以便在交互式重定基期间可以将其置于正确的顺序。(X1 M6 N1 X做相同的事情,但为X1 M7 N1 X加前缀。)
  • git rebase --interactive将打开一个文本编辑器(can be configured)来确认(或编辑)* 变基指令序列 *。文件中有变基指令更改的信息;只需保存并退出编辑器(:wq in vim)以继续变基。
  • --autosquash将自动按正确顺序放置任何--fixup=OLDCOMMIT提交。请注意,--autosquash仅在使用--interactive选项时有效。
  • OLDCOMMIT^中的^意味着它是对OLDCOMMIT之前提交的引用(OLDCOMMIT^OLDCOMMIT的第一个父提交)。
    可选自动化

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

6kkfgxo0

6kkfgxo03#

在git 1.7中,使用git rebase有一个非常简单的方法:
暂存文件:

git add $files

创建一个新的提交并重用你的“坏的”提交的提交信息

git commit -c master~4

在主题行中添加fixup!(如果你想编辑commit(message),则添加squash!):

fixup! Factored out some common XPath Operations

使用git rebase -i --autosquash来修正提交

pxy2qtax

pxy2qtax4#

你可以尝试一个**rebase --interactive**会话来修改你的旧提交(如果you did not already push那些提交到另一个repo)。
有时b.2.中修复的东西不能被修改成它修复的不太完美的提交,因为那个提交被深深地埋在补丁序列中
这正是交互式变基的目的:在大量的“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”和“fa 1afe 1”),所以不要删除或编辑提交名。

用命令“edit”替换命令“pick”,你可以让git rebase在提交后停止,这样你就可以编辑文件和/或提交信息,修改提交,然后继续rebase.

vc9ivgsu

vc9ivgsu5#

下面是一个实现@Greg 's answer的函数:

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

b4qexyjb

b4qexyjb6#

另外,如果你使用git rebase -i,并且想转到当前分支的第一次提交,你可以使用git rebase -i --root,现在你可以很容易地修改你的第一次提交。

mwngjboj

mwngjboj7#

在2023年,有一些工具可以做到这一点:特别是git absorb,它是一个很棒的工具,有可能改变很多陈旧的git工作流。

相关问题