Git 学习整理
笔者时隔一年再次整理关于git较新内容的整理,为日常使用服务,原理不做过多介绍。
笔者生产环境是Linux,只做命令行环境的整理。
参考:*Git Book version 2*
1. 起步
1.1 配置(config)
配置文件位置
目前共有三级配置文件,影响范围由低到高:
/etc/gitconfig
文件:全局配置文件,通过git config --system
写入(需要root权限)。~/.gitconfig
文件:用户配置文件,通过git config --global
写入。.git/config
文件:本仓库配置文件,通过git config --local
写入,--local
选项可省略。
配置文件应用的优先级中--local
最高,--system
最低。
查看配置信息
起步配置项
1.2 帮助(help)
git 有快速参考和综合手册两类帮助命令。
- 通过
-h
查看快速参考。 - 通过
-help
、man
、git help
都可查看综合手册。
2. 基础操作
创建仓库并对文件进行跟踪,而后对文件的修改进行提交,从而完成版本控制,一般地,下述三条命令解决大部分需求:
2.1 跟踪与暂存(add)
使用git add
可以对新文件进行跟踪,对已跟踪的文件的修改进行暂存。经过该命令后,文件或修改将由工作区转移到**暂存区(staged)**。
2.2 删除文件(rm)
- 对未跟踪的文件:直接删除即可。
- 对已跟踪的文件:
- 直接删除文件会形成一条删除记录,且未被加到暂存区。(不推荐)
- 使用
git rm --cached
在暂存区添加一条删除记录,并将文件重置为未跟踪(哪怕文件在之前多次的提交中也没关系)。(取消跟踪) - 使用
git rm -f
在暂存区添加一条删除记录,并将文件从磁盘上删除。(推荐删除方式)
2.3文件状态(satus)
git status
可以输出当前工作区和暂存区中待处理的文件状态信息,并猜测用户可能需要的操作,给出相应的命令提醒。
一种简化显示是 git status -s
,其效果如下:
左侧一共有两栏,左栏指示暂存区,右栏指示工作区,各标记含义如下:
M
: 修改。位于左栏表示修改并加入暂存区,位于右栏表示修改尚未加入暂存区,左右同时有M表示修改加入暂存区后又进行了修改。A
:添加到暂存区的新建文件。??
:新建文件,还未被跟踪。D
:删除。(同M)
2.4 文件差异(diff)
git diff
查看尚未暂存的修改。git diff --staged 或 --cached
查看提交到暂存区的修改。git diff commit-id -- file
查看某次提交中某文件的修改(省略-- file
则查看的是提交的修改)。
Note:git diff
无法查看未跟踪文件的差异。(合理)但是你也可以使用图形化的工具或外部 diff 工具来比较差异。 可以使用 git difftool 命令来调用 emerge 或 vimdiff 等软件(包括商业软件)输出 diff 的分析结果。 使用 git difftool –tool-help 命令来看你的系统支持哪些 Git Diff 插件。???
2.5 提交记录(commit)
暂存区提交
git commit
会将暂存区的内容形成记录,保存到仓库中,并关联一个commit id(本次提交的完整 SHA-1校验和)。
暂存并提交
git commit -a
命令会将已跟踪文件的修改自动添加到暂存区并提交。
2.6 查看提交历史(log)
使用命令git log
,查看本地仓库的提交记录。
上述命令通常可以结合使用。
更多功能:
2.7 撤销(restore reset)
修补提交
当 提交信息写错或者提交后才发现有漏掉的文件,可以通过git commit --amend
来进行修补。该命令会将当前暂存区的全部内容添加到最近的一次提交,并允许你重新提填写交信息。
撤销暂存区
当需要把文件从暂存区撤换下来时,可以通过git restore --staged <file>
来将文件从暂存区放回工作区。在老版本中的命令是git reset HEAD <file>
。
撤销工作区修改
当需要把工作区内对某个文件的修改撤销时,可以通过git restore <file>
来实现,其效果等同于git checkout <file>
。
撤销提交
当需要把commit 给撤销回工作区时,可以通过git reset --soft <commit-id>
重置HEAD指针,此前提交的修改将全部回到工作区,但你尚未提交的内容(暂存区和工作区)都不受影响。
撤销删除
首先要明白,文件之所以能恢复是因为在git版本库中保留了记录,如果你的文件没有提交过(被记录在版本库),则无法恢复。
分为两种情况:
- 已删除,但未提交,删除记录在工作区或暂存区:
- 将文件的删除记录恢复到工作区。
- 通过
git restore <file>
即可恢复。
- 已删除,并提交了删除记录(文件在版本库中被删除):
- 找到删除文件记录对应的提交 或 更久之前的提交
<commit-id>
,通过git reset --soft <commit-id>
来撤销此前的提交。 - 将文件的删除记录恢复到工作区。
- 通过
git restore <file>
即可恢复。
- 找到删除文件记录对应的提交 或 更久之前的提交
2.8 忽略文件(ignore)
对于无需纳入Git管理,且不希望总出现在未跟踪文件列表的文件,可以在.gitignore
中配置忽略文件的模式。
要养成一开始就为你的新仓库设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。
匹配规范
- 所有空行 或 以#开头的行 不会匹配。
- 以
/
开头只在当前目录下匹配,不递归。 - 以
/
结尾只匹配目录而不匹配文件。 - 使用
!
开头来对匹配取反。 - 标准glob模式(shell所使用的简化正则表达式),会递归地应用在整个工作区。
*
匹配零个或多个字符。**
匹配任意的中间目录。(与*不同,a/**/z可以匹配a/z)?
匹配一个字符。[abc]
匹配任何一个在方括号中的字符(a或b或c)。[a-z]
或[0-9]
在方括号中使用-
表示匹配范围。
匹配示例
匹配模板
Github提供了详细的匹配模板,可以在gitignore模板仓库查看。
多级忽略文件
仓库根目录(与.git
同级)下的.gitignore
文件会被递归地应用到整个仓库的每个角落,但也可以在子目录下创建额外的.gitignore
,该文件将只应用在所在目录中。
忽略文件不生效
.gitignore
只能忽略没有被跟踪的文件(且创建后无需提交即可对未跟踪文件生效),如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。
此类问题一般出现于未能及时创建忽略文件的情况下,解决方案是删除本地缓存后,再同提交忽略文件一起提交。
2.9标签(tag)
查看标签
创建标签
git中的标签分为两类:轻量标签和附注标签。
- 轻量标签:仅仅相当于某一特定提交的引用,不包括除标签号外的其他信息。
- 附注标签:存储在Git版本库中的一个完整对象,是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard (GPG)签名并验证。
删除标签
删除标签的操作很简单,只要git tag -d v1.0
即可。
3.分支 (branch)
3.1 分支的基础操作(branch checkout)
分支查看
通过git branch
可列出本地仓库当前的全部分支,如果需要列出远程分支和分支的指针情况,可以通过git branch -avv
来实现。
分支创建
常用的分支创建方式有两种:
分支切换
通过git checkout <分支名>
进行分支切换。
*Note:*在进行分支切换前,请确保工作区是干净的。可以在完成提交或者贮藏后再切换。
分支删除
首先确保不在被删除的分支中,然后通过git branch -d <分支名>
来完成对分支的删除。
分支改名
3.2 分支合并(merge)
简单合并
在分支情形不复杂的情况下,若需要将临时分支B的更改合并到分支A中,只需要:
合并类型
仍然是B作为A的分支,要将B合并到A中,我们列出分支合并最常见的两种形式:
快进合并(fast-forward)
:A分支指针仍然停留在B分支的分叉点上(C2),A和B仍然是线性的,只要快进移动A的指针到B的位置(C3)即可。三方合并
:A分支指针已领先于B分支的分叉点,A和B不满足线性,需要将A的最新快照(C4)、B的最新快照(C5)和他们的共同祖先(C2)来参与合并。
通常地,为了尽可能减少冲突,更推荐使用快进式合并,但在协作中往往会遇到三方合并的情景,为了减轻协作中远端维护人员的合并压力,一个常用的思路是:本地通过变基rebase来变更分支B的祖先,再由远端维护人员将B快进合并到A中。
3.3变基(rebase)
基础用法
rebase 的基本思路是将某一分支的修改全部应用于令一分支,与合并带来的最终结果相同(都整合了来自不同分支的修改),但是维护了快照(记录)历史的线性关系。
仍然是B作为A的分支,要将B的修改整理到A上,可以:
在我们的提交记录中,不会有合并的记录,而几乎像是在A分支上线性化地完成了一系列修改,变基维持了历史记录的线性流畅。
整理历史
若在本地进行开发时,提交了诸多过于零散的commit,你希望对这些commit 进行合并,你可以使用变基来整理:
在交互界面中,我们将要保留的父提交置为pick
,将要并入的提交标记为s
,保存退出后,将进入提交信息界面,再次保存退出后,即可完成提交合并。
金科玉律
变基在很多时候(尤其是协作中)是非常危险的操作,如果想要安全地使用变基,请始终遵循:如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
其含义是,你的变基所影响的提交范围,只应该是那些你在本地仓库创建且未推送到远程仓库的提交,而不应该对远程仓库中已经存在提交应用变基。
3.4 贮藏(stash)
在多分支工作时,常常需要将当前分支中产生的修改(不想提交的)贮藏起来,实质上相当于将修改先压入临时的”栈空间”中,需要时再取出。
查看当前的贮藏列表
将当前的修改贮藏
查看某次贮藏的内容
取出贮藏
后续更新 将持续进行 特别是针对 分布式Git的相关内容。