]> git.cworth.org Git - nogit/commitdiff
Implement "nogit clone"
authorCarl Worth <cworth@cworth.org>
Sun, 5 Jul 2020 05:44:09 +0000 (22:44 -0700)
committerCarl Worth <cworth@cworth.org>
Sun, 5 Jul 2020 05:49:39 +0000 (22:49 -0700)
This is logically just a git clone with the following two differences:

  1. It works in the current directory instead of making a new directory

  2. It puts its object store into .nogit instead of .git, (and it's just
     fine if there's already a .git here).

There are safety checks and it will refuse to clone in either of the
following cases:

  1. There is already a .nogit directory present

  2. Any of the working-tree files to be cloned already exist

nogit

diff --git a/nogit b/nogit
index c71b7ab5762738a26ff9b259eaebe81403103f67..b9a248e3f638ad9e2a203a1b8f77dd47601b4454 100755 (executable)
--- a/nogit
+++ b/nogit
@@ -1,4 +1,7 @@
 #!/bin/bash
+set -e
+
+NOGIT_DIR=.nogit
 
 usage_brief()
 {
@@ -52,7 +55,50 @@ usage()
 
 nogit_clone()
 {
-    echo "Internal error: 'nogit clone' not yet implemented"
+    url="$1"
+
+    if [ -e $NOGIT_DIR ]; then
+        echo "Error: .nogit already exists. Cowardly refusing to re-clone."
+        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
+
+    # 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()
@@ -71,19 +117,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 $?