'How to get the path of a file relative to the Git repository root?
Example:
$ cd lib
$ git absolute-path test.c # how to do this?
lib/test.c
Solution 1:[1]
Pasting the following into your bash terminal will work, regardless of whether "test.c" currently exists or not. You can copy the git-absolute-path function into your .bashrc file for future convenience.
git-absolute-path () {
fullpath=$([[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}")
gitroot="$(git rev-parse --show-toplevel)" || return 1
[[ "$fullpath" =~ "$gitroot" ]] && echo "${fullpath/$gitroot\//}"
}
git-absolute-path test.c
Solution 2:[2]
In order to get the path of the current directory, relative to the git root, I ended up doing this:
if gitroot=$(git rev-parse --show-toplevel 2>/dev/null); then
directory=$(realpath --relative-to="$gitroot" .)
fi
(I'm assuming Bash and I do not know how portable this is.)
Solution 3:[3]
I would like to improve on @gmatht's answer by making it work in an corner-case, by resolving the git root differently:
git-absolute-path () {
fullpath=$([[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}")
gitroot="$(echo $(cd $(git rev-parse --show-cdup) .; pwd))" || return 1
[[ "$fullpath" =~ "$gitroot" ]] && echo "${fullpath/$gitroot\//}"
}
The corner-case I'm referring to is when your git repo is in /tmp and you're on Windows. /tmp seems to be a special case: it refers to your Windows user's temp folder i.e. C:/Users/<user>/AppData/Local/Temp. (Not sure "how" it refers to that, it doesn't appear to be a symlink. Like I said, a special case). In any case, fullpath can be like /tmp/your-temp-repo but gitroot can be like C:/Users/<user>/AppData/Local/Temp/your-temp-repo but then they're not equal and git-absolute-path returns nothing incorrectly.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | YoungFrog |
| Solution 3 | JBSnorro |
