From 9a806c09cbe5a9a851e8cab3e00dd8da5b28ac1d Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Fri, 8 Dec 2023 11:06:30 -0800 Subject: [PATCH] Bug: links are relative to linkdir, not rootdir --- abspath.go | 3 +- main.go | 5 ++- test_e2e.sh | 120 +++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 95 insertions(+), 33 deletions(-) diff --git a/abspath.go b/abspath.go index 66468f8..793505b 100644 --- a/abspath.go +++ b/abspath.go @@ -48,7 +48,8 @@ func (abs absPath) Canonical() (absPath, error) { return absPath(result), nil } -// Join appends more path elements to abs, like filepath.Join. +// Join appends more path elements to abs, like filepath.Join. This will clean +// the final path (e.g. resolve ".." elements). func (abs absPath) Join(elems ...string) absPath { all := make([]string, 0, 1+len(elems)) all = append(all, abs.String()) diff --git a/main.go b/main.go index 2cf6209..1c2f5a4 100644 --- a/main.go +++ b/main.go @@ -1277,7 +1277,7 @@ func (git *repoSync) publishSymlink(ctx context.Context, worktree worktree) erro return fmt.Errorf("error making symlink dir: %w", err) } - // newDir is absolute, so we need to change it to a relative path. This is + // linkDir is absolute, so we need to change it to a relative path. This is // so it can be volume-mounted at another path and the symlink still works. targetRelative, err := filepath.Rel(linkDir, targetPath.String()) if err != nil { @@ -1573,7 +1573,8 @@ func (git *repoSync) currentWorktree() (worktree, error) { if filepath.IsAbs(target) { return worktree(target), nil } - return worktree(git.root.Join(target)), nil + linkDir, _ := git.link.Split() + return worktree(absPath(linkDir).Join(target)), nil } // SyncRepo syncs the repository to the desired ref, publishes it via the link, diff --git a/test_e2e.sh b/test_e2e.sh index a7d657f..884f36d 100755 --- a/test_e2e.sh +++ b/test_e2e.sh @@ -411,36 +411,6 @@ function e2e::init_root_fails_sanity() { assert_file_eq "$ROOT/link/file" "$FUNCNAME" } -############################################## -# Test init with an absolute-path link -############################################## -function e2e::sync_absolute_link() { - GIT_SYNC \ - --one-time \ - --repo="file://$REPO" \ - --root="$ROOT/root" \ - --link="$ROOT/other/dir/link" - assert_file_absent "$ROOT/root/link" - assert_link_exists "$ROOT/other/dir/link" - assert_file_exists "$ROOT/other/dir/link/file" - assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME" -} - -############################################## -# Test init with a subdir-path link -############################################## -function e2e::sync_subdir_link() { - GIT_SYNC \ - --one-time \ - --repo="file://$REPO" \ - --root="$ROOT" \ - --link="other/dir/link" - assert_file_absent "$ROOT/link" - assert_link_exists "$ROOT/other/dir/link" - assert_file_exists "$ROOT/other/dir/link/file" - assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME" -} - ############################################## # Test non-zero exit with a bad ref ############################################## @@ -539,6 +509,96 @@ function e2e::sync_head() { assert_metric_eq "${METRIC_FETCH_COUNT}" 3 } +############################################## +# Test sync with an absolute-path link +############################################## +function e2e::sync_head_absolute_link() { + # First sync + echo "$FUNCNAME 1" > "$REPO/file" + git -C "$REPO" commit -qam "$FUNCNAME 1" + + GIT_SYNC \ + --period=100ms \ + --repo="file://$REPO" \ + --ref=HEAD \ + --root="$ROOT/root" \ + --link="$ROOT/other/dir/link" \ + & + wait_for_sync "${MAXWAIT}" + assert_file_absent "$ROOT/root/link" + assert_link_exists "$ROOT/other/dir/link" + assert_file_exists "$ROOT/other/dir/link/file" + assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME 1" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 1 + assert_metric_eq "${METRIC_FETCH_COUNT}" 1 + + # Move HEAD forward + echo "$FUNCNAME 2" > "$REPO/file" + git -C "$REPO" commit -qam "$FUNCNAME 2" + wait_for_sync "${MAXWAIT}" + assert_file_absent "$ROOT/root/link" + assert_link_exists "$ROOT/other/dir/link" + assert_file_exists "$ROOT/other/dir/link/file" + assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME 2" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 2 + assert_metric_eq "${METRIC_FETCH_COUNT}" 2 + + # Move HEAD backward + git -C "$REPO" reset -q --hard HEAD^ + wait_for_sync "${MAXWAIT}" + assert_file_absent "$ROOT/root/link" + assert_link_exists "$ROOT/other/dir/link" + assert_file_exists "$ROOT/other/dir/link/file" + assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME 1" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 3 + assert_metric_eq "${METRIC_FETCH_COUNT}" 3 +} + +############################################## +# Test sync with a subdir-path link +############################################## +function e2e::sync_head_subdir_link() { + # First sync + echo "$FUNCNAME 1" > "$REPO/file" + git -C "$REPO" commit -qam "$FUNCNAME 1" + + GIT_SYNC \ + --period=100ms \ + --repo="file://$REPO" \ + --ref=HEAD \ + --root="$ROOT" \ + --link="other/dir/link" \ + & + wait_for_sync "${MAXWAIT}" + assert_file_absent "$ROOT/link" + assert_link_exists "$ROOT/other/dir/link" + assert_file_exists "$ROOT/other/dir/link/file" + assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME 1" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 1 + assert_metric_eq "${METRIC_FETCH_COUNT}" 1 + + # Move HEAD forward + echo "$FUNCNAME 2" > "$REPO/file" + git -C "$REPO" commit -qam "$FUNCNAME 2" + wait_for_sync "${MAXWAIT}" + assert_file_absent "$ROOT/link" + assert_link_exists "$ROOT/other/dir/link" + assert_file_exists "$ROOT/other/dir/link/file" + assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME 2" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 2 + assert_metric_eq "${METRIC_FETCH_COUNT}" 2 + + # Move HEAD backward + git -C "$REPO" reset -q --hard HEAD^ + wait_for_sync "${MAXWAIT}" + assert_file_absent "$ROOT/link" + assert_link_exists "$ROOT/other/dir/link" + assert_file_exists "$ROOT/other/dir/link/file" + assert_file_eq "$ROOT/other/dir/link/file" "$FUNCNAME 1" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 3 + assert_metric_eq "${METRIC_FETCH_COUNT}" 3 +} + ############################################## # Test worktree-cleanup ##############################################