X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=nogit;h=68420025c8dea9e6457e518c3b2b7bc4a01a93b4;hb=5834bcd7aebd13aa85167932053a535126de3fcb;hp=c71b7ab5762738a26ff9b259eaebe81403103f67;hpb=154e5546100e7141ce23903082528d7dab3d9c33;p=nogit diff --git a/nogit b/nogit index c71b7ab..6842002 100755 --- a/nogit +++ b/nogit @@ -1,4 +1,8 @@ #!/bin/bash +set -e + +NOGIT_DIR=.nogit +NOGIT_DIR_TMP=$NOGIT_DIR-tmp usage_brief() { @@ -52,12 +56,77 @@ usage() 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 @@ -71,19 +140,25 @@ cmd="$1" 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 $?