Merge pull request #656 from thockin/fix-back-to-back-rev-syncs

Fix cases of syncing different SHAs back to back
This commit is contained in:
Kubernetes Prow Robot 2023-01-08 02:43:27 -08:00 committed by GitHub
commit d9120f7a40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 144 additions and 27 deletions

View File

@ -1094,6 +1094,10 @@ func (git *repoSync) CleanupWorkTree(ctx context.Context, gitRoot, worktree stri
func (git *repoSync) AddWorktreeAndSwap(ctx context.Context, hash string) (bool, string, error) { func (git *repoSync) AddWorktreeAndSwap(ctx context.Context, hash string) (bool, string, error) {
git.log.V(0).Info("syncing git", "rev", git.rev, "hash", hash) git.log.V(0).Info("syncing git", "rev", git.rev, "hash", hash)
// If we don't have this hash, we need to fetch it.
if _, err := git.ResolveRef(ctx, hash); err != nil {
git.log.V(2).Info("can't resolve commit, will try fetch", "rev", git.rev, "hash", hash)
args := []string{"fetch", "-f", "--tags"} args := []string{"fetch", "-f", "--tags"}
if git.depth != 0 { if git.depth != 0 {
args = append(args, "--depth", strconv.Itoa(git.depth)) args = append(args, "--depth", strconv.Itoa(git.depth))
@ -1119,6 +1123,7 @@ func (git *repoSync) AddWorktreeAndSwap(ctx context.Context, hash string) (bool,
git.log.Error(err, "can't resolve commit, will retry", "rev", git.rev, "hash", hash) git.log.Error(err, "can't resolve commit, will retry", "rev", git.rev, "hash", hash)
return false, "", nil return false, "", nil
} }
}
// Make a worktree for this exact git hash. // Make a worktree for this exact git hash.
worktreePath := filepath.Join(git.root, hash) worktreePath := filepath.Join(git.root, hash)
@ -1373,6 +1378,16 @@ func (git *repoSync) LocalHashForRev(ctx context.Context, rev string) (string, e
if err != nil { if err != nil {
return "", err return "", err
} }
result := strings.Trim(string(output), "\n")
if result == rev {
// It appears to be a SHA, so we need to verify that we have it. We
// don't care what cat-file says, just whether it succeeds or fails.
_, err := git.run.Run(ctx, git.root, nil, git.cmd, "cat-file", "-t", rev)
if err != nil {
// Indicate that we do not have a local hash for this hash.
return "", err
}
}
return strings.Trim(string(output), "\n"), nil return strings.Trim(string(output), "\n"), nil
} }
@ -1494,16 +1509,20 @@ func stringContainsOneOf(s string, matches ...string) bool {
return false return false
} }
// GetRevs returns the local and upstream hashes for rev. // GetRevs returns the current HEAD and upstream hash for rev. Normally the
// current HEAD is a previous or current version of git.rev, but if the app was
// started with one rev and then restarted with a different one, HEAD could be
// anything.
func (git *repoSync) GetRevs(ctx context.Context) (string, string, error) { func (git *repoSync) GetRevs(ctx context.Context) (string, string, error) {
// Ask git what the exact hash is for rev. // Find the currently synced HEAD.
local, err := git.LocalHashForRev(ctx, git.rev) local, err := git.LocalHashForRev(ctx, "HEAD")
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
// Build a ref string, depending on whether the user asked to track HEAD or // Build a ref string, depending on whether the user asked to track HEAD or
// a tag. // a tag. We can't really tell if it is a SHA yet, so we will catch that
// case later.
ref := "HEAD" ref := "HEAD"
if git.rev != "HEAD" { if git.rev != "HEAD" {
ref = "refs/tags/" + git.rev ref = "refs/tags/" + git.rev
@ -1517,6 +1536,20 @@ func (git *repoSync) GetRevs(ctx context.Context) (string, string, error) {
return "", "", err return "", "", err
} }
// If we couldn't find a remote hash, it might have been a SHA literal.
if remote == "" {
// If git thinks it tastes like a SHA, we just return that and if it
// is wrong, we will fail later.
output, err := git.run.Run(ctx, git.root, nil, git.cmd, "rev-parse", git.rev)
if err != nil {
return "", "", err
}
result := strings.Trim(string(output), "\n")
if result == git.rev {
remote = git.rev
}
}
return local, remote, nil return local, remote, nil
} }

View File

@ -853,6 +853,90 @@ function e2e::sync_sha_once() {
assert_file_eq "$ROOT"/link/file "$FUNCNAME" assert_file_eq "$ROOT"/link/file "$FUNCNAME"
} }
##############################################
# Test rev-sync on a different rev we already have
##############################################
function e2e::sync_sha_once_sync_different_sha_known() {
# All revs will be known because we check out the branch
echo "$FUNCNAME 1" > "$REPO"/file
git -C "$REPO" commit -qam "$FUNCNAME 1"
REV1=$(git -C "$REPO" rev-list -n1 HEAD)
echo "$FUNCNAME 2" > "$REPO"/file
git -C "$REPO" commit -qam "$FUNCNAME 2"
REV2=$(git -C "$REPO" rev-list -n1 HEAD)
echo "$FUNCNAME 3" > "$REPO"/file
git -C "$REPO" commit -qam "$FUNCNAME 3"
# Sync REV1
GIT_SYNC \
--one-time \
--repo="file://$REPO" \
--branch="$MAIN_BRANCH" \
--rev="$REV1" \
--root="$ROOT" \
--link="link" \
>> "$1" 2>&1
assert_link_exists "$ROOT"/link
assert_file_exists "$ROOT"/link/file
assert_file_eq "$ROOT"/link/file "$FUNCNAME 1"
# Sync REV2
GIT_SYNC \
--one-time \
--repo="file://$REPO" \
--branch="$MAIN_BRANCH" \
--rev="$REV2" \
--root="$ROOT" \
--link="link" \
>> "$1" 2>&1
assert_link_exists "$ROOT"/link
assert_file_exists "$ROOT"/link/file
assert_file_eq "$ROOT"/link/file "$FUNCNAME 2"
}
##############################################
# Test rev-sync on a different rev we do not have
##############################################
function e2e::sync_sha_once_sync_different_sha_unknown() {
echo "$FUNCNAME 1" > "$REPO"/file
git -C "$REPO" commit -qam "$FUNCNAME 1"
REV1=$(git -C "$REPO" rev-list -n1 HEAD)
# Sync REV1
GIT_SYNC \
--one-time \
--repo="file://$REPO" \
--branch="$MAIN_BRANCH" \
--rev="$REV1" \
--root="$ROOT" \
--link="link" \
>> "$1" 2>&1
assert_link_exists "$ROOT"/link
assert_file_exists "$ROOT"/link/file
assert_file_eq "$ROOT"/link/file "$FUNCNAME 1"
# The locally synced repo does not know this new SHA.
echo "$FUNCNAME 2" > "$REPO"/file
git -C "$REPO" commit -qam "$FUNCNAME 2"
REV2=$(git -C "$REPO" rev-list -n1 HEAD)
# Make sure the SHA is not at HEAD, to prevent things that only work in
# that case.
echo "$FUNCNAME 3" > "$REPO"/file
git -C "$REPO" commit -qam "$FUNCNAME 3"
# Sync REV2
GIT_SYNC \
--one-time \
--repo="file://$REPO" \
--branch="$MAIN_BRANCH" \
--rev="$REV2" \
--root="$ROOT" \
--link="link" \
>> "$1" 2>&1
assert_link_exists "$ROOT"/link
assert_file_exists "$ROOT"/link/file
assert_file_eq "$ROOT"/link/file "$FUNCNAME 2"
}
############################################## ##############################################
# Test syncing after a crash # Test syncing after a crash
############################################## ##############################################