I'd like to git log
all the tagged commits on the master branch (and none of the untagged commits). Is this possible?
The --decorate flag makes git log display all of the references (e.g., branches, tags, etc) that point to each commit.
In order to create a Git tag for a specific commit, use the “git tag” command with the tag name and the commit SHA for the tag to be created. If you want to create an annotated tag for a specific commit, you can use the “-a” and “-m” options we described in the previous section.
We occasionally have two tags on the same commit. When we use git describe for that commit, git describe always returns the first tag. My reading of the git-describe man page seems to indicate that the second tag should be returned (which makes more sense).
Git rev-list will list commits in one branch that are not in another branch. It is a great tool when you're trying to figure out if code has been merged into a branch or not. Using the --oneline option will display the title of each commit. The ^ operator excludes commits in the specified branch from the list.
The secret trick to this is to realize that git log
uses the same rules as git rev-list
. The latter command has a --tags
flag to look at tags. So, as with the other answers so far, if you're willing to look at all tagged commits, this single command will do it:
git log --no-walk --tags
(The --no-walk
prevents this from starting with tags and finding all their parent commits, and the parents' parents, and so on.)
But you asked for "tagged commits on the master branch", which I assume means (in technical terms) "commits that are both pointed to by tags and reachable via the master
branch". This is substantially harder (git rev-list
can do set union via --stdin --no-walk
, but seems to have no way to do set intersection). Here are several methods of finding the right commit-IDs, with various drawbacks:
First make two file lists: "all tagged commits" and "all commits reachable from master":
git rev-list --tags --no-walk > /tmp/all-tags
git rev-list master > /tmp/all-master
Now just print lines that appear only in both files. The comm
utility can do this. It's documented to expect the files to be sorted, but in all implementations I have seen, the files merely need to be in the same order, as it were, so this works without pre-sorting:
comm -12 /tmp/all-tags /tmp/all-master
Drawbacks: needs two temporary files (unless you use the special bash
syntax that uses /dev/fd
); might not work without sorting; requires comm
.
Same idea as before, but use uniq -d
to produce the list. This really does require sorting, but you can eliminate the temporary files using a pipe:
(git rev-list --tags --no-walk; git rev-list master) | sort | uniq -d
Drawback: requires sorting. The commits come out in some strange order, not the order you would normally see with git log
.
Write your own utility that basically does what the comm
method would do, but invokes git rev-list
itself (perhaps a script that creates temp files using mktemp
to make unique names).
Drawback: requires a lot more work. :-)
In all cases, once you have the list of commit-IDs, you just need to pass them to git log --no-walk
, e.g.:
git log --no-walk $(comm -12 /tmp/all-tags /tmp/all-master)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With