Git:命令篇

基于 Version 2.35.1 for windows

符号释义

  • -a|--abbreviation:表示 -a 与 --abbreviation 同义,功能相同,二者可任选其一使用。

  • [...]:表示 [] 中的内容 ... 可以忽略。

  • <...>:参数项对应的具体参数值或指定内容。

  • <options>:表示一个可选的参数选项。

  • <branch>:表示一个分支名称。

  • <remote>:表示一个远程仓库在本地库中的别名。

  • <commit>:表示指定的分支 、标签或提交、有时也代表远程分支、标签的引用 忽略则默认为当前分支 HEAD。

主要命令

命令帮助

命令格式:

git help [<options>] [<command>]

常见用法:
# 输出指定命令的简略用法
$ git <command> -h

# 在浏览器中链接到指定命令的文档
$ git help <command>

# 输出全部命令的列表
$ git help -a|--all

# 输出 config 命令的全部配置项(此命令后不能加 command)
$ git help -c|--config

配置 Git

命令格式:

git config [<options>]

常见用法:
# 查看指定位置下的配置列表
$ git config [--system|--global|--local] -l|--list

# 配置指定位置下的用户名
$ git config [--system|--global|--local] user.name "<content>"

# 配置指定位置下的用户邮箱
$ git config [--system|--global|--local] user.email "<content>"

创建版本库

初始化
命令格式:

git init [<options>] [<pathspec>]

常见用法:
# 初始化当前目录为工作区并创建空版本库,同时生成一个默认分支(master)
$ git init

# 在当前目录创建并初始化指定目录为工作区并创建空版本库(默认分支 master)
$ git init <pathspec>

# 初始化当前目录为工作区并创建空版本库,并且指定默认分支的名称
$ git init -b <branch>|--initial-branch=<branch>

克隆版本库

命令格式:

git clone [<options>] [--] [<pathspec>]

常见用法:
# 将指定远程仓库克隆到本地当前目录(默认项目名称是远程地址最后面的内容)
# 默认远程仓库别名为 origin,默认创建一个与远程主分支具有上下游关系的同名分支
$ git clone <remote-address>

# 将指定远程仓库克隆到本地指定目录下,同时指定项目名称
$ git clone <remote-address> <pathspec>

# 将指定远程仓库克隆到本地目录,默认创建一个与远程指定分支具有上下游关系的同名分支
$ git clone -b|--branch <branch> <remote-address> [<pathspec>]

# 将指定远程仓库克隆到本地目录,同时指定远程仓库别名
$ git clone -o|--origin <remote> <remote-address> [<pathspec>]

# 将指定远程仓库克隆到本地目录,不克隆任何标签
$ git clone --no-tags <remote> <remote-address> [<pathspec>]

查看工作区状态

命令格式:

git status [<options>] [--] [<pathspec> ...]

常见用法:
# 列出工作区和索引区的状态(工作区并不一定是当前目录,但一定是 .git 所在目录)
$ git status

# 列出工作区和索引区指定文件、目录(多个路径间需要使用空格来分隔)的状态
$ git status [<pathspec> ...]

# 以短格式的形式列出工作区和索引区的状态
$ git status -s|--short [<pathspec> ...]

# 列出工作区和索引区的状态
# no:不显示未跟踪的文件;normal:显示未跟踪的文件和目录(默认值);all:显示未跟踪目录中的单个文件
$ git status -u<no|normal|all> [<pathspec> ...]

# 列出工作区和索引区的状态,包括被忽略文件(.gitignore 与 .git\info\exclude 中忽略的所有文件)
$ git status --ignored [<pathspec> ...]

添加内容到索引区

命令格式:

git add [<options>] [--] [<pathspec> ...]

常见用法:
# 将当前目录内(递归子目录)所有未忽略(未跟踪、已修改、已删除)的文件添加到索引区
# 在 Git 2.X 版本中与 “git add -A” 功能相同;在 Git 1.X 版本中不包括已删除的文件
$ git add .

# 将指定文件、指定目录内(递归子目录)所有未忽略(未跟踪、已修改、已删除)的文件添加到索引区
$ git add <pathspec> ...

# 将目录内所有未忽略(未跟踪、已修改、已删除)的文件添加到索引区
$ git add -A|--all [<pathspec> ...]

# 将目录内未跟踪、已修改的文件添加到索引区
$ git add --no-all .|<pathspec> ...

# 将目录内已更新(已修改、已删除)的文件添加到索引区
$ git add -u|--update [<pathspec> ...]

# 将目录内的文件以及被忽略的文件添加到索引区
$ git add -f|--force .|<pathspec> ...

# 补丁式添加(只显示已更新(同 "-u")的文件,其他范围参数无效(例如 "-A"、"."),但可以限制路径)
$ git add -p|--patch [<pathspec> ...]

# 交互式添加(只显示已修改、已删除的文件,其他范围参数无效,例如 "-A"、".",但可以限制路径)
$ git add -i|--interactive

提交内容到版本库

命令格式:

git commit [<options>] [--] [<pathspec> ...]

常见用法:
# 提交索引区内所有内容到版本库(作用范围是工作区,即 .git 所在目录)
$ git commit

# 提交指定路径的内容到版本库(指定路径后可直接将已修改未暂存的内容提交,作用同 "-a")
$ git commit <pathspec> ...

# 提交索引区的内容到版本库,附加提交信息
$ git commit -m "<content>"|--message="<content>" [<pathspec> ...]

# 提交工作区内已修改未暂存的内容到版本库(相当于执行 add 和 commit)
$ git commit -a|--all [<pathspec> ...]

# 提交本次变更内容到版本库,并用本次提交记录覆盖上一次提交记录(SHA1 发生变化),其中提交信息可以再次编辑,提交时间、作者、提交者不可变
$ git commit --amend [<pathspec> ...]

# 补丁式提交
$ git commit -p|--patch

补充提交信息(注释)

命令格式:

git notes [list|show|add|copy|edit|remove] [<options>] [<commit>|<from-commit> [<to-commit>]]

常见用法:
# 列出指定提交的注释对象。如果未指定提交,则显示所有注释对象及其关联的提交对象的 SHA1 列表
$ git notes list [<commit>]

# 列出指定对象的注释对象
$ git notes show <commit>

# 为指定提交添加(-f 强制添加,即覆盖原有注释)注释,同时指定注释信息(此操作不改变提交对象本身)
$ git notes add [-f|--force] <commit> -m "<content>"|--message="<content>"

