Junk Drawer

For all those little papers scattered across your desk


Git Branch Cheat

01 Jan 2017 in Code

Sometimes, you need to do a particular operation on every single branch in a repo, like pushing or merging. I thought it would be difficult. It’s not.

The Code (Script)

Preface: I do use Bash (no arguing about which shell is best), so this may not apply to everyone. I’m looking at you, Windows people.

for branch in $(ls .git/refs/heads); do
    git checkout $branch
    # git operation on branch
done

Update It has come to my attention that rather than parsing ls output, we can use globs.

for branch in .git/refs/heads/*; do
    branch="$(basename "$branch")"
    git checkout "$branch"
    # blah blah blah
done

Breaking It Down

The first part is a standard Bash for-loop. Lots of people caution against for loops on files this way, but we’re actually using filenames as branch names, and this is far more readable than using find.

The tricky part is $(ls .git/refs/heads). The $() bit means evaluate the parentheses as a shell command. The ls .git/refs/heads bit lists the files in .git/refs/heads, whose names are the names of branches.

Thus, we have a loop over the branch names. git checkout $branch is familiar to git cli users; simply checkout the branch. Then perform any operations on it you’d like. done signals the end of the loop.

Variations

You can optionally quote the branch listing into "$(ls .git/refs/heads)".

You can also follow done with another command, like checking out master again. You would then have done; git checkout master.

Uses

My most frequent uses are pushing all branches to remotes, and merging all branches with master. I only do this when I know it’s a fast-forward merge, but this makes it relatively easy to quickly update all branches with the lastest master developments (probably themselves merged in from one of the branches).


Tags:

Categories: Code

Previous Next