《精通Git 第2版》

目录

《精通Git 第2版》

一、入门

1.1 关于版本控制

本地 -> 集中式(例如SVN) -> 分布式(例如Git)

1.2 Git基础

快速,而非差异;几乎所有操作都在本地执行;Git的完整性;Git通常只增加数据;三种状态(已提交、已修改、已暂存);三个主要区域(Git目录、工作目录和暂存区)

1.3 安装Git

安装 方式
Liunx yum install git-allapt install git-all
Mac 通过安装Xcode命令行工具安装
Windows 官网下载
源码 参考官方文档

1.4 Git配置

层级 文件位置 配置参数
系统级 /etc/gitconfig --system
用户级 ~/.gitconfig~/.config/git/config --global
仓库级 Git目录.git/config

Windows中查找$HOME目录中查找配置文件

配置用户身份

1
2
git config --global user.name "ns-cn"
git config --global user.email "ns-cn@qq.com"

配置个人编辑器,需要输入消息的时候会用到编辑器

1
git config --global core.editor emacs

检查个人配置

1
2
3
4
5
6
# 列举所有配置
git config --list
# 查看配置的用户名
git config user.name
# 查看config帮助文档
git help config

二、Git基础

2.1 获取Git仓库

在现有目录中初始化仓库

1
git init

克隆现有仓库

1
2
git clone https://github.com/ns-cn/ns-cn.github.io # 以仓库名为文件夹名
git clone https://github.com/ns-cn/ns-cn.github.io webroot # 以webroot为文件夹名

2.2 记录变更

查看文件状态

1
2
git status
git status -s # 显示更简介的状态信息

跟踪新文件 或 暂存已修改文件

1
git add README.md

通过编辑.gitignore文件忽略文件变更

  • 空行或则以#开始的行会被忽略
  • 支持标准的glob模式,*号代表0个或多个字符,[abc]代表方括号内任意单个字符,?号匹配单个
  • 以/开头的模式可用于禁止递归匹配
  • 以/结尾的模式表示目录
  • 以感叹号开始的模式表示取反

查看已暂存和未暂存的变更

1
2
3
git diff # 查看暂存区和未暂存的所有变更
git diff --staged # 仅查看已暂存的变更
git diff --cached # 仅查看已暂存的变更,与--staged功能相同

提交变更

1
2
git commit -m "messages"
git commit -a -m "messages" # 自动把所有已跟踪的所有文件添加到暂存区然后提交

移除文件

1
2
3
4
5
rm README.md    # 删除本地文件,但未暂存变更
git rm README.md    # 删除本地文件并暂存变更
git rm -f README.md # 针对以修改并暂存了修改,必须使用-f参数强制删除
git rm --cached README.md # 暂存删除操作变更,但保留本地文件
git rm log/\*.log   # 通配符移除

移动文件

1
git mv README.md README

查看提交历史

1
2
3
4
5
6
7
git log # 所有历史
git log -p -2   # 查看最近两次提交并显示所引入的差异
git log --stat  # 查看 每个提交的简要统计信息(改动文件列表、文件数量及行数统计)
# 使用--pretty更改输出格式
git log --pretty=oneline    # 单行输出、其他short/full/fuller
git log --pretty=format:"%h - %an, %ar : %s"    # 自定义格式
git log --graph # 用ASCII字符的简单图表来显示分支和合并历史

具体的格式化格式参数参考:git log 使用及格式化参数详解

限制提交历史的输出范围

选项 描述
-(n) 只显示最新的n次提交
--since--after 只显示指定日期之后的提交
--util--before 只输出指定日期之前的提交
--author 只输出指定作者与指定字符串匹配的提交
--commiter 只输出提交这与指定字符串匹配的提交
--grep 只输出提交信息包含指定字符串的提交
-S 只输出包含“添加或删除指定字符串”的更改的提交

2.3 撤销操作 reset/checkout

补充提交内容或修改提交信息(只会产生一个提交记录)

1
2
3
git commit -m "initial commit"
git add README.md
git commit -amend   # 只会产生一次提交并补充提交暂存区内容

