git rebase would update refs to new commit that are picked and had references before rebase?
Before, no.
But while you are rebasing? Maybe.
With Git 2.38 (Q3 2022), "git rebase -i
"(man) learns to update branches whose tip appear in the rebased range with --update-refs
option.
See commit 7fefa1b (12 Jul 2022) by Junio C Hamano (gitster
).
See commit 4611884, commit aa37f3e, commit 3113fed, commit b3b1a21, commit 89fc0b5, commit 900b50c, commit a97d791, commit d7ce9a2, commit f57fd48, commit aa7f2fd, commit 18ea595, commit 1bec4d1 (19 Jul 2022) by Derrick Stolee (derrickstolee
).
(Merged by Junio C Hamano -- gitster
-- in commit 3d8e3dc, 01 Aug 2022)
rebase
: add --update-refs option
Signed-off-by: Derrick Stolee
When working on a large feature, it can be helpful to break that feature into multiple smaller parts that become reviewed in sequence.
During development or during review, a change to one part of the feature could affect multiple of these parts.
An interactive rebase can help adjust the multi-part "story" of the branch.
However, if there are branches tracking the different parts of the feature, then rebasing the entire list of commits can create commits not reachable from those "sub branches".
It can take a manual step to update those branches.
Add a new --update-refs
option to 'git rebase -i
'(man) that adds 'update-ref ' steps to the todo file whenever a commit that is being rebased is decorated with that .
At the very end, the rebase process updates all of the listed refs to the values stored during the rebase operation.
Be sure to iterate after any squashing or fixups are placed.
Update the branch only after those squashes and fixups are complete.
This allows a --fixup
commit at the tip of the feature to apply correctly to the sub branch, even if it is fixing up the most-recent commit in that part.
This change update the documentation and builtin to accept the --update-refs
option as well as updating the todo file with the 'update-ref' commands.
Tests are added to ensure that these todo commands are added in the correct locations.
This change does not include the actual behavior of tracking the updated refs and writing the new ref values at the end of the rebase process.
That is deferred to a later change.
git rebase
now includes in its man page:
--update-refs
--no-update-refs
Automatically force-update any branches that point to commits that
are being rebased.
Any branches that are checked out in a worktree
are not updated in this way.
And:
rebase
: update refs from 'update-ref' commands
Signed-off-by: Derrick Stolee
The previous change introduced the 'git rebase --update-refs
'(man) option which added 'update-ref <ref>
' commands to the todo
list of an interactive rebase.
Teach Git to record the HEAD position when reaching these 'update-ref' commands.
The ref/before/after triple is stored in the $GIT_DIR/rebase-merge/update-refs
file.
A previous change parsed this file to avoid having other processes updating the refs in that file while the rebase is in progress.
Not only do we update the file when the sequencer reaches these 'update-ref' commands, we then update the refs themselves at the end of the rebase sequence.
If the rebase is aborted before this final step, then the refs are not updated.
The 'before' value is used to ensure that we do not accidentally obliterate a ref that was updated concurrently (say, by an older version of Git or a third-party tool).
Result:
sequencer
: notify user of --update-refs
activity
Reported-by: Elijah Newren
Signed-off-by: Derrick Stolee
When the user runs 'git rebase -i --update-refs
'(man), the end message still says only
Successfully rebased and updated <HEAD-ref>.
Update the sequencer to collect the successful (and unsuccessful) ref updates due to the --update-refs
option, so the end message now says
Successfully rebased and updated <HEAD-ref>.
Updated the following refs with --update-refs:
efs/heads/first
efs/heads/third
Failed to update the following refs with --update-refs:
efs/heads/second
git rebase --update-refs
(man) would delete references when all update-ref
commands in the sequencer were removed, which has been corrected with Git 2.39 (Q4 2022).
See commit 44da9e0 (07 Nov 2022) by Victoria Dye (vdye
).
(Merged by Taylor Blau -- ttaylorr
-- in commit 35dc2cf, 18 Nov 2022)
Reported-by: herr.kaste
Helped-by: Phillip Wood
Helped-by: Derrick Stolee
Signed-off-by: Victoria Dye
Signed-off-by: Taylor Blau
In b3b1a21 ("sequencer
: rewrite update-refs as user edits todo list", 2022-07-19, Git v2.38.0-rc0 -- merge listed in batch #8), the 'todo_list_filter_update_refs()
' step was added to handle the removal of 'update-ref
' lines from a 'rebase-todo
'.
Specifically, it removes potential ref updates from the "update refs state
" if a ref does not have a corresponding 'update-ref
' line.
However, because 'write_update_refs_state()
' will not update the state if the 'refs_to_oids
' list was empty, removing all 'update-ref
' lines will result in the state remaining unchanged from how it was initialized (with all refs' "after" OID being null).
Then, when the ref update is applied, all refs will be updated to null and consequently deleted.
To fix this, delete the 'update-refs' state file when 'refs_to_oids
' is empty.
Additionally, add a tests covering "all update-ref lines removed" cases.
update-refs
feature solves this. (Released in v2.38 just a few months ago) – Brunhildaupdate-refs
line into yourgit-rebase-todo
. If you have a worktree that has checked outold-pr
, in another worktree you have "new-work-on-old-pr", and you are rebasing "new-work-on-old-pr" inside it's respective worktree, dropping aupdate-refs refs/heads/old-pr
line inside your git-rebase-todo file led to theold-pr
worktree getting put into a weird state with many "incoming" changes left in the working directory (quite strange dirty git status) – Brunhilda