diff --git a/.gitallowed b/.gitallowed new file mode 100644 index 0000000..6e6e61e --- /dev/null +++ b/.gitallowed @@ -0,0 +1 @@ +xxxyyyzzz diff --git a/cmd/git-sync/main.go b/cmd/git-sync/main.go index 788c075..579fcef 100644 --- a/cmd/git-sync/main.go +++ b/cmd/git-sync/main.go @@ -765,15 +765,6 @@ func (git *repoSync) AddWorktreeAndSwap(ctx context.Context, hash string) error } } - // Execute the command, if requested. - if *flSyncHookCommand != "" { - log.V(0).Info("executing command for git sync hooks", "command", *flSyncHookCommand) - _, err = runCommand(ctx, worktreePath, *flSyncHookCommand) - if err != nil { - return err - } - } - // Reset the root's rev (so we can prune and so we can rely on it later). _, err = runCommand(ctx, git.root, git.cmd, "reset", "--hard", hash, "--") if err != nil { @@ -787,17 +778,38 @@ func (git *repoSync) AddWorktreeAndSwap(ctx context.Context, hash string) error return err } setRepoReady() - if oldWorktree != "" { - // Clean up previous worktree - log.V(1).Info("removing old worktree", "path", oldWorktree) - if err := os.RemoveAll(oldWorktree); err != nil { - return fmt.Errorf("error removing directory: %v", err) - } - if _, err := runCommand(ctx, git.root, git.cmd, "worktree", "prune"); err != nil { - return err + + // From here on we have to save errors until the end. + + // Execute the hook command, if requested. + var execErr error + if *flSyncHookCommand != "" { + log.V(0).Info("executing command for git sync hooks", "command", *flSyncHookCommand) + // TODO: move this to be async like webhook? + // TODO: don't use global flags way down here + if _, err := runCommand(ctx, worktreePath, *flSyncHookCommand); err != nil { + // Save it until after cleanup runs. + execErr = err } } + // Clean up previous worktrees. + var cleanupErr error + if oldWorktree != "" { + log.V(1).Info("removing old worktree", "path", oldWorktree) + if err := os.RemoveAll(oldWorktree); err != nil { + cleanupErr = fmt.Errorf("error removing directory: %v", err) + } else if _, err := runCommand(ctx, git.root, git.cmd, "worktree", "prune"); err != nil { + cleanupErr = err + } + } + + if cleanupErr != nil { + return cleanupErr + } + if execErr != nil { + return execErr + } return nil } @@ -1062,7 +1074,7 @@ func (git *repoSync) SetupCookieFile(ctx context.Context) error { // The expected ASKPASS callback output are below, // see https://git-scm.com/docs/gitcredentials for more examples: // username=xxx@example.com -// password=ya29.xxxyyyzzz +// password=xxxyyyzzz func (git *repoSync) CallAskPassURL(ctx context.Context) error { log.V(1).Info("calling GIT_ASKPASS URL to get credentials") diff --git a/test_e2e.sh b/test_e2e.sh index e37d3f1..d6cc0f8 100755 --- a/test_e2e.sh +++ b/test_e2e.sh @@ -800,8 +800,10 @@ sleep 3 assert_link_exists "$ROOT"/link assert_file_exists "$ROOT"/link/file assert_file_exists "$ROOT"/link/sync-hook +assert_file_exists "$ROOT"/link/link-sync-hook assert_file_eq "$ROOT"/link/file "$TESTCASE 1" assert_file_eq "$ROOT"/link/sync-hook "$TESTCASE 1" +assert_file_eq "$ROOT"/link/link-sync-hook "$TESTCASE 1" # Move forward echo "$TESTCASE 2" > "$REPO"/file git -C "$REPO" commit -qam "$TESTCASE 2" @@ -809,8 +811,10 @@ sleep 3 assert_link_exists "$ROOT"/link assert_file_exists "$ROOT"/link/file assert_file_exists "$ROOT"/link/sync-hook +assert_file_exists "$ROOT"/link/link-sync-hook assert_file_eq "$ROOT"/link/file "$TESTCASE 2" assert_file_eq "$ROOT"/link/sync-hook "$TESTCASE 2" +assert_file_eq "$ROOT"/link/link-sync-hook "$TESTCASE 2" # Wrap up pass diff --git a/test_sync_hook_command.sh b/test_sync_hook_command.sh index 0ecf4a7..fb3684f 100755 --- a/test_sync_hook_command.sh +++ b/test_sync_hook_command.sh @@ -2,4 +2,5 @@ # Use for e2e test of --sync-hook-command. # This option takes no command arguments, so requires a wrapper script. -yes | cp -i file sync-hook +cat file > sync-hook +cat ../link/file > link-sync-hook