暂存区 -> 工作区

1
2
git reset HEAD <file>...
git reset HEAD --hard <file>... # 危险操作

撤销对文件修改(工作区保持与仓库同步,危险操作,丢失修改内容)

1
git checkout -- <file>...

想保留修改内容但要需要短时间使用仓库内容,可参考储藏(stash)或分支机制更好

2.4 远程仓库 remote

显示远程仓库

1
2
git remote  # 显示远程仓库名称
git remote -v   # 显示远程仓库和对应的url

添加远程仓库:git remote add [shortname] [url]

1
git remote add webroot https://github.com/ns-cn/ns-cn.github.io

从远程仓库获取和拉去数据: git fetch [remote-name]

会从远程仓库中获取所有本地仓库没有的数据。克隆仓库的时候会自动添加远程仓库

1
2
git fetch webroot
git pull    # 如果本地分支跟踪了远程分支,可以使用git pull

将数据推送到远程仓库:git push [remote-name] [branch-name]

1
git push origin master

检查远程仓库:git remote show [remote-name]

1
git remote show origin

重命名远程仓库

1
git remote rename pb paul

删除远程仓库

1
git remote rm paul

2.5 标记 tag

特定的历史版本标记为重要版本

列举标签

1
2
git tag
git tag -l "v1.8.5*"    # 通配符过滤

补加标签

1
git tag -a v1.2 9fceb02

共享标签:默认情况下git push不会将标签传输到远程服务器:git push origin [tag-name]

1
2
git push origin v1.5    # 推送指定标签到远程服务器
git push origin --tags  # 将服务器上没有的所有标签都推送

检出标签:无法真正检出标签,可以通过标签名称创建新的分支方式:git checkout -b [branch-name] [tag-name]

1
git checkout -b version2 v2.0.0

2.6 Git别名

通过设置git命令别名简化命令:git config --global alias.[别名] [原始命令]

1
2
git config --global alias.co checkout
git config --global alias.unstage 'reset HEAD --'

使用别名

1
2
git unstage fileA
git reset HEAD -- fileA #使用unstage等价

取消设置别名

1
git config --global --unset alias.co

三、分支机制

3.1 分支机制

Git的分支只不过是一个指向某次提交的轻量级的可移动指针。Git的特殊指针HEAD,指向当前所在的本地分支的指针。

创建新分支

1
2
3
4
# 创建一个名为testing的新分支(创建一个指向当前提交的新指针),并未切换到新创建的分支上
git branch testing
# 查看各个分支当前所指向的对象
git log --online --decorate

切换分支,HEAD指针指向切换的目标分支

分支切换会更改工作目录文件,如果当前状态下无法干净地完成恢复操作,就不会允许你切换分支。

1
git checkout testing

分支实际上就是一个简单文件,其中只包含了该分支所指向提交的长度为40个字符的SHA-1校验和。

3.2 分支与合并操作

3.2.1 直接父节点合并操作

创建并切到换对应分支增加-b选项

1
2
3
4
git checkout -b iss53
# 相当于
git branch iss53
git checkout iss53

在iss53上提交c3

master分支合并iss53分支的最新修改c3

1
2
git checkout master #切换到master分支
git merge iss53     #合并iss53分支到master分支

直接上游合并:如果分支是待合并分支的直接上游,Git会简化直接移动指针,git称为fast-forward

删除分支

1
git branch -d iss53

3.2.2 不同分支节点合并

合并之前初始状态

切换到master分支并合并iss53

1
2
git checkout master #切换到master分支
git merge iss53     #合并iss53分支到master分支

三方合并:使用待合并分支的最新快照,以及共同祖先的提交快照,基于合并解构创建新的快照,再创建一个提交指向新建的快照。

3.2.3 基本的合并冲突处理

修改同一文件的同一部分导致无法合并时,git merge不会创建提交,需要处理冲突后手动提交

3.3 分支管理

分支查看

1
2
3
4
git branch  #查看所有分支
git branch -v   # 查看每个分支的最新提交
git branch --merged # 筛选已合并到当前分支的所有分支
git branch --no-merged  # 筛选未合并到当前分支的所有分支

