Git里引用一个commit
git所有的操作, 其实都是在跟commit
打交道:
你stage
你的commit
, 创建一个commit,
查看之前的commit
, 把commit
在不同的branch之间挪动, push
你的commit
等等.
那么, 怎么指定commit
就很重要.
1. 通过commit hash
来指定.
一个commit
跟一个commit hash
是一一对应的, 这是最直接的指定commit
的方式.
2. 通过refs
refs
是一种间接指定commit
的方式, 相当于commit hash
的别名, 它更加对人类友好, 不过, 不是所有的commit hash
都有别名(也就是refs
)的. 通常你见到的branch name, 比如master
, 其实就是一种ref
.
1. 一般的ref
要知道你的repo有多少refs
, 可以在.git/refs
这个目录里看到类似下面的目录树.
如果你的git repo是一个大型repo, 很可能你的refs被压缩成一个叫.git/packed-refs的文件, 而不是在.git/refs目录下.
1 | heads/ # 这个目录里存放了你所有的local branch |
使用一个ref来指定一个commit很简单, 比如
1 | git show master |
2. 特殊的ref
除了.git/refs
(或者.git/packed-refs
)下的refs, 还有一些特殊的refs, 定义在.git
这个目录下, 说几个常见的:
HEAD
: 当然checkout的commit/branchFETCH_HEAD
: 最近一次从远端 fetch的branchMERGE_HEAD
: 你正在merge到当前brach的那个commit.
3. 相对refs
你可以指定通过一个commit
来指定另一个commit
:
~
这个字符, 可以帮助你指定你当前commit的parent commit.git show HEAD~1
: HEAD的上一个commit.如果发生过merge, 那么一个commit, 就有可能有两个parent, 这个时候, 如何指定另一个parent呢?
^
字符, 可以帮你:git show HEAD^2
~
跟^
的区别, 下面这张图你可以看到.
4. Reflog
你在local repo上做的所有关于commit hash的历史操作, git其实都为你保留在reflog
里. 可以通过git reflog
来查看:
1 | 5a9f9aa25 (HEAD -> xtao, origin/xtao, origin/HEAD) HEAD@{0}: reset: moving to origin/xtao |
如果你要恢复某一个历史commit hash, 你可以通过HEAD@{<n>}
这样的语法, 来指定在reflog里的一个commit hash, 比如:
git checkout HEAD@{1}
总结
通过了解git如何引用一个commit, 我们其实了解到了很多git内部的机制, 比如它是如何存储branch信息和tag信息的, 这会帮助我们更好的理解平时使用的git 命令.
有的时候, 我们还需要指定一定范围内的commit, 比如当你想把一个branch上最近提交的几个commit, 提交到另一个branch上, 该怎么做呢? 敬请期待下一篇啦.
参考: https://www.atlassian.com/git/tutorials/refs-and-the-reflog
原文作者: dgb8901,yinxing
原文链接: https://www.itwork.club/2018/10/17/git-refs/
版权声明: 转载请注明出处
为您推荐
体验小程序「简易记账」
关注公众号「特想学英语」