# 将指定提交的注释复制到第二个指定提交上(to-commit 默认为 HEAD)
$ git notes copy [-f|--force] <from-commit> [<to-commit>]

# 编辑指定提交的注释(commit 默认为 HEAD)
$ git notes edit [<commit>]

# 删除指定提交的注释(commit 默认为 HEAD)
$ git notes remove [<commit>]

删除内容

命令格式:

git rm [<options>] [--] ...

常见用法:
# 删除指定文件、目录在工作区和索引区的内容
$ git rm <pathspec> ...

# 删除指定文件、目录在索引区的内容
$ git rm --cached <pathspec> ...

# 强制删除指定文件、目录在工作区和索引区的内容
# 当要删除的内容在指令指定范围内(指是否指定 --cached)内容不一致时需要强制删除
$ git rm -f|--force <pathspec> ...

重命名(移动)文件或目录

命令格式:

git mv [<options>]

常见用法:
# 重命名(移动)指定文件或目录到目标路径(文件或目录未被追踪或不存在时,此命令会执行失败)
$ git mv <source-pathspec> <destination-pathspec>

# 重命名(移动)指定文件或目录到目标路径(文件或目录未被追踪或不存在时,此命令会跳过这些内容)
$ git mv -k <source-pathspec> <destination-pathspec>

# 重命名(移动)指定文件或目录到目标路径(被重命名(移动)的文件或目录即使在目的目录已存在也会强制执行)
$ git mv -f|--force <source-pathspec> <destination-pathspec>

从工作区中删除未跟踪的文件

命令格式:

git clean [<options>] [<pathspec> ...]

常见用法:
# 递归删除工作区内所有未跟踪的文件(不包括未被跟踪的目录和已忽略文件)
$ git clean

# 递归删除指定目录内所有未跟踪的文件(不包括忽略文件)
$ git clean -f -d [<pathspec> ...]

# 显示将要删除的内容
$ git clean -n|--dry-run [<pathspec> ...]

优化本地存储库

命令格式:

git gc [<options>]

常见用法:
# 清理不必要的文件并优化本地存储库
$ git gc

# 检查是否需要清理不必要的文件并优化本地存储库;需要就优化;否则不执行任何工作
$ git gc --auto

# 清理不必要的文件并优化本地存储库,同时使 Git 在以后更积极地优化存储库
$ git gc --aggressive

标签管理

命令格式:

git tag [<options>] ...

git tag [<options>] [<commit>|<object>]

常见用法:
# 列出全部标签
$ git tag

# 列出符合指定规则(规则个数不限)的全部标签
$ git tag -l|--list <pattern> ...

# 列出包含指定提交的全部标签
$ git tag --contains [<commit>]

# 列出不包含指定提交的全部标签
$ git tag --no-contains [<commit>]

# 列出在指定的提交上或在其之前的全部标签
$ git tag --merged [<commit>]

# 列出在指定提交之后的全部标签
$ git tag --no-merged [<commit>]

# 在指定提交上创建轻量标签(轻量标签不可以使用 -m,-a 等参数)
$ git tag <tag> [<commit>]

# 在指定提交上创建附注标签
$ git tag -a|--annotate <tag> [<commit>]

# 在指定提交上创建附注标签,附加提交信息
$ git tag -m "<content>"|--message="<content>" <tag> [<commit>]

# 在指定提交上强制创建标签。如果存在同名标签,已存在的同名标签将会被删除(不用 -f 创建标签,命令会执行失败)
$ git tag -f|--force <tag> [<commit>]

# 删除指定标签
$ git tag -d|--delete <tag> [...]

分支管理

命令格式:

git branch [<commit> ...]

git branch [<options>] [<commit>]

git branch [<options>] [<old-branch>]

常见用法:
# 列出本地全部分支
$ git branch

# 列出全部远程跟踪分支(本地的远程引用)
$ git branch -r|--remotes

# 列出全部分支(本地分支和远程跟踪分支)
$ git branch -a|--all

# 列出全部分支,并附加每个分支 HEAD 的 SHA1、提交信息以及和上游分支的关系
$ git branch -v|-vv|--verbose

# 列出包含指定提交的分支
$ git branch --contains [<commit>]

# 列出不包含指定提交的分支
$ git branch --no-contains [<commit>]

# 列出 HEAD 在指定的提交上或在其之前的全部分支
$ git branch --merged [<commit>]

# 列出 HEAD 在指定提交之后的全部分支
$ git branch --no-merged [<commit>]

# 基于当前分支的 HEAD 创建一个新分支
$ git branch <branch>

# 在指定的提交上创建一个新分支
$ git branch <branch> [<commit>]

# 基于当前分支的 HEAD 创建一个新分支,同时指定其上游分支(若要创建的分支已存在,则执行失败)
$ git branch -t|--track <branch> <remote>/<branch>

# 将指定远程分支设置为一个已存在本地分支的上游分支(branch 忽略,则默认为当前分支)
$ git branch [<branch>] -u <remote>/<branch>|--set-upstream-to=<remote>/<branch>

# 删除指定本地分支与其上游分支的关联(branch 忽略,则默认为当前分支)
$ git branch --unset-upstream [<branch>]

# 删除指定分支(不能删除当前所在分支;不能删除未与当前分支、上游分支完全合并的分支)
$ git branch -d|--delete <branch> ...
# 强制删除指定分支(不管分支的合并状态),"-D" 同义于 "-f -d"
$ git branch -D <branch> ...

# 重命名(移动)分支,若重命名(移动)后存在同名分支,则此命令会执行失败(old-branch 不写则默认为当前分支)
$ git branch -m|--move [<old-branch>] <new-branch>
# 强制重命名(移动)分支,同名则会覆盖掉前者,"-M" 同义于 "-f -m"(old-branch 不写则默认为当前分支)
$ git branch -M [<old-branch>] <new-branch>

切换提交或恢复工作区内容

命令格式:

git checkout [<options>] -- [<pathspec>]

git checkout [<options>] [<branch>] [<commit>]

常见用法:
# 切换到指定提交,此提交可以是分支、标签
# 如果目标分支在本地版本库中不存在,那么会匹配远程同名分支,若匹配到且未指定跟踪分支则此命令等效于 "git checkout -b <branch> --track <remote>/<branch>",否则此命令执行失败)
$ git checkout <branch>

