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/
版权声明: 转载请注明出处
为您推荐

体验小程序「简易记账」

关注公众号「特想学英语」