本文参考资料为Git官网的官方文档 Git - Reference ;
本文内容存在时效性,请在参考本文学习Git时注意甄别;
分支命令
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。下面我们详细了解一下Git常用的分支命令。
1. 基础
🌿 git branch
branch
既可以执行对分支的管理操作,也可以执行可视化分支的操作:
使用git branch <branch_name>
可以对分支进行管理,Git会在HEAD
所在的提交节点新建一个新的分支。branch
还支持如下分支管理方式:
选项 | 说明 |
---|---|
-f <branch> <target> |
强制移动一个分支(必须显示指出)指向另一个提交 |
-d <branch> |
安全删除已合并到当前分支的分支 |
-D <branch> |
强制删除分支,无论是否合并 |
-m <branch> |
安全重命名分支及其reflog ,如果目标分支名已存在,则会报错并拒绝操作 |
-M <branch> |
强制重命名分支及其reflog ,如果目标分支名已存在,则会覆盖原有分支 |
--track <local> <remote> |
创建一个新的分支,并为其指定其跟踪的远程分支 当不使用 --track 指定创建分支对应的<remote> 分支时,系统会自动指定origin/<local> 为远程分支 |
--no-track <local> |
创建分支时不跟踪远程分支 |
Git有一套独特的远程仓库同步方法,当我们使用push
或clone
与远程仓库交互时,Git的本地分支local
会与其对应的远程分支origin/local
交互。我们在创建本地分支时,使用--track
命令可以指定与其对应的远程分支,以便我们个性化的与远程仓库交互。
当我们使用-D
模式时,需要注意待删除分支不能是工作分支(worktree
的使用方法详见后续章节),否则会报如下错误:
1 | error: cannot delete branch '<branch>' used by worktree |
不添加操作目标<branch>
的git branch
命令可以对分支进行可视化。使用该命令会列出所有本地分支,并将当前分支用*
标记。此外,branch
还支持如下可视化方式:
选项 | 说明 |
---|---|
-a /--all |
显示所有分支,包括本地和远程分支 |
-r /--remotes |
仅显示远程分支 |
-v /--verbose |
显示本地分支的详细信息,包括:<branch_name> 、<latest_commit_id> 和<latest_commit_msg> |
-vv |
显示本地和远程分支的详细信息。相较于-v 选项,该选项可以显示本地分支追踪的远程分支 |
--merged /--no-merged |
控制是否列出已合并到当前分支的分支 |
-l /--list <pattern> |
列出满足匹配模式的分支 例如:执行 git branch -l "dev-*" ,Git会列出符合dev-* 匹配模式的分支 |
--contains <commit> --no-contains <commit> |
控制是否列出包含指定提交的分支 |
📦️ git stash
当我们在修改当前分支代码时,若需要临时切换分支处理其他任务,可以使用git stash
将工作区与暂存区的改动保存到Git的储藏堆栈中,以避免未完成的修改被提交。git stash
的常用命令如下:
git stash push
该命令是缓存未提交记录的主要命令,当我们使用
git stash
相当于使用该命令。该命令常用选项如下:选项 说明 -m
/--message
保存时添加说明信息,便于在还原缓存时识别 -u
/--include-untracked
保存未跟踪的文件(不包括被 .gitignore
忽略掉的文件)-k
/--keep-index
保存时保留暂存区内容, git add
添加到暂存区的数据不会被还原,仅缓存工作目录的更改。这里的index
就是暂存区的另一种表示-a
/--all
保存所有文件变动以及所有忽略/未跟踪文件 -p
/--patch
交互式选择要保存的内容(类似 git add -p
)我们使用
git stash list
可视化暂存堆栈可以看到形如stash@{index}
的堆栈索引,栈顶元素是最近一次存储(stash@{0}
);git stash show <stash>
:显示指定缓存的文件变动摘要,
<stash>
默认为stash@{0}
,常用选项如下:选项 说明 -p
/--patch
展示具体的代码行差异(类似 git diff
)-a
/--all
显示所有文件的代码行差异 -u
/--include-untracked
存储时使用了 -u
或-a
选项保存了未跟踪文件,此选项会显示这些文件的差异git stash apply
:该命令用于将保存的文件变动恢复到当前工作目录,但不同于
git stash pop
,该命令不会删除存储条目,常用选项如下:选项 说明 --index
恢复存储时,保留暂存区的状态 --quiet
静默模式,不显示操作信息 git stash pop
:该命令用于恢复并删除暂存栈顶的最新保存的文件变动,常用选项如下:
选项 说明 --index
恢复存储时,保留暂存区的状态 stash@{n}
指定恢复特定位置的 stash
需要注意的是,
git stash
应用缓存时也有可能出现冲突,如果出现冲突或者其他事件,都会打断git stash pop
的自动删除stash
任务,这时需要我们手动完成后续操作。git stash clean
:用于删除所有暂存的修改记录。git stash list
:列出当前已缓存的暂存提交节点列表;git stash drop <stash>
:用于删除Git暂存堆中指定的临时保存的修改记录,<stash>
默认为stash@{0}
。git stash branch <branch> <stash>
:该命令用于基于暂存记录,在当前HEAD
处创建新分支,并自动应用该stash
的修改,<stash>
默认为stash@{0}
;
🎯 git switch
& checkout
Git的分支切换是日常开发中常用操作之一,我们可以使用git checkout
或者git switch
完成分支切换操作。
git switch
该命令是Git 2.23引入的新命令,用于替代git checkout
中切换分支的功能。相比于git checkout
,git switch
语义更清晰、功能也聚焦于分支切换,其常用选项如下:
选项 | 说明 |
---|---|
-c /--create |
创建并切换到新分支 |
-C |
强制创建分支,若分支已存在则重建分支 |
-f /--force /--discard-changes |
强制切换,放弃当前改动 |
--detach |
进入detached HEAD状态 |
--orphan |
创建一个不含任何提交的新分支。使用该选项时,不需要再使用-c |
git switch --orphan
用于创建一个 孤立分支 | orphan branch
。这种分支的特点是:没有父提交,历史完全独立,适合需要完全隔离历史记录的场景,例如:使用Github Pages
部署静态网页时,我们不想要gh-pages
有其他构建文件,我们可以使用该选项创建gh-pages
。
需要注意的是,当我们使用此命令创建一个新的孤立分支时,未追踪/忽略文件会一并移入新分支的工作目录。部分情况下,暂存区中的数据也会移入新的分支中:
[✔︎] 暂存区中只有未追踪文件的变更记录,此时进入新的孤立分支也会有这些数据;
[✖] 暂存区中存在已最终文件的变更记录,此时创建新分支的任务会被中止,并出现如下报错:
1
2
3
4
5error: Your local changes to the following files
would be overwritten by checkout:
...
Please commit your changes or stash them before you switch branches.
Aborting当然我们可以使用
-f
进行分支强行切换。但是此后未追踪文件会被直接删除,不会移入新分支的工作目录。
git checkout
是一个相当全能的Git命令,它可以用来切换分支、恢复文件、检出特定提交等。这个命令在Git的多个操作中扮演关键角色,我们就在本章详细学习一下git checkout
的用法。其常用选项如下:
选项 | 说明 |
---|---|
-b <branch> |
创建并切换分支 等价命令: git switch -c <branch> |
-B <branch> |
强制创建分支,放弃当前改动 重置分支,如果分支已存在,则会重置到当前 HEAD |
<target> =<branch> /<commit> /<tag> |
切换到指定的本地分支/具体提交/标签上,这里我们用<target> 统一代指 |
--detach <target> |
进入detached HEAD状态,<target> 默认为HEAD 等价命令: git switch -d <target> |
--ours <file> /--theirs <file> |
合并冲突时选择版本,也可以用-- 指定处理文件等价命令: git restore --ours /--theirs |
-f /--force |
强制切换分支,忽略未保存更改 等价命令: git switch -f <target> |
<target> -- <file> |
恢复特定<target> 提交的文件等价命令: git restore --source <target> -- <file> |
🏷️ git tag
git tag
用于给某个特定提交打标签的一条命令。标签一般用于标记重要的版本点,比如发布版本,方便后续查找、检出 | checkout
和管理。我们可以使用该命令创建和管理标签,以下是常用的创建标签选项:
选项 | 说明 |
---|---|
-a <tag> [<commit>] /--annotate |
创建一个 附注标签 | annotated tag 。我们常使用git tag -a <tag> [<commit>] 创建标签。我们在创建标签时,可以指定commit 作为打标目标,如果不指定则会默认当前HEAD |
-s <tag> /--sign |
创建GPG签名标签,需要预先配置user.signingkey |
-u <pub_fp> /--local-user=<pub_fp> |
使用指定的GPG密钥ID(pub_key )创建GPG签名标签 |
-m <message> |
为标签添加说明信息,需配合-a /-s 使用 |
了解完Git标签如何创建后,我们再来学习一下如何管理标签。我们可以使用以下命令列出标签:
-l [<pattern>]
/--list
:用于列出标签,直接运行git tag
就等于执行了git tag -l
,常用的通配符如下:通配符 说明 *
任意字符 ?
单个任意字符 []
字符集合 例如,我们可以使用
git tag -l "v1.*"
来匹配所有以v1.
开头的标签;--sort=<key>
:用于排序标签列表,Git默认是按字典序排序(不是按时间),可以通过--sort
指定排序规则,常见的排序字段有:排序字段 说明 refname
✅标签名称,字典序排序 creatordate
标签创建日期 taggerdate
打标签者的时间 version
按照语义化版本排序(比如 v1.9
<v1.10
)-<key>
反向排序 --contains <commit>
:列出包含某提交的标签;--merged <commit>
:列出已合并到某提交的标签;--format=<format>
:自定义输出格式。我们可以自定义每个标签的输出格式,类似git log --pretty=format
的用法,常用占位符如下:占位符 说明 %(*objectname)
对应提交的 SHA1
%(refname)
标签全名( refs/tags/v1.0
)%(refname:short)
标签短名( v1.0
)%(taggername)
打标签人 %(creatordate:short)
创建时间(简短) %(subject)
标签说明第一行
关于Git标签,还有以下可能会用到的命令:
- 删除标签:使用
git push <remote> --delete <tag>
删除远程仓库中的标签,也可以使用git tag -d <tag>
删除本地标签; - 查看详情:使用
git show <tag>
显示标签内容和对应的提交详情; - 验证签名:使用
-v <tag>
选项,验证指定标签的GPG签名;
🌐 git worktree
git worktree
命令用于在同一个仓库Repository
下管理多个工作目录Working Directory
。这对于需要同时处理多个分支的开发场景非常有用。
当我们在需要在两个分支上同时工作时,频繁切换分支会浪费我们的时间,这时候可以使用git worktree
将某一个分支 检出 | checkout
到新的工作目录下,同时保留主仓库的原始工作目录,这样我们就可以在多个分支上同时工作。git worktree
常用命令如下:
git worktree add <path> <branch-or-commit>
:该命令是我们创建新工作目录的主要命令。其中
<path>
用于指定目录路径;<branch-or-commit>
可选,指定用于checkout
的branch
或者commit
,其参数设置有如下几种情况:- 指定已存在分支:Git会新建一个新目录并
checkout
在这个分支上; - 不指定分支:Git会在新目录中根据
path
创建一个新的分支,并checkout
这个分支; - 指定提交:Git会在新目录下以detached HEAD状态
checkout
这个提交;
git worktree add
的常用选项如下:选项 说明 -b <new-branch>
创建并 checkout
一个新分支(相当于git checkout -b
)--detach
以detached HEAD模式 checkout
一个提交--force
强制覆盖已存在的工作目录 <path>
,需要谨慎使用--checkout
/--no-checkout
控制添加工作目录后,是否显式执行 checkout
,默认是--checkout
--lock
锁定工作树,防止其被删除或移动 --orphan <branch>
创建一个孤立分支并 checkout
(相当于git checkout --orphan
)两个工作目录间如何合并,可以执行
worktree
的Merge Mock实验:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# Experiment-1
# main
git checkout first
git switch -c work_main
git worktree add ../sub_work
git lg
git checkout sub_work
# fatal: 'sub_work' is already used by worktree at 'D:/Code/Javascript/Learn/git-learn'
# sub
cd ../sub_work
git commit --allow-empty
cd ../learn-git
git lg
# 在sub_worktree中对分支的修改已经影响到main_worktree中的提交
# 这说明工作目录不同分支间是同步提交的上述实验有如下总结:
- 不同工作目录不能同时处于一个分支上;
- 工作目录间不同分支的提交记录是同步的;
- 指定已存在分支:Git会新建一个新目录并
git worktree move <old_path> <new_path>
:该命令用于移动工作目录(非主工作目录
main
),使用此命令移动工作目录不会改变其绑定的分支或提交信息;我们可以使用mv
作为move
的缩写命令。需要注意的是,
git worktree lock
会影响此命令的执行,当然我们可以使用-f
/--force
选项来强制更改工作目录位置。以下是要点总结:- ✅ 自动更新 Git 的内部路径记录;
- ⚠️ 手动移动目录会导致 Git 记录失效;
- ❌ 不支持主仓库工作目录移动;
- ❗
<old_path>
必须为有效路径,<new_path>
必须存在;
git worktree remove <exist_path>
:用于删除工作目录(非主工作目录main
),可以使用rm
作为remove
的缩写命令。如果待操作工作目录被锁定,需要解锁或者使用-f
/--force
强制执行;git worktree prune
:该命令是管理
worktree
的重要工具,用于清理Git仓库中已经失效的工作树记录,以确保.git/worktrees/
目录中的信息保持干净一致。其常用选项如下:选项 说明 -n
/--[no-]dry-run
控制是否执行 prune
命令-v
/--[no-]verbose
控制是否显示每个被清除的工作树信息 --[no-]expire <expiry-date>
用于清理“临时锁定”的工作树,只对锁定工作目录生效
时间格式可为:1.hour.ago
、2.days.ago
、now
、RFC时间等git worktree repair <path>
:该命令用于修复.git/worktrees/
元数据目录,主要用于在某些意外情况下(如物理目录移动、系统崩溃、备份还原等)重新同步Git对工作树的识别和绑定;git worktree list
:该命令用于可视化所有的工作目录。可以使用-v
/--verbose
显示更多信息;使用--[no-]expire <expiry-date>
可以根据prune
过期时间显示信息;git worktree lock <path>
:该命令用于将某个工作目录锁定,防止它被误删或自动清理。我们可以使用--reason <reason_msg>
说明锁定原因;git worktree unlock
:该命令用于将某个工作目录解锁;
2. 编辑
对分支的编辑操作是Git分支操作的核心,
🤝 git merge
git merge
命令用于将多个分支的内容合并成一个新的提交。如果HEAD
为detached HEAD状态,需要指定合并主分支、带合并分支;否则Git会默认主分支为HEAD
指向的分支。其常用选项如下:
选项 | 说明 |
---|---|
--ff /--no-ff |
控制是否进行快速合并,默认为进行快速合并 |
--ff-only |
只允许快速合并合并,不能快速合并时会报错 |
--squash |
合并多个提交为一个,但不会产生merge commit ,需要手动提交 |
--commit |
默认行为,合并成功后自动创建提交 |
--no-commit |
合并后不自动提交,可用于预览更改或做修改 |
--edit |
打开编辑器修改默认合并提交信息(默认开启) |
--abort |
取消当前冲突中的合并过程,回到合并前的状态 |
--continue |
在解决冲突后继续合并 |
快速合并 | fast-forward
适用与如下场景,当我在一个分支sub
上开发,这时main
没有任何新的提交,当我们使用git merge --ff
合并时,Git 可以通过--ff
将main
分支快速指向sub
分支的最新提交以达成快速地合并。--ff
/--no-ff
的实际效果如下:
--ff
效果:1
2
3
4
5
6
7A---B---C (main)
\
D---E (feature)
git merge feature --ff
A---B---C---D---E (main)--no-ff
效果:1
2
3
4
5
6
7
8
9A---B---C (main)
\
D---E (feature)
git merge feature --no-ff
A---B---C---------M (main)
\ /
D-----E (feature)
当我们想要将孤立分支合并到主分支上时,如果直接使用git merge
会出现 “警告没有共同祖先” 的报错,如果我们想要合并它们可以使用--allow-unrelated-histories
选项执行强行合并。此外,git merge
的多分支合并可以参考Git笔记:背景与基础;
当git merge
合并时若发生冲突,Git会依次打开冲突文件(如果多个的话),我们可以通过git mergetool
使用冲突合并工具处理冲突。
📏 git rebase
git rebase
也可用于分支的合并,它的合并原理是 变基 | rebase
一个分支到另一个分支的基础之上,从而实现更整洁、线性的提交历史。此命令同git merge
一样,需要区分不同HEAD
状态下的参数输入:
detached
:使用git rebase <base_branch> <attach_branch>
进行变基,先输入作为”基“的分支,再输入待变基的分支。例如:git rebase rb1 rb2
就是将rb2
的提交变基到rb1
上;branch
:使用git rebase <base_branch>
进行变基,是将当前分支变基到输入分支上;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15git checkout first
git branch rb1
git branch rb2
# rb1, rb2做如下操作
git checkout rb1
git commit --allow-empty
# 下面两种变基方式等价
git checkout rb1
git rebase -i rb2
git lg
git checkout <rb2_commit_hash>
git rebase -i rb2 rb1
需要注意的是,使用git rebase
进行分支融合,待变基分支的指向会随着命令执行而改变。git rebase
的常用选项如下:
选项 | 说明 |
---|---|
-i /--interactive |
进入交互式变基模式,可对每个提交进行操作(如修改、合并、重排等) |
--continue |
解决变基冲突后继续执行变基操作 |
--skip |
跳过当前出错的提交,不再应用它 |
--abort |
取消变基,恢复到开始前的状态 |
--keep-empty |
默认变基会丢弃空提交,使用该选项保留空提交 |
--autostash |
在变基前自动暂存工作区的变更,并在变基后恢复 |
--exec <cmd> |
在每个rebase 的提交之后执行一个命令(可用于测试) |
🍒 git cherry-pick
git cherry-pick
用于将提交从一个分支复制到当前分支,这不会改变原分支的指向。其使用方法如下:
git cherry-pick <commit-hash>
:复制单个提交;git cherry-pick <start-commit>..<end-commit>
:复制一组提交,注意提交先后顺序;git cherry-pick <hash1> <hash2> <hash3>
:按照先后顺序依次复制提交;其等价为:1
2
3git cherry-pick <hash1>
git cherry-pick <hash2>
git cherry-pick <hash3>
其常用选项如下:
选项 | 说明 |
---|---|
<commit> |
应用指定提交 |
-e <commit> |
修改提交信息 |
-x <commit> |
添加原提交信息 |
--abort |
放弃cherry-pick |
--continue |
解决冲突后继续 |
调试命令
1. 搜索
🔭 git grep
git grep
用于在版本库中的文件里搜索字符串或正则表达式。由于它只在Git跟踪的文件中查找,它的速度比普通grep
命令快。我们可以按照如下方式使用此命令:
git grep -e <pattern>
:在项目中的 文件/文件夹 下查找匹配<pattern>
的内容。需要注意,Git并不会匹配文件夹名称;git grep -e <pattern> -- <folder-or-filer>
:使用--
指定查找的范围;
git grep
的常用选项如下:
选项 | 说明 |
---|---|
-e <pattern> |
显式指定模式,支持正则表达式 |
-i |
忽略大小写进行匹配,默认区分大小写 |
-w |
只匹配整个单词,避免部分匹配 |
-n /--line-number |
显示匹配的行号 |
-c /--[no-]count |
显示匹配成功文件,与匹配行数 |
-l /--[no-]files-with-matches |
显示匹配成功文件,不显示行数 |
-L /--files-without-match |
列出不包含匹配内容的文件名 |
-A <n> |
匹配行 后 额外显示 n 行上下文 |
-B <n> |
匹配行 前 额外显示 n 行上下文 |
-C <n> |
匹配行前后各显示 n 行上下文(等价于 -A n -B n ) |
--untracked |
Git默认只搜索已跟踪的文件,使用此选项可以搜索未被跟踪的文件 |
--cached |
只在暂存区中搜索 |
--no-index |
使用此命令可以搜索非Git管理的仓库(即根目录下没有.git 的仓库)中的文件 |
🔍 git bisect
git bisect
用于快速定位引入bug的提交。它采用二分查找算法,通过标记「好」和「坏」的提交,自动帮你在提交历史中缩小范围,直到找出引入问题的那一个提交。
我们使用git bisect start
开始二分查找错误提交,使用git bisect bad
标记错误提交,使用git bisect good <commit>
来标记已知没有的提交。然后,Git会自动checkout
中间提交,我们只需测试每次checkout
的提交是否有问题,并用git bisect good/bad
告诉Git即可,当找出有问题的提交后,Git 会输出类似:
1 | <commit_hash> is the first bad commit |
🧾 git reflog
git reflog
用于查看本地 Git 仓库的 引用日志 | reference log
。它记录了所有分支引用(如 HEAD
)变动的历史,即使某些提交已经被reset
、rebase
、checkout
、commit --amend
等操作「隐藏」或「丢弃」,也能通过 reflog
找回。git reflog
的常用命令如下:
git reflog [show]
:该命令用于显示本地仓库的引用(
HEAD
、<branch>
)的历史记录。当我们使用git reflog
时,实际上就是在使用该命令。其常用选项如下:选项 说明 <target>
指定查看的引用,默认是 HEAD
,也可以用于分支引用的查看-n <N>
--max-count=<N>
限制显示最近的 <N>
条记录--pretty=<format>
格式化输出,支持格式: oneline
、short
、medium
、full
、raw
等--date=<format>
设置日期显示格式,支持: relative
、iso
、local
、default
、raw
--abbrev=<N>
/--no-abbrev
设置提交哈希缩写长度,默认是 Git 配置的 core.abbrev
,可以手动设置。
也可以使用--no-abbrev
关闭哈希缩写--all
查看所有分支和 HEAD
的Reflog
git reflog expire
:该命令用于清理引用日志。当我们使用Git编辑提交树时,会有一些节点从树上消失,但Git会将这些消失的提交记录保存起来。这些提交记录Git默认保存90天,我们也可以使用
git reflog expire
根据指定策略,删除不再需要保留的reflog
;注意!
git reflog expire
并不直接删除对象,而是让这些记录“过期”,供后续git gc
(垃圾回收)真正清理。其常用选项如下:选项 说明 --expire=<time>
指定普通(非 HEAD
)reflog
的过期时间(默认90天)--expire-unreachable=<time>
指定不可达对象的过期时间(默认30天) --all
作用于所有引用 --rewrite
Git默认行为是直接删除整个日志文件,使用该选项可以保留日志文件中仍然有效的条目,只删掉过期的部分 git reflog delete <reflog>
:该命令用于手动删除特定reflog
记录的命令;
2. 分析
🧐 git diff
git diff
是Git中最重要的几个命令之一,它为我们提供了行级别展示代码间 差异 | diff
的方案。我们可以使用如下方式使用该命令:
git diff
:当我们使用该命令时,情况更为复杂。git diff
默认比较暂存区与工作区;git diff --cached
/--staged
用于比较暂存区与HEAD
的差距;
- 限制范围:
- 我们可以使用
-- <file-or-folder>
限定Git比较范围,范围既可以是一个单独文件,也可以是个文件夹; - 我们也可以使用
git diff <ref>:<file-or-folder> <ref>:<file-or-folder>
的形式更加自由的使用diff
工具。这里的<ref>
是指Git引用,<file-or-folder>
同上;
- 我们可以使用
其常用选项如下:
选项 | 说明 |
---|---|
-u /-p |
生成补丁格式的差异输出,这是默认选项,不需要显示输入 |
--patch-with-stat |
输出补丁并附带统计信息 |
--stat |
显示简略统计(修改的文件及增减行数) |
--numstat |
显示数字统计(增/减行数) |
--name-only |
显示修改的文件名 |
--name-status |
显示文件名、变更状态(M - 修改,A - 添加,D - 删除) |
--color-words |
高亮显示单词级差异,适合Markdown 、Latex 等文本内容 |
-w |
忽略所有空格变化 |
-b |
忽略行末空格 |
-z |
用NUL 字符分隔输出(适合脚本解析) |
--full-index |
显示完整的对象哈希值,默认显示短哈希 |
--no-index <file> <file> |
直接比较两个文件间的差异,不需要考虑是否为Git项目,git grep 中也有该选项 |
git diff
有如下常用的combo
:
git diff <commit>^!
:对比某个提交与其父提交的差异。^!
是Git的语法糖,<commit>^!
等价于<commit>^ <commit>
;git diff <target>..<target>
:比较两个提交间的差异,我们也可以使用<target> <target>
来代替原输出,两种效果相同;git diff <branch_1>...<branch_2>
:比较<branch_2>
与<branch_1>
的最近共同祖先的差异;
我们也可以使用git difftool
调用第三方工具来查看diff
,我们只需要将上述git diff
改为git difftool
即可。注意,使用git difftool
时,不需要添加options
。
😠 git blame
git blame
用于逐行追溯文件修改历史的命令。它能帮助开发者快速查看代码的每一行最后一次被修改的提交、作者和时间。我们可以使用git blame <file>
来查看文件的提交记录,其常用选项如下:
选项 | 说明 |
---|---|
-e /--show-email |
显示作者的邮箱地址 |
-L <start>,<end> |
限制文件查看范围,聚焦于某几行 |
-w |
忽略空格修改 |
-C /-M |
检测代码是否是从其他文件移动或复制而来,其中: - -C 用于检查同一提交内的代码移动- -M 用于检测跨提交的代码移动 |
🐲 git ls-files
git ls-files
是用于显示Git各个分区中文件信息的命令。它主要用于查看Git跟踪的文件状态,适合脚本处理或精确查询文件状态。当我们直接使用git ls-files
时,Git会列出索引中所有已跟踪的文件,其常用选项如下:
选项 | 说明 |
---|---|
-c /--cached |
列出所有已被跟踪且在暂存区中的文件 |
-m /--modified |
列出已被跟踪,但工作目录中有修改且未暂存的文件 |
-d /--deleted |
列出索引中存在但工作目录中已删除 |
-o /--others |
列出未被Git跟踪的文件(默认排除.gitignore 中的文件) |
-i /--ignored |
列出被.gitignore 规则忽略的文件 |
-s /--stage |
显示文件的模式、哈希值和冲突阶段(用于合并冲突时) |
--recurse-submodules |
若项目包含子模块,递归列出子模块中的文件 |