# 比较全面的 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 branches
Commit Info
:提交信息,包括作者Author
、提交者Committer
、提交信息Commit Message
,可选项包括匹配所有提交信息条件Matches all Commit Info citeria
、不匹配所有提交信息条件Matches no Commit Info crteria
Changes to Files
:文件内容的更改,包括固定字符串Fixed String
、正则表达式匹配Regular Expression
Commit Dates
:提交时间,包括开始时间Since
和结束时间Until
Limit 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
:比较此提交和被标记的提交,不同于diff
Diff 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
:对差异和标注使用Textconv
Blame 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
或者询问ask
Show 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 Gui
Online 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) 同步更新,欢迎关注😉~