WheatField
WheatField

Git Cheatsheet

September 6, 20241360 words, 7 min read
Authors

用了 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 之前的文件。主要用法:

  1. 查看将被删除的文件(dry run,不实际删除),这个命令会列出当前目录下所有未被追踪的文件,但如果一个文件已经被 git add 了,那么即使有新的修改,它也不会被列出来。 同时子目录下的文件也不会被列出来,如果想要列出所有未被追踪的文件,可以使用 git clean -nd

    git clean -nd
    
  2. 删除未追踪的文件:

    git clean -f
    

    同样,这个命令不会删除子目录下的文件,如果想要删除子目录下的文件,需要结合使用 -d 选项。

  3. 删除未追踪的文件和目录:

    git clean -fd
    
  4. 结合 -x 选项删除未追踪的文件,包括被 .gitignore 忽略的文件:

    git clean -fx
    
  5. 交互式删除:

    git clean -i
    
  6. 删除未追踪的文件,但排除特定文件或目录:

    git clean -f -e build/
    

在放弃变改这点上,git clean 刚好跟 git checkout . 互补,git checkout . 是用于恢复工作目录中已追踪的文件,而 git clean 是用于删除未追踪的文件。

restore

git restore 用于恢复或丢弃工作树中的更改,主要用途是替代 git checkoutgit reset 的部分功能,使用 restore 这个名字,操作意图就明确很多。

  1. 丢弃工作目录中的修改(未暂存的更改):

    git restore <file>
    

    这等同于旧版本的 git checkout -- <file>

  2. 从暂存区恢复文件到工作目录(取消暂存):

    git restore --staged <file>
    

    这等同于 git reset HEAD <file>

  3. 将文件恢复到特定提交的状态:

    git restore --source=<commit> <file>
    

    这会将文件恢复到指定提交时的状态。

  4. 恢复多个文件:

    git restore <file1> <file2> <file3>
    
  5. 恢复当前目录下的所有文件:

    git restore .
    
  6. 同时取消暂存并丢弃修改:

    git restore --staged --worktree <file>
    
  7. 交互式选择要恢复的部分:

    git restore -p <file>
    
  8. 从其他分支恢复文件:

    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: 如何恢复到指定 commit?即一次恢复多个文件

在开发过程中,如果一顿操作猛如虎之后,发现效果还不如之前的某个版本,这时候如果想回退版本,应该怎么操作? 例如,当前版本 c1 已经提交并推送到了远程仓库,如何优雅的回到 c2 或者 c3?

c1: a89ccf1d8d
c2: 4b825dc642
c3: c0825dc642

根据是否有强制推送的权限,有两种方式:

有强制推送的权限

通过 git reset --hard 回到 c2 或者 c3,然后强制 push 到远程仓库。这个操作重置当前的分支,所有在 c1 之后的 commit 都会丢失。一般不建议这么做,特别是多人协作的项目,会增加冲突的概率。

git reset --hard c2
git push --force

没有强制推送的权限

通过 git restore 命令恢复文件,然后 git commit 重新提交。

git restore --source c2 -- .
git commit -m "Revert to c2"