From df7525e3e0c76bba009d8ae549fdb5cee9992502 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 14 Oct 2023 13:52:11 -0700 Subject: [PATCH] Recover if wrong worktree HEAD --- main.go | 11 ++++++++++ test_e2e.sh | 63 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index 8d5ee3014..20ce00c42 100644 --- a/main.go +++ b/main.go @@ -1188,6 +1188,17 @@ func (git *repoSync) sanityCheckWorktree(ctx context.Context, worktree worktree) return false } + // Make sure it is synced to the right commmit. + stdout, _, err := git.Run(ctx, worktree.Path(), "rev-parse", "HEAD") + if err != nil { + git.log.Error(err, "can't get worktree HEAD", "path", worktree.Path()) + return false + } + if stdout != worktree.Hash() { + git.log.V(0).Info("worktree HEAD does not match worktree", "path", worktree.Path(), "head", stdout) + return false + } + // Consistency-check the worktree. Don't use --verbose because it can be // REALLY verbose. if _, _, err := git.Run(ctx, worktree.Path(), "fsck", "--no-progress", "--connectivity-only"); err != nil { diff --git a/test_e2e.sh b/test_e2e.sh index 01039f054..36bbee0eb 100755 --- a/test_e2e.sh +++ b/test_e2e.sh @@ -609,7 +609,7 @@ function e2e::worktree_cleanup() { } ############################################## -# Test worktree-unexpected-removal +# Test worktree unexpected removal ############################################## function e2e::worktree_unexpected_removal() { GIT_SYNC \ @@ -635,7 +635,52 @@ function e2e::worktree_unexpected_removal() { # make a unexpected removal WT=$(git -C "$REPO" rev-list -n1 HEAD) - rm -r "$ROOT/.worktrees/$WT" + rm -r "$ROOT/.worktrees/$WT" + + # resume time + docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}" \ + | while read CTR; do + docker unpause "$CTR" >/dev/null + done + + echo "$METRIC_GOOD_SYNC_COUNT" + + wait_for_sync "${MAXWAIT}" + assert_link_exists "$ROOT/link" + assert_file_exists "$ROOT/link/file" + assert_file_eq "$ROOT/link/file" "$FUNCNAME" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 2 + assert_metric_eq "${METRIC_FETCH_COUNT}" 2 +} + +############################################## +# Test syncing when the worktree is wrong hash +############################################## +function e2e::sync_recover_wrong_worktree_hash() { + GIT_SYNC \ + --period=100ms \ + --repo="file://$REPO" \ + --root="$ROOT" \ + --link="link" \ + & + + # wait for first sync + wait_for_sync "${MAXWAIT}" + assert_link_exists "$ROOT/link" + assert_file_exists "$ROOT/link/file" + assert_file_eq "$ROOT/link/file" "$FUNCNAME" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 1 + assert_metric_eq "${METRIC_FETCH_COUNT}" 1 + + # suspend time so we can fake corruption + docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}" \ + | while read CTR; do + docker pause "$CTR" >/dev/null + done + + # Corrupt it + echo "unexpected" > "$ROOT/link/file" + git -C "$ROOT/link" commit -qam "corrupt it" # resume time docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}" \ @@ -1294,9 +1339,6 @@ function e2e::sync_sha_once_sync_different_sha_unknown() { ############################################## function e2e::sync_crash_no_link_cleanup_retry() { # First sync - echo "$FUNCNAME 1" > "$REPO/file" - git -C "$REPO" commit -qam "$FUNCNAME 1" - GIT_SYNC \ --one-time \ --repo="file://$REPO" \ @@ -1304,7 +1346,7 @@ function e2e::sync_crash_no_link_cleanup_retry() { --link="link" assert_link_exists "$ROOT/link" assert_file_exists "$ROOT/link/file" - assert_file_eq "$ROOT/link/file" "$FUNCNAME 1" + assert_file_eq "$ROOT/link/file" "$FUNCNAME" # Corrupt it rm -f "$ROOT/link" @@ -1317,7 +1359,7 @@ function e2e::sync_crash_no_link_cleanup_retry() { --link="link" assert_link_exists "$ROOT/link" assert_file_exists "$ROOT/link/file" - assert_file_eq "$ROOT/link/file" "$FUNCNAME 1" + assert_file_eq "$ROOT/link/file" "$FUNCNAME" } ############################################## @@ -1325,9 +1367,6 @@ function e2e::sync_crash_no_link_cleanup_retry() { ############################################## function e2e::sync_crash_no_worktree_cleanup_retry() { # First sync - echo "$FUNCNAME 1" > "$REPO/file" - git -C "$REPO" commit -qam "$FUNCNAME 1" - GIT_SYNC \ --one-time \ --repo="file://$REPO" \ @@ -1335,7 +1374,7 @@ function e2e::sync_crash_no_worktree_cleanup_retry() { --link="link" assert_link_exists "$ROOT/link" assert_file_exists "$ROOT/link/file" - assert_file_eq "$ROOT/link/file" "$FUNCNAME 1" + assert_file_eq "$ROOT/link/file" "$FUNCNAME" # Corrupt it rm -rf "$ROOT/.worktrees/" @@ -1348,7 +1387,7 @@ function e2e::sync_crash_no_worktree_cleanup_retry() { --link="link" assert_link_exists "$ROOT/link" assert_file_exists "$ROOT/link/file" - assert_file_eq "$ROOT/link/file" "$FUNCNAME 1" + assert_file_eq "$ROOT/link/file" "$FUNCNAME" } ##############################################