170

I saw an answer to a question here that helps restore a deleted file in git.

The solution was

git checkout <deleting_commit>^ -- <deleted_file_path> 

What does the caret character (^) do? I’ve seen it elsewhere doing very useful things in git. It’s magical. Someone please spoil it for me and tell me what it does?

2
  • 13
    FYI on windows: ^ doesn't work as expected in DOS shell. Use git bash shell and then it works. Commented Sep 27, 2011 at 0:59
  • 10
    That didn't even occur to me when I've attempted to use it (guessing on what it means). The caret (^) is the escape character in cmd.exe. Every time I've tried to use it to see if it would be helpful I was actually passing nothing, which explains why the results were never different. >_> Stupid cmd.exe. You can escape it by doubling it or quoting it: git log master^^ or git log "master^" Commented Jul 24, 2012 at 20:24

9 Answers 9

190

HEAD^ means the first parent of the tip of the current branch.

Remember that git commits can have more than one immediate parent. HEAD^ is short for HEAD^1, and you can also address HEAD^2 and so on as appropriate. Any commit with multiple parents is the product of a merge or a merge commit.

You can get to parents of any commit, not just HEAD. You can also move back through generations to any reachable ancestor: for example, master~2 means the grandparent of the tip of the master branch, favoring the first parent in cases of ambiguity. These specifiers can be chained arbitrarily. For example:

  • HEAD^^^, HEAD~~~, or HEAD~3 all refer to the great-grandparent commit, three generations back.
    • HEAD^3 is different: it means the third immediate parent of a merge commit — and strains the analogy to biology.
  • topic~3^2 starts at the tag or tip of the branch named topic, goes three generations back, and selects that merge commit’s (the great-grandparent’s) second immediate parent — the great-great-grandfather if you think of git history as being primarily matrilineal.

See also:

Sign up to request clarification or add additional context in comments.

Comments

30

The ^ (caret) can also be used when specifying ranges.

To exclude commits reachable from a commit, a prefix ^ notation is used. E.g. ^r1 r2 means commits reachable from r2 but exclude the ones reachable from r1.

<rev>

Include commits that are reachable from (i.e. ancestors of) .

^<rev>

Exclude commits that are reachable from (i.e. ancestors of) .

1 Comment

yep, this was exactly what I was searching for.
27

It means "parent of". So HEAD^ means "the parent of the current HEAD". You can even chain them together: HEAD^^ means "the parent of the parent of the current HEAD" (i.e., the grandparent of the current HEAD), HEAD^^^ means "the parent of the parent of the parent of the current HEAD", and so forth.

3 Comments

This answer is not right for merge commits. If HEAD is following a merge commit, then HEAD^ means the first parent of HEAD, and HEAD^^ (or HEAD^2) means the second parent of HEAD. In a merge commit, the second parent of HEAD is not the same thing as the parent of the parent of HEAD. See Ancestry References in the Git manual.
@bhagerty: That is wrong. While HEAD^2 does indeed indicate the second parent of HEAD, HEAD^2 and HEAD^^ are not synonymous. Multiple carets do refer to commits in relation to the first parent, so just as HEAD^^ refers in general to the grandparent of HEAD, HEAD^^ the grandparent of parent of the first commit of HEAD when HEAD is a merge commit; likewise, HEAD^2^ is the parent of the second parent.
Thanks, @mipadi. I assume you are correct, though the documentation doesn't come close to making this clear. As far as I can tell, HEAD~~ and HEAD~2 are synonymous, so by analogy, I expected the number operator to work similarly with the caret. From what you are saying, it does not. That is unfortunate.
16

Here's a visual explanation. Suppose you have a history like so:

 master ... <- B <- C <- D / ... <- E <- F feature 

When feature was merged into master, C was created with two ancestors. Git assigns these ancestors numbers. The mainline ancestor B is assigned 1 and the feature ancestor F is assigned 2.

Thus C^1 refers to B and C^2 refers to F. C^ is an alias for C^1.

You would only ever use <rev>^3. if you had performed a merge of three branches.

3 Comments

is that actually legal? can a merge commit contain three parents?
A merge commit can have N parents. The only distinction between a regular commit and a merge is the number of parents.
After going through this comment, reading stackoverflow.com/questions/2221658/… gives more clarity
9

The caret refers to the parent of a particular commit. E.g. HEAD^ refers to the parent of the current HEAD commmit. (also, HEAD^^ refers to the grandparent).

Comments

8

OP: What does the caret (^) character mean in Git?

The ^ (Caret) and ~ (Tilde) selectors

The difference between HEAD^ (Caret) and HEAD~ (Tilde) is how they traverse history backwards from a specified starting point, in this particular case HEAD.

Tilde ~

<rev>~[<n>] = select <n>th generation ancestor, following only first* parents

Caret ^

<rev>^[<n>] = select <n>th parent of first generation ancestors

*First parent is always the left hand side of the merge, e.g. the commit on the branch that got merged into.

Joining ~ and ^ together

As seen in the illustration below the two selectors ~ and ^ can be used in combination. Also note that instead of using HEAD as a starting point, any regular reference can be used such as a branch, tag or even a commit hash.

Further more, depending on what ancestor is intended to be selected ^ and ~ can be used interchangeably as seen below in the table.

Illustration of relative references in Git

Source: A thorough rundown can be found in this blog post on the subject.

2 Comments

This is a near-perfect explanation and diagram. The only minor comment I have relates to the letters in the diagram. I think it would be easier to understand if the letters went backwards in the alphabet. The way you have it now, the flow of the letters is contrary to the flow of time, which is counterintuitive. It's clear from your arrow of time that C came before B came before A in time. But this is not how we expect the alphabet to work.
Thanks for your feedback @bhagerty ! And great suggestion, I'll definitely look into making the change. Indeed, it's a bit counter intuitive.
4

The carat represents a commit offset (parent). So for instance, HEAD^ means "one commit from HEAD" and HEAD^^^ means "three commits from HEAD".

Comments

4

The (^) gets the parent source of the command i.e. HEAD^ will get the parent of HEAD.

Comments

2

Greg Bacon gave a great link, but it's pretty dense. The Git introductory docs online also introduce revision and range specifiers:

https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection

1 Comment

This link might be closer to the location intended. git-scm.com/book/en/v2/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.