Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Manage repo-level dependencies with an encrypted manifest and a gitignored clone
A public observer sees only 'this repo uses modules' — no names, no pinned commits, no count.

![lang: bash](https://img.shields.io/badge/lang-bash-4EAA25?style=flat&logo=gnubash&logoColor=white)
[![tests: 135 passing](https://img.shields.io/badge/tests-135%20passing-brightgreen?style=flat)](test/)
[![tests: 136 passing](https://img.shields.io/badge/tests-136%20passing-brightgreen?style=flat)](test/)
![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=flat)

</div>
Expand Down Expand Up @@ -122,7 +122,7 @@ cd modules && mise trust && mise install
mise run test
```

**135 tests** across 13 suites, using [BATS](https://github.com/bats-core/bats-core). All tests use local git repos in temp directories — no network, no external dependencies.
**136 tests** across 13 suites, using [BATS](https://github.com/bats-core/bats-core). All tests use local git repos in temp directories — no network, no external dependencies.

The `git-mechanics` suite verifies git's behavior around gitignored nested repos. The `merge-driver` suite simulates concurrent pin bumps to validate the manifest merge logic. The `roundtrip` suite drives the full setup → add → lock → fresh-clone → unlock → init path end-to-end with git-crypt.

Expand Down
8 changes: 5 additions & 3 deletions lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,11 @@ sync_tracked_branch() {
fi

if git -C "$mod_path" show-ref --verify --quiet "refs/heads/$branch"; then
if ! git -C "$mod_path" checkout -q "$branch" 2>&1; then
echo " $name: failed to checkout local branch '$branch'" >&2
return 1
if [ "$current_branch" != "$branch" ]; then
if ! git -C "$mod_path" checkout -q "$branch" 2>&1; then
echo " $name: failed to checkout local branch '$branch'" >&2
return 1
fi
fi
else
if ! git -C "$mod_path" checkout -q -b "$branch" --track "origin/$branch" 2>&1; then
Expand Down
17 changes: 17 additions & 0 deletions test/init.bats
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,23 @@ setup() {
[ "$upstream" = "origin/main" ]
}

@test "init skips checkout hook when tracked clone is already on target branch" {
modules add "$REMOTE" --name tracked --track main
git -C "$PARENT" commit -m "add tracked module"

local hook_log="$BATS_TEST_TMPDIR/post-checkout-fired"
cat > "$PARENT/modules/tracked/.git/hooks/post-checkout" <<EOF
#!/usr/bin/env bash
printf 'post-checkout fired\n' >> "$hook_log"
EOF
chmod +x "$PARENT/modules/tracked/.git/hooks/post-checkout"

run modules init
[ "$status" -eq 0 ]
[[ "$output" == *"tracking main"* ]]
[ ! -e "$hook_log" ]
}

@test "init refuses dirty tracked clones" {
modules add "$REMOTE" --name tracked --track main

Expand Down
Loading