#!/bin/bash
+set -e
+
+NOGIT_DIR=.nogit
+NOGIT_DIR_TMP=$NOGIT_DIR-tmp
usage_brief()
{
nogit_clone()
{
- echo "Internal error: 'nogit clone' not yet implemented"
+ url="$1"
+
+ if [ -e $NOGIT_DIR ]; then
+ echo "Error: $NOGIT_DIR already exists. Cowardly refusing to re-clone."
+ return 1
+ fi
+
+ if [ -e $NOGIT_DIR_TMP ]; then
+ echo "Error: $NOGIT_DIR_TMP already exists. Was a previous clone interrupted?"
+ echo "You'll want to clean that up before trying again."
+ return 1
+ fi
+
+ # Clone the repository into a temporary directory
+ mkdir $NOGIT_DIR_TMP
+ cd $NOGIT_DIR_TMP
+ git clone "$url" tmp >/dev/null 2>&1
+
+ # Sanity check that we won't be overwriting any files
+ EXISTING=()
+ cd tmp
+ for file in $(find . -mindepth 1 -a -path ./.git -prune -o -print); do
+ if [ -e "../../$file" ]; then
+ EXISTING+=($(echo "$file" | sed -s 's,^\./,,'))
+ fi
+ done
+ cd ..
+
+ if [ ${#EXISTING[@]} -gt 0 ]; then
+ echo "Error: The following existing files would be overwritten:" >&2
+ echo "" >&2
+ for file in ${EXISTING[@]}; do
+ echo " $file" >&2
+ done
+ echo "" >&2
+ echo "Cowardly refusing to clone" >&2
+ cd ..
+ rm -rf $NOGIT_DIR_TMP
+ false
+ fi
+
+ # Install the info/atttributes file that forces the "union" merge
+ # driver for all files, giving us the semantics of "keep both sides
+ # of all conflicts" that is at the heart of nogit.
+ mkdir -p tmp/.git/info
+ echo '* merge=union' > tmp/.git/info/attributes
+
+ # Now that we've passed the sanity check, install the cloned .git
+ # object store into $NOGIT_DIR, cleanup our temporary files, and
+ # checkout the (known to not be conflicting) files.
+ mv tmp/.git ../$NOGIT_DIR
+ cd ..
+ rm -rf $NOGIT_DIR_TMP
+ GIT_DIR=$NOGIT_DIR git reset --hard >/dev/null 2>&1
+
+ echo "Completed nogit clone of $url"
}
nogit_sync()
{
- echo "Internal error: 'nogit sync' not yet implemented"
+ # First commit any locally modified nogit files
+ GIT_DIR=$NOGIT_DIR git commit -a -m "nogit-sync commit" >/dev/null 2>&1 || true
+
+ # Then, fetch and merge any upstream changes
+ GIT_DIR=$NOGIT_DIR git fetch >/dev/null 2>&1
+ GIT_DIR=$NOGIT_DIR git merge -m "nogit-sync merge" >/dev/null 2>&1
+
+ # Finally, push any new commits up to the upstream repository
+ GIT_DIR=$NOGIT_DIR git push >/dev/null 2>&1
+
+ echo "Completed nogit sync"
}
if [ $# -lt 1 ]; then
case "$cmd" in
clone)
- nogit_clone
- ;;
+ if [ $# -lt 2 ]; then
+ echo "Error: 'nogit clone' requires the URL of a repository to clone"
+ false;
+ fi
+ nogit_clone "$2"
+ ;;
sync)
nogit_sync
- ;;
+ ;;
help)
usage
- exit 0
- ;;
+ true
+ ;;
*)
echo "Error: Unknown command: $cmd" >&2
echo ""
usage_brief >&2
- exit 1
+ false
;;
esac
+
+exit $?