Git笔记(25) 选择修订版本
Git笔记(25) 选择修订版本
- 1. 单个修订版本
- 1.1. 简短的 SHA-1
- 1.2. 分支引用
- 1.3. 引用日志
- 1.4. 祖先引用
- 2. 提交区间
- 2.1. 双点
- 2.2. 多点
- 2.3. 三点
1. 单个修订版本
可以通过 Git 给出的 SHA-1
值来获取一次提交
不过还有很多更人性化的方式来做同样的事情
1.1. 简短的 SHA-1
提供 SHA-1
的前几个字符就可以获得对应的那次提交
当然提供的 SHA-1 字符数量不得少于 4 个,并且没有歧义
也就是说,当前仓库中只有一个对象以这段 SHA-1 开头
例如查看一次指定的提交
假设执行 git log
命令来查看之前新增一个功能的那次提交:
$ git log
commit 734713bc047d87bf7eac9674765ae793478c50d3
Author: Bruce <Bruce@gmail.com>
Date: Fri Jan 2 18:32:33 2009 -0800fixed refs handling, added gc auto, updated testscommit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Bruce <Bruce@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800Merge commit 'phedders/rdocs'commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Bruce <Bruce@gmail.com>
Date: Thu Dec 11 14:58:32 2008 -0800added some blame and merge stuff
假设这个提交是 1c002dd....
,如果想 git show
这个提交
下面的命令是等价的(假设简短的版本没有歧义):
$ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
$ git show 1c002dd4b536e7479f
$ git show 1c002d
Git 可以为 SHA-1
值生成出简短且唯一的缩写
如果在 git log
后加上 --abbrev-commit
参数,输出结果里就会显示简短且唯一的值
默认使用七个字符,不过有时为了避免 SHA-1
的歧义,会增加字符数:
$ git log --abbrev-commit --pretty=oneline
ca82a6d changed the version number
085bb3b removed unnecessary test code
a11bef0 first commit
通常 8 到 10 个字符就已经足够在一个项目中避免 SHA-1
的歧义
比如 Linux 内核这个相当大的 Git 项目
目前有超过 90 万个提交,包含几百万个对象,也只需要前 11 个字符就能保证唯一性
1.2. 分支引用
指明一次提交最直接的方法是有一个指向它的分支引用
这样就可以在任意一个 Git 命令中使用这个分支名来代替对应的提交对象或者 SHA-1 值
例如,想要查看一个分支的最后一次提交的对象
假设 topic1
分支指向 ca82a6d
,那么以下的命令是等价的:
$ git show ca82a6dff817ec66f44342007202690a93763949
$ git show topic1
如果想知道某个分支指向哪个特定的 SHA-1
,或者想看任何一个例子中被简写的 SHA-1
可以使用一个叫做 rev-parse
的 Git 探测工具
rev-parse
是为了底层操作而不是日常操作设计的
不过,有时想看 Git 现在到底处于什么状态时,它可能会很有用
可以在分支上执行 rev-parse
$ git rev-parse topic1
ca82a6dff817ec66f44342007202690a93763949
1.3. 引用日志
当在工作时, Git 会在后台保存一个引用日志(reflog)
引用日志记录了最近几个月你的 HEAD 和分支引用所指向的历史
可以使用 git reflog
来查看引用日志
$ git reflog
734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd HEAD@{2}: commit: added some blame and merge stuff
1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
95df984 HEAD@{4}: commit: # This is a combination of two commits.
1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD
每当 HEAD
所指向的位置发生了变化
Git 就会将这个信息存储到引用日志这个历史记录里
通过这些数据,可以很方便地获取之前的提交历史
如果想查看仓库中 HEAD 在五次前的所指向的提交
可以使用 @{n}
来引用 reflog
中输出的提交记录。
$ git show HEAD@{5}
同样可以使用这个语法来查看某个分支在一定时间前的位置
例如,查看你的 master
分支在昨天的时候指向了哪个提交,你可以输入
$ git show master@{yesterday}
就会显示昨天该分支的顶端指向了哪个提交
这个方法只对还在你引用日志里的数据有用
所以不能用来查好几个月之前的提交
可以运行 git log -g
来查看类似于 git log
输出格式的引用日志信息:
$ git log -g master
commit 734713bc047d87bf7eac9674765ae793478c50d3
Reflog: master@{0} (Bruce <Bruce@gmail.com>)
Reflog message: commit: fixed refs handling, added gc auto, updated
Author: Bruce <Bruce@gmail.com>
Date: Fri Jan 2 18:32:33 2009 -0800fixed refs handling, added gc auto, updated testscommit d921970aadf03b3cf0e71becdaab3147ba71cdef
Reflog: master@{1} (Bruce <Bruce@gmail.com>)
Reflog message: merge phedders/rdocs: Merge made by recursive.
Author: Bruce <Bruce@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800Merge commit 'phedders/rdocs'
值得注意的是,引用日志 只存在于本地仓库
一个记录你在你自己的仓库里做过什么的日志
其他人拷贝的仓库里的引用日志不会和你的相同
而新克隆一个仓库的时候,引用日志是空的,因为在仓库里还没有操作
如果是五分钟前克隆的仓库,那么它将不会有结果返回
$ git show HEAD@{2.months.ago}
只有在克隆了一个项目至少两个月时才会有用
1.4. 祖先引用
祖先引用是另一种指明一个提交的方式
如果在引用的 尾部 加上一个 ^
, Git 会将其解析为该引用的上一个提交
假设提交历史是:
$ git log --pretty=format:'%h %s' --graph
* 734713b fixed refs handling, added gc auto, updated tests
* d921970 Merge commit 'phedders/rdocs'
|\
| * 35cfb2b Some rdoc changes
* | 1c002dd added some blame and merge stuff
|/
* 1c36188 ignore *.gem
* 9b29157 add open3_detach to gemspec file list
可以使用 HEAD^
来查看上一个提交,也就是 “HEAD
的 父提交”:
$ git show HEAD^
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Bruce <Bruce@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800Merge commit 'phedders/rdocs'
也可以在 ^
后面添加一个数字
例如 d921970^2
代表 “d921970
的第二父提交”
这个语法只适用于合并(merge)的提交,因为合并提交会有多个父提交
第一父提交是你合并时所在分支,而第二父提交是你所合并的分支:
$ git show d921970^
commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Bruce <Bruce@gmail.com>
Date: Thu Dec 11 14:58:32 2008 -0800added some blame and merge stuff$ git show d921970^2
commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548
Author: Tony <Tony+git@mjr.org>
Date: Wed Dec 10 22:22:03 2008 +0000Some rdoc changes
另一种指明祖先提交的方法是 ~
同样是指向第一父提交,因此 HEAD~
和 HEAD^
是等价的
而区别在于在后面加数字的时候
HEAD~2
代表“第一父提交的第一父提交”,也就是“祖父提交”
Git 会根据你指定的次数获取对应的第一父提交
例如,在之前的列出的提交历史中,HEAD~3
就是
$ git show HEAD~3
commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
Author: Medivh <Medivh@mojombo.com>
Date: Fri Nov 7 13:47:59 2008 -0500ignore *.gem
也可以写成 HEAD^^^
,也是第一父提交的第一父提交的第一父提交:
$ git show HEAD^^^
commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
Author: Medivh <Medivh@mojombo.com>
Date: Fri Nov 7 13:47:59 2008 -0500ignore *.gem
也可以组合使用这两个语法
可以通过 HEAD~3^2
来取得之前引用的第二父提交(假设它是一个合并提交)
2. 提交区间
之前的都是单次的提交,现在来看看如何指明一定区间的提交
当有很多分支时,这对管理你的分支时十分有用
可以用提交区间来 解决“这个分支还有哪些提交尚未合并到主分支?”的问题
2.1. 双点
最常用的指明提交区间语法是双点
这种语法可以让 Git 选出在一个分支中而不在另一个分支中的提交
例如,有如下的提交历史:
想要查看 experiment
分支中还有哪些提交尚未被合并入 master
分支
可以使用 master..experiment
来让 Git 显示这些提交
也就是在 experiment
分支中而不在 master
分支中的提交
为了使例子简单明了,使用了示意图中提交对象的字母来代替真实日志的输出
所以会显示:
$ git log master..experiment
D
C
即指出了experiment
中与master
不同的提交
反过来,如果想查看在 master
分支中而不在 experiment
分支中的提交
只要交换分支名即可:
$ git log experiment..master
F
E
这可以保持 experiment
分支跟随最新的进度以及查看即将合并的内容
另一个常用的场景是查看你即将推送到远端的内容:
$ git log origin/master..HEAD
这个命令会输出 在当前分支中而不在远程 origin 中的提交
如果执行 git push
并且当前分支正在跟踪 origin/master
由 git log origin/master..HEAD
所输出的提交就是会被传输到远端服务器的提交
如果留空了其中的一边, Git 会默认为 HEAD
例如,
$ git log origin/master..
将会输出与之前例子相同的结果
2.2. 多点
双点语法很好用,但有时候可能需要两个以上的分支才能确定所需要的修订
比如查看哪些提交是被包含在某些分支中的一个,但是不在你当前的分支上
Git 允许在任意引用 前 加上 ^
字符或者 --not
来指明不希望提交被包含其中的分支
因此下列3个命令是等价的:
$ 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
这就构成了一个十分强大的修订查询系统
可以通过它来查看你的分支里包含了哪些东西
2.3. 三点
最后一种主要的区间选择语法是三点
这个语法可以选择出被两个引用中的一个包含 但又不被两者同时包含 的提交
再看看之前双点例子中的提交历史
如果想看 master
或者 experiment
中包含的但不是两者共有的提交
可以执行
$ git log master...experiment
F
E
D
C
即指出了experiment
与master
中不同的提交
这和通常 log
按日期排序的输出一样,仅仅给出了4个提交的信息
这种情形下,log
命令的一个常用参数是 --left-right
它会显示每个提交到底处于哪一侧的分支
这会让输出数据更加清晰
$ git log --left-right master...experiment
< F
< E
> D
> C
有了这些工具,就可以十分方便地查看 Git 仓库中的提交
参考: git
以上内容,均根据git官网介绍删减、添加和修改组成
相关推荐:
Git笔记(24) 维护项目
Git笔记(23) 不同角色的贡献
Git笔记(22) 项目贡献要点
Git笔记(21) 分布式工作流程
Git笔记(20) 配置服务器
谢谢
Git笔记(25) 选择修订版本相关推荐
- 7.1 Git 工具 - 选择修订版本
现在,你已经学习了管理或者维护 Git 仓库.实现代码控制所需的大多数日常命令和工作流程. 你已经尝试了跟踪和提交文件的基本操作,并且发挥了暂存区和轻量级的分支及合并的威力. 接下来你将学习一些 Gi ...
- Git笔记(32) 高级合并
Git笔记(32) 高级合并 1. 合并冲突 1.1. 中断一次合并 1.2. 忽略空白 1.3. 手动文件再合并 1.4. 检出冲突 1.5. 合并日志 1.6. 组合式差异格式 2. 撤消合并 2 ...
- Git笔记(29) 搜索
Git笔记(29) 搜索 1. 浏览代码和提交 2. Git Grep 3. Git 日志搜索 4. 行日志搜索 1. 浏览代码和提交 无论仓库里的代码量有多少 经常需要查找一个函数是在哪里调用或者定 ...
- Git笔记(28) 签署工作
Git笔记(28) 签署工作 1. 签署工作 2. GPG 介绍 3. 签署标签 4. 验证标签 5. 签署提交 6. 使用环境 1. 签署工作 Git 虽然是密码级安全的,但它不是万无一失的 如果从 ...
- Git笔记(27) 储藏与清理
Git笔记(27) 储藏与清理 1. 混乱的状态 2. 储藏工作 3. 创造性的储藏 4. 从储藏创建一个分支 5. 清理工作目录 1. 混乱的状态 有时,当在项目的一部分上已经工作一段时间后,所有东 ...
- Git之深入解析如何选择修订的版本
一.前言 了解了管理或者维护 Git 仓库.实现代码控制所需的大多数日常命令和工作流程,尝试跟了踪和提交文件的基本操作,并且掌握了暂存区和轻量级地分支及合并的威力.如果想进一步对 Git 深入学习,可 ...
- 【Git笔记2】必知习惯和如何版本回退
良好的习惯会让工作和生活如鱼得水,在使用git的时候有些必知习惯和概念你要get一下,总有些许失误,如:已经提交了不合适的修改到版本库时还没有把自己的本地版本库推送到远程,想要撤销本次提交,或者已经p ...
- git笔记(廖雪峰版本)
git diff #是工作区(work dict)和暂存区(stage)的比较 git diff --cached #是暂存区(stage)和分支(master)的比较 Git比其他版本控制系统设计得 ...
- Git笔记(23) 不同角色的贡献
Git笔记(23) 不同角色的贡献 1. 私有小型团队 2. 私有管理团队 3. 派生的公开项目 4. 通过邮件的公开项目 1. 私有小型团队 可能会遇到的最简单的配置是有一两个开发者的私有(闭源)项 ...
最新文章
- 编程疑难杂症の怪诞的【黄色警告】
- 「高并发秒杀」mysql只修改字段名称
- python导包顺序_2019-03-21 python导入包以及Python程序执行顺序理解
- Scheme 语言概要
- python 形参 拷贝_Day124:python中的变量、引用、拷贝
- 【Chocolatey】安装python3
- linux创建新进程就分配空间,linux几种创建进程的方法
- Kafka 慌了!这个中间件,要火了?
- 卷积神经网络学习笔记与心得(2)数据集
- STM32笔记记录2
- 黑php的称呼,“黑”起母校都是把好手!这些高校别称你绝对想不到
- Xshell 外观配置
- Android打造自定义通用popWindow
- 网络设备的区分(自顶向下)
- armlinux开发板用户自动登录
- 使用PIL改变图像分辨率
- 一步一步从原理跟我学邮件收取及发送 7.读取一行命令的实现
- 手机端,跟pc 链接qq 客服
- eventscheduler mysql_Mysql 中的事件 事件调度器(Event Scheduler)
- 坦克大战(Tank Battalion)------Java代码实现
热门文章
- 使用nginx作为代理实现动静分离
- HDU-2525 Clone Wars 模拟
- metasploit-***测试工具
- 操作系统(3)-线程的六大状态、基于代码实战的线程创建及六个常用方法
- 算法高级(18)-Redis Cluster选举机制
- redis安装包_redis安装与调优部署文档(WinServer)
- linux编译内核后无法进入,编译linux内核,ubuntu,x86的环境出现warning,然后就出现无法启动ubuntu...
- 上交AI研究院副院长马利庄:基于大数据的人脸识别技术进展与展望
- WebService入门案例
- 写给对前途迷茫的朋友