Reputation: 21275
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
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
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
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
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
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:
From there, you could do some comparisons with some scripting if you need to automate.
Upvotes: 2
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
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