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最低。

查看配置信息

#列出当前仓库所使用的全部配置信息
git config --list   
#列出各配置项所在的配置文件 
 git config --list --show-origin

起步配置项

#(必须)首先配置机器上的用户信息和邮箱地址
git config --global user.name "xxx"
git config --global user.email "[email protected]"
#(推荐)配置git交互时 默认打开的编辑器
git config --global core.editor vim 

1.2 帮助(help)

git 有快速参考和综合手册两类帮助命令。

  • 通过-h查看快速参考。
  • 通过-helpmangit help都可查看综合手册。

2. 基础操作

创建仓库并对文件进行跟踪,而后对文件的修改进行提交,从而完成版本控制,一般地,下述三条命令解决大部分需求:

git init
git add . 
git commit -m"initial project version"

2.1 跟踪与暂存(add)

使用git add可以对新文件进行跟踪,对已跟踪的文件的修改进行暂存。经过该命令后,文件或修改将由工作区转移到**暂存区(staged)**。

2.2 删除文件(rm)

  • 对未跟踪的文件:直接删除即可。
  • 对已跟踪的文件:
    • 直接删除文件会形成一条删除记录,且未被加到暂存区。(不推荐)
    • 使用git rm --cached 在暂存区添加一条删除记录,并将文件重置为未跟踪(哪怕文件在之前多次的提交中也没关系)。(取消跟踪)
    • 使用git rm -f 在暂存区添加一条删除记录,并将文件从磁盘上删除。(推荐删除方式)

2.3文件状态(satus)

git status 可以输出当前工作区暂存区中待处理的文件状态信息,并猜测用户可能需要的操作,给出相应的命令提醒
一种简化显示是 git status -s,其效果如下:

$ git status -s 
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

左侧一共有两栏,左栏指示暂存区,右栏指示工作区,各标记含义如下:

  • 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 

# 在上述基础上将git diff输出在默认编辑器显示出来
git commit -v

#(使用最广泛)oneline 模式
git commit -m'提交信息'

暂存并提交

git commit -a 命令会将已跟踪文件的修改自动添加到暂存区并提交。

2.6 查看提交历史(log)

使用命令git log,查看本地仓库的提交记录。

#使得每次记录只显示单行的摘要,当记录较多时建议采用。
git log --oneline
#显示每次提交的简略统计信息
git log --stat
#添加了一些 ASCII 字符串来形象地展示你的分支、合并历史
git log --graph 
#隐藏历史中杂乱的仓库合并记录
git log --merge

上述命令通常可以结合使用。
更多功能:

  • git log --pretty=format:"%占为符... "可以个性化展示内容,可以在此查看常用占位符
  • 提交历史命令还支持很多过滤器选项

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] 在方括号中使用-表示匹配范围。

匹配示例

#忽略.o .a 文件
*.[ao]
# 对lib.a不忽略(即使前边忽略*.a)
! lib.a 
#只忽略当前目录下的Readme文件(不会递归)
/Readme 
#忽略任何目录下名为build的目录
build/
 # 忽略doc下的.class 不会递归!注意
 doc/*.class
# 忽略doc及其子目录下的.class文件
 doc/**/ *.class 

匹配模板

Github提供了详细的匹配模板,可以在gitignore模板仓库查看。

多级忽略文件

仓库根目录(与.git同级)下的.gitignore文件会被递归地应用到整个仓库的每个角落,但也可以在子目录下创建额外的.gitignore,该文件将只应用在所在目录中。

忽略文件不生效

.gitignore只能忽略没有被跟踪的文件(且创建后无需提交即可对未跟踪文件生效),如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。
此类问题一般出现于未能及时创建忽略文件的情况下,解决方案是删除本地缓存后,再同提交忽略文件一起提交。

git rm -r --cached  文件
git add .  
git commit -m"update .gitignore"

2.9标签(tag)

查看标签

#列出当前仓库的标签清单
git tag 
#按照通配符要求列出标签清单
git tag -l "v8.9.*"

创建标签

git中的标签分为两类:轻量标签和附注标签。

  • 轻量标签:仅仅相当于某一特定提交的引用,不包括除标签号外的其他信息。
  • 附注标签:存储在Git版本库中的一个完整对象,是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard (GPG)签名并验证。
    #为某次提交创建附注标签
    it tag -a v1.0 <commit-id>
    #为某次提交创建轻量级标签
    git tag -lw v1.0 <commit-id>

删除标签

删除标签的操作很简单,只要git tag -d v1.0即可。

3.分支 (branch)

3.1 分支的基础操作(branch checkout)

分支查看

通过git branch可列出本地仓库当前的全部分支,如果需要列出远程分支和分支的指针情况,可以通过git branch -avv来实现。

分支创建

常用的分支创建方式有两种:

# 以当前HEAD为父节点 创建新分支
git branch <分支名>
# 创建分支 并切换到新分支
git checkout -b <分支名>

分支切换

通过git checkout <分支名>进行分支切换。
*Note:*在进行分支切换前,请确保工作区是干净的。可以在完成提交或者贮藏后再切换。

分支删除

首先确保不在被删除的分支中,然后通过git branch -d <分支名>来完成对分支的删除。

分支改名

#若在改名的分支中
git branch -m <新分支名>
#若不在改名的分支中
git branch -m <旧分支名> <新分支名>

3.2 分支合并(merge)

简单合并

在分支情形不复杂的情况下,若需要将临时分支B的更改合并到分支A中,只需要:

#切换到A分支 
git checkout A 
#将B分支合并到A分支中
git merge B 
#(可选)删除临时分支
git branch -d B

合并类型

仍然是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上,可以:

#在B分支中(注意 无需切换到A) 将当前分支的修改 应用到A上 
git rebase A
#删除B分支
git checkout A 
git branch -d B 

在我们的提交记录中,不会有合并的记录,而几乎像是在A分支上线性化地完成了一系列修改,变基维持了历史记录的线性流畅。

整理历史

若在本地进行开发时,提交了诸多过于零散的commit,你希望对这些commit 进行合并,你可以使用变基来整理:

#选取最近的三次提交 -i是交互界面
git rebase -i HEAD~3 

在交互界面中,我们将要保留的父提交置为pick,将要并入的提交标记为s,保存退出后,将进入提交信息界面,再次保存退出后,即可完成提交合并。

金科玉律

变基在很多时候(尤其是协作中)是非常危险的操作,如果想要安全地使用变基,请始终遵循:如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
其含义是,你的变基所影响的提交范围,只应该是那些你在本地仓库创建且未推送到远程仓库的提交,而不应该对远程仓库中已经存在提交应用变基。

3.4 贮藏(stash)

在多分支工作时,常常需要将当前分支中产生的修改(不想提交的)贮藏起来,实质上相当于将修改先压入临时的”栈空间”中,需要时再取出。

查看当前的贮藏列表

#查看全部的贮藏列表
git stash  list

将当前的修改贮藏

#以下二选一
git stash  
git stash push 

查看某次贮藏的内容

git stash show <贮藏标号>

取出贮藏

#恢复贮藏 但不从列表中删除贮藏 贮藏还能二次恢复(多用于在其他分支应用某一贮藏)
git stash apply  <贮藏标号>
#恢复贮藏 并从列表中将其删除(推荐)
git stash  pop <贮藏标号>

后续更新 将持续进行 特别是针对 分布式Git的相关内容。


Git 学习整理
http://example.com/posts/7e40b4c1/
发布于
2022年9月25日
许可协议