# 从指定提交处创建并切换到新分支(若新分支与已存在分支重名,命令执行失败)
$ git checkout -b <branch> [<commit>]
# 从指定提交处创建并切换到新分支(若新分支与已存在分支重名,后者将被重置)
$ git checkout -B <branch> [<commit>]

# 从指定远程分支创建并切换到同名的本地分支,并将远程分支设置为新分支的上游分支
$ git checkout -t|--track <remote>/<branch>
# 从指定远程分支创建并切换到指定的本地分支,并将远程分支设置为新分支的上游分支
$ git checkout -b|-B <branch> [-t|--track] <remote>/<branch>

# 从指定提交处创建并切换到一个无父提交的新分支(无历史记录,类似于 init)
$ git checkout --orphan <branch> [<commit>]

# 切换到指定分支,如果当两个分支在当前工作区修改的内容处不一致,就会自动合并当前分支下所有未添加到索引区的修改到将要切换的分支,同时当前分支下的修改全部被丢弃
$ git checkout -m|--merge <branch>

# 将工作区内指定文件(目录)的内容恢复为索引区的内容
$ git checkout -- <pathspec>|.

# 将工作区、索引区内的指定文件(目录)的内容恢复为指定提交处的内容
$ git checkout [<commit>] <pathspec>|.

# 在发生冲突后选择当前分支内容以完成合并(在 rebase 中代表选择其他分支内容)
$ git checkout --ours [<commit>] <pathspec>|.

# 在发生冲突后选择其他分支内容以完成合并(在 rebase 中代表选择当前分支内容)
$ git checkout --theirs [<commit>] <pathspec>|.

切换分支(标签、提交)

命令格式:

git switch [<options>] [<branch>] [<commit>]

常见用法:
# 切换到指定分支
$ git switch <branch>

# 从指定提交处创建并切换到新分支(若新分支与已存在分支重名,命令执行失败)
$ git switch -c|--create <branch> [<commit>]
# 从指定提交处创建并切换到新分支(若新分支与已存在分支重名,后者将被重置)
$ git switch -C <branch> [<commit>]

# 从指定远程分支创建并切换到同名的本地分支,并将远程分支设置为新分支的上游分支
$ git switch -t|--track <remote>/<branch>
# 从指定远程分支创建并切换到指定的本地分支,并将远程分支设置为新分支的上游分支
$ git switch -c|-C <branch> [-t|--track] <remote>/<branch>

# 从指定提交处创建并切换到一个无父提交的新分支(无历史记录,类似于 init)
$ git switch --orphan <branch> [<commit>]

# 切换到指定分支,如果当两个分支在当前工作区修改的内容处不一致,就会自动合并当前分支下所有未添加到索引区的修改到将要切换的分支,同时当前分支下的修改全部被丢弃
$ git switch -m|--merge <branch>

恢复内容

命令格式:

git restore [<options>] [-S] [-W] [-s <commit>] [--]

常见用法:
# 将工作区内指定文件(目录)的内容恢复为索引区的内容
$ git restore -- <pathspec>|.

# 将指定位置内的指定文件(目录)的内容恢复为版本库中的内容(如果两组选项都没有指定,那么只会恢复工作区。指定 -S 只会恢复索引区。两组选项都指定会还原工作区和索引区)
$ git restore -W|--worktree [-S|--staged] <pathspec>|.

# 将工作区内指定文件(目录)的内容恢复为指定提交处的内容
$ git restore -s <commit>|--source=<commit> <pathspec>|.

# 在发生冲突后选择当前分支内容以完成合并(在 rebase 中代表选择其他分支内容)
$ git restore --ours -s [<commit>] <pathspec>|.

# 在发生冲突后选择其他分支内容以完成合并(在 rebase 中代表选择当前分支内容)
$ git restore --theirs -s [<commit>] <pathspec>|.

合并

命令格式:

git merge [<options>] ...

git merge --continue|--abort|--quit

常见用法:
# 将指定提交(...代表可指定多个分支)与当前分支合并(若无冲突则自动提交)
$ git merge <commit> ...

# 将指定提交与当前分支合并,附加提交信息(若无冲突则自动提交)
$ git merge -m "<content>" <commit> ...

# 将指定提交与当前分支合并,在合并发生冲突后自动选择当前分支内容(ours)或其他分支内容(theirs)以完成合并
$ git merge -X<ours|theirs> <commit> ...

# 将指定提交与当前分支合并(合并后的文件将会添加到索引区,手动提交)
$ git merge --no-commit <commit> ...

# 将指定提交与当前分支合并,指定分支在二者共同祖先提交处直至其 HEAD 内的所有提交会被压缩为一次提交(合并后的文件将会添加到索引区,手动提交)
$ git merge --squash <commit> ...

# 在合并发生冲突并解决后继续合并(此命令与 git commit -a 同义)
$ git merge --continue

# 在合并发生冲突后终止合并同时恢复到未合并状态(若此时有未提交的更改,也会被恢复,造成内容丢失)
$ git merge --abort

变基

命令格式:

