我有以下提交历史记录:
头部头部~头部~2头部~3
gitcommit--修改当前HEAD提交。但是如何修改HEAD~3?
我有以下提交历史记录:
头部头部~头部~2头部~3
gitcommit--修改当前HEAD提交。但是如何修改HEAD~3?
当前回答
完全非交互式命令(1)
我只是想分享一个我正在使用的别名。它基于非交互式交互式数据库。要将其添加到git中,请运行以下命令(解释如下):
git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`; git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^"; }; f'
或者,一个也可以处理未暂存文件的版本(通过先暂存,然后再卸载):
git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`; git stash -k && git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^" && git stash pop; }; f'
这个命令的最大优点是它不是vim。
(1) 当然,考虑到重新启动期间没有冲突
用法
git amend-to <REV> # e.g.
git amend-to HEAD~1
git amend-to aaaa1111
将名称修改为似乎合适IMHO。将流程与--修订:
git add . && git commit --amend --no-edit
# vs
git add . && git amend-to <REV>
解释
git-config—全局别名<名称>'<COMMAND>'-创建名为<NAME>的全局git别名,该别名将执行非git命令<COMMAND>f(){<BODY>};f-一个“匿名”bash函数。SHA=`git rev parse“$1”`;-将参数转换为gitrevision,并将结果赋给变量SHAgitcommit--fixup“$SHA”--fixup提交SHA。参见git提交文档GIT_SEQUENCE_EDITOR=true GIT rebase--交互式--autosquash“$SHA^”gitrebase——交互式“$SHA^”部分已被其他答案覆盖。--autosquash与gitcommit一起使用--fixup,有关更多信息,请参阅gitrebase文档GIT_SEQUENCE_EDITOR=true是使整个事情非交互式的原因。这是我从这篇博客文章中学到的。
其他回答
要获得非交互式命令,请在PATH中放置包含以下内容的脚本:
#!/bin/sh
#
# git-fixup
# Use staged changes to modify a specified commit
set -e
cmt=$(git rev-parse $1)
git commit --fixup="$cmt"
GIT_EDITOR=true git rebase -i --autosquash "$cmt~1"
使用它,先暂存更改(使用gitadd),然后运行gitfixup<commit to modify>。当然,如果您遇到冲突,它仍然是交互式的。
Run:
$git rebase--交互式commit_hash^
每个^表示要编辑的提交次数,如果只有一个(指定的提交哈希),则只需添加一个^。
使用Vim,您可以更改要更改、保存和退出的提交的单词pick to reword(:wq)。然后git将提示您标记为reword的每个提交,以便您可以更改提交消息。
您必须保存并退出(:wq)以转到下一个提交消息的每个提交消息
如果要退出而不应用更改,请按:q!
编辑:要在vim中导航,请使用j向上,k向下,h向左,l向右(所有这些都在正常模式下,按ESC键转到正常模式)。要编辑文本,请按i以进入INSERT模式,在该模式下插入文本。按ESC返回正常模式:)
更新:这里有一个来自github的链接,列出了如何使用git撤消(几乎)任何操作
使用令人惊叹的交互式rebase:
git rebase -i @~9 # Show the last 9 commits in a text editor
找到所需的提交,将pick更改为e(编辑),然后保存并关闭文件。Git将返回到该提交,允许您:
使用gitcommit--修改以进行更改,或使用gitreset@~放弃最后一次提交,但不放弃对文件的更改(即,将您带到编辑文件但尚未提交的位置)。
后者对于执行更复杂的任务(如拆分为多个提交)非常有用。
然后,运行git-rebase--continue,git将在修改后的提交之上回放后续更改。可能会要求您修复一些合并冲突。
注意:@是HEAD的简写,~是指定提交之前的提交。
阅读Git文档中有关重写历史的更多信息。
不要害怕重新启动
ProTip公司™: 不要害怕尝试“危险”的命令来重写历史*-默认情况下,Git不会在90天内删除您的提交;你可以在reflog中找到它们:
$ 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
*注意一些选项,比如硬和强制,它们可以丢弃数据。*此外,不要重写您正在合作的任何分支的历史。
在许多系统上,git-rebase-i将默认打开Vim。Vim不像大多数现代文本编辑器那样工作,所以看看如何使用Vim重新设置基础。如果您希望使用不同的编辑器,请使用git-config--global-core.editor或您最喜欢的文本编辑器对其进行更改。
基于文档
修改旧的或多个提交消息的消息
git rebase -i HEAD~3
上面显示了当前分支上最后3次提交的列表,如果需要更多,请将3更改为其他内容。列表将类似于以下内容:
pick e499d89 Delete CNAME
pick 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.
将pick替换为要更改的每个提交消息之前的改写。假设您更改了列表中的第二个提交,您的文件将如下所示:
pick e499d89 Delete CNAME
reword 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.
保存并关闭提交列表文件,这将弹出一个新的编辑器,供您更改提交消息、更改提交消息并保存。
最后,强制推行修改后的承诺。
git push --force
当我需要更深入地修复历史中以前的提交时,我经常使用交互式rebase和--autosquash。它本质上加快了ZelluX的回答所说明的过程,当您需要编辑多个提交时,它特别方便。
根据文档:
--自动撤销当提交日志消息以“squash…“(或”修复…“),并且有一个提交的标题以相同的开头…, 自动修改rebase-i的todo列表,以便标记为挤压的提交在要修改的提交之后立即出现
假设您的历史记录如下:
$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1
并且您有要修改为Commit2的更改,然后使用
$ git commit -m "fixup! Commit2"
或者,您可以使用commit sha而不是commit消息,因此“fixup!e8adec4”或甚至只是commit消息的前缀。
然后在提交之前启动交互式重新基础
$ git rebase e8adec4^ -i --autosquash
编辑器将打开已正确排序的提交
pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3
你只需要保存并退出