git reflogreflog是引用日志reference logs的简称，它完整的记录了git仓库中HEAD指针的变化历史，比如commit、reset、checkout、switch、merge、pull、rebase、cherry-pick、revert等，也就是说只要HEAD发生变化，就会有一条日志。比如我从test分支切换到main分支，然后再切换回test分支，输入git reflog会有如下的记录：41fc2e7 (HEAD -> test, master) HEAD@{0}: checkout: moving from main to test 7876a29 (main) HEAD@{1}: checkout: moving from test to main从日志中可以看到操作详情，开头的字符串就是HEAD的commit hash。其他情况类似。示例：当我们使用git reset --hard 7d8be96回退代码后，又突然后悔了，而且撤回的提交别的分支也没有。这时候git reflog就派上用场了。这时候使用git relog命令输出如下：7d8be96 (HEAD -> test) HEAD@{0}: reset: moving to 7d8be96e69dea59e2600ba2af3e1671d040281f9 41fc2e7 (master) HEAD@{1}: checkout: moving from main to test 7876a29 (main) HEAD@{2}: checkout: moving from test to main可以看到首条日志就是我们刚刚的操作reset，而我们想要回退到第二步，即从main刚切换到test的状态，这时只需要使用命令git reset --hard 41fc2e7就能够无损恢复了。此时reflog如下：41fc2e7 (HEAD -> test, master) HEAD@{0}: reset: moving to 41fc2e7 7d8be96 HEAD@{1}: reset: moving to 7d8be96e69dea59e2600ba2af3e1671d040281f9 41fc2e7 (HEAD -> test, master) HEAD@{2}: checkout: moving from main to test 7876a29 (main) HEAD@{3}: checkout: moving from test to main同理只要我们的操作被记录在了reflog中，都可以像乘时光机那样恢复到“过去”git push --force-with-lease假如有一个提交A和提交B，在push到仓库之后，突然发现B中有一些问题，于是通过git reset撤销了B这个提交的变更，在修改完之后生成一个新的提交C。这时问题就来了，当我们push的时候git会提示报错，不允许你提交，这时候我们可以用git push --force强制提交。但是会产生另一个问题，如果另一个同事在这个分支上推送了新的提交D，那么在git push --force时，就会把同事的代码给覆盖掉，这是一个非常恐怖的事情。好在git给我们了解决方法，这种情况下应该使用git push --force-with-lease，它在推送时会检测当前远程分支的指向是否和上次fetch / pull时的指向一致，只有一致的情况下才会允许推送，从而有效避免覆盖别人代码的情况。git commit --amend --no-edit当我们完成一些修改commit之后，突然发现还有一些小地方需要修改，修改完之后直接使用git commit --amend --no-edit可以将这个修改和上次提交合并，当然提交的commit hash会变更。--amend: 意思是“修正”。它告诉 git 不要生成一个新的提交（commit），而是把当前的改动“追加”到最近的一次提交上。从 git 的角度看，旧的提交被删除了，取而代之的是一个包含旧内容 + 新内容的新提交。--no-edit: 意思是“不要编辑”。通常使用 --amend 时，git 会打开编辑器让你修改提交信息。加上这个参数后，Git 会直接沿用上一次的提交信息，不再弹出编辑器。注意：如果修改已经提交到远程分支，那么最好使用git push --force-with-lease命令进行提交。版本选择符（~、^、@）写法描述查看方式HEAD~3当前 commit 的祖父的祖父（沿着父链 3 步）git show HEAD~3HEAD^3当前 commit 的第 3 个父节点（merge 才有）git show HEAD^3HEAD@{3}HEAD 三次操作之前的位置（来自 reflog）git show HEAD@{3}其中的HEAD可以更换为任意的commit hashgit cherry-pick 将提交的变更拷贝一份应用到当前分支上，这相当于是用commit的内容在本分支上新生成了一个提交，因此commit hash也是新的。参数可以是多个：git cherry-pick A..D；代表挑选从A到D之间的提交(A, D]，等价于git cherry-pick B C Dgit cherry-pick A C F；代表挑选提交A、C、F，他们可以不是连续的git add 或者 stash 的-p参数在已有多处改动的前提下，想要只提交某几行的变更，并且保留其他代码，可在git add或者git stash后添加-p参数，此命令将你的改动按照git规则分为多个块（hunk），以交互的方式依次询问你每个hunk是否需要提交，输入y为提交，n为不提交，输入e的话，可以手动控制hunk中每一行是否提交。git checkout -可以切换到上一个编辑的分支，多次执行的效果是在两个分支之间来回切换。从任意提交新建分支git checkout -b <新分支名> <commit hash>如上，如果不填写commit hash，以当前HEAD指针新建分支，否则以所填commit hash新建分支。参考资料：https://dangitgit.com/zhchatgpt