如果未合并到当前分支时对分支进行-d选项删除将不被允许,可使用-D强制删除

3.4 分支工作流

分支 说明
长期分支 按稳定程度划分
主题分支 短期、用于实现特定功能的分支

3.5 远程分支

3.5.1 理解远程分支

远程分支是指向远程仓库的分支的指针,有点像书签,提示你上一次连接服远程仓库时每个分支的位置。使用{remote}/{branch}表示,例如origin/master

orgin并非特殊名称,与master分支名称一样

git fetch查询远程服务器分支信息,从服务器取得本地未包含的数据,最后把origin/master指针移动到最新位置

1
git fetch origin

3.5.2 推送

推送到远程分支:git push (remote) (branch)

1
2
git push origin test        # 简化写法,推送本地的test分支到远程的test分支
git push origin test2:test   # 完整写法,推送本地的test2分支到远程的test分支

不用每次都键入密码:基于HTTPS进行数据推送默认每次都进行身份验证,可使用git config --global credential.helper cache命令进行凭证缓存,暂时保存到内存几分钟。

git fetch之后只是拿到了远程分支的数据,如果需要在工作区拿到这些数据,需要进行git merge

1
2
git fetch origin
git merge origin/test

3.5.3 跟踪分支

跟踪分支是与远程分支直接关联的本地分支。基于远程分支创建的本地分支会自动成为跟踪分支(tracking branch),或则有时候也会叫做上游分支(upstream branch)。

基于远程分支创建跟踪分支

1
2
3
git checkout --track origin/serverfix   # 切换到远程分支并自动跟踪
git branch serverfix    # 如果serverfix分支尚未创建,并且与某个远程分支名称一致,自动创建跟踪分支
git branch -b localserverfix origin/serverfix   # 基于远程分支创建并跟踪,但创建跟踪分支

针对已有分支设置跟踪分支,通过增加-u或则--set-upstream-to

1
git branch -u origin/serverfix

查看分支跟踪情况

1
git branch -vv

如果已经设置好上游分支,则可以通过@{upstream}@{u}来使用他,例如git merge @{u}来代替git merge origin/master

3.5.4 拉取

解读git fetchgit pull命令区别

命令 内容 结果
git fetch 拉取本地没有的远程所有最新更改数据 完全不会更改工作目录
git pull 等同于git fetch之后执行git merge 会尝试将远程分支上的修改合并到本地

推荐显式使用git fetch之后执行git mergegit pull的机制比较迷惑。

3.5.5 删除远程分支

通过git push--delete选项删除远程分支

1
git push origin --delete serverfix

3.6 变基

3.6.1 变基基础

变基rebase和合并merge的区别:rebase获得更加简洁的提交历史。

在master分支上git merge experiment操作的结果

在expriment分支上git rebase master操作的结果

3.6.2 有趣的变基操作

通过rebase部分操作到目标分支,暂不合并未经测试的内容

例如合并client分支但不包含c3部分到master分支

1
git rebase --onto master server client

命令含义:切换到client分支,找出client和server的共同祖先并提交,把client分支自共同祖先以来的所有工作在master分支重现。

接下来就可以针对master分支合并client分支

不需要切换当前分支执行变基操作可使用git rebase [basebranch] [topicbranch],例如读取server变更,在master分支上重现。

1
git rebase master server

3.6.3 变基操作的潜在危害

不要对已经存在于本地仓库之外的提交执行变基操作。1

变基:实际上是抛弃了已有的某些操作,随后创建了新的对应提交。

3.6.4 只在需要的时候执行变基操作

git pull --rebase指定pull操作使用rebase方式,可使用配置修改默认方式

1
git config --global pull.rebase true    # git pull时默认--rebase
情况 结果
变基操作用于推送前的整理和处理提交的手段,并且仅对本地还没有公开的提交进行变基 不会存在问题
对已经推送了的提交执行变基操作(别人已经基于提交作了自己的开发) 遇到大麻烦

