Example:
$ cd lib
$ git absolute-path test.c # how to do this?
lib/test.c
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.
 
    
    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
 
    
    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.)
 
    
    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.
