Git里程碑
git describe 显示提交的里程碑.若该提交没有里程碑,但其祖先有(加参数id),则显示为<tag-n-id>格式;也可--always参数
显示精简提交id,否则会出错: git descirbe master^ --always。
git log --oneline --decorate # --decorate可以看到提交对应的里程碑和引用
git name-rev HEAD 显示提交ID和引用 # HEAD master
git name-rev HEAD^ --tags 显示提交id和里程碑 #HEAD^ tags/jx/v1.0^0
轻量级里程碑:

当创建了里程碑后,会在版本库的.git/refs/tags目录下创建一个新文件mytags:
cat .git/refs/tags/mytag
使用git cat-file检查轻量级里程碑指向的对象:
git cat-file -t mytag
查看刚刚的空提交的内容:
git cat-file -p mytag
轻量级里程碑的缺点:
创建过程中没有记录,因此无法知道谁、何时创建的里程碑,团队协同开发时不要用。git describe默认不使用轻量级里程碑,
git describe --tags 允许使用轻量级里程碑作版本控制符。
带说明的里程碑:
带说明的里程碑就是使用参数-a或-m <msg>调用git tag。会在版本库中建立一个新的tag对象,这个对象会记录创建里程碑的用户,
时间和为什么要创建里程碑(而轻量级里程碑没有)。虽然mytag2是一个tag对象,但在很多Git命令中,可将其视为一个提交。
直接使用git rev-parse查看mytag2得到的是tag对象的id,而非提交对象的id。使用下面的表示法可获得mytag2对象所指向的提交
对象的id:
git rev-parse mytag2^ {commit}
git rev-parse mytag2^{}
git rev-parse mytag2^0
git rev-parse mytag2~0
删除里程碑: git tag -d mytag
里程碑没有类似reflog的变更记录机制,一旦删除不易恢复。一旦发现删除错误,赶紧补救还来得及: git tag mytag c9d3f6d
里程碑不能重命名,因为里程碑的名字不仅反映在.git/refs/tags引用目录下的文件名,对于带说明或签名的里程碑,名字还反映在
tag对象的内容中。git filter-branch可实现对里程碑自动重命名,但会使签名里程碑的签名去除,成为带说明的里程碑。
-f或--force参数以同样的里程碑名强制覆盖已有的里程碑实现重新建立,但慎重更改!!!
带签名的里程碑
带签名的里程碑和带说明的里程碑本质上是一样的,都是在创建里程碑的时候在Git对象库中生成一个tag对象,不过带签名的里程碑多做了:
为里程碑对象添加GnuPG签名。使用参数-s 或 -u <key-id>即可。但有一个前提:需要安装GnuPG,并建立相应的公钥/私钥对。
查看当前可用的GnuPG公钥: gpg --list-keys
在创建带签名的里程碑时,并非一定要使用签名者本人的公钥/私钥对进行签名,使用 -u <key-id> 参数就可以用指定的公钥/私钥对进行签名,
当没有可用的公钥/私钥对时,或者希望使用提交者本人的公钥/私钥对进行签名,就需要为提交者创建对应的公钥/私钥对。
创建公钥/私钥对:gpg --gen-key ,然后根据提示输入即可。然后--list-keys查看一下公钥链。
创建带签名的里程碑: git tag -s -m "GPG-signed tag" mytag3
查看该里程碑是否创建: git tag -l my* -n1
查看该提交看到其中包含了GnuPG签名: git cat-file tag mytag3
验证里程碑签名的有效性: git tag -v mytag3
共享里程碑
#查看上游版本库的引用: git ls-remote origin my*
向上游推送共享里程碑:
git push origin mytag
#git push origin refs/tags/* #推送本地建立的所有里程碑
git ls-remote origin my*
另一用户从版本库执行拉回操作,会自动获取里程碑: git pull
#note: 修改里程碑不能自动更新
为了更改远程共享服务器中的里程碑,需要显示推送: git push origin mytag2
另一用户此时必须显示的执行拉回操作: git pull origin refs/tags/mytag2:refs/tags/mytag2
#如果本地已有同名的里程碑,默认不会从上游同步里程碑。所以一旦共享,就不要再修改。
删除远程版本库中的里程碑/分支: git push <remote_url> :<tagname> #<ref>:<ref>,省略引用表达式的前值,即推送空值。
/************************************************************************************************************************/
Git分支
分支的3种类型:发布分支、特性分支、卖主分支。
发布分支:在软件新版本发布后经常使用此技术进行软件维护,发布升级版本。使用此分支功能,可以避免对已发布的软件版本进行Bug
修正时引入新功能的代码,或者因误删其他Bug修正代码导致已修复问题重现。
特性分支:采用分支(发布分支)将某个功能或模块的开发与开发主线独立开来。实验性、探索性的功能开发应该为其建立特性分支;功能
复杂、开发周期长(可能在本次发布中取消)的模块应该为其建立特性分支;会更改软件体系架构、破坏软件集成,或者容易导致冲突、影响他人
开发进度的模块,应该为其建立特性分支。
卖主分支:卖主分支解决了这样一个难题:有的项目要引入带三方库并需要对其进行定制,有的项目甚至整个就是基于某个开源项目进行的
定制,如何有效的管理本地定制和第三方(上游)代码的变更?卖主分支就是在版本库中创建一个专门和上游代码进行同步的分支,一旦有上游代码
发布就检入到卖主分支中。
显示本地分支列表:git branch
创建分支:git branch branchname
基于提交(里程碑)创建分支:git branch branchname start-point
删除分支:git branch -d branchname #检查要删除的分支若已合并到其他分支中,拒绝删除; -D 强行删除
重命名分支:git branch -m oldbranch newbranch #若存在,拒绝;-M 强行执行
切换分支:git checkout branchname
创建并切换到新分支:git checkout -b newbranch [start-point]
git checkout kai/v1.0 -- . #最后'.',只检出了暂存区和工作区,没有修改头指针
合并分支到主线:git checkout master #先切换,再合并
git merge user1/getopt
git push完成推送操作,完成本地分支向远程分支的同步 git push origin hello-1.x
git fetch将远程共享版本库的新分支hello-1.x复制到本地引用origin/hello-1.x:cd ... git fetch
git pull 将远程共享服务器的改动获取到本地并和本地提交进行合并