The project is available on GitHub, on the following link.
git-checkouter
is a tool that iterates on your parent Git folder, which includes all of your Git projects, and checkouts, lists, or rebase on top of master the given branch for each project.
What?
OK, it's a common practice to keep all of your work-related Git projects in some folder, let's say ~work
:
.
├── project1
├── project2
├── project3
├── project4
Now you are working on a ticket "xxx", and you changed projects 1, 2 and 4.
Imagine you have many more projects, and you're working on many more tickets. Now you want to run local tests for the feature "xxx", but you don't remember what projects you have changed for this feature:
$ ./git-checkouter.sh -p ~/work -b xxx -d
'xxx' found in 'project1'
'xxx' found in 'project2'
'xxx' found in 'project4'
providing -d
will only list which projects include the branch, and will not actually checkout.
It is also possible to set an environment variable: export PROJECTS_DIR=~/work
and omit the -p
flag.
After you saw which projects you changed for that specific feature, you can checkout the branch in all of them:
$ ./git-checkouter.sh -p ~/work -b xxx
project1: Switched to branch 'xxx'
project2: Switched to branch 'xxx'
project3: Switched to branch 'xxx'
project4: Switched to branch 'xxx'
If you want to ignore some projects, you can provide the -e
flag:
$ ./git-checkouter.sh -p ~/work -b master -e project2,project3
project1: Switched to branch 'xxx'
Project excluded: project2
Project excluded: project3
project4: Switched to branch 'xxx'
Sync all branches with the remote master using the -f
flag:
$ ./git-checkouter.sh -p ~/work -f
Rebasing project1: Current branch master is up to date.
Rebasing project2: Fast-forwarded xxx to origin/master.
Rebasing project3: Current branch xxx is up to date.
Rebasing project4: Current branch xxx is up to date.
The code:
#!/bin/bash
CYAN='\033[1;36m'
NC='\033[0m'
YELLOW='\033[0;33m'
display_usage() {
echo "Usage: $(basename "$0") [OPTIONS]"
echo ""
echo " -p path to your projects' dir. If not provided,"
echo " will use env variable 'PROJECTS_DIR'"
echo " -b git branch to checkout"
echo " -d only print projects that have the given branch,"
echo " without actually check it out"
echo " -e projects to exclude, separated by \",\" without spaces"
echo " -f rebase all directories on top of remote master branch"
echo ""
echo "Bugs and suggestions: <https://github.com/MarounMaroun/git-checkouter/issues>"
exit 1
}
projects=$PROJECTS_DIR
dry=''
branch=''
exclude=''
fetch=''
while getopts 'p:b:de:f' flag; do
case "${flag}" in
p)
projects=${OPTARG}
;;
b)
branch=${OPTARG}
;;
d)
dry="true"
;;
e)
exclude=${OPTARG}
;;
f)
fetch="true"
;;
*)
display_usage
exit 1
;;
esac
done
if [[ (-z "$branch" || -z "$projects") && "$fetch" != true ]]; then
echo "Error: both branch and projects dirs must be specified,"
echo "unless you're using -f flag"
echo ""
display_usage
fi
if [[ ! -z "$exclude" ]]; then
IFS=',' read -r exclude_projects <<< $exclude
fi
for d in $projects/*; do
project_name=$(basename $d)
if [[ ! -d "$d" ]]; then continue; fi
cd $d
if [ -d ".git" ]; then
if [[ "$fetch" = true ]]; then
printf "Rebasing branch ${CYAN}$(basename $d): ${NC}"
git fetch && git rebase origin/master
continue
fi
branches=$(git branch | cut -c 3-)
branch_found=$(echo $branches | grep -oP "\b$branch\b")
if [[ -z "$branch_found" ]]; then continue; fi
if [[ ! -z "$dry" ]]; then
printf "'$branch' found in ${CYAN}'$project_name'${NC}\n"
else
printf "${CYAN}$(basename $d): ${NC}"
project_name=$(basename $d)
if [[ $exclude_projects =~ .*$project_name.* ]]; then
printf "${YELLOW}Project excluded:${NC} $project_name\n"
continue
fi
git checkout $branch
fi
fi
done
Top comments (0)