[git] Feature request: track commit rewriting from Git
jj doesn't know about commits rewritten on the Git side, e.g. if I have this history:
C
|
B
|
A
and I swap B and C using git rebase -i, I'd want jj to tell me that my repo looks like:
B'
|
C'
|
A
Instead, jj tells me that my repo looks like:
B' C
| |
C' B
| /
A
One way to do this would be to add a Git post-rewrite hook (which IIRC is what git-branchless does).
I think it works in simple cases. I just tried it in a tiny repo with just three linear commits like in your example. Could it be that you have other branches still pointing to C or one of its descendants?
Ah, yes I had a branch pointing to one of those commits.
Maybe that wasn't the best example. Here's another one:
o E (branch-foo)
|
o D
|
o C
|
| B @ (working copy)
|/
o A (HEAD@git)
after rewording with git commit --amend --only (no files):
@ F (working copy)
|
o A' HEAD@git
|
| o E
| |
| o D
| |
| o C
| |
| o B
|/
o A
In another instance, jj thought that I had rewritten some commits in Git, but I actually didn't.
I don't have a good handle of the reproduction recipe or what the relevant data points are, but the scenario looked something like:
@
|
o
| o D
| |
| o
| |
| o
| |
| | o
| | |
| | o
| | |
| | o
| |/
| o C
| |
| o
| |
| o
| |
| o
| |
o |
:\ \
: ~/
: o A
:/
o-. B
:\ \
After importing refs, jj rebased C and its descendants onto B, losing A:C. Curiously, C has a branch pointing to it and jj moves the branch to B. This branch wasn't touched in Git at all.
Adding a Git branch to D prevents this bad rebase from happening. Adding a Git branch to A causes C and its descendants to be rebased onto A instead of B.
I think what happened is that the Git branch pointing to C was removed (or moved), so the commits A:C were effectively removed from the Git repo. When that happens, the next ref-import into jj will notice that you apparently wanted to remove A:C (since you - or maybe git fetch - decided that in the Git repo), so it rebases the descendants C.. off of them. Could that be what happened?
the Git branch pointing to C was removed (or moved)
IIRC, that's the exact opposite of what happened. I created a jj branch at C, and (since my jj branch exports aren't working well) I also created an identical branch in Git, but somehow jj thought that the branch should be at B instead. It was extra weird because B was a commit from the remote which was not rewritten.
Perhaps fiddling with the branch in both Git and jj was the source of the problem?
In the colocated repo case, I wonder if it makes sense to treat the Git refs like remotes and let the user manually resolve conflicts, e.g. we could have a conflicted foo-branch where Git's foo-branch@git-repo is different from jj's local foo-branch.