How to get file's relative path in git aliases with parameters?
Asked Answered
S

1

5

I have the following aliases in my .gitconfig:

[alias]
  lg = log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
  log-between = "!f() { git lgl `git merge-base $2 $1`..$2 -- $3 ; }; f"
  log-between-p = "!g() { git lgl -p $(git merge-base $2 $1)..$2 -- $3 ; }; g"
  diff-between = "!h() { echo $(pwd); git diff $(git merge-base $2 $1) $2 -- $3 ; }; h"

While it works fine in most of the cases the problem arises when I would like to get a log of a file (or a path) passing in the third parameter ($3) to diff-between.

The issue is that the command (h in this example) is being executed in the root directory of this repository (that's why I added pwd printing for checking) and I am passing in the name of the file or a path with a name but not always the absolute path.

E.g.

When I run this alias (added command printing to check to what command it will expand):

  diff-between = "!h() { echo $(pwd); echo "git diff $(git merge-base $2 $1) $2 -- $3" ; }; h"

under repo_root_dir/src/ like so:

git diff-between origin/master my_branch

I will get:

git diff 66efa91ba8c74aa624d05d9ec0b13cc93cbfb6d3 my_branch --

which is fine. But when I run this like so (with a file):

git diff-between origin/master my_branch some_other_subdir/src/Base.cpp

I will get:

git diff 66efa91ba8c74aa624d05d9ec0b13cc93cbfb6d3 my_branch -- some_other_subdir/src/Base.cpp

regardless of where this command has been run from (NOTE: bear in mind that this is run from the root_dir of this repo)


How to properly get the current directory so that:

  • having file root_dir/src/some_other_subdir/Base.cpp
  • when I'm in root_dir/src and run my alias with some_other_subdir/Base.cpp parameter I get the following result
  • NOTE: pwd inside git alias will return root_dir
Sheba answered 1/9, 2015 at 8:52 Comment(3)
not so sure about this. but, can you maybe try to change the diff-between alias into something like this? "!h() { echo $(pwd); git diff $(git merge-base $2 $1) $2 -- $(git rev-parse --show-toplevel)\/$3 ; }; h"Rascality
@Rascality $(git rev-parse --show-toplevel) this will show the absolute path to root dir of repo which is easy to get e.g. by $(pwd) since this will be the directory from which the commands will be executed.Sheba
aaa. ok, I think I'm confused on what you want here.Rascality
B
9

Git aliases are normally executed within the current directory. Except git aliases that execute in a shell (start with !). If a shell is started the shell's working dir will be the repository root.

Use the ${GIT_PREFIX:-./} variable. It will resolve to the absolute repository path of the current directory.

diff-between = "!h() { git diff $(git merge-base $2 $1) $2 -- ${GIT_PREFIX:-./}$3 ; }; h"
Barre answered 1/9, 2015 at 10:54 Comment(4)
You sir are a true genius :) Where did you get the info about that 'variable'?Sheba
From the release notes... ;) See github.com/git/git/blob/…Clothesline
But you can also use the git command git rev-parse --show-prefixClothesline
Thanks! I had to add cd ${GIT_PREFIX:-./}; to the beginning of my alias because it didn't take relative paths.Agnomen

© 2022 - 2024 — McMap. All rights reserved.