Git 使用 rebase 修改历史提交记录

一、只修改最后一次提交记录

运行以下这条命令之后,它会打开一个vim编辑器,我们就可以修改上一次commit时输入的提交信息。

git commit --amend

接下来你要是想修改描述信息的话,直接键入:i,此时进入了输入模式。

可用键盘上下键转到描述所在的那一行,然后进行修改。

修改完成后,按下 Esc 键退出编辑模式,在键入 :wq 回车退出并保存修改,完成提交。

amend:是补丁的意思,amend不是修改最近一次commit,而是整个替换掉他。amend后生成的commit是一个全新的commit,之前的老的commit会从项目历史中被删除。如果你amend了一个被其他开发者使用的commit,会严重影响其他开发者,所以要注意不要对一个公共的commit使用amend。

二、修改多个提交记录

执行以下命令,git会进入一个vim窗口,在这个窗口当中我们可以看到HEAD之前的2次提交

git rebase -i HEAD~2 // rebase HEAD之前的2次提交

// 或者

git rebase -i {commitID} // 例如 git rebase -i d95ddfb

HEAD~2:告诉 git 我要改变HEAD之前的2次提交

变基时可用的命令:

pick只是意味着包括提交。重新进行命令时,重新安排pick命令的顺序会更改提交的顺序。如果选择不包括提交,则应删除整行。

reword该命令与pick相似,但是使用后,重新设置过程将暂停并为您提供更改提交消息的机会。提交所做的任何更改均不受影响。

edit如果您选择edit提交,则将有机会修改提交,这意味着您可以完全添加或更改提交。您还可以进行更多提交,然后再继续进行变基。这使您可以将大型提交拆分为较小的提交,或者删除在提交中所做的错误更改。

squash该命令使您可以将两个或多个提交合并为一个提交。提交被压缩到其上方的提交中。Git使您有机会编写描述这两个更改的新提交消息。

fixup这类似于squash,但是要合并的提交已丢弃其消息。提交仅合并到其上方的提交中,并且较早提交的消息用于描述这两个更改。

exec这使您可以对提交运行任意的Shell命令。
 

1、修改提交记录 

在vim窗口里,按i进入编辑模式,把想要修改的commit前的pick改成edit。

注意:这一步只是告诉 git 你将要修改哪些提交记录,还不是真正的修改提交信息。

pick 6934312 add 1
pick 5ce6dde add 2

修改为

edit 6934312 add 1
pick 5ce6dde add 2

接着按Esc,输入:wq 保存退出。

退出之后,git 会自动带我们回到我们选择edit的分支提交之后的版本,有冲突要先解决冲突,之后我们再使用 git add . 以及 git commit --amend 进行修改提交结果。

注意:这一步才是真正的修改提交信息内容。

git commit --amend // 以当前代码重新覆盖本次提交

或者:如果不用修改提交信息

git commit --amend --no-edit  // 注意--no-edit的意思是不用再修改这个commit的commit信息

 git commit --amend 之后,会出现vim窗口,按i进入编辑模式,修改提交信息,接着按Esc,输入:wq 保存退出。

git rebase --continue  // 继续rebase,如果有冲突则解决冲突

全部修改完成之后我们执行 git rebase --continue,结束这次 rebase。

注意:如果有多个edit,则多重复几次上面的步骤(git commit --amend 和 git rebase --continue),把剩下要应用的变更应用完成。

直到出现以下提示,才说明全部修改已经完成。

​Successfully rebased and updated refs/heads/master.

2、提交记录顺序变更

修改顺序其实很简单,我们只需要修改 git rebase -i 之后弹出的vim窗口里的提交记录信息即可。

pick 8b485bb add 1
pick a75ed74 add 2

修改为(把2行的位置换一下)

pick a75ed74 add 2
pick 8b485bb add 1

小技巧:这个是vi编辑器,首先Esc ,进入命令模式,移动到第一行 按dd,本行就被剪切,pick a75ed74 add 5就变成了第一行,接着按 p刚刚剪切的就成了第二行,快速交换顺序

接着 Esc:wq 保存退出。

3、合并提交记录

我们只需要把pick修改成squash,git就会自动把所有 squash 的 commit 记录合并在一起。

