# 比较全面的 Git 命令手册,几乎涵盖日常所有的使用场景(下)

# Git 内部原理
# Git 对象
# Blob 对象
;Blob对象即文件快照,Git暂存时会保存文件快照于目录.git/objects下。git init初始化的仓库下.git/objects默认创建空的pack和info子目录。Git的核心是一个简单的键值对数据库(key-value data store),可理解为文件目录和文件为键key,目录内文件内容为对应值value。
运行如下底层命令,向Git数据库插入内容。其中echo 'content'输出content文本,|为管道符,即前一命令的输出作为后一命令的输入。-w表示将内容写入数据库,--stdin表示从管道读取内容。如下命令可大致概括为echo 'content'输出content文本传入管道中,git hash-object --stdin从管道读取content文本,再指定-w选项将其写入Git数据库,即保存于.git/objects目录下。
echo 'content' | git hash-object -w --stdin
d95f3ad1...
;d95f3ad1...即blob对象的SHA-1校验和,在目录.git/objects中体现为前两位用于命名子目录,余下的38位则用作文件名。如下find用来在指定目录下查找文件,-type表示指定文件类型,f表示文件类型为一般文件。
find .git/objects -type f
.git/objects/d9/5f3ad1...
;d95f3ad1...也即键key,运行如下命令获取Git数据库中键对应的值。其中-p表示自动判断内容的类型并显示为格式友好的内容,也可指定-t选项查看对象类型。
git cat-file -p d95f3ad1
content
可能echo方式写入内容到Git数据库稍显复杂,也可取文件内容写入数据库。如下将readme.md文件的内容写入数据库。
git hash-object -w readme.md
# 极简版本控制
创建一个新文件并将其内容存入数据库。
echo 'hello world' > readme.md
git hash-object -w readme.md
3b18e512...
再次写入新内容并存入版本库。
echo 'hi git' > readme.md
git hash-object -w readme.md
2984e649...
暂时查看数据库写入情况。
find .git/objects -type f
.git/objects/29/84e649...
.git/objects/3b/18e512...
控制文件内容为第一个版本。
git cat-file -p 3b18e512 > readme.md
cat readme.md
hello world
控制文件内容为第二个版本。
git cat-file -p 2984e649 > readme.md
cat readme.md
hi git
# Tree 对象
上述数据库中仅保存了文件内容,文件名尚未保存,而且记住每一个版本所对应的SHA-1校验和也不现实。Tree对象即树对象,则能很好解决此问题,一个树对象包含一条或者多条树对象记录,每条记录有一个指向数据对象(blob对象)或子树对象的SHA-1指针,以及相应的模式、类型、文件名或目录名。
某个树对象内容可能如下。其中master^{tree}表示master分支最新的提交所指向的树对象,readme.md和file.txt都是数据对象,dist为子树对象。
git cat-file -p master^{tree}
100644 blob a906cb12... readme.md
100644 blob 8f941322... file.txt
040000 tree 99f1a699... dist
查看子树对象。
git cat-file -p 99f1a699
100644 blob 47c63436... index.html
内部数据存储大致如下。
readme.md --> blob
/
tree —— file.txt --> blob
\
dist --> tree —— index.html --> blob
;Git是根据暂存区的状态来创建对应的树对象,因此需要将一些修改或文件加入暂存区。运行如下命令将修改暂存,若文件名不在暂存区中需指定--add选项,--cacheinfo表示将指定的信息加入暂存区,包括文件模式、SHA-1校验和与文件名,并且SHA-1校验和需指定完整值。如下命令可大致概括为暂存数据对象3b18e512...对应的修改,同时文件模式为100644,文件名为readme.md。
git update-index --add --cacheinfo 100644 \
3b18e512... readme.md
查看暂存区详细状态。
git ls-files -s
100644 3b18e512... 0 readme.md
运行如下命令,将暂存区内容写入一个树对象。其中7394b8cc...为树对象SHA-1校验和。
git write-tree
7394b8cc...
查看树对象内容和数据库写入情况
git cat-file -p 7394b8cc
100644 blob 3b18e512... readme.md
find .git/objects -type f
.git/objects/73/94b8cc...
# 子树对象
如上已经创建一个树对象,接下来再创建一个新树对象。
git update-index --add --cacheinfo 100644 \
2984e649... readme.md
也可暂存新文件,Git会根据新文件内容创建数据对象并写入数据库,再将数据对象SHA-1校验和、文件模式和文件名加入到暂存区。
echo 'file' > file.txt
git update-index --add file.txt
暂存区现在包括readme.md新版本和一个新文件file.txt,将暂存区内容再次写入一个新树对象。
git write-tree
e331c9c2...
查看暂存区域。
git ls-files -s
100644 f73f3093... 0 file.txt
100644 2984e649... 0 readme.md
现在数据库存在两个树对象7394b8cc...和e331c9c2...,运行如下命令将第一个树对象加入到暂存区域。其中--prefix表示将一个已有的树对象作为子树加入暂存区,dist为子目录名。
git read-tree --prefix=dist 7394b8cc
再次写入一个新树对象。
git write-tree
ccf028c6...
查看新树对象。
git cat-file -p ccf028c6
040000 tree 7394b8cc... dist
100644 blob f73f3093... file.txt
100644 blob 2984e649... readme.md
# 提交对象
现在已有三个树对象7394b8cc...、e331c9c2...和ccf028c6...,分别跟踪了不同文件快照。若想重用这些快照,需要记住如上三个SHA-1校验和。同时也不知道是谁保存了这些快照、在什么时刻保存的,以及为什么保存这些快照,以上则引出了提交对象。
运行如下命令创建一个提交对象。其中'A'即为提交信息,7394b8cc为创建后的提交对象指向的树对象。
echo 'A' | git commit-tree 7394b8cc
f0dcf2c3...
查看提交对象f0dcf2c3。
git cat-file -p f0dcf2c3
tree 7394b8cc...
author ...
committer ...
A
根据另外两个树对象创建提交对象,其中e331c9c2表示树对象校验和,-p表示指定父提交对象,f0dcf2c3为父提交对象校验和。
echo 'B' | git commit-tree e331c9c2 -p f0dcf2c3
5d3d89ce...
echo 'C' | git commit-tree ccf028c6 -p 5d3d89ce
b41c0107...
查看提交对象5d3d89ce。
git cat-file -p 5d3d89ce
tree e331c9c2...
parent f0dcf2c3...
author ...
committer ...
B
此时Git内部关系大致如下,但是暂时还不能git log查看提交历史,因为还不存在分支。
readme.md (2984e649) --> blob (hi git) ------------------------------------|
/ |
C (b41c0107) --> tree (ccf028c6) —— dist --> tree (7394b8cc) —— readme.md (3b18e512) --> blob (hello world) --|--|
| \ | |
| file.txt (f73f3093) --> blob (file) ------------------------------------| | |
| | | |
B (5d3d89ce) --> tree (e331c9c2) —— readme.md (2984e649) --> blob (hi git) --------------------------------|--| |
| \ | |
| file.txt (f73f3093) --> blob (file) ------------------------------------| |
| |
A (f0dcf2c3) --> tree (7394b8cc) —— readme.md (3b18e512) --> blob (hello world) ---------------------------------|
# 对象存储
;Git数据对象存储步骤大致如下。其实所有的Git对象均以此方式存储,区别仅在于类型标识,另两种对象类型的头部信息以字符串commit或tree开头,而不是blob。虽然数据对象的内容可以是任何东西,但提交对象和树对象的内容却有各自固定的格式。
- 读取文件内容,以对象类型
blob作为开头来构造一个头部信息,拼接头部信息和文件原始内容,记为content - 计算
content的SHA-1校验和,得到长度为40个十六进制字符的哈希值 - 取哈希值前两位作为文件目录,剩余
38为作为文件名 - 对
content执行lib压缩,获得新的二进制内容,存入文件中
# Git 引用
上述提交历史可运行git log b41c0107查看,其中b41c0107为提交记录C的部分校验和。但是查看提交历史仍然需记住某次记录的部分校验和,倘若用某个文件保存校验和,同时起一个简单的名字,问题将会得到很好解决,而这种文件就被称为引用。引用文件均保存在.git/refs目录下。
# 分支引用
若要创建一个分支引用,仅在.git/refs/heads目录下新增分支名,且内容为某次提交的校验和即可。Git提供了更加安全的命令update-ref,如下表示将部分校验和b41c0107对应的完整校验和写入.git/refs/heads目录下的master文件。
git update-ref refs/heads/master b41c0107
如下查看master分支文件的内容。同时也印证了分支是指向提交对象的可变指针。
cat .git/refs/heads/master
b41c0107...
# HEAD 引用
;HEAD是一个符号引用,指向当前所在分支,或者说是一个指向其他引用的分支。
运行git branch dev即创建一个dev分支,但是查看dev引用文件的内容,会有完整的校验和,此校验和即是通过HEAD来获取的。
创建dev分支时Git首先会找到HEAD指向的分支,再获取此分支保存的完整校验和,将此校验和写入.git/refs/heads目录下dev文件中。
git branch dev
cat .git/refs/heads/dev
b41c0107...
查看HEAD内容。
cat .git/HEAD
ref: refs/heads/master
如下表示将当前HEAD指向dev分支。
git symbolic-ref HEAD refs/heads/dev
# 标签引用
标签包括轻量标签和附注标签。
轻量标签是一个固定的引用,指向某个提交对象。
附注标签会指向一个标签对象,标签对象保存一个引用来指向某个提交对象。
运行如下底层命令,创建一个轻量标签v1.8.5。
git update-ref refs/tags/v1.8.5 HEAD
查看轻量标签v1.8.5,如下轻量标签v1.8.5指向提交b41c0107。
cat .git/refs/tags/v1.8.5
b41c0107...
创建附注标签v1.8.6。
git tag -a v1.8.6 HEAD -m 'message'
查看附注标签指向的标签对象的完整校验和,如下附注标签指向标签对象4740ea0b。
cat .git/refs/tags/v1.8.6
4740ea0b...
查看标签对象4740ea0b内容,其中object表示指向的提交记录。
git cat-file -p 4740ea0b
object b41c0107...
type commit
tag v1.8.6
tagger ...
message
# 远程引用
远程引用即本地仓库中保存远程仓库中各分支的指向信息。
远程引用是只读的,可以git checkout到某个远程引用,但是Git并不会将HEAD引用指向此远程引用。
远程引用一般保存在refs/remotes目录下,当与远程仓库交互时,远程引用会被更新。
若远程仓库repo含分支dev、master,添加远程仓库origin并拉取。
git remote add origin https://github.com/username/repo.git
git fetch origin
...
From https://github.com/username/repo
* [new branch] dev -> origin/dev
* [new branch] master -> origin/master
查看目录.git/refs/remotes/origin下文件。
find .git/refs/remotes/origin -type f
.git/refs/remotes/origin/dev
.git/refs/remotes/origin/master
查看远程仓库master分支,其中90edc78e为master分支指向的最新提交的校验和。
cat .git/refs/remotes/origin/master
90edc78e...
# 包文件
;Git跟踪了某个数千行代码的文件,若改动了此文件的某一行代码,Git会将整个文件保存为数据对象(blob)。此文件原始对象和改动后的对象被称为松散(loose)对象。
;Git向磁盘中存储对象时所使用的格式为松散对象格式,并时不时地将多个对象打包成一个的包文件(二进制文件),以此来节省空间和提高效率。 版本库中有太多的松散对象或者执行git gc,或者向远程服务器推送时,Git都会打包。
;git gc会将一个文件的完整内容保存为数据对象,再将与完整内容之间的差异保存为另一个数据对象。
# 打包
初始化一个空仓库repo,新增一个10kb左右的readme.md文件,暂存后查看暂存区readme.me文件大小(10311字节),提交此次修改。
git add readme.md
git ls-files -s
100644 767466fd... 0 readme.md
git cat-file -s 767466fd
10311
git commit -m 'A'
;readme.md文件尾部追加部分内容后也暂存并查看文件大小(10319字节)。
echo 'message' >> readme.md
git add readme.md
git ls-files -s
100644 f08cfd3e... 0 readme.md
git cat-file -s f08cfd3e
10319
git commit -m 'B'
查看.git/objects下新增的对象,其中包括6个对象,两个树对象、两个提交对象、两个数据对象。
find .git/objects -type f
.git/objects/76/7466fd...
.git/objects/f0/8cfd3e...
...
运行git gc打包松散对象,查看.git/objects下对象。其中包括一个.idx索引文件和一个.pack包文件,包文件包含了从Git数据库中移除的所有对象的内容,索引文件包含了包文件的偏移信息,通过索引文件可以快速定位任意一个指定对象。
注意大部分对象都会被打包到包文件中,但是Git会保留悬空的数据对象,即未被任何提交记录引用的数据对象。
git gc
.git/objects/info/packs
.git/objects/pack/pack-3575...a060.idx
.git/objects/pack/pack-3575...a060.pack
运行如下底层命令查看索引文件内容。其中包括6个对象,每一行含对象的SHA-1校验和、类型、文件大小、打包文件大小、打包文件偏移,可能再包含深度、基础SHA-1校验和。
注意readme.md第二个版本f08cfd3e保存了完整内容,反而第一个版本767466fd保存了差异内容,因为大多数情况下Git需要快速访问最新版本。
git verify-pack -v .git/objects/pack/pack-3575...a060.ind
f08cfd3e... blob 10319 2561 265
767466fd... blob 7 18 2921 1 f08cfd3e...
...
# 引用
;git gc会做的另一件事是打包.git/refs目录下的引用到文件.git/packed-refs中。若当前版本库中包含如下分支和标签。
find .git/refs -type f
.git/refs/heads/master
.git/refs/remotes/origin/master
.git/refs/tags/v1.8.5
.git/refs/tags/v1.8.6
打包后上述引用不会再出现在.git/refs目录下,均会被移动到.git/packed-refs文件中。其中^表示它上一行的标签是附注标签,^所在行是那个附注标签指向的提交记录的校验和。
打包后更新了引用,Git并不会修改packed-refs文件,而是在.git/refs目录下创建新的引用文件。若Git要获取引用文件的最新SHA-1校验和,首先会在.git/refs目录下查找指定的引用文件,然后再到packed-refs文件中查找。
cat .git/packed-refs
ceb21368... refs/heads/master
040db796... refs/remotes/origin/master
ceb21368... refs/tags/v1.8.5
9dcb07d9... refs/tags/v1.8.6
^ceb2136...
# 引用规格
本地仓库关联远程仓库后,查看.git/config文件。其中指定了远程版本库的名称、url和用于获取的引用规格。诸如<src>:<dst>的格式称为引用规格,<src>表示远程版本库中的引用,<dst>表示远程引用在本地所对应的位置,+表示不能快进情况下强制更新引用。
git remote add origin https://github.com/username/repo.git
cat .git/config
...
[remote "origin"]
url = https://github.com/username/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
默认情况下,运行git fetch将获取远程仓库refs/heads目录下所有引用,同时写入本地refs/remotes/origin目录下。
git fetch origin
...
From https://github.com/username/repo
* [new branch] dev -> origin/dev
* [new branch] master -> origin/master
find .git/refs/remotes/origin -type f
.git/refs/remotes/origin/dev
.git/refs/remotes/origin/master
# 拓展
本地仓库获取fetch远程仓库master分支后,查看此分支提交历史。如下三个命令等价,并最终都会被拓展为refs/remotes/origin/master。
git log origin/master
git log remotes/origin/master
git log refs/remotes/origin/master
# 获取
只获取远程仓库repo的master分支,而不是所有分支,修改为如下引用规格。
fetch = +refs/heads/master:refs/remotes/origin/master
获取多个远程分支。如下表示仅获取远程master和dev分支。
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/dev:refs/remotes/origin/dev
# 命名空间
推送本地master分支到远程仓库feat/master分支。
git push origin master:feat/master
仅获取远程仓库dev分支和命名空间feat下的分支,修改为如下引用规格。
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/feat/*:refs/remotes/origin/feat/*
# 强制更新
若远程仓库repo存在master分支,用户A、B和C均关联并获取fetch了最新的修改。
用户A将与原历史无关的提交历史强制推送到了master。
用户B仓库.git/config配置如下。
fetch = +refs/heads/*:refs/remotes/origin/*
用户C仓库.git/config配置如下,即删除+不开启强制更新。
fetch = refs/heads/*:refs/remotes/origin/*
用户B获取fetch远程仓库中的修改,其中forced update即表示强制更新了master提交历史。
git fetch origin
...
+ ... master -> origin/master (forced update)
用户C获取远程仓库修改,其中master分支的拉取被拒绝,因为其提交历史不能快进。
git fetch origin
...
! [rejected] master -> origin/master (non-fast-forward)
# 恢复与移除
# 数据恢复
若某版本库提交历史如下,当前HEAD指向master分支。
A —— B —— C —— D —— E <-- master <-- HEAD
回退master分支到提交记录C。
git reset --hard HEAD^^
此时若再将master分支提交记录切换到E,可运行git reflog查看引用日志中的提交E。
git reflog
...
329e7f4 HEAD@{1}: commit: E
运行git reset --hard HEAD@{1}可将master切换到提交E。
可能因为某些原因提交E不在引用日志reflog中,同时也没有任何引用指向提交E。
要模拟此场景首先还是将master指向提交C,然后删除.git/logs目录中的引用日志,此时再运行git reflog将没有任何输出。
rm -r .git/logs
运行如下命令,Git会检查数据库完整性,其中--full选项会显示出所有没有被其他对象指向的对象,dangling commit后即为提交E的校验和。
git fsck --full
...
dangling commit 329e7f4...
# 磁盘空间
运行如下命令,查看Git数据库中对象数量及其磁盘消耗。
git count-objects -v
count: 3
size: 4
in-pack: 6
packs: 1
size-pack: 132
prune-packable: 2
garbage: 0
size-garbage: 0
打印参数描述如下。
count:松散对象的数量size:松散对象占用的磁盘空间,以KiB为单位in-pack:包文件中所有对象的数量,即.git/objects/pack目录下所有以.idx为后缀名文件中保存的对象的个数packs:包文件的数量,即.git/objects/pack目录下以.pack为后缀名文件的个数size-pack:包文件占用的磁盘空间,以KiB为单位prune-packable:包文件中存在的松散对象的数量,运行git prune-packed可删除,运行git prune-packed -n显示将要删除的对象garbage:垃圾文件的数量,既不是有效的松散对象也不是有效包的文件数size-garbage:垃圾文件占用的磁盘空间,以KiB为单位
# 移除对象
如果某个人向Git版本库添加了一个特别大的文件,然后又从项目中移除了,但是由于Git提交历史跟踪了此文件,或者说通过提交历史可随时还原此文件,每次运行git clone克隆项目历史时,都会强制下载此文件,造成的情况就是每次克隆非常耗时。
因此必须从最早开始引用此文件的树对象开始重写每一个提交记录,此操作破坏性地修改了提交历史,其他人拉取记录时最好运行git pull --rebase。
可能由于历史线过长不知道那个特别大的文件是什么,可通过如下方式查找出那个文件。
首先运行git gc打包Git数据库中的对象,同时查看.git/objects/pack目录下文件。
git gc
find .git/objects/pack -type f
.git/objects/pack/pack-3aa8...a09e.idx
.git/objects/pack/pack-3aa8...a09e.pack
运行如下命令,查看索引文件内容并排序。其中第一行输出索引文件内容,通过管道传递给下一行命令。sort排序管道输入内容,-n表示按照数值大小排序,-k 3表示根据内容的第三列进行排序。tail -3表示显示内容的尾部3行。
git verify-pack -v .git/objects/pack/pack-3aa8...a09e.idx \
| sort -n -k 3 \
| tail -3
bc65c0d9... commit 206 141 437
c4a96707... commit 206 140 1145
072e320f... blob 7407405 6594320 1978
上述列表中数据对象072e320f占用了7M左右的空间,运行如下命令根据校验和查找对应文件名称。其中git rev-list --objects --all查看所有Git对象的校验和与文件名的关系,输入到管道符中,grep匹配校验和为072e320f的行,最终查找到file.zip即为那个7M的大文件。
git rev-list --objects --all | grep 072e320f
072e320f... file.zip
运行如下命令查看哪些提交记录对此文件做了改动,其中--branches表示范围为当前版本库所有分支。
git log --oneline --branches -- file.zip
9db12cc (HEAD -> master) remove file.zip
52bd5ce add file.zip
运行如下命令擦除提交历史,其中52bd5ce^..HEAD表示52bd5ce及以后的提交记录都会被擦除重写。
git filter-branch -f --prune-empty --index-filter 'git rm -f --cached --ignore-unmatch file.zip' 52bd5ce^..HEAD
再运行如下命令,彻底清理提交历史并对仓库重新分析打包。
- 擦除命令默认会生成备份,实质是保存了一个引用,指向原提交历史中的最新提交,
rm -rf删除.git/refs/original目录下引用 - 修剪当前时间点前的所有引用日志
- 打印出无法到达的对象
- 将包中的所有无法到达的对象变成松散的、未打包的对象,而不是留在旧包中。打包后若新创建的包使某些现有包变得多余,删除冗余包
- 花费更多时间更加积极地优化存储库,修剪当前时间点前的松散对象
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git fsck --full --unreachable
git repack -A -d
git gc --aggressive --prune=now
# Gitk
;Gitk是Git内置的图形可视化工具,包括提交历史图、每个提交的相关信息以及版本树中的文件。
;Git仓库根目录下运行gitk打开如下可视化界面。其中主要包括菜单栏A、提交历史B、提交信息C、版本树文件D四个区域。

# 菜单栏
# File

Update:更新,命令行操作仓库后,将更改反应在gitk中,更新引用并显示新旧差异。一般变基后运行,可以比较前一个分支头和新的分支头Reload:重新加载Reread references:重读引用List references:引用列表,包括标签和分支。其中Filter内*表示所有引用,*master则筛选master、remotes/origin/master分支

Start git gui:打开git gui可视化工具Quit:退出
# Edit

首选项Preferences包括常用设置、颜色和字体设置。注意提交信息区C中可能出现部分中文乱码的情况,需要在当前仓库下.git/config中追加如下。
[gui]
encoding = utf-8

Maximum graph width (lines):最大图形宽度(线)Maximum graph width (% of pane):最大图形宽度(窗格百分比)Show local changes:显示本地更改Auto-select SHA1 (length):自动选择SHA-1校验和(长度)Hide remote refs:隐藏远程引用Tab spacing:标签间距Display nearby tags/heads:显示最近的标签或者引用Maximum # tags/heads to show:标签或引用最大显示数Limit diffs to listed paths:限制列出路径的差异Support per-file encodings:支持文件编码External difftool:外部diff工具Web browser:Web浏览器Use themed widgets:使用小部件主题
# View

设置快速查询视图,可根据查询条件筛选查询记录,进而对比两个视图之间的差异。添加后的视图可编辑或者删除。

View Name:视图名称Branches & tags:分支或标签名,多个用空格隔开,可选项包括所有引用All refs、所有本地分支All (local) branches、所有标签All tags、所有远程跟踪分支All remote-tracking branchesCommit Info:提交信息,包括作者Author、提交者Committer、提交信息Commit Message,可选项包括匹配所有提交信息条件Matches all Commit Info citeria、不匹配所有提交信息条件Matches no Commit Info crteriaChanges to Files:文件内容的更改,包括固定字符串Fixed String、正则表达式匹配Regular ExpressionCommit Dates:提交时间,包括开始时间Since和结束时间UntilLimit and/or skip a number of revision (positive integer):显示固定数量的提交日志,可从头跳过一定数量的日志Miscellaneous options:其他选项,包括按时间排序Strictly sort by date、标记分支侧Mark branch sides、限制第一父提交Limit to first parent、简要历史Simple history,也可自定义git log的参数Enter files and directories to include, one per line:包括的文件和目录,一行一个
# Help

;gitk帮助包括gitk简介、快捷键。
# 提交历史

提交历史包括提交信息、提交者、提交时间。
点击不同的提交历史会被高亮为蓝色背景,最下方显示此提交的SHA-1校验和,每次点击都会被gitk记录,左右箭头切换记录的提交,Row为当前点击的提交的行数和总行数。
提交信息会高亮本地分支、标签、远程跟踪分支,其中本地分支为绿色背景,HEAD指向的分支为黑色粗体,标签为黄色背景,远程跟踪分支为橙色背景。
;find上下箭头切换满足查询条件的提交记录。
# 分支右键菜单

Check out this branch:切换到此分支,即HEAD指向此分支Rename this branch:重命名此分支Remove this branch:删除此分支Copy branch name:拷贝分支名
# 记录右键菜单

Create tag:创建标签Copy commit reference:拷贝此提交简略信息,包括7位SHA-1校验和、提交信息和提交时间(年月日)Write commit to file:导出详细提交信息为文件,包括具体修改内容Create new branch:创建新分支Cherry-pick:拣选此提交Reset master branch to here:重置master分支到此提交,包括Soft、Mixed和Hard,其中Hard将重置工作目录和暂存区,Mixed将重置暂存区域,Soft仅撤销此提交后的提交

Mark this commit:标记此提交,被标记的提交含黑色边框,注意只能有一个被标记的提交Revert this commit:还原此提交,即生成新的提交来撤销此提交的修改
# 标记后右键菜单
标记某个提交后,其余的提交将开启部分右键菜单。

Return to mark:跳转到被标记的提交Find descendant of this and mark:查找当前提交和被标记的提交的最近的共同后代Compare with marked commit:比较此提交和被标记的提交,不同于diffDiff this -> markedcommit:diff此提交和被标记的提交Diff marked commit -> this:diff被标记的提交和此提交
# 选中后右键菜单
选中某次提交后,右键其他提交将开启部分右键菜单。

Diff this-> selected:diff此提交和被选中的提交Diff selected -> this:diff被选中的提交和此提交Make patch:将此提交和被选中的提交的diff生成一个patch文件
# 提交历史查询
底部commit后为查询类型列表。

containing:包含,配合后面范围参数touching paths:文件路径adding/removing string:修改内容包括添加或删除的字符串changing lines matching:修改的行数
查询方式。

Exact:精确匹配IgnCase:忽略大小写Regexp:正则表达式
查询范围。

All fileds:所有范围Headline:提交信息的标题Comments:提交信息的内容Author:作者Committer:提交者
# 提交信息
显示提交的具体信息或两个提交的diff差异。

# 选项参数
Diff:显示两个提交的diff差异Old version:旧版本New version:新版本Lines of context:变更区域的上下文行数ignore space change:忽略空格变化diff样式:包括Line diff、Markup words和Color words

# 提交信息
Author:作者Committer:提交者Tags:当前标签节点Parent:当前提交的父提交,合并提交存在多个父提交Branches:当前节点最近的分支Follows:当前节点最近的上一个标签Precedes:当前节点最近的下一个标签
# 版本树

# 选项参数
Patch:仅显示变更的文件列表Tree:显示完整文件树
# 右键菜单

Highlight this too:高亮修改过此文件的提交记录Highlight this only:仅高亮修改过此文件的提交记录,若当前提交历史中还高亮有其他文件,则取消其他文件的高亮External diff:使用外部diff工具查看Blame parent commit:查看此文件的全部内容的变更记录Copy path:拷贝文件路径
# Git Gui
;Git Gui也是Git内置的可视化工具,大部分操作相对于命令行显得方便很多,其中部分暂存等是命令行方式所达不到的。
仓库根目录下右击Git GUI Here或者命令行运行git gui打开如下可视化界面。其中主要包括菜单栏A、工作区变更B、差异对比C、暂存区D、提交信息E五个区域。

# 菜单栏
# Repository

Explore Working Copy:浏览工作目录Git Bash:Git命令行Browse master's Files:浏览当前分支文件Browse Branch Files:浏览所有分支文件,其中Revision Expression为版本正则表达式,待选分支包括本地分支Local Branch、远程跟踪分支Tracking Branch、标签Tag,搜索栏关键字搜索待选分支

Visualize master's History:可视化当前分支的历史Visualize All Branch History:可视化所有分支的历史Database Statistics:数据库统计,其中包括松散对象数量Number of loose objects、 松散对象占用的磁盘空间Disk space used by loose objects、包文件中的对象数量Number of packed objects、包文件数量Number of packs、包文件中对象占用的磁盘空间Disk space used by packed objects、包文件中的松散对象Packed objects waiting for pruning、垃圾文件Garbage files,Compress Database即打包git gc数据库

Compress Database:打包数据库Verify Database:验证fsck数据库连贯性和有效性Create Desktop Icon:创建桌面图标Quit:退出
# Edit

;Edit用于操作提交信息区域,包括撤销Undo、重做Redo、剪切Cut、复制Copy、粘贴Paste、删除Delete、全选Select All、选项Options,除了Options外的选项一般用处不大,都能通过快捷键实现。

其中repo Repository为当前仓库下的配置选项,Global (All Repository)为全局下的仓库配置选项。
Summarize Merge Commits:汇总合并提交Show Diffstat After Merge:合并后显示diff统计use Merge Tool:使用合并工具Trust File Modification Timestamps:信任文件的改动时间Prune Tracking Branches During Fetch:获取时清除跟踪分支Match Tracking Branches:匹配跟踪分支Use Textconv For Diffs and Blames:对差异和标注使用TextconvBlame Copy Only On Changed Files:仅标注变动的文件Maximum Length of Recent Repositories List:当前版本库列表的最大长度Minimum Letters To Blame Copy On:标注副本的最少字母数量Blame History Context Radius (days):标注历史上下文范围(天)Number of Diff Context Line:diff差异的上下文行数Additional Diff Parameters:其他diff参数Commit Message Text Width:提交信息文本宽度Commit Message Text Width:新分支名称模板Default File Contents Encoding:默认文件内容编码格式Warn before committing to a detached head:提交到一个游离的HEAD前警告Staging of untracked files:暂存未跟踪的文件,包括是yes、否no或者询问askShow untracked files:显示未跟踪的文件
# Branch

Create:创建分支,可输入分支名称Name创建,也可匹配远程跟踪分支Match Tracking Branch Name检出跟踪分支。或者从本地分支Local Branch、远程跟踪分支Tracking Branch、标签Tag检出分支,相关分支选项Options为更新存在的分支Update Existing Branch,包括无操作No、仅快进Fast Forward Only、重置Reset,拉取跟踪分支Fetch Tracking Branch,创建分支后并检出Checkout After Creation

Checkout:检出分支Rename:分支重命名Delete:删除分支Reset:重置当前分支,若包括有未提交的修改,重置时将丢失
# Commit

Amend Last Commit:修改最后一次提交Rescan:刷新,外部命令行操作了版本库,刷新同步Statge To Commit:暂存选中的文件Stage Changed Files To Commit:暂存工作区文件Unstage Form Commit:撤销暂存选中的文件Show Less Context:diff显示更少的上下文Show More Context:diff显示更多的上下文Sign Off:提交信息末尾追加操作者信息,一般拣选时不清楚提交记录的来源,可追加操作者信息便于追溯Commit:提交
# Merge

Local Merge:选择本地分支合并Abort Merge:撤销合并,某些情况下合并造成冲突,退回合并前的状态
# Remote

Fetch from:获取某个远程库更新Prune from:裁剪从某个远程库删除的跟踪分支Remove Remote:删除某个远程库Add:添加某个远程库,包括立即拉取Fetch Immediately、初始化远程仓库并推送Initialize Remote Repository and Push、无操作Do Nothing EIse Now

Push:推送,可推送至指定远程仓库,也可强制覆盖已存在的分支Force overwrite existing branch (may discard changes)、使用简包Use thin pack (for slow network connections)、包括本地标签Include tags

Delete Branch:删除某个远程库的分支
# Tools

Add:添加新的命令,包括命令名称Name、命令指令Command,运行前可显示对话框Show a dialog before running,用户选中一个版本Ask the user to select a revision或者询问用户附加参数Ask the user for additional arguments,不显示命令输出窗口Don't show the command output window,仅选择了diff才运行Run only if a diff is selected

Remove:删除某个添加的命令
# Help

About Git Gui:关于Git GuiOnline Documentation:在线文档Show SSH Key:显示SSH公匙,当前不存在可点击Generate Key生成Key

# 差异对比

差异对比区域无任何文件时右键菜单。
Undo Last Revert:撤销最后一次丢弃Revert,丢弃文件Revert Hunk或丢弃行Revert Line均会丢弃掉修改,Git Bash命令行git checkout丢弃掉修改则无法再恢复,但是Git Gui缓存了最后一次丢弃前的那个文件的版本Refresh:刷新Copy:复制Select All:全选Copy All:复制全部Decrease Font Size:缩小字体Increase Font Size:放大字体Encoding:文件内容编码Options:选项
# 工作区变更

点击文件前蓝色图标可快捷暂存文件,差异对比开启部分右键菜单。

Stage Hunk For Commit:暂存文件Stage Line For Commit:暂存某一行或者多行,可通过点击某一行或者托选多行实现选中Rever Hunk:撤销或丢弃文件的修改Rever Line:撤销或丢弃某一行或者多行的修改Show Less Context:显示更少的上下文Show More Context:显示更多的上下文
# 暂存区

点击文件前绿色图标可快捷取消暂存文件,差异对比开启部分右键菜单。

Unstaged Hunk From Commit:取消暂存文件Unstaged Line From Commit:取消暂存文件的某一行或者多行
# 提交信息

Rescan:刷新Staged Changed:暂存文件Sign Off:签署,提交信息的末尾追加一行操作者信息Push:推送Amend Last Commit:修改最后一次提交Commit Message:提交信息
提交信息右键菜单与菜单栏基本一致。

# 🎉 写在最后
🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star (opens new window) ✨支持一下哦!
手动码字,如有错误,欢迎在评论区指正💬~
你的支持就是我更新的最大动力💪~
GitHub (opens new window) / Gitee (opens new window)、GitHub Pages (opens new window)、掘金 (opens new window)、CSDN (opens new window) 同步更新,欢迎关注😉~