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

时间:2010-04-27 07:59:43

标签: 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

有什么想法吗?

6 个答案:

答案 0 :(得分:515)

使用git rebase。具体做法是:

  1. 使用git stash存储您要添加的更改。
  2. 使用git rebase -i HEAD~10(或者您希望查看多少提交内容)。
  3. 通过将该行开头的单词a0865...更改为pick来标记有问题的提交(edit)以进行编辑。不要删除其他行,因为删除提交。[^ vimnote]
  4. 保存rebase文件,git将退回到shell并等待您修复该提交。
  5. 使用git stash pop
  6. 弹出存储
  7. 使用git add <file>
  8. 添加文件
  9. 使用git commit --amend --no-edit修改提交。
  10. 执行一个git rebase --continue,它将重写其余提交的新提交。
  11. 如果您已经标记了多个提交进行编辑,则从步骤2开始重复。
  12. [^ vimnote]:如果您使用vim,则必须按 Insert 键进行编辑,然后按 Esc 并输入{{ 1}}保存文件,退出编辑器,然后应用更改。或者,您可configure a user-friendly git commit editor使用:wq

答案 1 :(得分:239)

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

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

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


  • git rebase --interactive将调出一个文本编辑器(can be configured)来确认(或编辑) rebase指令序列。文件中有rebase instruction个更改的信息;只需保存并退出编辑器(:wq in vim)即可继续使用rebase。
  • --autosquash会自动按所需顺序提交任何--fixup=OLDCOMMIT次提交。请注意,--autosquash仅在使用--interactive选项时有效。
  • ^中的OLDCOMMIT^表示它是OLDCOMMIT之前提交的引用。

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

请参阅git commitgit rebase。与往常一样,rewriting git history时,您应该只修改或压缩尚未发布给其他人的提交(包括随机互联网用户和构建服务器)。

答案 2 :(得分:57)

使用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 --autosquash来修复您的提交

答案 3 :(得分:7)

您可以尝试 rebase --interactive 会话来修改旧提交(提供you did not already push这些提交到另一个回购集。)

  

有时在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
...
  

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

     

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

答案 4 :(得分:0)

这是一个实现@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

答案 5 :(得分:0)

此外,如果您使用 -----> Building on the Heroku-20 stack -----> Auto detecting buildpacks... buildpack detected -----> Node.js app detected -----> Creating runtime environment NPM_CONFIG_PRODUCTION=false NPM_CONFIG_LOGLEVEL=error NODE_VERBOSE=false NODE_ENV=testing NODE_MODULES_CACHE=true -----> Installing binaries engines.node (package.json): 10.23.* engines.npm (package.json): 6.14.8 Resolving node version 10.23.*... Downloading and installing node 10.23.3... Bootstrapping npm 6.14.8 (replacing 6.14.11)... npm 6.14.8 installed -----> Restoring cache - node_modules -----> Installing dependencies Installing node modules . > PayJsRouter@1.40.0 preinstall /app > npx npm-force-resolutions npx: installed 6 in 2.844s > core-js@2.6.11 postinstall /app/node_modules/core-js > node -e "try{require('./postinstall')}catch(e){}" > protobufjs@6.10.1 postinstall /app/node_modules/protobufjs > node scripts/postinstall > fsevents@1.2.13 install /app/node_modules/babel/node_modules/fsevents > node install.js Skipping 'fsevents' build as platform linux is not supported > fsevents@1.2.13 install /app/node_modules/steal-tools/node_modules/fsevents > node install.js Skipping 'fsevents' build as platform linux is not supported > fsevents@1.2.13 install /app/node_modules/nodemon/node_modules/fsevents > node install.js Skipping 'fsevents' build as platform linux is not supported > nodemon@1.19.4 postinstall /app/node_modules/nodemon > node bin/postinstall || exit 0 Love nodemon? You can now support the project via the open collective: > https://opencollective.com/nodemon/donate > PayJsRouter@1.40.0 postinstall /app > npm run build-steal && npm run build-lodash && npm run build-prepare > PayJsRouter@1.40.0 build-steal /app > node ./scripts/buildSteal > PayJsRouter@1.40.0 build-lodash /app > node ./node_modules/lodash-cli/bin/lodash compat exports=umd modularize --development --output node_modules/lodash/ Created 420 modules in 17.29 seconds. > PayJsRouter@1.40.0 build-prepare /app > mkdir -p ./public/dist/templates added 1738 packages in 85.344s -----> Build Running build > PayJsRouter@1.40.0 build /app > grunt steal-build ... MANY LINES OF BUILD OUTPUT Build was successful. Done. -----> Caching build - node_modules -----> Pruning devDependencies Skipping because NODE_ENV is not 'production' -----> Build succeeded! -----> No test-setup command provided. Skipping. 并且想要转到当前分支的第一次提交,您可以使用 git rebase -i。现在您可以轻松修改您的第一次提交。