Skip to content

Instantly share code, notes, and snippets.

@aleffert
Forked from inhies/subtree
Last active December 30, 2015 12:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aleffert/7831670 to your computer and use it in GitHub Desktop.
Save aleffert/7831670 to your computer and use it in GitHub Desktop.
#!/bin/bash
# subtree -- a utility to help working with git subtree's
# creator: inhies
# modified: aleffert
# 24 November 2013
version=1.1.2
function usage() {
case "$1" in
"")
echo "Usage: subtree <add | pull | rm | list | add-all-remotes>"
;;
"add")
echo "Usage: subtree add <remote name> <git url> <branch> <prefix>"
echo " Prefix is the directory path relative to root"
;;
"pull")
echo "Usage: subtree pull <prefix | 'all'>"
echo " Prefix is the directory path relative to root"
;;
"list")
echo "Usage: subtree list"
echo " Lists all known subtrees"
;;
"push")
echo "Usage: subtree push <prefix | 'all'>"
echo " Prefix is the directory path relative to root"
;;
"add-all-remotes")
echo "Usage: subtree add-remotes"
echo " Adds all the remotes from the subtree files"
echo " Prefix is the directory path relative to root"
;;
"rm")
echo "Usage: subtree rm <prefix>"
echo " Prefix is the directory path relative to root"
;;
esac
exit 1
}
# Check if we are in the root of a git repository.
isGit=$(git rev-parse --git-dir 2> /dev/null)
if [ ! -d .git ]; then
if [ "$isGit" == "" ]; then
# Check for a blank response, indicating a non-existant git repository.
echo "subtree: You are not within a git repository"
exit 1
else
# We are in a git repository, but not in the root of it, where we need to be.
echo "subtree: Subtree must be ran from within the git root directory, `dirname $isGit`"
exit 1
fi
exit
else
if [ "$isGit" != ".git" ]; then
# A .git folder exists in this directory, but git says we aren't actually in a repository.
echo "subtree: A .git directory exists, but this doesnt seem to be a valid git repository"
exit 1
fi
fi;
declare -a rawMap # Global associative array to hold raw .subtrees lines
# Load the subtrees file in to the map.
function loadSubtrees(){
if [ -f .subtrees ]
then
while read line
do
temparray=( $line )
rawMap[${temparray[0]}]=$line
done < "./.subtrees"
fi
}
function add() {
# Add the remote and return if there is an error
echo git remote add -f $1 $2
git remote add -f $1 $2
if [ "$?" -ne "0" ]; then
return
fi
echo git subtree add --prefix $4 $1 $3 --squash
git subtree add --prefix $4 $1 $3 --squash
# If there was an error adding the subtree, remove the remote we just added
if [ "$?" -ne "0" ]; then
git remote rm $1
return
fi
echo "$1 $2 $3 $4" >> .subtrees
git add .subtrees
git commit -m "Pull .subtrees for $1"
}
# name prefix
function remove() {
echo "subtree: Removing remote $1"
git remote rm $1
if [ "$?" -ne "0" ]; then
echo "subtree: Error removing remote $1"
return
fi
echo "subtree: Removing files from $4"
rm -rf ./$4
if [ "$?" -ne "0" ]; then
echo "subtree: Error removing files from $4"
git remote add -f $1 $2
return
fi
git rm -r $4
if [ "$?" -ne "0" ]; then
echo "subtree: Error removing files '$4' from git"
git remote add -f $1 $2
return
fi
sed -i ".bak" "/^$1/d" .subtrees
rm .subtrees.bak
if [ "$?" -ne "0" ]; then
echo "subtree: Error removing subtree $1 from .subtrees file"
git remote add -f $1 $2
return
fi
git add .subtrees
git commit -m "Removed subtree $1 from '$4'"
if [ "$?" -ne "0" ]; then
echo "subtree: Error commiting removal of subtree $1"
return
fi
}
function pull(){
git fetch $1 $3
if [ "$?" -ne "0" ]; then
return
fi
git subtree pull --prefix $4 $1 $3 --squash
}
function push(){
git subtree push --prefix $4 $1 $3 --squash
}
function add-remote() {
git remote add -f $1 $2
if [ "$?" -ne "0" ]; then
echo "Skipping $1"
fi
}
case "$1" in
"-v" | "--version")
echo "subtree version $version"
exit 0
;;
"pull")
loadSubtrees
case "$2" in
"all")
for v in "${rawMap[@]}"; do
pull $v
if [ "$?" -ne "0" ]; then
echo "subtree: error updating subtree:\n\t$v"
exit 1
fi
done
;;
*)
if [ "$2" == '' ]; then
usage "pull"
fi
if [ "${rawMap[$2]}" == "" ] ; then
echo "subtree: $2 is not a subtree item. Check .subtrees file"
exit 1
fi
pull ${rawMap[$2]}
if [ "$?" -ne "0" ]; then
echo "subtree: error updating subtree $2"
exit 1
fi
;;
esac
;;
"push")
loadSubtrees
case "$2" in
"all")
for v in "${rawMap[@]}"; do
push $v
if [ "$?" -ne "0" ]; then
echo "subtree: error updating subtree:\n\t$v"
exit 1
fi
done
;;
*)
if [ "$2" == '' ]; then
usage "push"
fi
if [ "${rawMap[$2]}" == "" ] ; then
echo "subtree: $2 is not a subtree item. Check .subtrees file"
exit 1
fi
push ${rawMap[$2]}
if [ "$?" -ne "0" ]; then
echo "subtree: error updating subtree $2"
exit 1
fi
;;
esac
;;
"add-all-remotes")
loadSubtrees
for v in "${rawMap[@]}"; do
add-remote $v
if [ "$?" -ne "0" ]; then
echo "subtree: error adding remote for subtree :\n\t$v"
exit 1
fi
done
;;
"list")
loadSubtrees
for v in "${rawMap[@]}"; do
echo $v
done
;;
"add")
loadSubtrees
if [ "${rawMap[$2]}" != "" ] ; then
echo "subtree: $2 already exists"
exit 1
fi
if [ "$5" == '' ]; then
usage "add"
fi
add $2 $3 $4 $5
if [ "$?" -ne "0" ]; then
echo "subtree: error adding subtree $2"
exit 1
fi
;;
"rm" | "remove")
if [ "$2" == '' ]; then
usage "rm"
fi
loadSubtrees
if [ "${rawMap[$2]}" == "" ] ; then
echo "subtree: $2 is not a subtree item. Check .subtrees file"
exit 1
fi
remove ${rawMap[$2]}
if [ "$?" -ne "0" ]; then
echo "subtree: error removing subtree $2"
exit 1
fi
;;
*)
usage
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment