Git
本系列博客为《Missing in CS Class(2020)》课程笔记
Git是一种分布式版本控制系统,被其跟踪的文件可被查询精细到行的修改记录、回退版本、建立分支等
模型
一般流程:工作区 → \to →暂存区 → \to →仓库(本地 → \to →远端)
-
工作区:项目的工作台,用户在此处直接编辑文件
-
暂存区(索引):用于暂存准备提交至本地仓库的文件,Git只跟踪暂存区内的文件
git ls-files
:查看暂存区
-
仓库:存储版本历史的版本库,分为本地仓库与远端仓库。
git init
:将此目录初始化为本地仓库(位于.git
下)git status
:查看该仓库中文件状态,包括修改、新增、删除、未跟踪等信息
配置
- 为标识提交者,需通过配置进行标识
- 用户名配置:
git config --global user.name ["name"]
- 邮箱配置:
git config --global user.email ["email"]
global
选项代表对所有仓库有效- git的配置可在
.gitconfig
文件中找到
文件状态
未跟踪态
-
未跟踪:该文件未被Git跟踪,即其仅存在于工作区中,不在暂存区或仓库中
git add [Name]
:将文件或文件夹添加至暂存区(支持使用通配符)
选项-p
:交互式添加文件
-
将未在仓库中的文件/文件夹名添加至
.gitignore
中,即可忽略Git对其一切管理(注意文件夹以/
结尾)
已跟踪态
- 未修改:该文件相较于当前版本仓库无任何修改
- 已修改:该文件在工作区已修改,但修改还未被添加至暂存区
git stash
:临时保存工作区更改git blame [Name]
:查看文件历史修改
- 已暂存:文件已准备提交至本地仓库
文件删除
git rm --cached [Name]
:在暂存区删除文件(工作区不删除)git rm -f [Name]
:同时在暂存区和工作区删除文件
提交、标签
提交
-
提交(Commit):将暂存区文件提交至本地仓库,并产生一个新版本,每个版本通过唯一的16进制字符串标识。
-
HEAD
指针:永远指向当前操作版本,随新提交而自动更新(相当于链表的头节点)。git reflog
:查看HEAD
指针变动历史。
-
访问提交:
- 直接使用16进制字符串访问提交。
- 通过
HEAD
指针访问:HEAD~[num]
或HEAD^[num]
,代表HEAD
之前的第num个版本,若num为1可省略。
-
git commit -m ["Reason"]
:将暂存区中的文件提交至本地仓库,提交原因必填。若省略["Reason"]
,则调用默认编辑器填写提交原因。
选项:-a
将所有文件添加至暂存区并提交 -
git log
:查看提交历史、当前HEAD
指针位置
选项:--oneline
每个提交只输出一行
--graph
以ASCII图显示提交历史 -
git checkout [Commit]
:将HEAD
指针指向特定提交,将发生头指针分离。 -
头指针分离:
HEAD
指针被指向某一版本,而非该分支最新版本,此状态被称为头指针分离。该状态下只能查看历史记录,而不能进行分支操作。进入头指针分离应当为临时操作,否则可能会丢失信息。
标签
git tag -a [TagName] [Commit]
:为版本打标签。若[Commit]
省略,则给HEAD
打标签。git tag -d [TagName]
:在本地删除标签。
回退
回退提交
git reset [--mode] [Commit]
:将HEAD
指针回退至指定版本,mode
为指定的回退模式:-
mixed
:回退仓库与暂存区,工作区不变(当mode省略时的默认选项)。 -
soft
:仅回退仓库,工作区和暂存区不变。 -
hard
:同时回退仓库、工作区和暂存区。(慎用!)
-
回退文件/文件夹
git reset [Commit] -- [Name]
:将某一文件回退至指定版本git checkout -- [Name]
:从暂存区恢复该文件到工作区git checkout [Commit] -- [Name]
:从特定提交中恢复该文件git restore [Options] [Name]
:更清晰的恢复文件(推荐替代git checkout
)- 选项:
--source=[Commit]/-s [Commit]
从指定提交中恢复内容(默认为HEAD
) --staged/-S
:将暂存区的内容恢复至工作区--ours
:当合并冲突时,恢复为当前分支的版本--theirs
:当合并冲突时,恢复为另一分支的版本
- 选项:
差异对比
git diff
:工作区与暂存区间差异。git diff HEAD
:工作区与最新版本间差异。git diff --cached
:查看暂存区与最新版本差异。git diff [ID1] [ID2]
:比较两个版本间差异。git diff [Name] [Name]
:比较两个分支间差异。
分支
分支(Branch):每个分支都是独立的,拥有独立的分支指针(指向该分支的最新版本)、工作区、暂存区、本地仓库等。分为本地分支与远程分支。
当本地仓库被初始化时,默认仅具有一个main分支。
分支的创建、重命名、删除
git branch
:查看所有分支,当前所在分支会被以*
标识。- q
-r
:查看远程分支 -a
:查看所有分支
- q
git branch [Branch]
:创建分支(但不切换)git branch -m [OldName] [NewName]
:重命名分支git branch -m [Newname]
:重命名当前分支。使用-M
选项强制重命名。git branch -d [Branch]
:删除已合并的分支[Branch]
,使用-D
选项进行强制删除(无论是否合并)
切换分支
git checkout
git checkout [Branch]
:HEAD
指针切换至该分支的最新提交。git checkout -
:切换至前一个分支
git checkout -b [Branch]
:创建并切换至该分支
git switch
git switch [Branch]
:更清晰地切换分支,避免产生歧义(推荐用于替代checkout
)git switch -c [Branch]
:创建并切换至此分支
合并分支
git merge [Branch]
:将分支[Branch]
快速合并至当前分支,合并后会产生一次合并提交,提交图成环状结构。需手动处理解决冲突,使用git status
查看冲突文件。- 合并冲突:当两个分支修改了同一文件的同一部分时,会造成冲突。
>>>>>>HEAD
下方为当前分支的代码,<<<<<<[Name]
上方为[Name]
分支的代码,======
用于分隔两者。手动编辑处理冲突后使用git add
添加至暂存区,使用git merge --continue
继续合并分支。 git mergetool
:使用工具解决合并冲突git merge --abort
:取消合并
分支的变基
git rebase [Branch]
:求当前分支与目标分支的LCA(最近公共祖先)版本,将当前分支自LCA版本的下个版本起,全部移植至目标分支的分支指针上,HEAD
指针不动。提交图仍为线性结构。
远端仓库
远程仓库的添加、重命名、删除
git remote
:查看本地仓库的远端仓库列表。
选项-v
:查看远端仓库的URLgit remote add [RemoteName] [RemotePath]
:在远端仓库列表中添加名为[RemoteName]
、地址为[RemotePath]
的远端仓库。[RemoteName]
默认为origin
,[RemotePath]
可为路径、URL等。git remote show [RemoteName]
:查看远端仓库详细信息git remote rm [Remote_Name]
:从远端仓库列表中删除该远端仓库git remote rename [RemoteOldName] [RemoteNewName]
:重命名远端仓库git remote set-url [RemoteName] [RemoteNewPath]
:更新远端仓库路径
设置上游分支
设置上游分支建立了本地分支与远程分支的联系。在执行git pull
、git push
前,必须设置上游分支,否则需在对应操作时候手动通过-u
选项设置关联。
git branch -u [RemoteName]/[RemoteBranch] [LocalBranch]
:将远程分支[RemoteName]/[RemoteBranch]
设置为本地分支[LocalBranch]
的上游分支。[LocalBranch]
默认为当前分支。
克隆、拉取、推送
git clone [RemoteURL] [SaveName]
:完整克隆远端仓库(包括所有分支及版本)
选项:-b [Branch]
仅克隆指定分支
--depth=1
仅克隆最新的版本(浅克隆)git fetch [RemoteName]
:拉取远端仓库最新版本,需使用git merge
合并到工作区git pull [RemoteName] [RemoteBranch]
:拉取远端仓库最新版本,合并到本地当前分支工作区(相当于git fetch
+git merge
)。若当前分支已设置上游分支,可直接运行git pull
,否则需使用-u
选项关联远程分支。git push [RemoteName] [LocalBranch]:[RemoteBranch]
:将本地的分支版本上传到远端仓库并合并。若当前分支已设置上游分支,可直接运行git push
,否则需使用-u
选项关联远程分支。使用--tags
选项显式推送所有标签。