2

I am trying to create a global git alias to delete a local and a remote copy of a branch in one command. I would like the alias to take the following input:

$ git purge myBranch

And generate the following commands:

$ git branch -d myBranch
$ git push origin --delete myBranch

Among many other attempts, I've tried this:

$ git config alias.purge '!sh "git branch -d $1; git push origin --delete $1"'

But I get this error:

sh: 0: Can't open git branch -d myBranch; git push origin --delete myBranch
fatal: While expanding alias 'purge': 'sh "git branch -d $1; git push origin --delete $1"': No such file or directory

How can I create a global git alias that accepts an argument and forwards it to two separate git commands in this fashion?

Update:

Per @Chris' suggestion I've tried out the following:

git config --global alias.purge '!git branch -d $1 && git push origin --delete $1'

Here is the result:

$ git purge test
warning: deleting branch 'test' that has been merged to
         'refs/remotes/origin/test', but not yet merged to HEAD.
Deleted branch test (was 1316434).
error: dst ref refs/heads/test receives from more than one src.
error: failed to push some refs to 'git@github.com:testrepo/repo.git'

I've confirmed that this works properly if I run the commands directly:

$ git branch -d test && git push origin --delete test
warning: deleting branch 'test' that has been merged to
         'refs/remotes/origin/test', but not yet merged to HEAD.
Deleted branch test (was b610eca).
To git@github.com:testrepo/repo.git
 - [deleted]         test
Jake
  • 7,565
  • 6
  • 55
  • 68

1 Answers1

4

Edit:

My original answer will probably work in most cases, but it looks like the repetition of positional argument $1 is generating a strange doubling effect.

For example:

git config --global alias.foo '!echo $1 && echo $1'
git foo bar
# bar
# bar bar

In this case it seems that the old shell function technique works better:

git config alias.purge '!f() { git branch -d $1 && git push origin --delete $1; }; f'

This technique used to be very common, but became unnecessary for most use cases sometime before 1.8.2.1.

Original answer:

I have a similar alias in my ~/.gitconfig file. Mine doesn't invoke sh, and it uses && instead of ; to ensure that the second command only runs if the first one succeeds.

Something like this should work for you:

[alias]
        purge = "git branch -d $1 && git push origin --delete $1"

Using git config:

git config alias.purge '!git branch -d $1 && git push origin --delete $1'
Community
  • 1
  • 1
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
  • Here is the error I get when I use the latter config option: "Expansion of alias 'purge' failed; '!git branch -d $1 && git push origin --delete $1' is not a git command". I'm particularly interested in the config command since I need to automate the process of creating the alias. – Jake Jun 30 '15 at 13:27
  • @Jake, what if you remove the inner quotes, i.e. `git config alias.purge '!git branch -d $1 && git push origin --delete $1'`? – ChrisGPT was on strike Jun 30 '15 at 16:03
  • This is closer - updated my question. I will play around with this some more as soon as I have a chance, you've definitely helped get me in the right direction. – Jake Jul 01 '15 at 11:39
  • @Jake, I did some more testing and found a strange doubling effect when using the same positional argument (`$1`) in both commands. See if this works: `git config alias.purge '!f() { git branch -d $1 && git push origin --delete $1; }; f'`. It seems to do the trick for me. If it works for you I'll update my answer. – ChrisGPT was on strike Jul 01 '15 at 14:23
  • @Chris answer works well for me. I created this: '!f() { git branch $1 && git checkout $1; }; f' and it works like a charm – Jesse Liberty Nov 13 '20 at 21:55