diff options
| author | Louis Burda <dev@sinitax.com> | 2025-10-28 22:42:35 +0100 |
|---|---|---|
| committer | Louis Burda <dev@sinitax.com> | 2025-10-28 22:42:35 +0100 |
| commit | 5eeabd971076975ffa60560a7a9623e6bb6bcfb7 (patch) | |
| tree | c6c00d1e3111e0554eb9437440d8a1e8bd87ab90 | |
| parent | 64c4396bca419044bbf591077eb030df3171ebf2 (diff) | |
| download | subgit-master.tar.gz subgit-master.zip | |
| -rwxr-xr-x | src/subgit-add | 50 | ||||
| -rwxr-xr-x | tests/test-add-path.sh | 114 |
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" |
