Jo Liss
Jo Liss

Reputation: 32945

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

Upvotes: 40

Views: 25283

Answers (4)

Jo Liss
Jo Liss

Reputation: 32945

Use git ls-files:

$ cd lib
$ git ls-files --full-name test.c
lib/test.c

This only works for files that have been committed into the repo, but it's better than nothing.

Upvotes: 41

JBSnorro
JBSnorro

Reputation: 6726

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.

Upvotes: 1

YoungFrog
YoungFrog

Reputation: 1180

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.)

Upvotes: 3

gmatht
gmatht

Reputation: 835

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

Upvotes: 7

Related Questions