hIpPy
hIpPy

Reputation: 5095

Is there a way to create a shortcut or alias for git option(s)

I find myself using --name-status option a lot with git log, git diff, git show. I'm aware of git aliases but they only work for a command or a combination of command and/or option(s). I do not want to create git aliases just for this option.

# l is an alias for log with pretty format
git l --name-status

So I can do something like this where --ns is shortcut for --name-status:

git l --ns

Update: See my own answer for the different considerations.

Upvotes: 1

Views: 218

Answers (3)

hIpPy
hIpPy

Reputation: 5095

I hope this hack is helpful to someone so posting it here. It's based on the answer to this question.

I could have created my own git commands ~/bin/git-<custom command> but preferred to change my existing git aliases as I backup my .gitconfig. git commands have the advantage of executing in the current directory when <path> is mentioned (no need for cd ${GIT_PREFIX:-.} mentioned below).

I pulled out the replace options logic into a helper fn options. It's then used for aliases l (log), d (diff), dt (difftool), etc. I intentionally kept that fn in gitconfig rather than a shell script so everything is in one place. It's easy to add new options to that fn too.

cd ${GIT_PREFIX:-.} is required to honor <path> for git aliases that execute as shell commands (see this). This is important for git log.

Note that shell commands will be executed from the top-level directory of a repository, which may not necessarily be the current directory.

I already had aliases for log, diff, difftool. It is not possible to have a git alias or custom git command to override a built-in git command and did not want to create one for show so I left out git show.

Before:

[alias]
    l       = !"cd ${GIT_PREFIX:-.} && git lg2"
    d       = diff
    dt      = difftool
    lg2     = # alias for log

After:

[alias]
    l       = "!f() { cd ${GIT_PREFIX:-.} && git lg2 $(git options "$@"); }; f"
    d       = "!f() { cd ${GIT_PREFIX:-.} && git diff $(git options "$@"); }; f"
    dt      = "!f() { cd ${GIT_PREFIX:-.} && git difftool $(git options "$@"); }; f"
    lg2     = # alias for log
    #workaround: helper fn to alias options
    options = "!f() { \
                echo "$@" \
                    | sed 's/\\s/\\n/g' \
                    | sed 's/^--ns$/--name-status/' \
                    | sed 's/^--no$/--name-only/' \
                    | xargs; \
            }; f"

So now I can do:

git l --ns
git d head~ --ns
git dt head~ --ns

# with paths:
git l --ns -- <path>
git d head~ --ns -- <path>
git dt head~ --ns -- <path>

Upvotes: 1

Pockets
Pockets

Reputation: 1264

Barring modifying the source code to recognize additional flags, your best bet is probably using aliases to rewrite the flag:

[alias]
    l = "!l() { : git log ; git log $(echo \"$@\" | sed \"s/--ns/--name-status/\") ; } && l"

Alternatively you can define some alias g in bash that will do this for you (you can configure auto-complete to work with this but I don't remember how to do that off the top of my head):

function g {
    git $(echo "$@" | sed "s/--ns/--name-status/")
}

Upvotes: 1

tehp
tehp

Reputation: 6394

I do not think aliasing command line arguments is possible.

Upvotes: 0

Related Questions