导图社区 Git
Git思维导图,主要内容有:设置、符号和名称、创建版本、库暂存、提交分支、变基、历史记录、本地版、本库。
编辑于2022-06-25 23:12:24Git
设置
修改用户名
git config --global user.name "User"
必填选项
修改邮箱
git config --global user.email "Email"
必填选项
窗口颜色
git config --global color.ui "always"
选项
auto:自动
always:bash和命令行下均彩色
false:不使用彩色
显示设置
git config --global --list
设置命令别名
示例:git config --global alias.ci "commit"
符号和名称
HEAD
当前分支末梢
^
一个脱字符作用为回溯一个版本
示例:18f822e^表示18f822e之前的版本
注意
Windows中如出现^应加双引号
可以使用多个脱字符
可以混合~使用
*~N
回溯N个版本
示例:18f822e~2
标签和分支的有效名称
可以使用反斜杠/,但是不能以之结尾
可以像组织文件目录结构一样组织标签和分支
可以使用圆点.,但不能置于各段名称的开头
不能使用空格、~、^、:、?、*、[等
不能使用编码小于\040的控制字符和删除键
不能出现双圆点..
创建版本库
1.进入源代码存放目录
2.初始化
git init
创建一个.git目录,存放版本库元数据
暂存
将文件添加到版本库的索引
术语
暂存的变更
stage change
工作目录树中打算提交到版本库的变更
暂存区
staging area
暂存操作更新的git的内部索引
示例:git add index.html
参数
-i
交互添加方式
用来选择要暂存的文件或文件的部分内容
功能
1.status.显示与该方式启动时相同的输出
2.update.添加文件到暂存区
输入要暂存的文件号
文件前显示*表示文件将缓存
回车退出该模式
3.revert.取消已暂存的修改
4.add untracked.暂存还没被git跟踪的文件
5.patch.
可选择单个或多个文件添加到暂存区
回车显示这些文件当前内容与版本库的差异
Stage this hunk?
y:是
n:否
q:退出不暂存
a:添加剩余修改
d:放弃剩余修改
g:选择一个块前往
/:正则查找块
j:未决定状态离开这个块,查看下一个未决定块
J:未决定状态离开这个块,查看下一个块
k:未决定状态离开这个块,查看前一个未决定块
K:未决定状态离开这个块,查看前一个块
s:切分当前块到更小
e:手工编辑当前块
?:帮助
6.diff.
7.quit.
8.help.
-p/--patch
进入patch模式
-u
暂存已纳入git版本控制的文件的修改
提交
提交到本地版本库
示例
先暂存再提交
git add some-file
git commit -m "comments"
提交工作目录树所有修改
git commit -m "comments" -a
指定要提交的文件或文件列表
git commit -m "comments" some-file
参数
-m:本次提交的留言
可接受任意多次留言的输入
不带-m参数,启动编辑器提交留言
环境变量GIT_EDITOR的值
Git的设置core.editor的值
环境变量VISUAL的值
环境变量EDITOR的值
上述值为空,启动VI
-v:把要提交内容与版本库版本比较结果添加到编辑器中
-a:提交全部修改过的文件
尚未追踪的文件不会添加
SHA-1
用来跟踪提交的哈希码
提交时显示40位哈希码的前7位
注意
git不会跟踪空目录
解决:在目录里添加一个空文件(文件名任意,习惯使用点号.)
增补提交
git commit -C HEAD -a --amend
-C:告诉git复用指定提交的提交留言
-c:打开编辑器,修改已有留言
HEAD:指定的提交名称
--amend:不在版本库里多新的提交记录
注意
增补提交只能针对最后一个提交
如果想更正几个提交前的某个错误,应先git revert
反转提交
git revert -n <提交名称>
-n:告诉git先不提交,可运行多次,最后一次性提交
--no-edit:直接使用默认的提交留言
复位
复位版本库到一个特定版本,之后修改放入工作目录树
git reset <提交名称>
默认为HEAD
可以使用^和~
--soft:暂存所有因复位带来的差异,但不提交
--hard:从版本库和工作目录树中同时删除提交
不可恢复
谨慎使用
分支
创建时机
试验性更改
增加新功能
bug修复
创建
git branch <新分支名> <父分支名/标签名>
git branch <新分支名>
以当前分支为父分支
显示版本库分支
git branch
本地
git branch -r
远程
git branch -a
所有
*绿色字位当前检出分支
切换(检出)分支
git checkout <分支名>
创建并检出分支
git checkout -b <新分支名> <父分支名>
删除分支
注意
从标签到版本树起点的提交记录均在,此时删除分支只是删除分支名字
只有当要删除的分支已经成功合并到当前分支,删除分支操作才会成功
git branch -d <分支名>
git branch -D <分支名>
强制删除
压合合并和拣选合并必须用-D
创建同名新分支,覆盖已有分支
git branch -f <已存在的分支> [<start point>]
分支重命名
git branch -m <原名> <新名>
不会覆盖已有分支名称
git branch -M <原名> <新名>
如果分支名已存在,强制覆盖现有分支
合并分支间的修改
直接合并(straight merge)
把两条分支上的历史轨迹合并
git merge <想合并到当前分支的源分支名>
--no-commit:合并但不提交
压合合并(squadhed commits)
把一条分支上的若干提交条目压合成一个提交条目,提交到当前分支末梢
git merge --squash <要提交压合的分支>
注意
merge后并未提交,需要提交
拣选合并(cherry-picking)
拣选另一条分支上的某个提交条目的改动到当前分支
git cherry-pick <提交的7位hash码>
拣选多个提交
git cherry-pick -n <提交的7位hash码>
可多次执行该语句,直至完成
最后git commit提交,不加-m
冲突处理
简单合并
手工修改
复杂合并
Linux、Windows:kdiff3
OS X:opendiff
git mergetool
启动一个合并工具
查看本地git设置中的merge.tool的值
可以是kdiff3、tkdiff、meld、xxdiff、emerge、vimdiff、gvimdiff、ecmerge、opendiff
变基
把一条分支上的修改在另一条分支末梢重现
git rebase <变基到的分支末梢>
出现冲突
修改
git add
git rebase --continue
实现原理
分支A、B,分叉点Y
在分支B上告诉git变基到A的末梢
git将从Y到B的当前末梢间的所有提交顺序加到A的末梢
形成新的分支B及其末梢
分支A机器末梢不变
git rebase --onto <分支A> <分支B> <分支C>
将<分支C>从<分支B>脱离,移动到<分支A>
示例:git rebase --onto master contacts search
历史记录
显示工作目录树状态
git status
日志
git log
-num:限制log输出条数
--pretty=
oneline
每个提交单行显示
format:"%h %s"
格式化输出
-p:显示版本间差异
--stat:显示改动行数统计
--name-status:显示改动文件名称和状态
<hash码>:显示指定版本
至少4位
无论几位都会设法匹配
一般7-8位即可保证唯一性
指定查找范围
--since
最近一段时间
示例:git log --since="5 hours"
git能接受大多数英文格式日期
--before
一段时间以前
<最老版本..最新版本>
指定两个版本间(左开右闭)为查找范围
示例
git log 18f822e..0bb3dfb
git log 18f822e..HEAD
git log 18f822e..
同HEAD
git log 1.0..HEAD
可以使用标签名
注意
指定版本不存在时,会得到“未知版本”报错
-C -C -p
检测文件的复制
日志格式
40位SHA-1
提交者
提交时间
留言
日志浏览
j:向下
k:向上
q:退出
查看特定代码块历史信息
git blame
用法
git blame <文件名>
git blame -L <开始>,<结束> <文件名>
结束可以为行数
可以使用RE
可以指定查找范围
git blame -M <文件名>
检测同一文件内移动或复制的代码行
git blame -C -C <文件名>
查看文件间的复制
示例
git blame index.html
git blame -L 12,14 index.html
git blame -L 12,+2 index.html
git blame -L "/<\/body>/",+2 index.html
git blame -L "/<\/body>/",-2 4333289e^ -- index.html
脱字符表示版本库中第一个提交
改写历史记录
场景
给历史记录重新排序
编辑器中将提交重新排序
将多个提交压合成一个提交
将提交B移到提交A后的一行,将B的pick改为squash
保存退出,变基前弹出编辑器,编辑压合后的留言
将一个大的提交拆分成多个提交
将提交的pick修改成edit,保存退出,变基启动
运行到edit行时git会暂停给出提示
git reset分解提交,即撤销该提交,创建两个独立提交
git rebase --continue
git rebase -i
交互式rebase
查看修改内容
git diff:显示工作目录树中未被暂存的改动
git diff --cached:显示暂存区和版本库的区别
git diff HEAD:显示工作目录树与版本库的差别
指定版本范围
同log
git diff --stat <范围>
默认值为当前工作目录树
统计代码变更统计数据
重现隐藏的历史
git reflog
恢复方法
检出/创建分支
配置
gc.reflogExpireUnreachable:改变有效期
本地版本库
标签
打标签
git tag <标签名> <希望打标签的点(可选,默认为当前工作目录树)>
查看标签列表
git tag
注意
只读
检出标签版本后,处于no branch状态,无法提交和跟踪改动,需要创建新分支
发布分支
即将要发布代码的地方
注意
通常少许改动,侧重于bug和逻辑修正,很少添加新功能
修正时基于标签创建一个新分支,以RB_为前缀
通常以RB_为前缀
持续时间不长,通常只用于发布代码的最终测试期间
一旦版本发布,应使用标签标记,删除分支
记录和跟踪多个项目
多个项目共享一个版本库
项目需要统一的历史记录时适用
这些组件同时发布
多项目多版本库
小项目需单独发布时
git子模块
跟踪外部版本库,允许在某个版本库里再存储一个版本库,并且完全独立
查看
git submodule
hash码前
有-表示未初始化
有+表示子模块不是“容器”版本库记录的子模块版本
添加
git submodule add <源版本库> <存储该版本库的路径>
初始化:git submodule init <子模块>
克隆含子模块的版本库
首先克隆版本库
初始化:git submodule init hocus
git submodule update <源版本库>
改变子模块版本
注意
git子模块不会自动引用版本库最新提交
添加时git总是用源库的HEAD
方法
切换到子模块目录下
检出
如:git checkout HEAD^
暂存
提交
注意
调用git add时结尾处不要有\
结尾的\被视为将源库的全部文件添加到当前库,而不是子模块引用的版本
git submodule update会覆盖本地子模块中所有没提交的内容
改动子模块前要检出要使用的子模块分支
子模块提交修改要确保送回远程版本库
远程版本库
git提供的网络协议
SSH
<用户名>@<服务器名>/版本库路径
示例:git@github.com/tswicegood/mysite.git
注意
如果使用本机登录名作为用户名,则不用指定用户名
一般使用SSH用户更新推入版本库
git
<协议>://<服务器名>/<版本库路径>
示例:git://github.com/tswicegood/mysite.git
特点
无须加密
速度快
匿名
一般为只读的,用于将更新拖入本地
防火墙可能受限
HTTP/HTTPS
示例:http://github.com/tswicegood/mysite.git
特点
通信效率最低
能通过严格的防火墙
易于架设
github不支持
克隆远程版本库
示例:git clone git://github.com/tswicegood/mysite.git mysite-remote
参数
远程版本库的位置
存放该版本库的本地目录(可选)
--depth <num>:只下载最近num个提交的历史记录
版本库同步
git fetch
更新远程分支,但不会把远程分支的修改合并到本地分支
git pull
更新远程分支,然后合并
参数
远程版本库名称
要拖入的远程分支名(不用加origin/)
注意
可以像检出本地分支一样检出远程分支,但不应修改
如果要修改,应先建立一个本地分支,再进行修改
推入改动
git push
不带参数推入默认版本库origin中,并把本地版本库当前分支变更推入远程版本库对应分支
只会推入已检入的改动
--dry-run:查看推入哪些提交
参数与pull相同
注意
一个版本库经常被用来接收推入,则最好不要有本地改动,可以在git init时加上--bare
添加新的远程版本库
注意
本地版本库中,远程版本库别名默认为origin
给远程版本库起别名
git remote add origin git@example.com:/repos/pocud.git
git remote
不带参数:查看本地创建的全部远程版本库别名
show <name>:查看某个远程版本库信息
rm:删除别名
prune:删除远程版本库已不存在的分支
文件
创建归档文件
示例
git archive --format=zip --prefix=mysite-1.0/ 1.0 > mysite-1.0.zip
git archive --format=tar --prefix=mysite-1.0/ 1.0 | gzip > mysite-1.0.tar.gz
参数
--format
归档格式
tar、zip
--prefix
指明包中所有东西放入的目录
要归档的标签名
压缩结果重定向
| gzip > mysite-1.0.tar.gz
> mysite-1.0.zip
文件重命名和移动
git mv <原文件名> <新文件名>
复制
不提供文件复制命令
不需要复制命令
忽略文件
把文件名加入版本库的.gitignore文件中
版本库级别
把文件名加入.git/info/exclude
本地级别
高阶功能
压缩版本库
原因
git版本库存储了所有东西,一些无用信息被留下了
节约磁盘空间
git gc
--aggressive:可进一步优化,但增加时间
二分查找
目的
定位哪个历史版本引入了bug
git bisect
基于一个已知的坏提交和一个已知的好提交
过程
移到坏的提交
git bisect start:开始查找
git bisect bad
git bisect good <某一个提交或标签>
git会进入两点中间的地方检出
如果提交是坏的,标记git bisect bad
如果提交是好的,标记git bisect good
找到问题点后,git bisect reset回到出发点,进行修改
git bisect visualize
可视化历史记录
git bisect log
显示提交的好坏标记
修改
将log存储成一个文件,删除错误的标识及其后记录
git bisect replay <某一文件>
自动化测试
git bisect run <脚本名>
构建脚本的返回值
通过:0
失败:正数(通常是1)
跳过:125
迁移到git
SVN
方法
从SVN导入所有历史记录到git,使用git作为主要的版本控制工具
保持SVN为上游版本库
工具
git-svn
检查可用性
git svn --version
导入SVN版本库
git svn clone
如果SVN版本库遵循默认结构,应加参数-s
如果分支和标签地址在不同位置,使用-b和-t参数
主干没有命名为trunk,使用-T指定具体名称
-r:指定从哪个版本开始克隆
示例:git svn clone --prefix svn/ -s svn://svnrepo/sunshine
提交过多的SVN版本库,克隆结束后应使用git gc
与SVN版本库同步更新
git svn fetch
取来远程修改到远程分支,不合并本地分支
git svn rebase
常用
类似于先git svn fetch,再git rebase
将修改推入SVN
git svn dcommit
参数
-n:演练