162

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?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Charles Ma
  • 47,141
  • 22
  • 87
  • 101
  • 13
    FYI on windows: ^ doesn't work as expected in DOS shell. Use git bash shell and then it works. – Cincinnati Joe Sep 27 '11 at 00:59
  • 9
    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^"` – bambams Jul 24 '12 at 20:24

9 Answers9

180

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

Remember that git commits can have more than one parent. HEAD^ is short for HEAD^1, and you can also address HEAD^2 and so on as appropriate.

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 in cases of ambiguity. These specifiers can be chained arbitrarily , e.g., topic~3^2. See related answer to What’s the difference between HEAD^ and HEAD~ in Git?

For the full details, see the “Specifying Revisions” section of git rev-parse --help.

Cara McCormack
  • 388
  • 1
  • 7
  • 21
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
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.

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 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](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection) in the Git manual. – bhagerty Oct 07 '22 at 23:05
  • @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. – mipadi Oct 09 '22 at 03:23
  • 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. – bhagerty Oct 15 '22 at 03:24
27

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) .

cmcginty
  • 113,384
  • 42
  • 163
  • 163
15

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.

cdosborn
  • 3,111
  • 29
  • 30
  • is that actually legal? can a merge commit contain three parents? – matthias_buehlmann Feb 08 '21 at 15:41
  • A merge commit can have N parents. The only distinction between a regular commit and a merge is the number of parents. – cdosborn Feb 08 '21 at 17:49
  • After going through this comment, reading https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git/2222920#2222920 gives more clarity – Albert Nov 28 '22 at 07:08
8

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).

mopoke
  • 10,555
  • 1
  • 31
  • 31
5

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

Amber
  • 507,862
  • 82
  • 626
  • 550
4

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

TALLBOY
  • 1,079
  • 1
  • 10
  • 13
3

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.

  • 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. – bhagerty Oct 08 '22 at 03:12
  • Thanks for your feedback @bhagerty ! And great suggestion, I'll definitely look into making the change. Indeed, it's a bit counter intuitive. – Alexis Määttä Vinkler Oct 09 '22 at 08:22
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

Pod
  • 3,938
  • 2
  • 37
  • 45
Ncat
  • 417
  • 3
  • 10
  • 3
    This link might be closer to the location intended. http://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Ancestry-References – bholben Nov 07 '14 at 02:12