Generic script to recursively cd into directories and git pull

Hi all,

I'm trying to write a script to recursively cd into my Git projects and pull them, and will later expand it to build my projects as well.

I'm having a bit of trouble with my current script, as I want to supply a command line argument to tell it which branch to check out. I can hard code it to check out a specific branch but it's failing to take in my arguments.

My current script is:

#!/bin/bash
BRANCH=$2
echo "Checking out branch $BRANCH"
find . -type d -name .git -exec sh -c 'cd "$1"/../ && pwd && git checkout $BRANCH && git pull; echo "Branch being passed in: $BRANCH' _ '{}' "$BRANCH" \;

A snippet of the output when I run it from the top level of a directory containing many git projects is:

cows@Whiskey:~/windows/Workspace/git-projects/my-project$ ~/gitupdate.sh _ development
Checking out branch development
/home/cows/windows/Workspace/git-projects/my-project
Your branch is up-to-date with 'origin/master'.
Already up-to-date.
Branch being passed in:

So it looks like the -exec part of the script isn't pulling in my arguments and is just defaulting to the current branch. Any ideas on how to resolve this will be much appreciated. I don't mind if I have to rework how the script works entirely.

The recursive part of the script seems to work fine. If I run the script from ~/windows/Workspace/git-projects , it correctly descends into my-project , my-project-2 , my-other-project , etc.

Thanks in advance for any help.

Edit: Fixed formatting. Sorry mods!

Without digging deeper: text within single quotes ' won't be expanded by the shell. In your above construct, it's a bit difficult to tell what is to be expanded by the parent shell, and what were to be passed unaltered to the subshell. But almost for sure, the second will not know about $BRANCH if that is not exported.
So it might be worthwhile to

  • export variables for subshells
  • replace single by double quotes, but make sure double quotes intended for the subshell are escaped.
1 Like

Thanks for the pointer. I thought it would be something to do with that. I've got it working now after exporting $2 before calling the subshell.

#!/bin/bash
BRANCH=$2
export BRANCH
echo "Checking out branch $BRANCH"
find . -type d -name .git -exec sh -c 'cd "$1"/../ && pwd && git checkout "$BRANCH" && git pull; echo "Branch being passed in: $BRANCH"' _ '{}' "$BRANCH" \;