如何将最后的git commit编辑为补丁文件?

wod*_*dow 5 git

有时通过编辑补丁文件而不是直接更改文件,将它们添加到工作集中然后修改提交来修改提交很有用。

为了简化操作,在git中使用一个命令来打开最新的提交$EDITOR 作为补丁文件很有用,就像发出git commit --amend(无需分阶段进行任何更改)立即允许在编辑器中编辑提交消息一样。

这可能在git中吗

  1. 作为一个命令
  2. 不会丢失提交消息?

Chr*_*aes 5

I'm not sure if it is possible in a single command, but almost:

git reset HEAD~
git add --edit
git commit --reuse-message=ORIG_HEAD
Run Code Online (Sandbox Code Playgroud)

some explanations:

  • git reset HEAD~ : destroy last commit but keep the changes
  • git add --edit allows you to edit your changes in patch format
  • git commit --reuse-message=ORIG_HEAD : commit your staged changes with the commit message from ORIG_HEAD which is the pointer to the commit you made before git reset.

NOTE: since only git add --edit needs for interaction, you could even just chain the commands on one line and create a bash or git alias for it if desired:

git reset HEAD~ && git add --edit && git commit --reuse-message=ORIG_HEAD
Run Code Online (Sandbox Code Playgroud)

NOTE2 if you edit your commit, some changes will remain in your git repository after this command. You must choose to throw them all away (git checkout -- :/) or commit them or...

If you don't do anything with these changes; then calling the above commands twice will always show you the changes from your very first commit:

git commit -am "very first commit"
git reset HEAD~
git add --edit # edit very first commit as patch
git commit --reuse-message=ORIG_HEAD
# you now have some unstaged changes lying around.
git reset HEAD~ # undo second commit
# the unstaged changes that are lying around now 
# are a combination of second commit and the unstaged changes
# that were still lying around.
# That combination = content of very first commit
git add --edit # edit that combination
git commit --reuse-message=ORIG_HEAD
Run Code Online (Sandbox Code Playgroud)

If you would like a full command that you can continue applying; you could include the throwing away of changes:

git reset HEAD~ && git add --edit && git commit --reuse-message=ORIG_HEAD && git checkout -- :/
Run Code Online (Sandbox Code Playgroud)

请注意,这样做很危险,因为您可能会放弃更改。


成熟的脚本

您可以将此脚本另存为/usr/bin/git-edit-last-commit,然后可以将其运行为git edit-last-commit

#!/bin/bash
set -e # exit on first error
if ! git diff-files --quiet
then
    echo "Your git repository is not clean: you have unstaged changes."
    exit 1
fi
if ! git diff-index --quiet --cached HEAD --
then
    echo "Your git repository is not clean: you have staged changes."
    exit 1
fi
git reset HEAD~
git add --edit
git commit --reuse-message=ORIG_HEAD
# supposing that this edit is really what you wanted, we can throw away leftovers
# if work was lost, in can be recovered using git reflog
git checkout -- :/
Run Code Online (Sandbox Code Playgroud)