0

I have the following code in my .gitconfig file:

[alias]
  john = "!f(){ git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done; git fetch --all; git pull --all; };f"

Which is basically creating an alias for pulling every branch on the remote server. But is constantly trowing an error. Can someone help me understand what is going wrong, I've tried dissecting the command, but I can't find what is going wrong.

gespinha
  • 7,968
  • 16
  • 57
  • 91
  • 1
    What's the error? – Jeff Puckett Oct 19 '16 at 12:03
  • have you tried using single quotes ( `'` instead of `"` ) characters as outer delimiters for your command ? that or escaping your double quotes ( `\"` instead of `"`) *inside* the string. – LeGEC Oct 19 '16 at 12:52

1 Answers1

0

You need to escape embedded double quotes with backslashes. For instance:

[alias]
    next = "!f() { id=$(git rev-list --reverse --ancestry-path ..master | head -1); test -n \"$id\" && git checkout $id || echo 'no more commits'; }; f"

(which I actually have commented out since hardcoding master is bogus: this is a leftover from this answer).

You can also wrap long lines with backslash-newline:

    next = "!f() { \
        id=$(git rev-list --reverse --ancestry-path ..master | head -1); \
        test -n \"$id\" && git checkout $id || echo 'no more commits'; }; f"

(untested, but should work).

All that said, this is wrong:

Which is basically creating an alias for pulling every branch on the remote server.

Your sample alias attempts to create a new local branch for each remote-tracking branch (which is fine as far as it goes, but not possible in full generality, e.g., if you have both refs/remotes/origin/zorg and refs/remotes/evil/zorg, you cannot have local branch zorg track both remote-tracking branches). (For scripting purposes, it's better to use git for-each-ref here, but the existing loop should work well enough for your purposes.)

But, then you run git fetch --all, which means fetch from all remotes (fetch defaults to fetching from the "current" remote, which is pretty loosely defined as "the current branch's remote, or origin if the current branch has no remote set). Once the fetch finishes, you run git pull --all, which passes --all to git fetch again, then attempts to merge (or rebase) the current branch based on its configured remote and merge settings.

This therefore updates at most one of the branches you created in the while loop.

To merge-or-rebase each local branch, you need to loop over the local branches (again, preferably using git for-each-ref).

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775