git-branchless icon indicating copy to clipboard operation
git-branchless copied to clipboard

`git sync` while on non-detached `main` causes a `git checkout main` for every stack

Open mlcui-corp opened this issue 1 year ago • 2 comments

Description of the bug

This causes git syncs to be significantly slower, especially if git checkout main takes a while. This isn't usually the case, unless you're in a huge monorepo.

Good (checked out at a non-main commit, or detached at main):
Attempting rebase in-memory...
[1/2] Committed as: REDACTED
[2/2] Committed as: REDACTED
branchless: processing 2 rewritten commits
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/3] Committed as: REDACTED
[2/3] Committed as: REDACTED
[3/3] Committed as: REDACTED
branchless: processing 3 rewritten commits
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/3] Committed as: REDACTED
[2/3] Committed as: REDACTED
[3/3] Committed as: REDACTED
branchless: processing 3 rewritten commits
In-memory rebase succeeded.
Attempting rebase in-memory...
Synced REDACTED...
Bad (checked out non-detached main):
Attempting rebase in-memory...
[1/2] Committed as: REDACTED
[2/2] Committed as: REDACTED
branchless: processing 2 rewritten commits
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/3] Committed as: REDACTED
[2/3] Committed as: REDACTED
[3/3] Committed as: REDACTED
branchless: processing 3 rewritten commits
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/1] Committed as: REDACTED
branchless: processing 1 rewritten commit
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
[1/3] Committed as: REDACTED
[2/3] Committed as: REDACTED
[3/3] Committed as: REDACTED
branchless: processing 3 rewritten commits
branchless: creating working copy snapshot
branchless: running command: git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
branchless: processing checkout
In-memory rebase succeeded.
Attempting rebase in-memory...
Synced REDACTED...

I also see working copy snapshots being created - not too sure if that's related.

To work around this, git switch --detach & git sync instead.

Expected behavior

git sync on main is fast in monorepos.

Actual behavior

git sync on main is slow in monorepos.

Version of rustc

No response

Automated bug report

No response

Version of git-branchless

git-branchless-opts 0.7.0 (~/.cargo/git/checkouts shows fbd95855559a73153b83fd0d1e87d75ef2906fee)

Version of git

No response

mlcui-corp avatar Dec 18 '23 00:12 mlcui-corp

This occurs on 35ae2b3a too.

mlcui-corp avatar Dec 18 '23 00:12 mlcui-corp

Maybe it's due to this:

https://github.com/arxanas/git-branchless/blob/81e298dad0bd0335c4d330816c97fab38a24524a/git-branchless-lib/src/core/rewrite/execute.rs#L926-L948

We detach HEAD before moving branches and then check HEAD back out, but that's inefficient in this case. I'm not sure what the best solution is. There might be something better we can do to preserve the index state, or otherwise we could simply add a fast path in check_out_updated_head for the situation that we want to switch to a branch that points to the current commit.

arxanas avatar Dec 28 '23 01:12 arxanas