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. myql命令行乱码问题,以及设置数据库编码

    使用命令修改数据库编码格式参见:https://www.cnblogs.com/clsn/p/8047028.html#auto_id_3 命令行乱码设置修改参见:https://www.cnblog ...

  2. ORA-00979: 不是 GROUP BY 表达式

    在oracle数据库中,sql语句中group by子句报错,原因是select 存在列字段,而group by中不存在.

  3. linux复习2:Fedora17系统的安装和删除

    一.Linux系统下硬盘的基本知识 1.分区命名方案: (1)Linux系统使用字母和数字的组合来指代硬盘分区 (2)Linux系统使用一种更加灵活的命名方案,该命名方案是基于文件的,文件的命名格式为 ...

  4. 高效开发之使用Cmder替换cmd

    一.为什么要更换为cmder 在做项目时,有些时候我想复制控制台上面的代码时,cmd有的时候复制粘贴很麻烦,Cmder则不会,并且Cmder可以分屏多开窗口,可以设置窗口颜色,字体大小,并且很多快捷键 ...

  5. 68. Text Justification (JAVA)

    Given an array of words and a width maxWidth, format the text such that each line has exactly maxWid ...

  6. kali下纯文本与窗口环境切换

    切到纯文本环境,想返回 试了半天ctrl+alt+f7不行,  最后我想试试ctrl+alt+f8竟然成了: 而且那是之前以root账户登录图像界面时切换回去是f8,普通用户是f9 ,为何如此,我还不 ...

  7. k8s+docker+proget 镜像制作

    安装proget 1 首先在k8s上运行proget的数据库配置有个注意点:要根据proget官网要求的sql server排序方式建数据库,不然数据保存的时候会报错 2 proget运行起来后,默认 ...

  8. 学习-Pytest(三)setup/teardown

    1. 用例运行级别 模块级(setup_module/teardown_module)开始于模块始末,全局的 函数级(setup_function/teardown_function)只对函数用例生效 ...

  9. (转) Java中的负数及基本类型的转型详解

    (转) https://my.oschina.net/joymufeng/blog/139952 面这行代码的输出是什么? 下面两行代码的输出相同吗? 请尝试在Eclipse中运行上面的两个代码片段, ...

  10. putty ssh常用命令小结

    打开putty 输入VPS的IP地址输入root回车输入密码回车 vps 更改文件夹所属组 cd /home/vpsuser/domains/afish.cnblogs.com/ chown -R v ...