Glide
Glide

Reputation: 21275

find out if a git commit was checked in before or after another commit given the hashes

One thing I miss about using svn was the simple-numbering of revision numbers. I can easily see if the version deployed in the testing environment is before or after a certain commit.

With git using hashes for its commits, what is a way to tell if a commit was made before or after another commit?

Upvotes: 23

Views: 10229

Answers (7)

petee
petee

Reputation: 111

With all the remarks mentioned by @me_and, you can also try:

git rev-list --no-walk commitA commitB

In output you will see provided commits displayed in reverse chronological order by commit time. So it's order of provided commits does not matter (in contradiction to idea suggested by @Douglas Bagnall).

Upvotes: 1

Dane White
Dane White

Reputation: 3562

git merge-base has a flag for that. It simply returns a 0/1 exit code.

git merge-base --is-ancestor <commit> <commit>

Upvotes: 16

Douglas Bagnall
Douglas Bagnall

Reputation: 816

git rev-list --count can help. Supposing 110a187 comes 4 commits before 5d41af1, then:

 $ git rev-list --count 110a187..5d41af1
4
 $ git rev-list --count 5d41af1..110a187
0

Thus something like:

test $(git rev-list --count $a..$b) == 0 && \
       echo "$a is not an ancestor of $b"

Upvotes: 7

me_and
me_and

Reputation: 15654

Things, as you note, aren't so simple in Git. In particular, the definition of "before" and "after" need a little more clarification.

If you trust the people committing to your repository not to mess with timestamps, and you already know both commits are on the same branch, you can compare the timestamps of the commits and just see which one is earlier. Use the following command for each commit, and compare the result.

git log -1 --format='%ci' <commit>

With Git, you can't necessarily trust the timestamps, however, since unlike Subversion there isn't a central repository with a job of producing them. You also can't be sure that two commits are on the same branch (although that problem also exists with Subversion).

To avoid those problems, talk about whether one commit is an ancestor of another, rather than whether it comes before or after it. In the following commit graph, B and C are ancestors of A, while B is not an ancestor of C nor vice versa:

B    (master)
| C  (branch)
|/
A    (root)

To determine whether commit A is an ancestor of commit B, use the following command (based on an article at git ready):

git rev-list <commitA> | grep $(git rev-parse <commitB>)

The first part lists all the commits that are ancestors of commit A; the second part gets the full hash of commit B, then searches the ancestor list for that commit. If you see any output, commit A is an ancestor of commit B. Swap the arguments to work out if commit A is an ancestor of commit B instead.

This second form is slower, but gives you absolute certainty that one commit is an ancestor of another.

Upvotes: 19

Michal
Michal

Reputation: 2532

You can get all commit info from the log which shows the hash, author, date, and comment:

git log

You can pull a specific commit's time/date from the commit log. Something like:

git log -1 --format="%cd" <commit>

The '%cd' gives you the date in the log's format, you can also do:

  • %cD: RFC2822 style
  • %cr: relative
  • %ct: UNIX timestamp
  • %ci: ISO 8601 format

From there, you could do some comparisons with some scripting if you need to automate.

Upvotes: 2

Philip Rieck
Philip Rieck

Reputation: 32578

Use git show on each commit to find the date of the commit. There's no way just looking at the hash to determine order, since it's nothing but a hash.

You can use custom format strings to show just what you want, check the man pages for more info.

git show --format="%ci" <commit>

Upvotes: 4

Zombo
Zombo

Reputation: 1

If you use tags you can do

git describe --tags

This will tell you how many commits since the last tag.

Upvotes: 0

Related Questions