https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git

Rules of thumb

  • Use ~ most of the time — to go back a number of generations, usually what you want
  • Use ^ on merge commits — because they have two or more (immediate) parents

Mnemonics:

  • Tilde ~ is almost linear in appearance and wants to go backward in a straight line
  • Caret ^ suggests an interesting segment of a tree or a fork in the road

Tilde

The “Specifying Revisions” section of the git rev-parse documentation defines ~ as

<rev>~<n>, e.g. master~3
A suffix ~<n> to a revision parameter means the commit object that is the nth generation ancestor of the named commit object, following only the first parents. [For example,] <rev>~3 is equivalent to <rev>^^^ which is equivalent to <rev>^1^1^1

You can get to parents of any commit, not just HEAD. You can also move back through generations: for example, master~2 means the grandparent of the tip of the master branch, favoring the first parent on merge commits.

Caret

Git history is nonlinear: a directed acyclic graph (DAG) or tree. For a commit with only one parent, rev~ and rev^
mean the same thing. The caret selector becomes useful with merge
commits because each one is the child of two or more parents — and
strains language borrowed from biology.

HEAD^ means the first immediate parent of the tip of the current branch. HEAD^ is short for HEAD^1, and you can also address HEAD^2 and so on as appropriate. The same section of the git rev-parse documentation defines it as

<rev>^, e.g. HEAD^, v1.5.1^0
A suffix ^ to a revision parameter means the first parent of that commit object. ^<n> means the nth parent ([e.g.] <rev>^ is equivalent to <rev>^1). As a special rule, <rev>^0 means the commit itself and is used when <rev> is the object name of a tag object that refers to a commit object.

http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde

I spent a little bit of time playing with Git today, specifically the way that the ^ (caret) and ~ (tilde) work and thought I'd document it here in case I forget.

The short version

If you want a deeper explanation skip down to "The long version".

ref~ is shorthand for ref~1 and means the commit's first parent. ref~2 means the commit's first parent's first parent. ref~3 means the commit's first parent's first parent's first parent. And so on.

ref^ is shorthand for ref^1 and means the commit's first parent. But where the two differ is that ref^2 means the commit's second parent (remember, commits can have two parents when they are a merge).

The ^ and ~ operators can be combined.

Here's a diagram showing how to reference various commits using HEAD as the starting point.

HEAD~1^2    commit的 first parent的second parent

The long version

I've created a dummy repository with several commits in it.

$ git log --graph --oneline
* 8329384 Seventh commit
* f5717b0 Merge branch 'my_branch'
|\
| * 956c87d Fourth commit on a branch
* | a8fe411 Sixth commit
|/
* c7c2590 Third commit on a branch
* 86362ff Second commit on a branch
* 748855b First commit on a branch
* 1855b25 Fifth commit
* 67cf3a7 Fourth commit
* ea29778 Third commit
* 28c25b1 Second commit
* cd00b76 First commit

Starting at the bottom, the early commits were made straight onto master.

The commits starting at 748855b and moving up to c7c2590 were made on a branch and merged into master, but no changes had been made on master in the mean time.

The commits a8fe411 and 956c87d were made on separate branches at the same time. They were merged together in commit f5717b0.

Finally, 8329384 was committed straight onto master.

We can use git show to look at individual commits.

You'll already know that HEAD points to the tip of the current branch:

$ git show --oneline HEAD
8329384 Seventh commit

Putting the caret symbol (^) next to a commit means the parent of that commit. So the following will show the parent of HEAD:

$ git show --oneline HEAD^
f5717b0 Merge branch 'my_branch'
...

HEAD^ is shorthand for saying HEAD^1, which literally means show me parent 1 of that commit. You can also say HEAD^2 but in this instance it won't make any sense:

$ git show --oneline HEAD^2
fatal: ambiguous argument 'HEAD^2': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

Because HEAD only has 1 parent.

But f5717b0, the point where the two branches were merged, has two parents, one on master and one on the branch:

$ git show --oneline f5717b0^1
a8fe411 Sixth commit
... $ git show --oneline f5717b0^2
956c87d Fourth commit on a branch
...

The tilde symbol (~) works in a similar way. In fact HEAD~ will reference the same commit as HEAD^:

Again, HEAD~ is shorthand for HEAD~1, but here this means the first ancestor of HEADHEAD~2 is not the second parent of HEAD but the grandparent of HEAD:

$ git show --oneline HEAD~1
f5717b0 Merge branch 'my_branch'
... $ git show --oneline HEAD~2
a8fe411 Sixth commit
... $ git show --oneline HEAD~3
c7c2590 Third commit on a branch

