Skip to content

2023

Git describe with git tags

Getting tags on a git repository

Use git describe --tags to get the tags.

Using git describe

Examples using git describe

Using git describe --tags:

git describe --tags
## output
v0.2.1-15-g7a82bbe

Using git describe

git describe
## output
v0.1.2-39-g7a82bbe

Using git describe --abbrev=0 --tags to get the tag from the current branch

git describe --abbrev=0 --tags
## output
v0.2.1

Using git describe with git rev-list to get tags across all branches, not just the current branch

git describe --tags `git rev-list --tags --max-count=1`
## output
v0.2.1

Other examples
Other git describe examples (click to expand) ### Other examples using git describe Get the latest tagged version and remove the `v` prefix:
git tag --sort=committerdate | grep -E '[0-9]' | tail -1 | cut -b 2-7
## output
0.2.1
Using `git describe` with `--abbrev` set to `0`
git describe --abbrev=0
## output
v0.1.2

Sorting tags

Using the --sort option

From https://stackoverflow.com/questions/14273531/how-to-sort-git-tags-by-version-string-order-of-form-rc-x-y-z-w?#answer-22634649

With Git 2.0 (June 2014), you will be able to specify a sorting order!

Using --sort=<type>

Sort in a specific order. Supported type is: * "refname" (lexicographic order), * "version:refname" or "v:refname" (tag names are treated as versions).

Prepend "-" to reverse sort order.

So, if you have:

git tag foo1.3 &&
git tag foo1.6 &&
git tag foo1.10

Here is what you would get:

# lexical sort
git tag -l --sort=refname "foo*"
foo1.10
foo1.3
foo1.6

# version sort
git tag -l --sort=version:refname "foo*"
foo1.3
foo1.6
foo1.10

# reverse version sort
git tag -l --sort=-version:refname "foo*"
foo1.10
foo1.6
foo1.3

# reverse lexical sort
git tag -l --sort=-refname "foo*"
foo1.6
foo1.3
foo1.10

Examples using git tag to sort tags

Sort by -taggerdate

git tag --sort=-taggerdate
## output
v0.1.2
v0.1.1
v0
v0.1.0
v0.2
v0.2.0
v0.2.1

Sort by taggerdate

git tag --sort=taggerdate
## output
v0
v0.1.0
v0.2
v0.2.0
v0.2.1
v0.1.1
v0.1.2

Sort by -committerdate

git tag --sort=-committerdate
## output
v0.2.1
v0
v0.2
v0.2.0
v0.1.0
v0.1.1
v0.1.2

Sort by committerdate

git tag --sort=committerdate
## output
v0.1.1
v0.1.2
v0.1.0
v0
v0.2
v0.2.0
v0.2.1

Getting the latest tag

You can use any of the following commands to get the latest tag

Using git ls-remote

Using git ls-remote --tags --sort=committerdate:

git ls-remote --tags --sort=committerdate | grep -o 'v.*' | sort -r
## output
From https://github.com/rwaight/actions.git
v0.2.1
v0.2.0
v0.2
v0.1.2^{}
v0.1.2
v0.1.1^{}
v0.1.1
v0.1.0
v0

Using git ls-remote --tags --sort=committerdate | grep -o 'v.*':

git ls-remote --tags --sort=committerdate | grep -o 'v.*'
## output
v0.1.1
v0.1.2
v0.1.0
v0.1.1^{}
v0.1.2^{}
v0.2.0
v0
v0.2
v0.2.1

Using git ls-remote --tags --sort=taggerdate | grep -o 'v.*' | sort -r:

git ls-remote --tags --sort=taggerdate | grep -o 'v.*' | sort -r
## output
From https://github.com/rwaight/actions.git
v0.2.1
v0.2.0
v0.2
v0.1.2^{}
v0.1.2
v0.1.1^{}
v0.1.1
v0.1.0
v0

Using git tag

Using git tag --sort=-taggerdate | tail -1:

git tag --sort=-taggerdate | tail -1
## output
v0.2.1

Using git tag --sort=committerdate | grep -o 'v.*' | sort -r:

