Git Cheatsheet
- Authors
- @SLIPPERTOPIA
用了 Git 这么多年,时不时发现还有一些操作不知道该用什么命令,或者如何用更快捷方便的用法来完成一些操作,这里总结一些不常见但非常有用的命令,以备不时之需。官方 cheatsheet 已经有很多快速上手的命令,这些基础命令本文就不赘述了。
cherry-pick
俗称“捡樱桃”,用于将某个或某些特定提交的更改应用到当前分支。比如当前是 master 分支,需要将 hotfix 分支上关于 main.py
的修改应用到 master 分支。
git cherry-pick hash
如果需要应用多个提交,可以使用 git cherry-pick hash1 hash2 hash3
。
适用场景
- 功能分支到发布分支:如果特定的功能已经完成,并进行了多次提交,现在只有其中部分需要合并到发布分支,可以使用 git cherry-pick。
- 错误修复转移:修复一个错误后,你需要将这些修复应用到多个分支,cherry-pick 可以精确提取特定提交。
clean
clean
命令用于从工作目录中删除未被追踪的文件,也即是 git add
之前的文件。主要用法:
查看将被删除的文件(dry run,不实际删除),这个命令会列出当前目录下所有未被追踪的文件,但如果一个文件已经被
git add
了,那么即使有新的修改,它也不会被列出来。 同时子目录下的文件也不会被列出来,如果想要列出所有未被追踪的文件,可以使用git clean -nd
。git clean -nd
删除未追踪的文件:
git clean -f
同样,这个命令不会删除子目录下的文件,如果想要删除子目录下的文件,需要结合使用
-d
选项。删除未追踪的文件和目录:
git clean -fd
结合
-x
选项删除未追踪的文件,包括被.gitignore
忽略的文件:git clean -fx
交互式删除:
git clean -i
删除未追踪的文件,但排除特定文件或目录:
git clean -f -e build/
在放弃变改这点上,git clean
刚好跟 git checkout .
互补,git checkout .
是用于恢复工作目录中已追踪的文件,而 git clean
是用于删除未追踪的文件。
restore
git restore
用于恢复或丢弃工作树中的更改,主要用途是替代 git checkout
和 git reset
的部分功能,使用 restore 这个名字,操作意图就明确很多。
丢弃工作目录中的修改(未暂存的更改):
git restore <file>
这等同于旧版本的
git checkout -- <file>
从暂存区恢复文件到工作目录(取消暂存):
git restore --staged <file>
这等同于
git reset HEAD <file>
将文件恢复到特定提交的状态:
git restore --source=<commit> <file>
这会将文件恢复到指定提交时的状态。
恢复多个文件:
git restore <file1> <file2> <file3>
恢复当前目录下的所有文件:
git restore .
同时取消暂存并丢弃修改:
git restore --staged --worktree <file>
交互式选择要恢复的部分:
git restore -p <file>
从其他分支恢复文件:
git restore --source=<branch> <file>
switch
语义更清晰的 checkout
命令,主要用于切换分支,用于简化和澄清分支操作。 checkout 承担的任务太多了,有必要拆分出一个专门的命令来负责切换分支。
- 切换到已存在的分支:
git switch branch-name
- 创建新分支并切换到新分支:
git switch -c new-branch-name
- 创建新分支但不切换到新分支:
git switch -c new-branch-name --no-track
- 切换到上一个分支:
git switch -
- 强制切换到指定分支:
git switch -C branch-name
。如果分支已经存在,则强制切换到指定分支,并丢弃所有未提交的更改。 - 切换到远程分支:
git switch -c local-branch-name origin/remote-branch-name
FAQs
Q: 单文件回退到某个版本
git checkout c0825dc642 -- filePath
# or
git restore --source c0825dc642 -- filePath
这两个命令都可以将文件 filePath
回退到指定版本 c0825dc642。
如果只想查看而不想恢复,可以使用 git show
命令。
git show c0825dc642:filePath
注意中间的 :
号,如果不加 :
号而使用空格,则会显示当前版本和指定版本的差异。
Q: 如何撤销历史提交?
比如在开发过程中不小心改了一个文件,并把它提交到了远程仓库,这时候应该怎么撤销?
如果不涉及机密信息,笨方法是手动再改回来,然后重新提交。而如果涉及机密信息,就需要费点功夫了,可以参考我写的另一篇博客《如何从 git 历史中删除敏感信息》。
对于第一种情况,git 有更优雅的解决方案,即 git revert
。
git revert commit-hash
git revert
刚好是 git commit
的反操作,即把指定提交的更改再改回去。与 git reset
不同的是,它不会修改历史提交,而是创建一个新的提交,相当于对一个文件改了两遍,第二遍把内容又改回去了。
如果想撤消多个提交,可以使用 git revert commit-hash1 commit-hash2 commit-hash3
来指定多个提交。
Q: 如何恢复到指定 commit?即一次恢复多个文件
在开发过程中,如果一顿操作猛如虎之后,发现效果还不如之前的某个版本,这时候如果想回退版本,应该怎么操作? 例如,当前版本 c1 已经提交并推送到了远程仓库,如何优雅的回到 c2 或者 c3?
c1: a89ccf1d8d
c2: 4b825dc642
c3: c0825dc642
这个需求看起来跟上面的 如何撤销历史提交? 看起来很像,而实际上两者确实有重叠的地方。当前问题相当于连续撤消最近的若干次提交,因此可以通过 git revert
来解决。
但如果要恢复的提交过多,就需要更方便快捷的命令了。根据是否有强制推送的权限,有两个解决思路:
1. 大权在握,可以强推
通过 git reset --hard
回到 c2 或者 c3,然后强制 push 到远程仓库。这个操作重置当前的分支,所有在 c1 之后的 commit 都会丢失。一般不建议这么做,特别是多人协作的项目,会增加冲突的概率。
git reset --hard c2
git push --force
2. 位卑言轻,没有强推权限
通过 git restore 命令恢复文件,然后 git commit
重新提交。
git restore --source c2 -- .
git commit -m "Revert to c2"
Q: 如何修改作者信息
如果修改最近一次提交的作者信息,可以使用 git commit --amend
命令。
git commit --amend --author="New Author <[email protected]>"
如果需要修改历史提交的作者信息,可以使用 git rebase
命令,例如:
git rebase -i HEAD~3
在弹出的编辑器中,找到需要修改的提交,将 pick
改为 edit
,保存并退出编辑器。
pick c0825dc642 Author Name <[email protected]>
# Rebase 4b825dc642 onto c0825dc642 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
保存并退出编辑器后,通过以下命令修改 author
信息:
git commit --amend --author="New Author <[email protected]>"
git rebase --continue