As you can see, 956c87d Fourth commit on a branch is not visible when using the tilde operator. This is because the tilde operator always presumes you want to view the first parent's parent.

To access the second parent's parent the tilde and caret symbols can be combined:

$ git show --oneline HEAD~1^1
a8fe411 Sixth commit
... $ git show --oneline HEAD~1^2
956c87d Fourth commit on a branch
...

In this way you should be able to reference any commit in your repository's history.

What's the difference between HEAD^ and HEAD~ in Git?的更多相关文章

  1. 学习笔记之Git / Gitflow / TortoiseGit

    Git - Wikipedia https://en.wikipedia.org/wiki/Git Git (/ɡɪt/) is a version control system for tracki ...

  2. Git命令中波浪号~与脱字符^的区别

    0.前言 波浪号~,英文名叫 tilde.脱字符^,英文名叫caret. 这两种符号常见于git reset的情景,简单的项目结构和操作一般不会涉及到两者之间的区别,似乎用哪个都可以.如果遇到比较繁杂 ...

  3. Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)

    --reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...

  4. What's the difference between a stub and mock?

    I believe the biggest distinction is that a stub you have already written with predetermined behavio ...

  5. [转载]Difference between <context:annotation-config> vs <context:component-scan>

    在国外看到详细的说明一篇,非常浅显透彻.转给国内的筒子们:-) 原文标题: Spring中的<context:annotation-config>与<context:componen ...

  6. What's the difference between <b> and <strong>, <i> and <em> in HTML/XHTML? When should you use each?

    ref:http://stackoverflow.com/questions/271743/whats-the-difference-between-b-and-strong-i-and-em The ...

  7. difference between forward and sendredirect

    Difference between SendRedirect and forward is one of classical interview questions asked during jav ...

  8. Add Digits, Maximum Depth of BinaryTree, Search for a Range, Single Number,Find the Difference

    最近做的题记录下. 258. Add Digits Given a non-negative integer num, repeatedly add all its digits until the ...

  9. MySQL: @variable vs. variable. Whats the difference?

    MySQL: @variable vs. variable. Whats the difference?   up vote351down votefavorite 121 In another qu ...

随机推荐

  1. String转int,int转String

    String转int 1) int i = Integer.parseInt([String]);  int i = Integer.parseInt([String],[int radix]); 2 ...

  2. drf模块分析

    drf请求模块.渲染模板.解析模块.响应模块.异常模块 请求模块 drf的请求模块 1.drf的request是在wsgi的request基础上再次封装 2.wsgi的request作为drf的req ...

  3. 2019-11-29-git-需要知道的1000个问题

    title author date CreateTime categories git 需要知道的1000个问题 lindexi 2019-11-29 8:36:7 +0800 2018-2-13 1 ...

  4. 遍历获取html页面所有元素的id

    因为要写一个权限管理系统精确到每个标签.以前用过的是给每个标签加权限判断的代码.但感觉这种方式太麻烦和落后,向让页面加载时自动把每个标签的id扫描到并保存到数据库.通过id控制.研究了下实现代码如下: ...

  5. Ubuntu16.04下caffe CPU版的详细安装步骤

    一.caffe简介 Caffe,是一个兼具表达性.速度和思维模块化的深度学习框架. 由伯克利人工智能研究小组和伯克利视觉和学习中心开发. 虽然其内核是用C++编写的,但Caffe有Python和Mat ...

  6. PrimeFaces ab function

    The PrimeFaces.ab function is a shortcut function for PrimeFaces.ajax.AjaxRequest. //ajax shortcut a ...

  7. 【模板】AC自动机加强版

    题目大意:给定 N 个模式串和一个文本串,求每个模式串在文本串中出现的次数. 题解:文本串在自动机上匹配的过程中,记录下自动机上每一个状态被访问的次数.对于访问到的节点 i,则状态 i 的后缀中存在的 ...

  8. jmeter请求时出现no cookies

    现象: 解决步骤: 1.添加http cookie管理器 2.检查http信息头管理器是否正确

  9. java常用关键词关键字,方法源码解析

    transient volatile native final Integer String Class &&Object newInstance Class.forName,Clas ...

  10. 【NOIP2016提高A组集训第3场10.31】高维宇宙

    题解 分析 因为只有奇数和偶数配对才有可能得出质数, 暴力求出每一对\(a_i+a_j\)为质数,将其中的奇数想偶数连一条边. 二分图匹配,匈牙利算法. #include <cmath> ...