Last active
February 24, 2017 05:30
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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