Repository navigation
fix: keep shallow sync finalization blob-filtered #2854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2955,10 +2955,11 @@ fi | |
| if !opts.GitOverlay && !opts.PlainManifest && opts.HydrateGit && opts.BaseRef != "" { | ||
| refspec := "+refs/heads/" + opts.BaseRef + ":refs/remotes/origin/" + opts.BaseRef | ||
| script += `if exact_git_root && git remote get-url origin >/dev/null 2>&1; then | ||
| hydrate_fetch() { git fetch --quiet --filter=blob:none origin "$@"; } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On a POSIX target running Git 2.18, a hydration-only sync ( Useful? React with 👍 / 👎. |
||
| if [ "$(git rev-parse --is-shallow-repository 2>/dev/null)" = true ]; then | ||
| git fetch --quiet --unshallow origin ` + shellQuote(refspec) + ` || git fetch --quiet --depth=1000 origin ` + shellQuote(refspec) + ` || git fetch --quiet origin ` + shellQuote(refspec) + ` || git fetch --quiet origin ` + shellQuote(opts.BaseRef) + ` || true | ||
| hydrate_fetch --unshallow ` + shellQuote(refspec) + ` || hydrate_fetch --depth=1000 ` + shellQuote(refspec) + ` || hydrate_fetch ` + shellQuote(refspec) + ` || hydrate_fetch ` + shellQuote(opts.BaseRef) + ` || true | ||
| else | ||
| git fetch --quiet origin ` + shellQuote(refspec) + ` || git fetch --quiet origin ` + shellQuote(opts.BaseRef) + ` || true | ||
| hydrate_fetch ` + shellQuote(refspec) + ` || hydrate_fetch ` + shellQuote(opts.BaseRef) + ` || true | ||
| fi | ||
| fi | ||
| ` | ||
|
|
@@ -3058,7 +3059,7 @@ coherence_committed=; coherence_mutated=; head_changed=; index_changed= | |
| tmp_ref="refs/crabbox/sync-$expected_token"; advertised_branch=` + shellQuote(plan.Branch) + `; expected_origin=` + shellQuote(plan.RemoteURL) + ` | ||
| ` + remoteGitOriginTransportFunctions() + ` | ||
| coherence_fetch() { | ||
| set -- --quiet --no-tags | ||
| set -- --quiet --filter=blob:none --no-tags | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On a POSIX target running Git 2.18, this unconditional option makes every coherence fetch fail because that version's documented fetch options include Useful? React with 👍 / 👎. |
||
| # An existing shallow boundary can hide ancestors of the advertised branch. | ||
| if [ "$(git rev-parse --is-shallow-repository 2>/dev/null)" = true ]; then | ||
| set -- "$@" --unshallow | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| //go:build !windows | ||
|
|
||
| package cli | ||
|
|
||
| import ( | ||
| "os" | ||
| "os/exec" | ||
| "path/filepath" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestRemoteFinalizeSyncDoesNotDownloadHistoricalBlobs(t *testing.T) { | ||
| f := newGitCoherenceFixture(t) | ||
| runGit(t, f.origin, "config", "uploadpack.allowFilter", "true") | ||
| oldBlob := gitOutput(f.source, "rev-parse", f.a+":tracked.txt") | ||
| for _, scenario := range []struct { | ||
| name string | ||
| coherence, hydrate bool | ||
| }{ | ||
| {name: "coherence", coherence: true}, | ||
| {name: "hydrate", hydrate: true}, | ||
| {name: "coherence-and-hydrate", coherence: true, hydrate: true}, | ||
| } { | ||
| t.Run(scenario.name, func(t *testing.T) { | ||
| workdir := filepath.Join(t.TempDir(), "work") | ||
| origin := "file://" + filepath.ToSlash(f.origin) | ||
| if out, err := exec.Command("git", "clone", "--quiet", "--depth=1", origin, workdir).CombinedOutput(); err != nil { | ||
| t.Fatalf("shallow clone: %v\n%s", err, out) | ||
| } | ||
| assertOldBlobMissing := func() { | ||
| t.Helper() | ||
| cmd := exec.Command("git", "-C", workdir, "-c", "protocol.allow=never", "cat-file", "-e", oldBlob) | ||
| cmd.Env = append(os.Environ(), "GIT_NO_LAZY_FETCH=1") | ||
| if err := cmd.Run(); err == nil { | ||
| t.Fatal("downloaded a blob that exists only in history") | ||
| } | ||
| } | ||
| assertOldBlobMissing() | ||
| plan := gitCoherencePlan{} | ||
| if scenario.coherence { | ||
| plan = f.plan(t, f.c) | ||
| plan.RemoteURL = origin | ||
| } | ||
| const token = "1234567890abcdef1234567890abcdef" | ||
| stageCoherenceFinalize(t, workdir, token) | ||
| command := remoteFinalizeSync(workdir, remoteSyncFinalizeOptions{ | ||
| Token: token, Coherence: plan, HydrateGit: scenario.hydrate, BaseRef: "main", | ||
| }) | ||
| if out, err := exec.CommandContext(t.Context(), "/bin/sh", "-c", command).CombinedOutput(); err != nil { | ||
| t.Fatalf("finalize: %v\n%s", err, out) | ||
| } | ||
| assertOldBlobMissing() | ||
| requireGitOutput(t, workdir, "false", "rev-parse", "--is-shallow-repository") | ||
| requireGitOutput(t, workdir, f.c, "rev-parse", "HEAD") | ||
| // Commit ancestry remains available even though historical file bytes | ||
| // are deferred until a caller explicitly asks Git for them. | ||
| runGit(t, workdir, "merge-base", "--is-ancestor", f.a, "HEAD") | ||
| requireGitOutput(t, workdir, "A", "show", f.a+":tracked.txt") | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This statement is false for native Windows targets:
syncWindowsNativestill finalizes throughwindowsGitCoherence, whose fetch atinternal/cli/sync_windows_target.go:264has neither--filter=blob:nonenor shallow-history completion. Consequently a native Windows workspace can still download all fetched blobs, and a shallow checkout does not gain the promised ancestry. Git documents that--filter=blob:noneomits file contents until needed; mirror the filtering and shallow handling in the Windows finalizer, or scope the documented fix explicitly to POSIX/WSL targets.Useful? React with 👍 / 👎.