Search code examples
gitgit-alias

git alias arguments with default, without blocking the rest of the line


Here's my alias for interactively rebasing, by default onto the point where my branch diverged from develop.

git config --global alias.ri '!git rebase -i ${1-$(git merge-base HEAD origin/develop)} #'

Without commenting out the rest of the line with #, writing git ri develop would get me git rebase -i develop develop. But with the #, I cannot add other arguments such as -Xtheirs. How can I allow arguments with default values while also having any number of other arguments?

One approach would be to add a dozen arguments with empty defaults: ${2-} ${3-} and so on. But I'm hoping for something more elegant.


Solution

  • In the case of OP, simply replacing ${1- with ${@- works, since the rest of the arguments go right after the first. There are different ways to get all parameters: $@ vs $* vs "$@" vs "$*". See here for the differences.

    However, none of these ways work in another case: when I try to alias cf as config --global with default value -l. For example, git cf alias.rs 'restore -s': here $@ turns the arguments into alias.rs restore -s, losing the quotes. The same issue occurs if I write the alias as a shell function.

    It's better to let the alias look at the arguments without handling them directly, so you don't need to end with #:

    git config --global alias.cf '!if [[ -z $1 ]]; then arg="-l"; else arg=""; fi; git config --global $arg'
    

    Shorter version:

    git config --global alias.cf '!git config --global $([[ -z $1 ]] && echo -l)'