Skip to content

Instantly share code, notes, and snippets.

@sunsong
Last active February 24, 2017 05:30
Show Gist options
  • Save sunsong/5cf351372b9fb2c296417a7b5cf4b49e to your computer and use it in GitHub Desktop.
Save sunsong/5cf351372b9fb2c296417a7b5cf4b49e to your computer and use it in GitHub Desktop.
Stash all changes in each git folder, make those folders bare repositories in a root folder
#!/bin/bash
#################
#
# Author: Song Sun
# Github: https://github.com/sunsong
# Date: Aug 31, 2016
# Description: Stash all changes in each git folder, make those folders bare repositories in a root folder
# Feature:
# * Make a git repository to a bare repository
# * Stash all the changes in the current repository, which can be recovered to the original state.
# * Remove all tracked files for disk space optimization, which also can be recovered.
# * The untracked files will be stashed and can be recovered.
# * Git repository in the subfolder of an to-be-processed git repository will be untouched.
# * Irrelevant files will not be touched or removed.
#################
function echo_usage {
echo "This script stash all changes in each git folder in a root folder, make those folders bare repositories."
echo "Usage: ./git-barify.sh <barify|unbarify> <root-dir>"
}
if [ "$1" != "barify" ] && [ "$1" != "unbarify" ]; then
echo "Incorrect behavior provided!"
echo_usage
exit 1
fi
if [ -z "$2" ]; then
echo "No folder location provided!"
echo_usage
exit 1
fi
cd $2
root=$(pwd)
# Create a temporary folder works both in Linux & Mac OS
function create_tmp_folder {
tmp_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'barify')
}
# Remove the temporary folder.
function remove_tmp_folder {
rmdir $tmp_dir
}
function barify {
echo "Start processing $1"
cd $root/$1
git status 2>/dev/null 1>/dev/null
rc=$?
if [ $rc = 0 ]; then
git_stash_all
# Remove files and folders tracked in this repository.
remove_tracked_files
git_barify
git_mv_to_temp
git_mv_from_temp $1
rmdir $root/$1
fi
cd $root
echo "Finish processing $1"
}
function unbarify {
cd $root/$1
if [ "$(git rev-parse --is-bare-repository)" == "true" ]; then
echo "Start processing $1"
git_unbarify .
cd $root
folder=${1%.git}
mkdir -p $root/$folder
mv $root/$1 $root/$folder/.git
cd $root/$folder && git checkout .
git_unstash_all
echo "Finish processing $1"
fi
cd $root
}
function git_stash_all {
git stash save --all
}
function git_unstash_all {
git stash pop
}
# Trick got from http://superuser.com/questions/442625/git-delete-all-tracked-files
function remove_tracked_files {
git ls-files -z | xargs -0 rm -f
git ls-tree --name-only -d -r -z HEAD | sort -rz | xargs -0 rmdir
}
function git_barify {
git --git-dir=.git config core.bare true
}
function git_unbarify {
git --git-dir=$1 config core.bare false
}
function git_mv_to_temp {
create_tmp_folder
mv .git $tmp_dir/
}
function git_mv_from_temp {
mv $tmp_dir/.git $root/$1.git
remove_tmp_folder
}
files=$(ls -A)
if [ "$1" == "barify" ]; then
for file in $files; do
if [ -d "$file" ]; then
barify $file
fi
done
fi
if [ "$1" == "unbarify" ]; then
for file in $files; do
if [[ "$file" == *.git ]]; then
unbarify $file
fi
done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment