Stella
Stella

Reputation: 2633

Git Alias - Multiple Commands and Parameters

I am trying to create an alias that uses both multiple Git commands and positional parameters. There are Stackoverflow pages for each, and it would appear painfully obvious to do both, but I am having trouble.

As an example, I want to switch to branch foo and perform a status. So in my .gitconfig, I have:

  [alias] 
     chs = !sh -c 'git checkout $0 && git status'

which doesn't work. Whereas something like this will work.

chs = !sh -c 'git checkout $0'

echoes = !sh -c 'echo hi && echo bye'

Any insight would be appreciated.

Upvotes: 263

Views: 113032

Answers (13)

cmu = "!f() { git add . && git commit -m $1 && git push -u origin $2; }; f"

Upvotes: 0

crowx
crowx

Reputation: 1

As far as Lily Ballard have a good answer with a shell function, it looks better when we pipe all the alias arguments:

[alias] chs = "!f(){ git checkout \"${@:1}\" && git status; };f"

Upvotes: 0

Mageician
Mageician

Reputation: 2927

This is an old post, but no one has provided what I think is the simplest solution. This works in my *nix-based CLI, your mileage may vary.

[alias]
    chs = "!git checkout $1; git status"

A simple semi-colon (;) is all you need to run multiple git commands.

Upvotes: 1

Eng_Farghly
Eng_Farghly

Reputation: 3017

[alias]
      chs = !git checkout && git status
      ac = !git add . && git commit -m 

what is ! ?

If the alias expansion is prefixed with an exclamation point, it will be treated as a shell command. What does the exclamation mark mean in git config alias?

To call alias from .gitconfig file

git chs
git ac "write_your_commit_message" 

alias is more useful for add and commit in git you can do more fast Gif show more datails

Upvotes: 15

imme
imme

Reputation: 645

An example for people who want to try out what different aliases do.

Putting this in the alias-section of GIT's configuration-file (e.g. ~/.gitconfig) :

[alias]
    a0 = "!echo $*"
    a1 = "!echo $* #"
    a2 = "!f () { echo \"$*\"; }; f "
    a3 = "!f () { echo \"$*\"; }; f #"
    a4 = "!f () { echo \"$*\"; }; f \"$*\" #"
    a5 = "!f () { echo \"$*\"; }; f \"$@\" #"
    a6 = "!f () { echo \"$*\"; }; f \"$1\" #"

And then executing this command:

cat ~/.gitconfig | grep --extended-regexp -- '(a[0-9])|(alias)' ; \
echo "" ; \
export CMD ; \
for I in {0..6} ; \
do \
    CMD="a""${I}" ; \
    echo -n "Executing alias.${CMD} = " ; \
    git config --global alias."${CMD}" ; \
    git $CMD 'hoi daar' en nu ; \
    git $CMD hoi daar en nu ; \
    echo "" ; \
done ; \
unset CMD ;

Should give this as output:

[alias]
    a0 = "!echo $*"
    a1 = "!echo $* #"
    a2 = "!f () { echo \"$*\"; }; f "
    a3 = "!f () { echo \"$*\"; }; f #"
    a4 = "!f () { echo \"$*\"; }; f \"$*\" #"
    a5 = "!f () { echo \"$*\"; }; f \"$@\" #"
    a6 = "!f () { echo \"$*\"; }; f \"$1\" #"

Executing alias.a0 = !echo $*
hoi daar en nu hoi daar en nu
hoi daar en nu hoi daar en nu

Executing alias.a1 = !echo $* #
hoi daar en nu
hoi daar en nu

Executing alias.a2 = !f () { echo "$*"; }; f 
hoi daar en nu
hoi daar en nu

Executing alias.a3 = !f () { echo "$*"; }; f #



Executing alias.a4 = !f () { echo "$*"; }; f "$*" #
hoi daar en nu
hoi daar en nu

Executing alias.a5 = !f () { echo "$*"; }; f "$@" #
hoi daar en nu
hoi daar en nu

Executing alias.a6 = !f () { echo "$*"; }; f "$1" #
hoi daar
hoi

Upvotes: 4

Brondahl
Brondahl

Reputation: 8597

This targets Windows batch / msysgit bash; might not work on other environments.

As Olivier Verdier and Lily Ballard have said

[alias] chs = !git checkout $1 && git status

almost works, but gives a spurious extra insertion of the argument ...

git chs demo -> git checkout demo && git status demo

But if you add && : to the end of your alias, then the spurious argument is consumed into a location tag.

So

[alias] chs = !git checkout $1 && git status && :

gives the correct output ... git chs demo -> git checkout demo && git status

Upvotes: 143

Lily Ballard
Lily Ballard

Reputation: 185841

You can define a shell function.

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"

Upvotes: 97

VitalyB
VitalyB

Reputation: 12855

I was able to create multi-line and quite complex git aliases. They work fine on Windows but I assume they'd work elsewhere too, for example:

safereset = "!f() { \
                trap 'echo ERROR: Operation failed; return' ERR; \
                echo Making sure there are no changes...; \
                last_status=$(git status --porcelain);\
                if [[ $last_status != \"\" ]]; then\
                    echo There are dirty files:;\
                    echo \"$last_status\";\
                    echo;\
                    echo -n \"Enter Y if you would like to DISCARD these changes or W to commit them as WIP: \";\
                    read dirty_operation;\
                    if [ \"$dirty_operation\" == \"Y\" ]; then \
                        echo Resetting...;\
                        git reset --hard;\
                    elif [ \"$dirty_operation\" == \"W\" ]; then\
                        echo Comitting WIP...;\
                        git commit -a --message='WIP' > /dev/null && echo WIP Comitted;\
                    else\
                        echo Operation cancelled;\
                        exit 1;\
                    fi;\
                fi;\
            }; \
            f"

I wrote a post and have a few more examples here.

Upvotes: 41

Ben Collins
Ben Collins

Reputation: 20686

The problem here is that the positional parameters seem to be getting sent to the shell command twice (as of git 1.9.2). To see what I mean, try this:

[alias]
  test = !git echo $*

Then, do git test this is my testing string. You should observe the following output (last two lines edited here for clarity):

03:41:24 (release) ~/Projects/iOS$ git test this is my testing string
this is my testing string this is my testing string
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
          #1                         #2

One way to work around this would be to

[alias]
  chs = !git checkout $1 && git status && git echo x >/dev/null

This will consume the extra positional parameter as it gets applied to that last echo command and have no effect on the results.

Upvotes: 5

gmarik
gmarik

Reputation: 156

It's possible to have multiline git alias by appending \ at the end of each line.

[alias] 
   chs = "!git checkout $1 \ 
          ; git status     \
         "

Upvotes: 7

brocksamson
brocksamson

Reputation: 812

Try this one:

[alias]
    chs = "!sh -c 'git checkout \"$0\" && git status'"

Call it like this: git chs master

Upvotes: 7

FractalSpace
FractalSpace

Reputation: 5685

[alias]
chs = !git branch && git status

Upvotes: 29

Olivier Verdier
Olivier Verdier

Reputation: 49246

This will work (tested with zsh and bash):

[alias] chs = !git checkout $1 && git status

Upvotes: 211

Related Questions