git笔记(三)

743 阅读7分钟

修改最近一次的提交

最近一次的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 --forcegit 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