git rebase [-i] [<options>] [--onto <base-commit>] [<from-commit> [<to-commit>]

git rebase --continue|--abort|--skip|--edit-todo

常见用法:
# 将上游分支变基到此分支(没有上游分支则此命令执行无效)
$ git rebase

# 将一个分支(base-commit 可以是上游分支)变基到指定分支(commit)
# 个人理解:以 base-commit 为基,对比并取出从 base-commit 与 to-commit 共同的祖先提交到 to-commit 范围内的差异(注意对比方向),强制重置 to-commit 到 base-commit,并将差异按原有提交重新应用(如果 to-commit 不在当前分支,那么此命令等效于:git checkout <branch> 然后 git rebase <base-commit>。to-commit 忽略则默认为 HEAD)
$ git rebase <base-commit> [<to-commit>]

# 与 "git rebase <base-commit> [<to-commit>]" 作用相同,在变基发生冲突后自动选择 to-commit 内容(theirs)或 base-commit 内容(ours)以完成合并
$ git rebase -X<ours|theirs> <base-commit> [<to-commit>]

# 可以由:
#     A---B---C---D---E              master
#              \
#               F---G---H---I        test
#                    \
#                     J---K---L      hotfix
# 变基为(git rebase --onto master test hotfix):
#     A---B---C---D---E              master
#              \       \
#               \       J'--K'--L'   hotfix
#                \
#                 F---G---H---I      test
# 个人理解:以 master 为基,对比从 test 与 hotfix 共同的祖先提交到 hotfix 范围内的差异并为这些差异打出补丁,hotfix 强制重置(reset --hard)到 master,再将补丁按照原有提交次序与内容应用到 hotfix 上。
# 还可以由:
#         -   -
#     E---F---G---H---I---J          master
# 变基为(git rebase --onto master~5 master~2 master):
#     E---H''---I''---J''            master
# 原理与上面相同,只是在一个分支上操作,等效于删除 F、G 两处的提交。
#
# 以 base-commit 为基,对比从 from-commit 与 to-commit 共同的祖先提交到 to-commit 范围内的差异(注意 diff方向)并为这些差异打出补丁,to-commit 强制重置(reset --hard)到 base-commit,再将补丁按照原有提交次序与内容应用到 to-commit 上(变基过程中如果某个提交已经在当前分支中包含,则跳过该提交)
$ git rebase --onto <base-commit> <from-commit> <to-commit>

# 交互式变基
$ git rebase -i

# 在变基发生冲突并解决后继续变基(此命令与 git commit -a 同义)
$ git rebase --continue

# 在变基发生冲突后终止变基同时恢复到未变基状态(若此时有未提交的更改,也会被恢复,造成内容丢失)
$ git rebase --abort

# 在变基发生冲突后跳过冲突继续变基(commit 中有冲突的提交对象(blob)都会丢弃,保留 base-commit 的内容与日志)
$ git rebase --skip

远程存储库管理

命令格式:

git remote [<options>] [<remote> [<remote-address>]]

常见用法:
# 列出所有远程仓库
$ git remote

# 列出所有远程仓库及其地址(SSH、HTTP 等)
$ git remote -v|--verbose

# 显示最新的远程仓库信息(先使用 ls-remote 获取最新信息)
$ git remote show <remote>

# 显示本地缓存的远程仓库信息
$ git remote show -n <remote>

# 添加远程仓库,remote 为远程仓库在本地的自定义名称,remote-address 为远程仓库地址
# 此命令只在本地配置文件中生成一个远程仓库信息(没有远程分支引用)
$ git remote add <remote> <remote-address>

# 添加远程仓库,同时运行 "git fetch <remote>"(添加远程分支引用:refs/remotes/.../...)
$ git remote add -f <remote> <remote-address>

# 添加远程仓库,从远程仓库导入全部标签(默认只导入 fetch 分支内的标签)
$ git remote add --tags <remote> <remote-address>

# 添加远程仓库,不会导入远程仓库任何标签(默认只导入 fetch 分支内的标签)
$ git remote add --no-tags <remote> <remote-address>

# 查看指定远程仓库地址
$ git remote get-url <remote>

# 更换指定远程仓库(remote)的地址,而不影响远程跟踪分支
$ git remote set-url <remote> <new-emote-address>

# 重命名远程仓库 old-remote 为 new-remote,所有远程跟踪分支和远程配置都会更新
$ git remote rename <old-remote> <new-remote>

# 删除远程仓库 remote,所有远程跟踪分支和远程配置都会删除
$ git remote remove <remote>

# 删除在远程仓库中已删除(已删除的分支)但是在本地仍然存在的远程分支引用
$ git remote prune <remote>

推送本地内容到远程仓库

命令格式:

git push [<options>] [<remote>] [<branch> ...|<local-branch>:<remote-branch> ...]

常见用法:
# 推送当前分支到指定远程仓库(remote 若忽略,默认远程仓库为 origin)的上游分支(无上游分支,则失败)
$ git push [<remote>]

# 推送本地指定分支到指定远程仓库同名的分支(如果远程分支不存在则创建)
$ git push <remote> <branch> ...

# 推送本地指定分支到指定远程仓库指定的分支(如果远程分支不存在则创建)
$ git push <remote> <local-branch>:<remote-branch> ...

# 推送指定分支到指定远程仓库的指定分支,同时将二者关联为上下游关系
$ git push -u|--set-upstream [<remote>] [<branch> ...|<local-branch>:<remote-branch> ...]

# 推送本地所有分支到指定远程仓库,不存在则创建,否则对应到同名分支
$ git push --all <remote>

# 推送本地所有标签到指定远程仓库,不存在则创建,否则对应到同名标签
$ git push --tags <remote>

# 推送指定分支到指定远程仓库对应的分支,如果本地分支已不存在,那么删除指定远程仓库中对应的远程分支
$ git push --prune <remote> <branch>

# 推送所有本地分支到指定远程仓库对应的分支,删除指定远程仓库中所有未与本地任何分支对应的远程分支
$ git push --prune [--all]|[--tags] <remote>

# 删除指定远程仓库中指定 ref
$ git push <remote> :<remote-branch> ...

# 删除指定远程仓库中指定 ref
$ git push -d|--delete <remote> <branch>

# 强制执行推送等操作(如直接覆盖 ref 内容等)
$ git push -f|--force

抓取远程仓库内容到本地

命令格式:

git fetch [<options>] [<remote>] [<branch> ...]

常见用法:
# 抓取指定远程仓库(remote 若忽略,默认远程仓库为 origin)所有分支引用和标签信息
$ git fetch [<remote>]

# 抓取指定远程仓库指定的分支
$ git fetch <remote> <branch> ...

# 抓取指定远程仓库所有的标签
$ git fetch -t|--tags <remote>

拉取远程仓库内容到本地(fetch + merge/rebase)

命令格式:

git pull [<options>] [<remote>] [<branch> ...|<local-branch>:<remote-branch> ...]

常见用法:
# 拉取当前分支在指定远程仓库(remote 若忽略,默认远程仓库为 origin)中的上游分支内容到本地(无上游分支,则失败)
$ git pull [<remote>]

# 拉取指定远程仓库指定分支到当前分支
$ git pull <remote> <branch> ...

# 拉取指定远程仓库指定分支到本地指定分支(如果本地 ref 不存在则创建)
$ git pull <remote> <local-branch>:<remote-branch> ...

# 拉取指定远程仓库指定分支到当前分支,对当前分支进行变基(fetch + rebase)
$ git pull -r|--rebase <remote> <branch> ...

# 拉取指定远程仓库指定分支到当前分支,merge 合并后不进行自动提交
$ git pull --no-ff --no-commit <remote> <branch> ...

# 强制执行拉取等操作(如直接覆盖本地分支内容等)
$ git pull -f|--force

显示具体的内容(分支、标签、提交)

命令格式:

git show [<options>] [<commit> ...] [<pathspec> ...]

常见用法:
# 显示指定提交处相对于它上次提交的更改内容(类似于 "git diff HEAD HEAD~")
$ git show [<commit>]

# 显示指定提交处相对于它上次提交所修改的文件列表
$ git show --name-only [<commit>]

# 显示指定提交处相对于它上次提交所更改的文件列表和这些文件的更改类型(M、D、A 等)
$ git show --name-status [<commit>]

# 显示指定提交处指定文件相对于它上次提交中该文件的更改内容(类似于 "git diff HEAD HEAD~ <pathspec>")
$ git show [<commit>] [<pathspec> …]

显示分支及其提交

命令格式:

git show-branch [<options>] [<commit> ...]

常见用法:
# 显示本地所有分支列表,同时列出从各分支共同祖先提交到各分支 HEAD 的提交记录
$ git show-branch

# 显示远程所有分支列表,同时列出从各分支共同祖先提交到各分支 HEAD 的提交记录
$ git show-branch [-r|--remotes]

# 显示所有分支(本地和远程)列表,同时列出从各分支共同祖先提交到各分支 HEAD 的提交记录
$ git show-branch [-a|--all]

# 显示本地指定提交所涉及的分支列表,同时列出从各分支共同祖先提交到各指定提交的提交记录(如果 commit 仅为一个,那么只显示该提交处的提交信息)
$ git show-branch [<commit> …]

# 显示本地指定提交所涉及的分支列表,同时列出各分支的共同祖先提交的 SHA1(如果 commit 仅为一个,那么只显示该提交处的提交信息)
$ git show-branch --merge-base [<commit> …]

显示版本库中的引用

命令格式:

git show-ref [<options>]

常见用法:
# 显示版本库中所有的引用及其 SHA1
$ git show-ref

# 显示版本库中所有的分支引用及其 SHA1
$ git show-ref --heads

# 显示版本库中所有的标签引用及其 SHA1
$ git show-ref --tags

# 显示版本库中所有的引用及其 SHA1,同时控制 SHA1 显示位数 n(n 可不必指定,系统会默认)
$ git show-ref --abbrev[=<n>]

列出索引区(相对于工作区)文件的信息

命令格式:

git ls-files [<options>] [<pathspec> ...]

常见用法:
# 列出索引区全部文件
$ git ls-files [-c|--cached]

# 列出索引区指定路径的文件
$ git ls-files [-c|--cached] <pathspec> ...

# 列出在索引区中存在但是在工作区被删除的文件
$ git ls-files -d|--deleted

# 列出在索引区中存在但是在工作区被修改(包括被删除)的文件
$ git ls-files -m|--modified

# 列出工作区未跟踪、已忽略的文件
$ git ls-files -o|--others

# 列出索引区全部文件,同时附带文件模式、SHA1 等信息,可以指定 SHA1 显示位数
$ git ls-files -s|--stage [--abbrev[=<n>]]

# 列出索引区全部文件,如果整个目录被归类为 “others”,只显示它的名称
$ git ls-files --directory

列出提交中的内容

命令格式:

git ls-tree [<options>] [<pathspec> ...]

常见用法:
# 列出指定提交包含的全部内容
$ git ls-tree <commit>

# 列出指定提交代表的目录本身
$ git ls-tree -d <commit>

# 列出指定提交包含的全部内容,递归子目录
$ git ls-tree -r <commit>

# 列出指定提交包含的全部内容
$ git ls-tree --abbrev[=<n>] <commit>

# 列出指定提交包含的全部内容(不包括 SHA1 等信息,只有内容名称)
$ git ls-tree --name-only <commit>

# 列出指定提交包含的全部内容,内容路径是相对于当前工作目录的路径而非绝对路径
$ git ls-tree --full-name <commit>

列出远程存储库中的引用

命令格式:

git ls-remote [<options>] [<remote> [<commit> ...]]

常见用法:
# 列出指定远程仓库中所有可用的引用及其头部的 SHA1(remote 若忽略,默认远程仓库为 origin)
$ git ls-remote [<remote>]

# 列出指定远程仓库中所有分支及其头部的 SHA1
$ git ls-remote -h|--heads <remote>

# 列出指定远程仓库中所有标签及其头部的 SHA1
$ git ls-remote -t|--tags <remote>

# 列出指定远程仓库中所有指定的引用及其头部的 SHA1
$ git ls-remote <remote> <commit> ...

比较提交、索引区和工作区间的差异

命令格式:

git diff [<options>] [--cached] [<commit>] [--] [<pathspec> ...]

常见用法:
# 比较并显示工作区与索引区间的差异
$ git diff

# 比较并显示索引区与版本库间的差异
$ git diff --cached

# 比较并显示工作区(或索引区)与版本库指定提交中指定文件间的差异
$ git diff [--cached] [<commit> ...] [<pathspec> ...]

# 比较并显示工作区(或索引区)与索引区间的差异统计信息
$ git diff [--cached] --stat

比较提交范围间的差异

命令格式:

git range-diff [<options>] ...

git range-diff [<options>]

git range-diff [<options>] .. ..

常见用法:
# 比较并显示两个提交范围内提交记录的差异,若有冲突则会显示首先发生冲突的两个提交间的差异内容
$ git range-diff <commit1>..<commit2> <commit3>..<commit4>

# 比较并显示两个提交范围内提交记录的差异,若有冲突则会显示首先发生冲突的两个提交间的差异内容
# 相当于 "git range-diff <to-commit>..<from-commit> <from-commit>..<to-commit>"
$ git range-diff <from-commit>...<to-commit>

# 比较并显示两个提交范围内提交记录的差异,若有冲突则会显示首先发生冲突的两个提交间的差异内容
# 相当于 "git range-diff <base-commit>..<commit1> <base-commit>..<commit2>"
$ git range-diff <base-commit> <commit1> <commit2>

查看提交日志

命令格式:

git log [<options>] [<revision-range>] [[--] <pathspec> ...]

常见用法:
# 显示当前分支的提交记录
$ git log

# 显示当前分支指定路径的提交记录
$ git log [<pathspec> ...]

# 显示指定提交中指路径沿其所在分支的提交记录(记录到指定提交为止)
$ git log [<commit> ...] [<pathspec> ...]

# 显示(指定路径)从 target-commit 未合并到 base-commit 的提交记录
$ git log <base-commit>..<target-commit> [<pathspec> ...]

# 显示(指定路径)从 target-commit 和 base-commit 未合并到对方的提交记录
# 相当于 git log base-commit..target-commit 与 git log target-commit..base-commit 的内容总和
$ git log <base-commit>...<target-commit> [<pathspec> ...]

# 显示当前分支指定路径的提交记录(包括文件的重命名),只支持单个文件或目录
$ git log --follow <pathspec>

# 显示当前分支提交记录同时附带每次提交的统计信息(如被更改的文件列表)
$ git log --stat

# 显示内容(代码)中 content 第一次被添加的提交记录
$ git log -S "<content>"

# 显示出指定路径的提交记录,包含每次更改的内容 diff
$ git log -p [<pathspec> ...]

# 显示当前分支提交记录同时附带每次提交被更改的文件列表
$ git log --name-only

# 显示当前分支提交记录同时附带每次提交被更改的文件列表及其更改类型(M、D、A 等)
$ git log --name-status

### 日志过滤
# 显示所有分支的提交记录
$ git log --all

# 显示指定个数的提交记录
$ git log -<number>|-n <number>|--max-count=<number>

# 显示跳过指定个数下面的提交记录(从 HEAD(或指定提交)开始,跳过 number 个记录,然后输出)
$ git log --skip=<number>

# 显示指定日期之后的提交记录(date-pattern 类似于 yyyy-MM-dd 等)
$ git log --after="<date-pattern>"|--since="<date-pattern>"

# 显示指定日期之前的提交记录(date-pattern 类似于 yyyy-MM-dd 等)
$ git log --before="<date-pattern>"|--until="<date-pattern>"

# 显示由指定(或正则匹配)作者(或提交者)提交的记录
$ git log --author="<pattern>"|--committer="<pattern>"

# 显示包含指定(或正则匹配)提交内容的提交记录,可指定全匹配,可指定反转 grep,可指定正则字符串忽略大小写
# 反转 grep:即隐藏 grep 指定的提交记录,反而显示未指定的记录
$ git log [--invert-grep] [--all-match] [--regexp-ignore-case] --grep="<pattern>"

# 显示指定提交之前的所有合并的提交记录
$ git log --merges [<commit>]

# 显示指定提交之前的所有非合并的提交记录
$ git log --no-merges [<commit>]

### 日志格式
# 以指定格式显示提交记录
$ git log --format=<format>

# 以指定预设格式显示提交记录
$ git log --pretty=<oneline|short|medium|full|fuller|email|reference>

# 以简略的 SHA1 显示提交记录
$ git log --abbrev-commit

# 以单行的格式显示提交记录,相当于 "git --pretty=oneline --abbrev-commit"
$ git log --oneline

# 以指定格式(format)的日期时间显示提交记录
$ git log --date=<format>

# 以图形化的格式显示提交记录(在记录的左侧绘制基于文本的提交历史图形)
$ git log --graph

查看本地引用日志

命令格式:

git reflog [show|expire|delete|exists] [<options>] [<branch>]

常见用法:
# 显示所有本地分支的引用记录
$ git reflog

# 显示指定本地分支的引用记录
$ git reflog <branch>

# 显示指定个数的引用记录
$ git reflog -<number>|-n <number>|--max-count=<number>

查看发布日志

命令格式:

git shortlog [<options>] [<revision-range>] [[--] <pathspec> ...]

常见用法:
# 列出所有提交信息(默认根据作者分组按提交顺序正序排序)
$ git shortlog

# 列出指定提交所在分支的所有提交信息(记录截止到该提交)
$ git shortlog [<commit>]

# 列出与指定路径下的内容相关提交信息
$ git shortlog <pathspec> ...

# 列出所有提交的统计结果(如某人一共进行了多少次提交)
$ git shortlog -s|--summary

# 列出所有提交的统计结果,附带作者邮箱地址(如某人一共进行了多少次提交)
$ git shortlog -e|--email

# 显示指定个数的提交信息
$ git shortlog -<number>|-n <number>|--max-count=<number>

# 显示跳过指定个数下面的提交信息(从 HEAD(或指定提交)开始,跳过 number 个记录,然后输出)
$ git shortlog --skip=<number>

# 显示指定日期之后的提交信息(date-pattern 类似于 yyyy-MM-dd 等)
$ git shortlog --after="<date-pattern>"|--since="<date-pattern>"

# 显示指定日期之前的提交信息(date-pattern 类似于 yyyy-MM-dd 等)
$ git shortlog --before="<date-pattern>"|--until="<date-pattern>"

# 显示由指定(或正则匹配)作者(或提交者)提交的信息
$ git shortlog --author="<pattern>"|--committer="<pattern>"

# 显示包含指定(或正则匹配)提交内容的提交信息,可指定全匹配,可指定反转 grep,可指定正则字符串忽略大小写
# 反转 grep:即隐藏 grep 指定的提交信息,反而显示未指定的信息
$ git shortlog [--invert-grep] [--all-match] [--regexp-ignore-case] --grep="<pattern>"

重置分支指针位置

命令格式:

git reset [--mixed] [<options>] [<commit>] [--] [<pathspec> ...]

git reset [--soft|--mixed|--hard|--merge|--keep] [<options>] [<commit>]

常见用法:
# 重置当前分支版本库中的所有内容到指定提交
$ git reset --soft [<commit>]

# 重置当前分支版本库、索引区的所有内容到指定提交
$ git reset --mixed [<commit>]

# 重置当前分支索引区指定文件(目录)的内容到指定提交(当前分支指针指向的提交没有重置)
$ git reset --mixed [<commit>] [--] [<pathspec> ...]

# 重置当前分支版本库、索引区、工作区的所有内容到指定提交
$ git reset --hard [<commit>]

# 重置当前分支版本库、索引区、工作区内 “未修改” 或 “已修改且添加到索引区” 的内容(保留已修改且未暂存的内容,即保留工作区和索引区之间的差异)到指定提交(对于保留的内容,若当前分支 HEAD 中与它对应的内容在指定提交处有变更(两个版本的内容不一致),则命令会失败)
$ git reset --merge [<commit>]

# 重置当前分支版本库、索引区、工作区内 “未修改” 的内容(保留已修改内容,不论是否添加到索引区,即保留工作区和 HEAD 之间的差异)到指定提交(对于保留的内容,若当前分支 HEAD 中与它对应的内容在指定提交处有变更(两个版本的内容不一致),则命令会失败)
$ git reset --keep [<commit>]

拣选应用指定提交

命令格式:

git cherry-pick [<options>] ...

git cherry-pick --continue|--skip|--abort|--quit

常见用法:
# 拣选并应用指定提交
$ git cherry-pick <commit> [...]

# 拣选并应用指定提交(<from-commit>...<to-commit> 范围是左开右闭区间)
$ git cherry-pick <from-commit>..<to-commit>

# 应用指定提交在记录提交时,在每个原始提交信息后添加一行 “(cherry picked from commit …)”,以指示此更改是从哪个提交中挑选的,仅适用于没有冲突的应用
$ git cherry-pick -x <commit> [...]

# 拣选并应用指定提交,并将应用后的内容添加到索引区,需要手动提交
$ git cherry-pick -n|--no-commit [<commit>] [...]

# 拣选并应用指定提交,在应用发生冲突后自动选择当前内容(ours)或指定提交内容(theirs)以完成合并
$ git cherry-pick -X<ours|theirs> [<commit>] [...]

# 当拣选并应用的指定提交有不止一个父提交(如合并分支)时选择要应用的父提交内容,其他父提交内容不会被应用
# git merge <branch> 下的当前分支编号为 1,branch 编号为 2,多个父提交都是按此规律进行主次的分别,主分支比次分支要小
$ git cherry-pick -m|--mainline <parent-number> [<commit>] [...]

# 在应用拣选的提交发生冲突并解决后继续应用拣选的提交(此命令与 git commit -a 同义)
$ git cherry-pick --continue

# 在应用拣选的提交发生冲突后终止应用同时恢复到未应用状态(若此时有未提交的更改,也会被恢复,造成内容丢失)
$ git cherry-pick --abort

# 在应用拣选的提交发生冲突后跳过冲突(保留当前内容)并继续应用
$ git cherry-pick --skip

撤销应用指定提交

命令格式:

git revert [<options>] ...

git revert --continue|--skip|--abort|--quit

常见用法:
# 撤销指定提交引入的内容,并为此创建一个新提交
$ git revert <commit> [...]

# 撤销指定提交间引入的内容,并为此创建一个新提交(<from-commit>...<to-commit> 范围是左开右闭区间)
$ git revert <from-commit>..<to-commit>

# 撤销指定提交引入的内容,并将撤销后的内容添加到索引区,需要手动提交
$ git revert -n|--no-commit [<commit>] [...]

# 当撤销指定的提交有不止一个父提交(如合并分支)时选择要保留的父提交,并执行撤销
# git merge <branch> 下的当前分支编号为 1,branch 编号为 2,多个父提交都是按此规律进行主次的分别,主分支比次分支要小
$ git revert -m|--mainline <parent-number> [<commit>] [...]

# 撤销指定提交引入的内容,在撤销发生冲突后自动选择当前内容(ours)或指定提交内容(theirs)以完成合并
$ git revert -X<ours|theirs> [<commit>] [...]

# 在撤销发生冲突并解决后继续撤销(此命令与 git commit -a 同义)
$ git revert --continue

# 在撤销发生冲突后终止撤销同时恢复到未撤销状态(若此时有未提交的更改,也会被恢复,造成内容丢失)(如果此时有未提交的更改,那么也会被恢复,造成内容丢失)
$ git revert --abort

# 在撤销发生冲突后跳过冲突(保留当前内容)并继续撤销
$ git revert --skip

贮藏工作区和索引区修改

命令格式:

git stash [list|show|push|pop|apply|drop|clear] [<options>] [[<stash> ...]|[<pathspec> ...]]

常见用法:
# 列出当前所有贮藏
$ git stash list

# 显示指定的贮藏
$ git stash show [<stash>]

# 将已修改、已暂存的内容全部贮藏(不可以使用 <pathspec> 参数)
$ git stash

# 此命令等效于 "git stash"
$ git stash push

# 将指定路径(不指定默认全部)内已修改、已暂存的内容全部贮藏,同时提供贮藏信息
$ git stash push [<pathspec> ...] [-m|--message <message>]

# 将指定路径内已暂存的内容全部贮藏,忽略已修改的内容
$ git stash push -S|--staged

# 将已修改、已暂存的内容全部贮藏,同时包括未被跟踪的内容(默认只贮藏被跟踪的内容修改)
$ git stash push -u|--include-untracked

# 将指定贮藏应用于 HEAD 上,同时删除此贮藏(stash 省略则默认为栈顶(stash@{0})处的贮藏)
$ git stash pop [<stash>]

# 将指定贮藏应用于 HEAD 上(stash 省略则默认为栈顶(stash@{0})处的贮藏)
$ git stash apply [<stash>]

# 删除指定贮藏(stash 省略则默认为栈顶(stash@{0})处的贮藏)
$ git stash drop [<stash>]

# 删除全部贮藏
$ git stash clear

Git Flow 管理

命令格式:

git flow


版本更新

命令格式:

git update-git-for-windows


附录

Git 命令清单

下面是 Git 全部命令,被注释命令代表已学习

Main Porcelain Commands(主要命令)
   # add                向索引中添加文件内容
   am                   从邮箱应用一系列补丁
   archive              从指定的提交创建压缩文件
   bisect               使用二分搜索来查找引入 bug 的提交
   # branch             列出、创建或删除分支
   bundle               通过压缩文件移动对象和引用
   # checkout           切换分支或恢复工作树文件
   # cherry-pick        应用一些现有提交引入的更改
   citool               git-commit 的 GUI 选择
   # clean              从工作区中删除未跟踪的文件
   # clone              将存储库克隆到一个新目录中
   # commit             记录对存储库的更改
   describe             根据可用的引用给对象一个人类可读的名称
   # diff               显示提交与提交、提交与工作区之间的变化等等
   # fetch              从另一个存储库下载引用和对象
   format-patch         为电子邮件提交准备补丁
   # gc                 清理不必要的文件并优化本地存储库
   gitk                 Git 存储库浏览器
   grep                 打印匹配指定模式的行
   gui                  移植到 Git 的图形界面
   # init               创建一个空的存储库或重新初始化一个现有的存储库
   # log                显示提交日志
   maintenance          运行任务优化 Git 存储库数据
   # merge              将两个或更多的分支合并一起
   # mv                 移动或重命名文件、目录或符号链接
   # notes              添加或检查对象注释
   # pull               从另一个存储库或本地分支获取并与之集成
   # push               更新远程引用和相关对象
   # range-diff         比较两个提交范围(例如一个分支的两个提交)
   # rebase             在另一个提交上重新应用提交
   # reset              重置当前 HEAD 到指定的状态
   # restore            恢复工作树文件
   # revert             恢复一些现有的提交
   # rm                 从工作区和索引中删除文件
   # shortlog           总结 git 日志输出
   # show               显示各种类型的对象
   sparse-checkout      初始化和修改稀疏签出
   # stash              将更改隐藏在一个脏的工作目录中
   # status             显示工作树状态
   submodule            初始化、更新或检查子模块
   # switch             切换分支
   # tag                创建、列出、删除或验证用 GPG 签名的标签
   worktree             管理多个工作树

Ancillary Commands / Manipulators(辅助命令)
   # config             获取和设置存储库或全局选项
   fast-export          导出 Git 数据
   fast-import          导入 Git 数据
   filter-branch        重写分支
   mergetool            运行合并冲突解决工具来解决合并冲突
   pack-refs            打包 HEAD 和标签,以便有效地访问存储库
   prune                从对象数据库中删除所有不可访问的对象
   # reflog             管理 reflog 信息
   # remote             管理一组跟踪存储库
   repack               将未打包的对象打包到存储库中
   replace              创建、列出、删除引用来替换对象
   annotate             用提交信息注释文件行
   blame                显示哪个版本和作者最后修改了文件的每一行
   bugreport            收集用户提交 bug 报告所需的信息
   count-objects        计算已解包的对象数量及其磁盘消耗
   difftool             使用常用的差异工具显示差异
   fsck                 验证数据库中对象的连接性和有效性
   gitweb               Git web 界面(web 端到 Git 仓库)
   # help               显示 Git 的帮助信息
   instaweb             立即在 gitweb 浏览您的工作存储库
   merge-tree           显示三路合并而不触及索引
   rerere               重用记录的合并冲突解决方法
   # show-branch        显示分支及其提交
   verify-commit        检查提交的 GPG 签名
   verify-tag           检查标签的 GPG 签名
   whatchanged          根据不同的提交介绍显示日志

Interacting with Others(交互和其他命令)
   archimport           导入一个 GNU Arch 库到 Git 中
   cvsexportcommit      将单个提交导出到 CVS 签出
   cvsimport            从别人讨厌的 SCM 中拯救你的数据
   cvsserver            用于 Git 的 CVS 服务器模拟器
   imap-send            从 stdin 发送补丁集合到 IMAP 文件夹
   p4                   导入并提交到 Perforce 存储库
   quiltimport          将 quilt 补丁集应用到当前的分支上
   request-pull         生成挂起更改的摘要
   send-email           以邮件形式发送补丁集合
   svn                  Subversion 存储库和 Git 之间的双向操作

Low-level Commands / Manipulators(底层命令)
   apply                对文件、索引应用补丁
   checkout-index       将文件从索引区复制到工作区
   commit-graph         编写并验证 Git 提交图文件
   commit-tree          创建一个新的提交对象
   hash-object          计算对象 ID 并可选地从文件创建一个 blob
   index-pack           为现有的打包压缩构建压缩索引文件
   merge-file           运行三路文件合并
   merge-index          对需要合并的文件运行合并
   mktag                创建一个带有额外验证的标记对象
   mktree               从 ls-tree 格式的文本构建一个树对象
   multi-pack-index     编写和验证多包索引
   pack-objects         创建一个打包的对象存档
   prune-packed         删除包文件中已经存在的额外对象
   read-tree            将树信息读取到索引区中
   symbolic-ref         读取、修改和删除符号引用
   unpack-objects       从打包的压缩文件中解压对象
   update-index         将工作树中的文件内容注册到索引区
   update-ref           安全地更新存储在 ref 中的对象名称
   write-tree           从当前索引区创建树对象
   cat-file             为存储库对象提供内容或类型和大小信息
   cherry               查找尚未应用于上游的提交
   diff-files           比较工作区和索引区中的文件
   diff-index           比较提交树与工作区或索引区
   diff-tree            比较通过两个树对象找到的 blobs 的内容和模式
   for-each-ref         每个引用的输出信息
   for-each-repo        在存储库列表中运行 Git 命令
   get-tar-commit-id    从使用 git-archive 创建的压缩文件中提取提交 ID
   # ls-files           在索引区和工作区中显示有关文件的信息
   # ls-remote          列出远程存储库中的引用
   # ls-tree            列出树对象的内容
   merge-base           为合并找到尽可能好的共同祖先
   name-rev             找出给定提示的符号名称
   pack-redundant       找到多余的包文件
   rev-list             列表按时间倒序提交对象
   rev-parse            挑选和推断参数
   show-index           显示压缩归档索引
   # show-ref           列出本地存储库中的引用
   unpack-file          创建一个包含 blobs 内容的临时文件
   var                  显示一个 Git 逻辑变量
   verify-pack          验证打包的 Git 压缩文件
   daemon               一个非常简单的 Git 存储库服务器
   fetch-pack           从另一个存储库接收丢失的对象
   http-backend         服务器端实现的 Git over HTTP
   send-pack            通过 Git 协议将对象推送到另一个存储库
   update-server-info   更新辅助信息文件,以帮助简易的服务器
   check-attr           显示 gitattributes 信息
   check-ignore         调试 .gitignore、exclude 文件
   check-mailmap        显示联系人的规范名称和电子邮件地址
   check-ref-format     确保引用名称是格式良好的
   column               按列显示数据
   credential           检索和存储用户凭据
   credential-cache     将密码暂存在内存中的助手
   credential-store     在磁盘上存储凭据的助手
   fmt-merge-msg        生成合并提交消息
   interpret-trailers   在提交消息中添加或解析结构化信息
   mailinfo             从单个电子邮件中提取补丁和作者身份
   mailsplit            简单的 UNIX mbox 拆分程序
   merge-one-file       与 git-merge-index 一起使用的标准帮助程序
   patch-id             为补丁计算唯一 ID
   sh-i18n              Git i18n shell 脚本的设置代码
   sh-setup             常见的 Git shell 脚本设置代码
   stripspace           删除不必要的空格

External commands(外部命令)
   askpass
   askyesno
   credential-helper-selector
   # flow
   lfs
   # update-git-for-windows
posted @ 2022-03-18 23:12  Programmer-杨  阅读(89)  评论(0)    收藏  举报