git tag --sort=committerdate | grep -o 'v.*' | sort -r
## output
v0.2.1
v0.2.0
v0.2
v0.1.2
v0.1.1
v0.1.0
v0

Using git tag --sort=committerdate | grep -o 'v.*' | sort -r | head -1:

git tag --sort=committerdate | grep -o 'v.*' | sort -r | head -1
## output
v0.2.1

Using git for-each-ref

Using git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags:

git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags
## output
refs/tags/v0.1.0 Mon Mar 11 12:10:23 2024 -0500
refs/tags/v0.1.1 Mon Mar 11 13:37:32 2024 -0500
refs/tags/v0.1.2 Mon Mar 11 13:50:12 2024 -0500
refs/tags/v0 Mon Mar 11 20:00:06 2024 -0500
refs/tags/v0.2 Mon Mar 11 20:00:06 2024 -0500
refs/tags/v0.2.0 Mon Mar 11 20:00:06 2024 -0500
refs/tags/v0.2.1 Thu Mar 14 11:39:55 2024 -0500

Examples using git tag
Examples using git tag (click to expand) ### Examples using git tag Using `git tag -l`:
git tag -l
## output
v0
v0.1.0
v0.1.1
v0.1.2
v0.2
v0.2.0
v0.2.1
Using `git tag -l | tail -1`:
git tag -l | tail -1
## output
v0.2.1
Using `git tag | sort -V`:
git tag | sort -V
## output
v0
v0.1.0
v0.1.1
v0.1.2
v0.2
v0.2.0
v0.2.1
Examples using git rev-list
Examples using git rev-list (click to expand) ### Examples using git rev-list Using `git rev-list --tags --max-count=1`:
git rev-list --tags --max-count=1
## output
d702f1832400f86753094a219e8383ae817ade34

Revert commits in git

Examples to revert changes in a repo, primarily using git revert. These examples come from the following sources:

  • https://stackoverflow.com/questions/3293531/how-to-permanently-remove-few-commits-from-remote-branch
  • https://christoph.ruegg.name/blog/git-howto-revert-a-commit-already-pushed-to-a-remote-reposit

Revert an already pushed commit

Important: Make sure you specify which branches on git push -f or you might inadvertently modify other branches![*]

Delete the last n commits

Example: Delete the last 4 commits:

git reset --hard HEAD~4

Then run the following command (on your local machine) to force the remote branch to rewrite its history:

git push --force

Delete to a specific commit ID

Retrieve the desired commit ID by running

git log

In the example, the desired commit is 8675309.

Then you can replace HEAD~N with the desired commit ID like this:

git reset --hard 8675309

If you want to keep changes on file system and just modify index (commit history), use --soft flag like git reset --soft HEAD~4. Then you have chance to check your latest changes and keep or drop all or parts of them. In the latter case running git status shows the files changed since <desired-commit-id>. If you use --hard option, git status will tell you that your local branch is exactly the same as the remote one. If you don't use --hard nor --soft, the default mode is used that is --mixed. In this mode, git help reset says:

Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated.

Revert the full commit

git revert 8675309

Delete the last commit

On a remote branch:

git push <<remote>> +8675309^:<<BRANCH_NAME_HERE>>

On a local branch:

git reset HEAD^ --hard
git push <<remote>> -f

Where +8675309 is your commit hash and git interprets x^ as the parent of x, and + as a forced non-fastforwared push.

Delete the commit from a list

git rebase -i 8675309^

This will open and editor showing a list of all commits. Delete the one you want to get rid off. Finish the rebase and push force to repo.

git rebase --continue
git push <remote_repo> <remote_branch> -f

Remove commits from remote without removing from local

clean way of removing your commits from the remote repository without losing your work

git reset --soft HEAD~1 # 1 represents only last 1 commit 
git stash # hold your work temporary storage temporarily.
git pull # bring your local in sync with remote
git reset --hard HEAD~1 # hard reset 1 commit behind (deletes local commit)
git push -f # force push to sync local with remote
git stash pop # get back your unpushed work from stash