* 1 起步
** 关于版本控制
*** 什么是版本控制?
记录文件变化,查阅特定版本,回溯到之前的状态。任何类型的文件进行版本控制。
复制整个目录 加上备份时间 简单 混淆 无法恢复
本地版本控制 数据库记录历次差异更新
rcs 保存并管理文件补丁(对应文件修订前后的内容变化) 不断打补丁
*** 集中化的版本控制系统
不同系统上的开发者协同工作 单一的集中管理的服务器,保存所有的修订版本
。协同人员通过客户端连到这台服务器,取出最新文件或者提交更新。
一定程度上看到项目中的其他人在做什么,掌控开发者的权限,只需管理维护一
个服务器。缺点是服务器的单点故障,宕机 ,磁盘故障,备份不及时,丢失历史更改数据。
*** 分布式版本控制系统
客户端不只提取最新版本的文件快照,而是把代码仓库完整的镜像下来。协同工
作用的服务器发生故障,任何一个镜像出来的本地仓库修复。提取操作,是对代码仓库的完整备份。
和不同的远端代码仓库进行交互。
** 简史
linux内核 bitkeeper 开发属于自己的版本控制
速度 简单设计 对非线性开发模式强力支持 完全分布式 超大规模(速度和数据量)
** git 基础
*** 直接记录快照,而非差异比较
git只关心数据的整体是否发生变化,不关心文件内容的具体差异,不保存差异
数据,快照那些变化的文件。记录在一个文件系统中。每次提交更新时,遍历文件的
指纹信息,并对文件做一个快照,保存一个指向这次快照的索引。文件没有变化,对上次保存的快照做一链接。
*** 近乎所以操作都是本地执行
绝大部分操作只访问本地的文件和资源,不用联网。
离线频繁提交更新,有网络的时候再上传到远程仓库。
*** 时刻保持数据的完整性
保存到git前,所有数据都要进行内容的校验和计算,并将此结果作为数据的唯
一标识和索引。建在整体架构的最底层,文件传输,或磁盘损坏导致数据缺失,
git会立即察觉。使用SHA-1算法计算数据的校验和,对文件内容和目录结构计算
出SHA-1哈希值,作为指纹字符窜。40个16进制字符
*** 多数操作仅添加数据
常用的git操作是把数据添加到数据库。不可逆的操作,使回退和重现历史版本变得困难。
*** 文件的三种状态
已提交
文件被安全的保存在本地数据库中
已修改
修改了某个文件,但还没有提交保存
已暂存
把已修改的文件放在下次提交时要保存的清单中
git管理项目时,文件流转的三个工作区域:
git目录(本地仓库)
git clone时的.git目录;
git clone --bare时,新建的目录本身就是git目录
用于保存元数据和对象数据库的地方
克隆镜像仓库时,实际拷贝的就是这个目录的数据
git的工作区
从项目中取出某个版本的所有文件和目录,用以开始后续工作。
这些文件从git目录中的压缩对象数据库中提取出来,对工作目录中对这些文件进行编辑
暂存区
只是一个文件,放在git目录中。
*** git的工作流程
工作目录中修改某些文件
对修改后的文件进行快照,然后保存到暂存区
提交更新,将保存在暂存区中的文件快照永久转存到git目录中
从文件所处的位置来判断状态
** 安装git
***
源码安装;为特定平台预编译好的安装包
源码安装,最新的版本,尝试改进用户体验
*** debian源码编译git
*** ubuntu 12.04 ppa安装git
*** ubuntu 12.04 源码安装git
git的源码使用git clone 获取。先安装git,下载源码
$ sudo apt-get install git
获取编译git的依赖
$ sudo apt-get build-dep git
下载git源码
$ git clone git://git.kernel.org/pub/scm/git/git/git.git git
$ cd git
$ make
$ sudo make install
*** ubuntu 安装预编译好的二进制安装包
$ sudo apt-get install git -y
*** windows 上安装
msysgit
下载地址:http://msysgit.github.com/
安装之后,可以使用命令行的git工具,自带ssh客户端。
还有图形化的git项目管理工具--乌龟 (tortoisegit)
** 初次运行git前的配置
***
配置自己的git工作环境,只需配置一次,以后升级时,会沿用现在的配置。可
以使用相同的命令修改已有的配置。
git config , 用来配置读取相应的工作环境变量。
环境变量可以放在三个不同的地方:
/etc/gitconfig
git config --system ,系统中所有用户适用
~/.gitconfig
git config --global ,用户目录下的配置文件,只适用于该用户
当前项目的git目录中的配置文件(也就是工作目录中的.git/config文件)
只针对当前项目有效
每一个级别的配置会覆盖上层的相同配置
*** 用户信息
个人的用户名和电子邮件地址
git提交时,会引用这两条信息,说明是谁提交了更新,随更新内容一起永久纳入历史记录
$ git config --global user.name "vipzrx"
$ git config --global user.email "vipzrx@gmail.com"
*** 文本编辑器
默认使用的文本编辑器,输入一些额外的消息。
$ git config --global core.editor emacs
使用emacsclient
*** 差异分析工具
解决合并冲突时,使用那种差异分析工具,合并工具。
使用ediff
*** 查看配置信息
检查已有的配置信息
$ git config --list
user.name=vipzrx
user.email=vipzrx@gmail.com
core.editor=emacsclient
diff.tool=ediff
diff.guitool=ediff
difftool.ediff.cmd=~/.emacs.d/shell/ediff.sh $LOCAL $REMOTE $MERGED
merge.tool=ediff
mergetool.ediff.cmd=~/.emacs.d/shell/ediff.sh $LOCAL $REMOTE $MERGED $BASE
mergetool.ediff.trustexitcode=true
有时会看到重复的变量名,说明他们来自不同的配置文件,git最终采用的是最后一个。
可以直接检阅某个环境变量的设定,只要把特定的名字跟在后面即可
$ git config user.name
vipzrx
** 获取帮助
阅读工具的使用帮助
$ git help <verb>
$ git <verb> --help
$ man git-<verb>
** irc
#git
#github
irc.freenode.net
* git 基础
**
初始化一个代码仓库
适当配置
开始或者停止追踪某些文件
暂存或者提交某些更新
git忽略某些文件,或者名称符合特定模式的文件
撤销犯下的小错误
浏览项目的更新历史
查看两次更新之间的差异
从远程仓库拉数据下来
推数据到远程仓库
** 取得项目的git仓库
*** 两种方法:
1 在现存的目录下,通过导入所有文件来创建新的git仓库
2 从已有的git仓库克隆出一个新的镜像仓库
*** 在工作目录中初始化新仓库
对现有的某个目录开始用git管理,只需在此项目所在的目录,执行:
$ git init
初始化后,在当前目录下会出现一个名为.git的目录。所有git需要的数据和资
源都存放在这个目录中。仅是按照既有的结构框架初始化好了里面所有的文件和
目录,还没有开始追踪管理项目中的任何一个文件。
当前目录下的文件想要纳入版本控制,需要先使用 git add ,告诉git 开始对
这些文件进行跟踪,然后提交
$ git add *.c
$ git add README
$ git commit -m "XXXX"
*** 从现有仓库克隆
为开源项目出力,先把该项目的git仓库复制一份出来,使用git clone
git获取的是项目历史的所有数据(每一个文件的每一个版本),服务器上有的数据克隆
之后本地也有了。服务器磁盘发生故障,用任何一个克隆出来的客户端可以重建服务器上的仓库,可能会损失服务器端的挂钩设置。
克隆仓库的命令是: git clone [git://XXXXX-XXX.git] <DIR>/<dir>
会在<DIR>创建<dir>目录,其中包含一个.git目录,用于保存下载下来的所有版本记录,
然后从中取出最新版本的文件拷贝。
git支持多种协议,
git://
http(s)://
ssh协议 user@server:/path.git
*** 记录每次更新到仓库
有了项目的git仓库,并从这个仓库中取出所有文件的工作拷贝。对这些文件修
改,完成一个阶段的目标后,提交本次更新到仓库。
工作目录下的文件不外乎两种状态: 已跟踪或未跟踪
已跟踪:本来就纳入版控的文件,上次快照中有他们的记录,工作一段时间后,
他们的状态可能是未更新,已修改或者已经放入暂存区。
未跟踪:既没有上次更新时的快照,也不在当前的暂存区域。
初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪,且状态为未修改。
在编辑过某些文件之后,git将这些文件标记为已修改。逐步把修改过的文件放
到暂存区,直到最后一次性提交所有这些暂存起来的文件。
*** 检查当前文件的状态
确定哪些文件处于什么状态,使用 git status
未跟踪的文件意味着git在之前的快照(提交)中没有这些文件,git不会自动将之纳入跟踪范围,除非使用git add
*** 跟踪新的文件
开始跟踪一个新的文件,使用 git add
$ touch README
$ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# README
nothing added to commit but untracked files present (use "git add" to track)
$ git add README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
文件README已经被跟踪,并处于暂存状态
在# Changes to be committed: 这行下面的,就说明是已暂存状态。
git add 后面可以指明要跟踪的文件或者目录路径。如果是目录,递归跟踪目录下的所有文件。
git add 是将目标文件,已跟踪的,快照放入暂存区;未跟踪过的文件标记为需要跟踪,并放入暂存区
*** 暂存已修改的文件
修改README
$ echo 123 >>README
修改之后的status
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README
#
README文件出现了两次,一次算未暂存,一次算已暂存。 实际上git 只是暂存了运行git add时的版本,如果现在提交,提交的是git add时的版本,不是git add之后修改过的版本。
在运行了git add 之后又做了修改的文件,需要重新运行git add把最新的版本暂存起来。
$ git add README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
*** 忽略某些文件
有些文件无需纳入git的管理,也不希望他们总出现在未跟踪文件列表中。
通常是自动生成的文件,如日志文件,编译过程中创建的临时文件。
可以创建一个名为.gitignore的文件。列出要忽略的文件模式
.gitignore的格式规范:
所有空行或者以注释符号#开头的行都会被git忽略
可以使用标准的glob模式匹配
匹配模式最后跟返斜杠(/)说明要忽略的是目录
要忽略指定模式以外的文件和目录,可以在模式前加上惊叹号(!)取反
所谓glob模式是shell所使用的简化了的正则表达式
* 零个或多个任意字符
[abc]匹配任何一个列在方括号中的字符(要么匹配一个a,要么匹配一个b,要么匹配一个c)
?只匹配一个任意字符
[0-9]方括号中使用短划线分隔两个字符,表示在这两个字符范围内的都可以匹配
*** 查看已暂存和未暂存的更新
git status 仅显示修改过的文件。
要查看具体修改了什么地方,可以用git diff
查看尚未暂存的文件更新可哪些部分 git diff
git diff 比较的是工作目录中当前文件和暂存区快照之间的差异,也就是修改之后还没有暂存起来的变化内容
要查看已经暂存起来的文件和上次提交时的快照之间的差异,可以使用 git diff --cached ,git 1.6 版本之后可以用 $ git diff --staged
修改benchmarks.rb后不暂存
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: benchmarks.rb
#
$ git diff
diff --git a/benchmarks.rb b/benchmarks.rb
index e69de29..a8a0be4 100644
--- a/benchmarks.rb
+++ b/benchmarks.rb
@@ -0,0 +1,2 @@
+123
+1233456
使用git diff --cached 查看已经暂存起来的变化
$ git diff --cached
diff --git a/README b/README
index 190a180..b4ee7ef 100644
--- a/README
+++ b/README
@@ -1 +1,2 @@
123
+12345
*** 提交更新
暂存区准备好之后,就可以提交了。
在提交之前,要确定修改过的或是新建的文件有没有git add过,否则提交的时候不会记录这些还没有暂存起来的变化。
每次提交前,先用git status 看下是不是都已暂存起来了,然后运行提交命令:git commit
$ git commit 这种方式会启动文本编辑器,输入本次提交的说明。
使用git config --global core.editor设定使用的编辑器
默认的提交信息包含最后一次运行 git status 的输出,放在注释行里。
开头有一空行,以供输入提交说明。
使用-v ,将修改差异的每一行都包含到注释中来。
退出编辑器,git会丢掉注释行,将说明内容和本次更新提交到仓库。
不填写提交说明,不能进行提交;提示信息如下:
Aborting commit due to empty commit message.
也可以使用-m 参数后跟提交说明的方式,在一行命令中提交更新:
$ git commit -m "提交的更新说明"
$ git commit -v
Waiting for Emacs...
[master ad44b9c] dsafas
1 file changed, 1 insertion(+)
提交后的输出信息,可以看到 ,当前是在哪个分支(master)提交,本次提交的完整SHA-1校验和是ad44b9c,以及在本次提交中,有
一个文件修订过,1行增加
提交时记录的是放在暂存区中的快照,任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版控。
每次提交操作,都是对你项目的一次快照,以后可以回到这个状态,或者比较。
*** 跳过使用暂存区
使用暂存区的方式可以精心准备要提交的细节,有时显得繁琐。
git提供一个跳过暂存区的方式,使用git commit -a ,git会自动把所有已经跟踪过的文件暂存起
来一并提交,从而跳过暂存区
*** 移除文件
从git中移除文件,需从已跟踪文件清单中清除(确切说,暂存区),然后提交。
用git rm ,从已跟踪清单中删除文件,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪
文件清单中了,当前工作目录中的文件也被删除了,该文件不再纳入版控管理了。
$ git rm README
rm 'README'
$ ls README
ls: cannot access README: No such file or directory
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: README
$ git commit -m "delete README"
master 1206d93] delete README
1 file changed, 2 deletions(-)
delete mode 100644 README
Changes not staged for commit: 是未暂存清单
Changes to be committed:对于已跟踪文件是暂存清单;对于未暂存文件,是已跟踪清单和暂存清单
如果只是简单的从工作目录中手工清除文件,运行git status 会在未暂存清单看到
如果删除前,修改过并且已经放到暂存区,但还没有提交,使用-f 。
想把文件从git仓库中删除(从暂存区移除),但仍然希望保留在当前工作目录中。即仅从跟踪清单中删除,但不删除文件,以便在.gitignore文件补上,用--cached
$ git rm --cached README
后面可以列出文件或者目录的名字,也可以使用glob模式
$ git rm log/*.log
git有自己的文件模式匹配方式
$ git rm *~
递归删除当前目录及其子目录中所有~结尾的文件
*** 移动文件
git不跟踪文件的移动。在git中重命名了某个文件,仓库中存储的元数据不会体现出这是一次改名操作。不过git能够推断出究竟发生了什么。
$ git mv file_from file_to
运行git mv 相当于下面三条命令:
$ mv file_from file_to
$ git rm file_from
$ git add file_to
如此分开操作,git也会意识到这是一次改名操作。
直接用git mv 轻便;有时用其他工具批量改名的话,记得在提交前删除老的文件,再添加新的文件名
** 查看提交历史
提交了若干更新,或者克隆了某个项目,想回顾一下提交历史,用git log
默认不用任何参数,git log 会按照提交时间列出所有的更新,最近的更新排在最上面。
每次更新都有一个SHA-1校验和、 作者的名字和邮箱、提交时间、最后缩进一个段落显示提交的说明
常用的选项:
-p 展开显示每次提交的内容差异
-2 仅显示最近的两次更新
--stat 仅显示简要的增改行数统计
每个提交都列出了修改过的文件,以及其中添加和移除的行数,并在最后列出所有增减数小计
--pretty 指定完全不同于默认格式的方式展示提交历史
--pretty=oneline 将每个提交放在一行显示,在提交数很大的时候有用
--pretty=format: 可以定制显示的记录格式,这样的输出便于后期分析
常用的格式占位符及其代表的意义
作者和提交者的差别
作者指的是实际作出修改的人,提交者是最后将此工作成功提交到仓库的人
用oneline 或format时,结合--graph选项,可以看到开头多出一些ASCII字符串表示的简单图形,形象的展示了每个提交所在的分支及其分化衍合情况
*** 限制输出长度
除了定制输出格式的选项,git log 还有限制输出长度的选项,也就是只输出部分提交信息。
按时间做限制的选项
--since
--until
$ git log --since=2.weeks
可以给出各种时间格式 :具体的某一天 或者多久以前
还可以给出若干搜索条件,列出符合的提交
用--author 指定提交的作者
用--grep搜索提交说明中的关键字
要得到同时满足这两个选项搜索条件的提交,必须用--all-match .否则,满足任意一个条件的提交都会被匹配出来
如果只关心某些文件或者目录的历史提交。可以在git log选项的最后指定他们的路径。因为是放在最后位置上的选项,所以用两个短划线--隔开之前的选项和后面限定的路径名
$ git log -- <path>
$ git log -- ./111
*** 使用图形化工具检阅提交历史
图形化工具更容易展示历史提交的变化。
使用tcl/tk写成, 是git log的可视化版本,凡是git log 可以用的选项也都可以用在gitk上
安装
$ sudo apt-get install gitk
启动
$ gitk
** 撤销操作
***
任何时候 ,都有可能撤销刚才所做的某些操作。有些操作是不可逆的
*** 修改最后一次的提交
提交完了发现漏掉了几个文件没有追加,或者提交信息写错了。想要撤销刚才
的提交操作,可以使用--amend
$ git commit --amend
此命令将使用当前的暂存区快照提交。如果刚才提交完,没有做任何改动,直接
运行此命令,相当于重新编写提交说明,将要提交的文件和之前的一样
启动文本编辑器之后,会看到上次提交的说明,编辑它后确定没有问题后保存,
退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时,忘了暂存某些文件,可以先补上暂存操作,然后再运行--amend提交
$ git commit -m "initial commit"
$ git add forgotten_file
$ git commit --amend -m "the correct commit"
上面的三条命令只是产生一个提交,第二个提交命令修正了第一个的提交内容。
*** 取消已经暂存的文件
查看文件状态的时候就提示了该怎么撤销
$ git reset HEAD <file>
*** 取消对文件的更改
抛弃文件修改,恢复到修改前的版本
$ git checkout -- <file>
这个命令很危险,用之前版本的文件复制过来重写了此文件
在使用这条命令前,务必确定真的不需要保留刚才的修改。
如果只是想回退版本,同时保留刚才的修改,以便将来继续工作,可以用stashing和分支来处理
任何提交到git的,都可以恢复。即便在已经删除的分支中的提交,或者用--amend重新改写的提交,都可以恢复。
你可能失去的数据,仅是没有提交过的,对git来说,他们就像从未存在过一样
** 远程仓库的使用
***
参与git项目的协作,需了解如何管理远程仓库。
远程仓库是托管在网络上的项目仓库,可能会有好几个,其中有些你只能读,有些你可以写。
同他人协作开发某个项目,需要管理这些远程仓库,以便推送或拉取数据,分享各自的工作进展。
*** 查看当前的远程仓库
查看当前配置的远程仓库,使用 git remote,他会列出每个远程仓库的简短名
字。在克隆完某个项目之后,至少可以看到一个名为origin的远程仓库,git默
认使用这个名字来标识你所克隆的原始仓库。
git remote -v 显示对应的克隆地址
如果有多个远程仓库,此命令将全部列出
*** 添加远程仓库
添加一个远程仓库 ,可以指定一个简单的名字,以便将来使用。
git remote add [short_name] [url]
可以使用short_name来指代对应的仓库地址。
*** 从远程仓库抓取数据
从远程仓库抓取本地仓库中没有的数据到本地。
运行完之后,就可以在本地访问远程仓库中的所有分支,将其中的分支合并到本
地,或者只是取出某个分支。
$ git fetch [remote_name]
如果是克隆了一个仓库,此命令会自动将远程仓库归于origin名下。所以 git fetch origin
会抓取从你上次克隆以来,别人上传戴此仓库中的所有更新(或是上次fetch以来别人提交的更新)
fetch命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只
有当你准备好了,才能收定合并
如果设置了某个分支用于跟踪某个远端仓库的分支,可以使用git pull 命令自
动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。
*** 推送数据到远程仓库
项目进行到一个阶段,要同别人分享目前的成果,可以将本地仓库中的数据推送到远程仓库。
git push [remote_nmae] [branch_name]
如果要把本地的master分支推送到origin服务器上,使用
$ git push origin master
只有在所克隆的服务器上有写权限,而且同一时刻没有其他人在推送数据,这条
命令才会成功。
如果在你推送数据之前,已经有其他人推送了若干更新,你的推送操作会被驳回。
你必须先把他们的更新抓到本地,合并到自己的项目中,然后才可以再次推送。
*** 查看远程仓库的信息
通过git remote show [remote_name] 查看某个远程仓库的详细信息
$ git remote show origin
* remote origin
Fetch URL: https://github.com/vipzrx/11.git
Push URL: https://github.com/vipzrx/11.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
*** 远程仓库的删除和重命名
$ git remote rename <old_name> <new_name>
对远程仓库的重命名,也会使对应的分支名称发生变化,原来的
<old_name>/master变成 <new_name>/master
碰到远程仓库服务器迁移,或者原来的克隆镜像不再使用,又或者某个参与者不
再贡献代码,那么就需要移除对应的远端仓库
$ git remote rm <remote_name>
** 打标签
***
git可以对某一时间点上的版本打上标签。人们在发布某个软件版本的时候,经常这样做。
*** 列显已有的标签
$ git tag
显示的标签按照字母顺序排列
可以使用特定的搜索模式列出符合条件的标签
*** 新建标签
git使用的标签有两种:轻量级的和含附注标签
轻量级标签是个不会变化的分支,实际上它是个指向特定提交对象的引用。
含附注的标签是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,邮件地址和日期,以及标签的说明,标签本身允许使用GPG来签署或验证。
一般建议使用含附注的标签,以便保留相关的信息
如果临时加注标签,或者不需要额外信息,用轻量级标签没问题,很方便。
*** 含附注的标签
$ git tag -a <tag-name> -m "tag-commit-description"
-m指定相应的标签说明,git会将此说明一同保存在标签对象中。如果没有给出
该选项,git会启动文本编辑器供你输入标签说明
$ git show 2013-11-28
tag 2013-11-28
Tagger: vipzrx <vipzrx@gmail.com>
Date: Thu Nov 28 15:52:40 2013 +0800
2013年11月28日
commit ff9b3b04785b2f1635afa37036437c67315038e6
Author: vipzrx <vipzrx@gmail.com>
Date: Thu Nov 28 11:15:34 2013 +0800
qqq
diff --git a/111 b/111
new file mode 100644
index 0000000..190a180
--- /dev/null
+++ b/111
@@ -0,0 +1 @@
+123
$ git show <tag-name>
显示相应标签的版本信息,并连同显示打标签时的提交对象
提交对象信息上面,列出了此标签的提交者和提交时间,以及相应的标签说明
*** 签署标签
如果你有自己的私钥,可以使用GPG来签署标签
$ git tag -s <tag-name> -m "tag-commit-description"
再次运行git show <tag-name> 会看到对应的GPG签名也附在其中
*** 验证已经签署的签名
$ git tag -v <tag-name>
验证已经签署的标签
此命令会调用GPG来验证签名,所以你需要有签署者的公钥,存放在keyring中,才能验证
*** 后期加注标签
后期对早先的某次提交加注标签
在打标签的时候跟上对应提交对象的校验和(或前几位数字)
$ git tag -a <tag-name> <某次提交对应的校验和>
*** 分享标签
默认情况下,git push不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库
$ git push <remote-name> <tag-name>
$ git push origin <tag-name>
如果要一次推送本地所有新增的标签上去,使用
$ git push origin --tags
其他人克隆仓库或拉取数据同步后,也会看到这些标签
*** 轻量级标签
轻量级标签实际上是一个保存着对应提交对象的校验和信息的文件。
$ git tag <tag-name>
使用git show <tag-name>查看此标签,就只有相应的提交对象摘要
** 技巧和窍门
*** 自动补全
apt安装的git 支持自动补全
$ ls /etc/bash_completion.d/ | grep git
git
/etc/bash_completion.d/ 这个目录中的脚本,会在bash启动时自动加载
输入git命令的时候,可以敲两次TAB,就会看到列出所有匹配的可用的命令建议
命令的选项也可以用这样的方式完成
*** git 命令别名
git不会推断你输入的几个字符将会是哪条命令,可以使用git config 为命令设置别名
$ git config --global alias.<别名> <命令>
使用这种技术还可以创造出新的命令
取消暂存文件时的输入比较繁琐
这样设置:
$ git config --global alias.unstage 'reset HEAD'
这样一来,下面的两条命令完全等同
$ git unstage fileA
$ git reset HEAD -- fileA
$ git config --global alias.last 'log -1 HEAD'
查看最后一次的提交信息
$ git last
git的别名只是简单地在命令中替换了你设置的别名。
希望运行某个外部命令,而非git的子命令。只需要在命令前加上!就行
自己写处理git仓库信息的脚本,可以用这种技术包装起来。
设置用git visual启动gitk
$ git config --global alias.visual '!gitk'
*** 小结
git的本地操作:创建和克隆仓库,作出修改,暂存并提交修改,以及查看所有历史修改记录