Skip to content

Instantly share code, notes, and snippets.

@hfossli
Last active June 27, 2018 04:56
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hfossli/7562257 to your computer and use it in GitHub Desktop.
Save hfossli/7562257 to your computer and use it in GitHub Desktop.
A bash script for fetching all branches and tags of a git project as snapshots into separate folders
#!/bin/bash
# Created by Håvard Fossli <hfossli@gmail.com> in 2013
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>
#
# Description
# A bash script for fetching all branches and tags of a git project as snapshots into separate folders
#
# Keywords
# Terminal, bash, unix, mac, shell, script, git, folders, directories, branch, branches, tag, tags, snapshot
#
function usage {
echo "For help and detailed guide type:"
echo "\$ $0 -h"
}
# Allow to be terminated with ctrl + c
trap "exit" INT
# Set variables and default values
OUT_FORMAT=''
REPO=''
VERBOSE=false
PLAY_SOUND=false
DRY_RUN=false
GET_TAGS=false
GET_BRANCHES=false
HELP=false
# Grab input arguments
while getopts “g:o:vptbhd” OPTION
do
case $OPTION in
g) REPO=$(echo "$OPTARG" | sed 's/ /\\ /g' ) ;;
o) OUT_FORMAT=$(echo "$OPTARG" | sed 's/ /\\ /g' ) ;;
v) VERBOSE=true ;;
p) PLAY_SOUND=true ;;
t) GET_TAGS=$(echo "$OPTARG" | sed 's/ /\\ /g' ) ;;
b) GET_BRANCHES=$(echo "$OPTARG" | sed 's/ /\\ /g' ) ;;
h) HELP=true ;;
d) DRY_RUN=true ;;
?) usage
exit 1
;;
esac
done
function detailed_guide {
echo "
Example gets all branches and tags:
\$ $0 -g git@github.com:hfossli/drmobile-integration.git -o ~/Desktop/drmobile-integration/branches/{{name}}/ -t -b
Flags:
-g Git repo
E.g. git@github.com:hfossli/drmobile-integration.git
-t Tags
-b Branches
-o Path to folder with format (string)
Possible variables:
- {{name}} (name of tag or branch)
- {{type}} ('tag' | 'branch')
E.g. ./path/{{name}}/ will produce ./path/develop/
-h Takes no arguments
Help - detailed guide
-d Takes no arguments
Dry-run (no actual writing)
"
}
if $HELP ; then
detailed_guide
exit 1
fi
if [[ -z $REPO ]] ; then
echo "Invalid git repo"
usage
exit 1
fi
if !$GET_TAGS && !$GET_BRANCHES ; then
echo "Specify wether you want branches or tags or both"
usage
exit 1
fi
TMP_DIR=$(mktemp -dt "git_branches_as_folders")
if $VERBOSE ; then
echo "Cloning repo $REPO to $TMP_DIR"
fi
git clone ${REPO} ${TMP_DIR}
if $VERBOSE ; then
echo "Looping over all branches:"
fi
local_git="git --git-dir=${TMP_DIR}/.git --work-tree=${TMP_DIR}/"
for branch in `$local_git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
branch_name=`echo $branch | sed -e "s/remotes\/origin\///g"`
folder=`echo $OUT_FORMAT | sed -e "s/{{name}}/$branch_name/g" | sed -e "s/{{type}}/branch/g" `
if $VERBOSE ; then
echo " Checking out branch $branch as $branch_name"
fi
$local_git checkout -b $branch $branch_name
if $VERBOSE ; then
echo " Creating directory: '$folder'";
fi
mkdir -p $folder
if $VERBOSE ; then
echo " Copying contents of folder $TMP_DIR to $folder";
fi
cp -R $TMP_DIR/* $folder
done
for tag in `$local_git tag -l`; do
tag_name=`echo $tag | sed -e "s/remotes\/origin\///g"`
folder=`echo $OUT_FORMAT | sed -e "s/{{name}}/$tag_name/g" | sed -e "s/{{type}}/tag/g" `
if $VERBOSE ; then
echo " Checking out tag $tag as $tag_name"
fi
$local_git checkout -b $tag $tag_name
if $VERBOSE ; then
echo " Creating directory: '$folder'";
fi
mkdir -p $folder
if $VERBOSE ; then
echo " Copying contents of folder $TMP_DIR to $folder";
fi
cp -R $TMP_DIR/* $folder
done
if $VERBOSE ; then
echo "Deleting temp folder";
fi
rm -rf $TMP_DIR
if $PLAY_SOUND ; then
# & means async
say "Done! ." &
fi
@lukeber4
Copy link

mktemp will not work on some distros:

mktemp [OPTION]... [TEMPLATE]

Create a temporary file or directory, safely, and print its name.
TEMPLATE must contain at least 3 consecutive `X's in last component.
If TEMPLATE is not specified, use tmp.XXXXXXXXXX, and --tmpdir is implied.

Fixed that, and it worked! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment