修改最近一次的提交
最近一次的commit信息或commit内容可以用git commit --amend
如果需要修改提交的内容先执行git add添加内容再执行。
git commit --amend
将会打开文本编辑器,可以编辑之前的信息并关闭编辑器后,新的提交会替换之前的提交。
需要注意并不是直接修改原 commit,而是替换原有的commit,即commitid会变。
git rebase -i 对提交做更多的操作
rebase -i 是 rebase --interactive 的缩写,意为交互式rebase。
执行完后会进入一个交互式界面,可以指定要rebase的commit链中的每一个commit是否需要进一步修改。
以下是具体步骤:
使用以下命令启动交互式 rebase,并指定你想要修改的提交的前一个提交的哈希值
git rebase -i <commit-hash>~
会看到一个提交列表,展示了指令里commit-hash以来的所有提交
pick f123456 Commit message 1
pick abc1234 Commit message 2
pick def5678 Commit message 3
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
常用的rebase功能翻译如下
p, pick <commit>: 选择(保留)指定的提交。这是默认操作,如果你不修改任何内容,所有的提交都将被原样保留。r, reword <commit>: 选择指定的提交,但是允许你编辑该提交的提交信息。e, edit <commit>: 选择指定的提交,但是允许你修改该提交的内容。s, squash <commit>: 选择指定的提交,但是将其内容合并到前一个提交中,不会保留该提交的提交信息。d, drop <commit>: 删除指定的提交,从提交历史中移除它。
我们需要更改的commit前将pick改成对应的 指令 就行,
改成reword就是重新编辑该commit的提交信息
改成edit就可以重新修改该commit的内容
改成squash 就可以将该commit并入上一次commit
注意
如果你已经推送了提交到远程仓库,并且想要修改这些提交的信息,你需要使用 git push --force 或 git push --force-with-lease 来更新远程仓库的提交历史。但这可能会导致其他协作者的git历史出现问题,需要沟通好再操作。
git reset --hard
后面可以跟一个commit值,将Git仓库的状态重置到这个特定的历史点,同时丢弃所有自这个点以来的更改。无论是已提交的改动还是未提交的改动。
比如撤销最近一次的commit可以用 git reset --hard HEAD^,
它的实质行为并不是撤销,而是移动 HEAD,它把 HEAD 和它所指向 的 branch 一起移动到了当前 commit 的父 commit 上,从而起到了「撤销」的效果。
git reflog
通过 git reflog,你可以找到丢失的提交,
如果执行了 git reset --hard 并丢失了一些提交,你可以运行 git reflog 来查看最近的 HEAD 移动历史。然后找到来是你丢失的提交的哈希值,并使用 git checkout <commit-hash> 来检出那个提交,或者使用 git reset --hard <commit-hash> 来将 HEAD 重置到那个提交。
git reflog 显示的日志条目数量是有限的,并且旧的条目可能会因为新的操作而被覆盖,丢弃的commit也有可能被回收,因此,如果需要恢复一些工作,最好尽快查看 git reflog 并采取行动。
reflog 默认查看 HEAD 的移动历史,也可以手动加上名称来查看其他引用的移动历史,例如 git reflog master
偏移符号^ 和 ~
在 Git 中,有两个偏移符号: ^ 和 ~ 。
先看一个示例,创建一个git记录如下,从master分支创建两个branch,并分别提交两次,最后又合并到master分支。然后我们在master分支上,通过指令看看每个操作对应的哈希值。
测试^
git rev-parse HEAD^ 9bb82a
git rev-parse HEAD^1 9bb82a
git rev-parse HEAD^2 6fd1d5
git rev-parse HEAD^3
fatal: ambiguous argument 'HEAD^23': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
git rev-parse HEAD^1^1 887fe5
对于^,是以所指向的commit的parents依次取值,默认取第一个,所以git rev-parse HEAD^3报错,因为只有两个parents。^可以写多次来顺序执行,所以git rev-parse HEAD^1^1取到当前commit的第一个parents的第一个parents值,值为887fe5。
测试~
对于~,是以所指向的commit的层级依次取值,默认取第一个,所以git rev-parse HEAD^3取到了根master的值,而git rev-parse HEAD^4报错,因为没有更上一个层级的数据。~也是可以写多次来顺序执行。
git rev-parse HEAD~ 9bb82a
git rev-parse HEAD~1 9bb82a
git rev-parse HEAD~~ 887fe51
git rev-parse HEAD~2 887fe51
git rev-parse HEAD~3 5d2302
git rev-parse HEAD~4
fatal: ambiguous argument 'HEAD~4': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
^和~是可以混用的
git rev-parse HEAD^1~1 887fe5
git revert
git revert <commit-hash> 命令用于撤销某个提交,它会创建一个新的提交来抵消指定提交所做的更改,会自己创建提交并跳转到输入提交信息页面。
git checkout
checkout 的本质是签出指定的 commit ,所以不止可以切换 branch ,也可以指定 commit 作为参数,来把 HEAD 移动到指定的 commit 。
checkout 和 reset 都可以切换 HEAD 的位置,reset 在移动 HEAD 时会带着它所指向的 branch 一起移动,而 checkout 不会。当你用 checkout 指向其他地方的时候, HEAD和它所指向的branch 就自动脱离了。
git stash
在开发过程中,如果突然需要切换到另一个分支去处理临时任务,但当前分支的工作还没有完成,这时可以使用 git stash 命令将工作目录中的改动临时保存起来。
保存当前工作目录的改动
git stash
没有被add过的文件不会被 stash 起来,如果想把这些文件也一 起stash,可以加上-u 参数
git stash -u
处理完临时任务后,可以切换回原分支,并使用 git stash pop 命令将之前保存的改动恢复回来。
git stash pop
git stash pop 会将栈顶的 stash 条目应用到当前工作目录,并从栈中删除该条目。如果您想保留栈中的 stash 条目以便稍后再次使用,可以使用 git stash apply 命令。
git stash apply
指定恢复特定的 stash 条目
如果您在栈中保存了多个 stash 条目,可以使用 stash@{index} 语法来指定要恢复的条目。
# 查看栈中的所有 stash 条目
git stash list
# 指定恢复某个 stash 条目(例如,恢复第一个条目)
git stash apply stash@{0}
git cherry-pick:
从一个分支中选择特定的提交,并将更改“复制”到另一个分支上,新提交并不是原始提交的“副本”或“快照”,而是包含了相同更改的独立提交。因此,它们会有不同的提交哈希值,并且在提交历史中占据不同的位置。
git cherry-pick abcdef123456