7 ms·
> That last part goes further than git rebase --update-refs, which only moves refs sitting inside the range you’re actively rebasing. git history instead finds
by shepmaster 2mo ago
> That last part goes further than git rebase --update-refs, which only moves refs sitting inside the range you’re actively rebasing. git history instead finds and rewrites every local branch descended from the commit (while also having an option to limit it to only the current branch).
I'm reading that to mean that when I use `git rebase --update-refs` in this situation, where I've currently checked out `D` and update `B` to `B'`:
A ──► B ──► C ──► D
│
└───► E
I'll end up with this state, where `E` remains untouched?
A ──► B' ─► C' ─► D'
│
└───► B ──► E
(EDIT: Originally I had `E` point to `B'`, which doesn't make sense)
If I use `git history fixup`, it would also update `E` and end up with this?
A ──► B' ─► C' ─► D'
│
└───► E'
If that's the case, is there a way to get `git rebase` to have the same behavior? I've got decades of `git rebase` burned into my fingers at this point.
- jolmg 2mo ago> I'll end up with this state, where `E` remains untouched? Can't, because a commit's hash takes into account the parent hashes. Haven't used --update-refs, but reading it, it should result in your third graph. So, > is there a way to get `git rebase` to have the same behavior? is already the case.
- rmunn 2mo agoUnless E remained untouched because it was not rewritten, and ended up staying parented on B instead of getting reparented onto B'. Which is usually not what you want; most of the time you want E', which is E reparented onto B'. But sometimes you want E to remain untouched and stay parented on the original B. Depends on the situation.
- jolmg 2mo agoExactly, but the second graph where untouched E is reparented to B' is not something that git would allow.
- shepmaster 2mo agoAh, good catch. That's more of a graphic issue and not what I was trying to express. Updated the OP.
- deleted 2mo ago[deleted]
- shepmaster 2mo ago> Haven't used --update-refs, but reading it, it should result in your third graph. I don't think it does. I tried locally: mkdir test; cd test; git init touch a; git add a; git commit -m 'a' touch b; git add b; git commit -m 'b' touch c; git add c; git commit -m 'c' git checkout -b branched-feature HEAD~ touch d; git add d; git commit -m 'd' git checkout main echo 'change' > b; git add b; git commit -m 'fix b' git rebase -i --root --update-refs And ended up with this graph (`git log --graph --all`) * commit (HEAD -> main) | | c | * commit | | b | | * commit (branched-feature) | | | | d | | | * commit |/ | b | * commit a Replacing the `git commit -m 'fix b'; git rebase -i --root --update-refs` with `git history fixup HEAD~` produces what I'd like: * commit (branched-feature) | | d | | * commit (HEAD -> main) |/ | c | * commit | | b | * commit a
- jolmg 2mo agoHuh.. That's a shame :(. Maybe what it refers to is if you had a branch on B rather than D, it might update that. EDIT: Yeah, this seems to be it. `git branch b` on b, then `git rebase -i --update-ref @~3` from main caused branch ref `b` to move from d86229e to 02fcaf7: * 1e354fb (HEAD -> main) fix b * 40e6f70 c * 02fcaf7 (b) b | * f4188e0 (branched-feature) d | * d86229e b |/ * 5fe78fa a
- Izkata 2mo ago> And ended up with this graph (`git log --graph --all`) Add --oneline to get the compact version from the other reply.
- seba_dos1 2mo agoIt won't result in the third graph on its own as E isn't reachable from D, but it could if you first merged D and E together and then used --update-refs with --rebase-merges. You could then just discard the merged branch and only take care of D' and E' on their own (and since you don't care about the merged branch, you don't have to care about resolving conflicts while preparing it either).
- lelandfe 2mo agoSee: https://blog.hot-coffee.dev/en/blog/git_update_refs/ https://blog.hot-coffee.dev/en/blog/git_update_refs/
- shepmaster 2mo agoI'm not sure that answers my question. That shows a linear set of branches (my-feature-v3 depends on my-feature-v2 depends on my-feature-v1 depends on main). I'm asking about the case where two or more branches fork from a common ancestor and you want to fix the common ancestor.
- m463 2mo agooff-topic, but that is a very clear readable comment you left with those line-drawing characters.
- shepmaster 2mo agoYou can thank ASCIIFlow for that ;) https://asciiflow.com/ https://asciiflow.com/
- WorldMaker 2mo ago> If that's the case, is there a way to get `git rebase` to have the same behavior? I've got decades of `git rebase` burned into my fingers at this point. One of the GitHub blog posts of git changelog highlights implied that this new power of `git history` was certainly under discussion for a possible feature addition to `git rebase` but it is partly still a discussion because it is a higher-level function and if the goal is to keep `git history` the "high level" and `git rebase` the "low level" then such features probably make sense to remain only in `git history` for now. It also sounds like there are camps thinking `git history` is only the learning path to make a better `git rebase` UX and eventually the commands will reconverge somehow. Both sides of that conversation sound worth exploring to me, and I'm curious to hear how that conversation continues.