3.6.5 变基与合并的对比

总结:对本地尚未推送的更改进行变基操作,从而简化提交历史,但决不能对任何已经推送到服务器的变更进行变基操作。

四、Git服务器

4.1 协议

协议 样例 优点 缺点
本地 git clone file:///src/project.git 简单易用 本地网络之外的无法访问
HTTP git clone https://example.com/project.git 账号+密码方式方便、协议速度快、传输效率高 基于HTTP的Git服务不方便搭建
SSH git clone ssh://user@server/project.git 应用广泛、安全、传输加密 不能实现对仓库的匿名访问
Git 速度最快 缺少用户验证机制

4.2 在服务器上搭建Git

  1. 将裸仓库防止在服务器上
  2. 小型团队配置(通过SSH访问)

4.3 GitWeb

Git自带的图形化界面

1
git instaweb --httpwebrick

4.4 GitLab

开源、功能完善、现代化的Git服务器软件。

用户 项目 钩子

五、分布式Git

5.1 分布式工作流

集中式工作流:推送变更之前都必须合并上一个人的修改(常见SVN)

集中式管理者工作流:创建项目的公开克隆,推送自己的修改,请求主项目维护人员合并你的变更。(常见Github或GitLab)

司令官与副官工作流:多仓库工作流的一个变体,通常由涉及上百名协作人员的大型项目使用。

5.2 为项目做贡献

5.2.1 提交准则

  1. 不要出现与空白字符相关的错误;(使用git diff --check鉴别并列出可能存在的空白字符错误)
  2. 尽量使每次提交在逻辑上都是一个独立的变更集;(使用git add --patch部分暂存文件)
  3. 创建高质量的提交信息。