pick 6934312 add 1
pick 5ce6dde add 2

修改为

squash 6934312 add 1
squash 5ce6dde add 2

接着 Esc:wq 保存退出。

开始执行变更

然后 在弹出来的编辑框里 写提交信息,我们可以修改提交消息,默认是把两个消息都合并

接着 Esc:wq 保存退出。

git log查看,合并成功。

4、拆分提交记录

有的时候一个commit非常巨大,我们可能也会想要将它拆分,其实操作也很简单。比如我们想要把commit 2 拆分成两条,首先,我们在rebase的时候将commit 2 前面的pick修改成edit。

pick 6934312 add 1
pick 5ce6dde add 2

修改为

pick 6934312 add 1
edit 5ce6dde add 2

接着 Esc:wq 保存退出。

当我们退出的时候,我们会进入到 commit 2 刚刚提交完的状态。由于我们要做的是拆分 commit 2 这个提交,所以我们需要执行 git reset HEAD^,把上一次提交重置。然后再分别add我们想要拆分开来提交的文件,这样就把commit 2拆分成了两个commit插入到了历史记录当中了。

git reset HEAD^
git add test/*
git ci -m 'add test'
git add code/*
git ci -m 'update code'
git rebase --continue

命令写错了怎么办

You can fix this with 'git rebase --edit-todo'.
# 用 git rebase --edit--todo  来重新编辑命令

注意:如果我们的commit已经被提交到了远程,是不可以直接 git push 同步的,因为git会校验提交代码的hash值,发现对不上之后会禁止提交。所以如果想要提交到远程的话,只能使用 git push -f 强制覆盖。但是这是一个非常非常危险的操作,如果你 git push -f 了,会覆盖之前的提交记录,导致没人知道你修改了什么,所以只建议在自己独有的分支上如此操作,一定一定要谨慎使用。

三、修改特定commit的内容

1、要修改 id 为 commitid 的 commit。

2、运行 git rebase --interactive commitid^(指定commit的父commit)。

git rebase --interactive commitID^

// 或者

git rebase -i {commitID^} // 例如 git rebase -i d95ddfb

注意:我们要 rebase 到要修改的 commit 的前一个commit,即指定 commit 的父 commit。

3、在跳出的编辑器中,将 commitid 所在行的 pick 改成 edit,保存后退出。

4、进行想要的修改,并且 git add,然后用 git commit --amend --no-edit 进行 commit

注意:--no-edit的意思是不用再修改这个 commit 的 commit 信息。

5、git rebase --continue。这个命令会回到最初的HEAD commit。这里如果有冲突, 需要先解决冲突。

四、恢复代码 和 取消 rebase 操作

1、恢复代码

有时候可能会由于某些误操作,某些 git 命令会从您的视图中删除提交,例如:git reset 可能会从您当前的分支中删除提交,因此这些提交会从您的视图中消失,修改提交也会从您的视图中删除提交。

这时候可以使用 git reflog 命令,该命令允许您通过显示 HEAD 指针移动来查找此类提交。它将向您显示 git 最近创建的所有提交。这包括临时创建的提交,或者已经被删除的,在分支上不再可见的提交

// 查看 HEAD 引用的完整更改历史记录
git reflog


# <output>
cf616d4 HEAD@{1}: reset: moving to 45ca2045be3aeda054c5418ec3c4ce63b5f269f7
# ... snip ...
1f1a73a HEAD@{2}: commit: More chaanges - typo in the commit message
45ca204 HEAD@{3}: commit: These are new changes
cf616d4 HEAD@{4}: commit (initial): Initial commit
# </output>


// 使用 reset 指定 commitID 来选择要恢复的记录
git reset --hard 1f1a73a

2、取消 rebase

如果 rebase 过程中不想 rebase 了,可以使用

git rebase --abort 	// 终止rebase

--abort 和 --skip 的区别:

git rebase --abort  取消本次操作。是无风险的操作,会回到rebase操作之前的状态,2个分支的commits毫发无损。


git rebase --skip  跳过这个错误,继续本次操作。是高风险的操作,引起冲突的commits会被丢弃(这部分代码修改会丢失)。

猜你喜欢

转载自blog.csdn.net/qq_31851435/article/details/128937241