summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Burda <dev@sinitax.com>2025-10-28 22:42:35 +0100
committerLouis Burda <dev@sinitax.com>2025-10-28 22:42:35 +0100
commit5eeabd971076975ffa60560a7a9623e6bb6bcfb7 (patch)
treec6c00d1e3111e0554eb9437440d8a1e8bd87ab90
parent64c4396bca419044bbf591077eb030df3171ebf2 (diff)
downloadsubgit-master.tar.gz
subgit-master.zip
Allow extracting remote info from existing git repoHEADmaster
-rwxr-xr-xsrc/subgit-add50
-rwxr-xr-xtests/test-add-path.sh114
2 files changed, 157 insertions, 7 deletions
diff --git a/src/subgit-add b/src/subgit-add
index 1411dc8..e1e0d19 100755
--- a/src/subgit-add
+++ b/src/subgit-add
@@ -2,11 +2,14 @@
usage() {
die $(cat <<-EOF
- Usage: subgit add [-c COMMIT] [-b BRANCH] [ARG..] REMOTE DEST
+ Usage: subgit add [-c COMMIT] [-b BRANCH] REMOTE DEST
+ subgit add [-c COMMIT] [-b BRANCH] PATH
- Begin tracking a remote repository, optionally at a specific branch
- or commit, as a subgit repo in the current path. Can also be used
- to add an existing repos.
+ Begin tracking a remote repository, optionally at a specific branch
+ or commit, as a subgit repo in the current path.
+
+ REMOTE DEST: Clone from remote URL to destination path
+ PATH: Add existing local repo, extracting remote/commit from it
EOF
)
}
@@ -24,9 +27,42 @@ while [ "$1" ]; do
*) break;;
esac
done
-[ $# -ne 2 ] && usage
-remote=$1
-path=$(realpath -m $2)
+
+if [ $# -eq 1 ]; then
+ # Single argument - existing local repo
+ if [ ! -d "$1" ]; then
+ die "Directory does not exist: $1"
+ fi
+
+ path=$(realpath "$1")
+
+ if [ ! -d "$path/.git" ]; then
+ die "Not a git repository: $path"
+ fi
+
+ # Extract remote URL from existing repo
+ remote=$(git -C "$path" remote get-url origin 2>/dev/null || echo "")
+ if [ -z "$remote" ]; then
+ die "No remote 'origin' found in $path"
+ fi
+
+ # Extract current branch if not specified with -b
+ if [ -z "$branch" ]; then
+ branch=$(git -C "$path" branch --show-current)
+ fi
+
+ # Extract current commit if not specified with -c
+ if [ -z "$commit" ]; then
+ commit=$(git -C "$path" rev-parse HEAD)
+ fi
+
+elif [ $# -eq 2 ]; then
+ # Two arguments - remote and destination (original behavior)
+ remote=$1
+ path=$(realpath -m "$2")
+else
+ usage
+fi
root=$(realpath .)
[ "${path#$root/}" = "$path" ] && die "Not a subdirectory"
diff --git a/tests/test-add-path.sh b/tests/test-add-path.sh
new file mode 100755
index 0000000..3a6a6a7
--- /dev/null
+++ b/tests/test-add-path.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+set -e
+
+# Setup: Add src directory to PATH and create isolated test directory
+SRCDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../src" && pwd)"
+export PATH="$SRCDIR:$PATH"
+
+TESTDIR=$(mktemp -d)
+trap "rm -rf '$TESTDIR'" EXIT
+
+cd "$TESTDIR"
+
+echo "=== Test: subgit add with single path argument ==="
+
+# Step 1: Create an upstream repository
+mkdir -p upstream/repo1
+cd upstream/repo1
+git init
+git config user.email "test@test.com"
+git config user.name "Test User"
+echo "test content" > file1.txt
+git add file1.txt
+git commit -m "Initial commit"
+REPO_COMMIT=$(git rev-parse HEAD)
+REPO_BRANCH=$(git branch --show-current)
+UPSTREAM_PATH=$(pwd)
+cd "$TESTDIR"
+
+# Step 2: Create parent repo
+mkdir parent
+cd parent
+git init
+
+# Step 3: Clone the repo inside parent to create a local copy with .git
+git clone ../upstream/repo1 myrepo
+
+# Step 4: Add the local copy using single-path syntax
+subgit add myrepo
+
+# Step 5: Verify that the repo was added correctly
+
+# Check that .subgitrc was created
+if [ ! -f .subgitrc ]; then
+ echo "FAIL: .subgitrc not created"
+ exit 1
+fi
+
+# Check that remote was extracted correctly (git clone sets it to the path cloned from)
+source .subgitrc
+EXPECTED_REMOTE="$TESTDIR/parent/../upstream/repo1"
+if [ "${subgitinfo[myrepo/remote]}" != "$EXPECTED_REMOTE" ]; then
+ echo "FAIL: remote not extracted correctly (expected $EXPECTED_REMOTE, got ${subgitinfo[myrepo/remote]})"
+ exit 1
+fi
+
+# Check that branch was extracted correctly
+if [ "${subgitinfo[myrepo/branch]}" != "$REPO_BRANCH" ]; then
+ echo "FAIL: branch not extracted correctly (expected $REPO_BRANCH, got ${subgitinfo[myrepo/branch]})"
+ exit 1
+fi
+
+# Check that commit was extracted correctly
+if [ "${subgitinfo[myrepo/commit]}" != "$REPO_COMMIT" ]; then
+ echo "FAIL: commit not extracted correctly (expected $REPO_COMMIT, got ${subgitinfo[myrepo/commit]})"
+ exit 1
+fi
+
+# Check that .git was moved to .subgit/
+if [ ! -d .subgit/myrepo ]; then
+ echo "FAIL: bare repo not created in .subgit/"
+ exit 1
+fi
+
+# Check that .git is now a symlink
+if [ ! -L myrepo/.git ]; then
+ echo "FAIL: .git symlink not created"
+ exit 1
+fi
+
+# Check that files are still accessible
+if [ ! -f myrepo/file1.txt ]; then
+ echo "FAIL: file1.txt not present in working directory"
+ exit 1
+fi
+
+echo "=== Test: add path with explicit commit override ==="
+
+# Clone another repo inside parent
+git clone ../upstream/repo1 myrepo2
+cd myrepo2
+echo "new content" > file2.txt
+git add file2.txt
+git commit -m "Second commit"
+SECOND_COMMIT=$(git rev-parse HEAD)
+cd ..
+
+# Add with explicit commit (should use the specified commit, not HEAD)
+subgit add -c "$REPO_COMMIT" myrepo2
+
+source .subgitrc
+if [ "${subgitinfo[myrepo2/commit]}" != "$REPO_COMMIT" ]; then
+ echo "FAIL: explicit commit not used (expected $REPO_COMMIT, got ${subgitinfo[myrepo2/commit]})"
+ exit 1
+fi
+
+# Working directory should be at the specified commit
+ACTUAL_COMMIT=$(git -C myrepo2 rev-parse HEAD)
+if [ "$ACTUAL_COMMIT" != "$REPO_COMMIT" ]; then
+ echo "FAIL: working directory not at specified commit"
+ exit 1
+fi
+
+echo "PASS: add path test"