5.2.2 工作流推荐

  1. 私有小团队:每次push之前先fetch+merge
  2. 私有管理团队:使用分支独立管理提交内容
  3. 派生的公开项目:创建fork仓库并提交变更,生成拉取请求(pull request

5.3 维护项目

  1. 使用主题分支(可为分支指定命名空间git branch sc/ruby_client master
  2. 应用来自电子邮件的补丁
  3. 检出远程分支(将派生仓库的分支作为远程分支在本地合并)
  4. 确定引入内容
    • 在分支contrib中查看排除master分支的日志:git log contrib --not master
    • 查看与其他分支的对比:git diff master
    • 查看与特定版本的对比:git diff 36c7db
    • 在所处分支的最新提交和两个分支的共同祖先之间进行diff操作:三点语法git diff master...contrib
  5. 整合所贡献的工作结果:合并工作流
  6. 为发布版打标签:参考#2.5 标记tag
  7. 生成构建编号:使用git describe命令为提交生成一个可读性的名称2
  1. 准备发布:创建一个包含代码最新快照的归档文件git archive
  2. 简报:快速得到上次发布或发送电子邮件之后新增内容的各类变更日志git shortlog

六、GitHub

七、Git工具

7.1 选择修订版本

7.1.1 单个修订版本

短格式的SHA-1:只要能确定唯一就行SHA-1

1
git log s12s3

分支引用:使用分支代表最后一次提交版本

1
2
git log 432645e5dcbe3488c3ec013429314cebf82c79d4
git log topic   #等同于使用分支名称

reflog:保存在本地的HEAD和分支引用的日志

1
2
3
4
git reflog  #查看本地的reflog
git log HEAD@{5}    # 引用HEAD在之前第5次的值
git log master@{yesterday}  # 通过日期指定
git log -g master   # 日志输出中以reflog形式输出

祖先引用:通过特定版本查询父查询,通过^~配合数字指定

1
2
3
4
git show HEAD^       # 指定提交的父提交
git show d921970^2   # 特定版本的第二个父提交
git show HEAD~      # 首个父提交
git show HEAD~2     # 首个父提交的父提交

7.1.2 提交范围

双点号:那些不在同一分支上的提交

1
2
3
git log master..experiment  # 在expriment分支但不在master分支的提交
git log origin/master..HEAD  # 在HEAD提交但在远程分支的,即未推送的
git log origin/master..     # 可省略HEAD

多点:通过^或则--not来指定不包含在其中的提交

1
2
3
4
5
6
7
8
# 如下三个命令是等效的
git log refA..refB
git log ^refA refB
git log refB --not refA

# 包含在refA或refB中但不包含在refC中的提交
git log refA refB ^refC
git log refA refB --not refC

三点号:指定仅包含在其中任意一个引用中的所有提交

1
2
git log master...experiment # 属于master和expriment的非共有引用
git log --left-right master...experiment    # 显示每个结果属于那个左边分支还是右边分支

7.2 交互式暂存

通过git add -igit add --interactive进入交互式shell显式管理暂存区

1
2
3
4
5
> git add -i

*** Commands ***
  1: status	  2: update	  3: revert	  4: add untracked
  5: patch	  6: diff	  7: quit	  8: help

暂存补丁:暂存文件的部分修改

  1. 方式1:在交互式提示符下输入5或则p,针对每个文件的每个区块进行暂存选择。
  2. 方式2:命令行上使用git add --patchgit add -p来启动部分暂存

补丁模式的其他命令:

  1. 重置部分文件:reset --patch
  2. 检查部分文件:checkout --patch
  3. 储藏部分文件:stash save -patch

7.3 储藏与清理

7.3.1 储藏基础操作

未完成提交情况下需要切换分支,使用git stash储藏未提交的变更

将新的储藏内容推入栈中

1
git stash   # 或git stash save,储藏变更

查看存储在栈中的储藏

1
git stash list

重新应用栈中的某个储藏

1
2
git stash apply # 应用最近的储藏
git stash apply stash@{2}   # 应用指定的储藏

apply选项只会尝试应用储藏过的内容,而这些内容仍然保存在栈上

删除储藏内容

1
git stash drop stash@{2}

7.3.2 灵活运用储藏

  1. 不跟踪已经用git add命令暂存过的内容:git stash --keep-index
  2. 储藏未跟踪的文件(默认不储藏未跟踪文件):git stash --include-untracked(或-u

7.3.3 从储藏中建立分支

git stash branch testchanges:建立新分支testchanges,检出储藏区的内容并应用,成功后删除储藏区内容

7.3.4 清理工作目录

命令 清理结果 选项说明
git clean 删除所有未跟踪文件(默认不包含被忽略的未跟踪文件) -x连被忽略的一并删除;-i交互式处理
git stash --all 删除全部内容,并以储藏形式保存

7.4 签署工作

通过加密提交及验证提交内容,验证提交源是否可信,略

7.5 搜索

7.5.1 git grep

在任何提交树或工作目录中方便地差好啊某个字符串或正则表达式3

1
2
3
4
git grep gmtime_r
git grep -n gmtime_r    # 显示行号
git grep -c gmtime_r    # 统计数量,或--count
git grep -p gmtime_r    # 显示属于的函数或方法

7.5.2 Git日志搜索

git log通过提交信息,甚至diff内容查找特定的提交

查询常量ZLIB_BUF_MAX最初时什么时候出现的

1
git log -S ZLIB_BUF_MAX --online

查询文件zlib.c中函数git_deflate_bound的所有改动

1
git log -L :git_deflate_bound:zlib.c

7.6 重写历史

  1. 修改最近一次变更:git commit --amend,如果需要变更提交文件先在变更到暂存区再执行命令
  2. 修改多个提交信息:利用变基交互式实现,git rebase -i HEAD~3
  3. 重排提交:执行多个变基操作时变基排序实现
  4. 压缩提交:执行多个变基操作时,指定squash应用该变更及之前的变更并将提交信息合并
  5. 拆分提交:参考资料4
  1. 大面积修改提交记录:git filter-branch,参考资料5

7.7 重置揭秘

7.7.1 三棵树

三棵树

用途
HEAD 最近提交的快照,下次提交的父提交
索引 预计的下一次提交的快照
工作目录 沙盒

7.7.2 reset

reset参数简介

参数 移动HEAD 更新索引 更新工作目录
--soft
--mixed或缺省
--hard
1
git reset --hard HEAD^  # 回滚到上一个提交版本

--hard是reset命令仅有的一个危险用法,也是Git造成数据损坏的极少数情况之一。

通过reset实现压缩提交: 不清空暂存区reset到目标快照,然后提交

1
2
git reset --soft HEAD^3
git commit

7.7.3 checkout

git checkout [branch]git reset --hard [branch]对比

命令 是否影响工作区 更新HEAD方式
checkout × 移动HEAD,指向其他分支
reset 移动HEAD指向的分支

利用checkout恢复文件内容,会变更暂存区并覆盖工作目录

1
git checkout file.txt

7.8 合并的高级用法

7.8.1 冲突的基本处理

中止合并:会尝试恢复到合并之前的状态(保留了未暂存和未提交的变更)

1
git merge --abort   # 实在无法恢复可使用 git reset --hard丢失修改并强制恢复

忽略空白字符:可将空白字符不同大致的冲突视为相同

1
git merge -Xignore-space-change otherbranch

手动合并:获取冲突文件的个人版本、他人版本以及公用版本,并手动合并这个单独的文件。合并后可使用git diff配合不同参数查看对比

1
2
3
4
git diff --theirs   # 与他们版本做对比
git diff --base     # 查看两侧是如何改动的
手动合并后可使用clean清除多余的文件
git clean -f

查询导致合并冲突的日志:通过git log配合--merge查看那些提交导致了冲突

1
2
git log --oneline -left-right HEAD...MERGE_HEAD     #HEAD和合并内容差异的所有提交
git log --oneline -left-right --merge   # 使用--merge选项仅查询所有导致冲突的差异

组合式差异格式:在出现合并冲突后执行git diff输出格式

检出冲突内容git_checkout

--ours--theirs作为选项时,仅检出目标方的内容,例如非文本文件时完全信任一方的变更

git checkout--conflict选项指定文件冲突标记样式,可使用git config --global merge.conflictstyle diff3更改全局默认冲突标记方式

--conflict 样式
merge或缺省 仅提供自己的版本和他人版本
diff3 提供自己的版本、他人版本和公用版本的内容
1
git checkout --conflict=diff3 hello.rb

7.8.2 撤销合并

master分支已经合并了topic分支,但需要撤销

修复引用:移动分支,使其指向你希望指向的地方

1
git reset --hard HEAD~

会重写历史记录,导致无法追溯

还原提交:使用revert命令生成一个新的提交,撤销已提交的所有变更

1
git revert -m 1 HEAD

-m 1指明哪一个父节点是应该保留的主线,这里表示第一个父节点保留并撤销第二个父节点内容,新生成的提交和合并之前一致,但保留了提交历史

还原提交方式的撤销因为已经包含了合并分支的内容,所以再次执行合并时无法合并目标分支。可对还原执行撤销。

7.8.3 其他类型的合并

ours和theirs合并:配合-Xours-Xtgeirs选项在合并时如果有冲突直接应用自己的还是三方的

1
git merge -Xours mundo

7.9 rerere

rerere(reuse recorded resolution):重用记录过的解决方案。用于处理相同类型的冲突自动处理

1
2
3
4
git config --global rerere.enabled true # 启用rerere功能
git rerere status   # 查看rerere记录的冲突解决方案
git rerere diff     # 记录的解决方案现状(解决之前和之后的样子)
git rerere          # 尝试使用记录的解决方案自动解决冲突

7.10 使用Git调试

文件标注:使用blame命令针对每一行查看最后修改信息

1
2
git blame -L 12,22 samplegit.rb # 查看12到22行每行的最后修改信息
git blame -C -L 12,22 samplegit.rb  # 使用-C参数尝试分析代码的原始来源,例如文件重命名导致的移动

二分查找:通过当前错误版本与正常版本进行二分查找快速定位发生问题的提交

1
2
3
4
5
6
git bisect start    # 启动排查过程
git bisect start HEAD v.10  # 通过范围快速开始排查过程
git bisect bad      # 当前版本存在问题
git bisect good v1.0    # 1.0版本正常,此时会切到二分版本,验证后判断是否正常

git bisect reset    # 问题排查结束够将HEAD重置到排查开始之前的位置

7.11 子模块

添加子模块,添加后仅暂存,需要push才会提交到远程仓库,子模块信息存储在.gitmodules文件中

1
2
git submodule add https://github.com/ns-cn/ns-cn.github.io.git
git submodule add https://github.com/ns-cn/ns-cn.github.io.git webRoot  # 指定目录位置

关于子模块的相关命令:也可以进入对应的目录当成一个git仓库执行命令执行

1
2
3
git submodule init  # 初始化子模块本地配置文件
git submodule update    # 从项目中获取所有数据并检出付项目中适合的提交
git clone --recursive [repository]  # 克隆并更新仓库中的每个子模块

发布子模块变更:主仓库推送但子模块未推送会存在问题,可在push时使用--recurse-submodules选项设置为check或on-demand(尝试将子模块推送),如果子模块变更未推送就推送失败

1
git push --recurse-submodules=check

子模块技巧之foreach命令: 在每个子模块中执行命令

1
git submodule foreach 'git stash'

子模块之分支切换问题:分支切换时子模块依然存在,需要手动处理

7.12 打包

将指定仓库打包为文件发送给别人,方便别人本地重建

1
2
git bundle create repo.bunlde HEAD master   # 打包
git clone repo.bundle repo      # 通过文件重建仓库

7.13 replace

替换某个版本保存的数据git replace e52wgs 12g5sw

八、自定义Git

8.1 配置Git

基本

配置 说明
core.editor 默认文本编辑器,比如commit的提交信息输入
commit.template 提交信息模板
core.pager 分页输出的处理,可选more或less,也可以设置空串来关闭
user.signgkey 签名
core.excludesfile 全局忽略文件配置
help.autocorrent 命令自动推测

Git的配色

配置 说明
color.ui 是否启用彩色终端输出
color.* 针对具体项配置彩色输出,例如diff、status等

外部合并工具

1
git mergetool

格式化与空白字符

配置 说明
core.autocrlf 处理CRLF为LF,消除操作系统差异
core.whitespace 配置针对空白字符的处理

8.2 Git属性

配置读取配置的位置,以及相关策略,略

8.3 Git钩子

在重要的事情发生时触发自定义的脚本,分为客户端钩子和服务端钩子

九、Git与其他系统

9.1 作为客户端的Git

9.1.1 Git与Subversion

使用git检出svn代码

1
git svn clone [svn-repository] -T trunk -b branches -t tags

-T trunk -b branches -t告诉Git该仓库遵循基本分支与标签惯例

提交代码并推送到svn仓库

1
2
git commit -am message
git svn dcommit

拉取最新的代码(如果存在冲突则不允许推送,需要先在本地合并),使用git svn rebase因为单分支问题

1
git svn rebase

在svn仓库中使用git分支

1
2
git svn branch opera    # 创建分支
git branch opera remotes/origin/opera   # 映射为本地的一个分支

在git中使用svn命令

1
2
git svn log     # 历史
git svn info    # svn仓库信息

忽略文件

1
2
git svn create-ignore   # 基于svn的svn:ignore生成.gitignore文件
git svn show-ignore     # 在命令行打印忽略文件内容

9.1.2 Git与其他

目标 使用工具
Mercurial 使用git-remote-hg作为桥接实现对mercurial仓库的管理
Perfoce 使用Git Funsion作为桥接实现对Perforce仓库的管理。
TFS git-tfgit-tfs

9.2 迁移到Git

十、Git内幕

10.1 底层命令和高层命令

执行git init之后的初始.git目录

文件(夹) 说明
description 仅供GitWeb使用
config目录 项目特定的配置选项
info 保存了一个全局性排除文件
hooks 客户端或服务端钩子脚本
HEAD 指向当前已检出的分支
index 保存暂存区信息
objects 保存个人数据库的所有内容
refs 存储的指针

通过底层命令维护版本树、资源池和引用等内容

10.2 其他略

0%