Execute git commands in -C{path} when git cwd and toplevel are different#236
Execute git commands in -C{path} when git cwd and toplevel are different#236Kortantic wants to merge 2 commits into
-C{path} when git cwd and toplevel are different#236Conversation
|
I use git worktrees and don't observe the problem as you described it. The divergence seems to happen only when Are you sure the problem is with |
|
I think it stems from how OpenCode is building its snapshots. I assume it's using direct I dug through DiffView's Log output and noticed it was showing that the CWD was getting reset to the git I'll take a look at the OpenCode repo to see if I can figure out the exact calls it's using to put its snapshot git directory into the state it's in to come up with a test that can reproduce it better. I'll also get you a minimum config and git repo to try it against. I'll have some more time this evening after the chores are done and kids are in bed, and probably tomorrow as well (since this may not be as cut and dry as I assumed). |
Based on this, your PR doesn't fix the issue. Your I don't understand why you're overriding |
|
I've fixed the issue with the divergence between the git dir and the worktree dir as you described it, in #238. Please let me know if this fixes the problem wtih OpenCode for you. |
|
Your commit fixes it. I agree entirely with the commit you made, it's cleaner and doesn't have the side effect of botching the binary check. I swung too far in the other direction with the idea that "cpath" means we should always execute git commands there. Thank you so much for solving it for me. |
Summary
I ran into a case where
git -C <path> diff <rev>returned a proper diff, but:DiffviewOpen -C=<path> <rev>couldn't.This PR makes
DiffviewOpen -C=<path>behave the way git would in snapshot/worktree-like layouts where--show-topleveland--git-dirdo not resolve to the same directory.Problem
Diffview was treating two concepts as the same path:
-Cusage works for normal repos, but breaks where:-Cdirectorygit rev-parse --show-toplevelpoints somewhere elseMy use case was against an OpenCode snapshot directory, but the underlying problem would occur in snapshot/worktree-like setups where git's cwd and its reported toplevel diverge.
While working through this, I hit another issue affecting single-rev commit-vs-local diffs. The RHS
LOCALfile could collapse todiffview://nullwhen it was mistakenly classified as a binary.Fix
This PR separates the execution root from the path-resolution root in the case that toplevel and git-dir are not the same.
ctx.exec_rootfor git command executionctx.toplevelfor repo-relative path resolutionparse_revs()resolveHEADlazily so aCOMMITtoLOCALdiff doesn't require aHEADLOCALfile is text before falling back to the existing untracked binary checkResult
This restores the expected behavior for snapshot/worktree-style
-Cdiffs, including::DiffviewOpen -C=<snapshot> <rev>:DiffviewOpen -C=<snapshot> <revA>..<revB>In particular, the RHS
LOCALside now opens the real working-tree file instead of collapsing to a null buffer.Note
This is not a general
-Cfix for ordinary repos; those already worked. The narrower issue here is that git's execution root and reported repo toplevel can differ, and Diffview was assuming they were always the same.The main semantic change is:
toplevelstays the base for repo-relative pathsexec_rootbecomes the cwd for git operations