Skip to content

(bug fix): use explicit force-with-lease refs for stack sync#1

Open
ravi-pplx wants to merge 1 commit into
mainfrom
ravi/explicit-force-with-lease
Open

(bug fix): use explicit force-with-lease refs for stack sync#1
ravi-pplx wants to merge 1 commit into
mainfrom
ravi/explicit-force-with-lease

Conversation

@ravi-pplx

Copy link
Copy Markdown
Owner

Build per-branch force-with-lease arguments so pushes do not rely on Git inferring the destination branch from local branch config.

During gh stack sync, the relevant command flow is still fetch/rebase/push. For a branch b1, the old push shape was:

git fetch origin b1
git rebase ...
git push origin --force-with-lease --atomic b1

This can fail at the final push when Git cannot derive the expected value for refs/heads/b1 from the same local tracking ref that the fetch updated.

The fixed shape resolves the fetched tracking ref explicitly and pins the destination ref in both the lease and refspec:

git fetch origin b1
git rebase ...
git rev-parse --verify --quiet refs/remotes/origin/b1
git push origin --force-with-lease=refs/heads/b1:<fetched-sha> --atomic b1:refs/heads/b1

If someone updates b1 after the fetch, the final push fails because refs/heads/b1 no longer equals <fetched-sha>. If b1 had no tracking ref, the lease is empty, so the push fails if someone created refs/heads/b1 first.

Update fake-git coverage for tracked branches, missing tracking refs, and the non-force path skipping lease lookup. The fake git is built as a small Go executable so exec.LookPath("git") finds it on Windows as git.exe, instead of relying on an extensionless POSIX script.

Build per-branch force-with-lease arguments so pushes do not rely on Git inferring the destination branch from local branch config.

During `gh stack sync`, the relevant command flow is still fetch/rebase/push. For a branch `b1`, the old push shape was:

```console
git fetch origin b1
git rebase ...
git push origin --force-with-lease --atomic b1
```

This can fail at the final push when Git cannot derive the expected value for `refs/heads/b1` from the same local tracking ref that the fetch updated.

The fixed shape resolves the fetched tracking ref explicitly and pins the destination ref in both the lease and refspec:

```console
git fetch origin b1
git rebase ...
git rev-parse --verify --quiet refs/remotes/origin/b1
git push origin --force-with-lease=refs/heads/b1:<fetched-sha> --atomic b1:refs/heads/b1
```

If someone updates `b1` after the fetch, the final push fails because `refs/heads/b1` no longer equals `<fetched-sha>`. If `b1` had no tracking ref, the lease is empty, so the push fails if someone created `refs/heads/b1` first.

Update fake-git coverage for tracked branches, missing tracking refs, and the non-force path skipping lease lookup. The fake `git` is built as a small Go executable so `exec.LookPath("git")` finds it on Windows as `git.exe`, instead of relying on an extensionless POSIX script.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant