Sometimes when I'm rewriting history, I've got multiple branches that contain the rewritten commits. For example:
A---B---C---D---E
\ \ \
master featA featB
This is common if I'm working on a feature, and decide that I want to publish a subset of commits to PR right now while I continue to work on the rest.
With this setup, if I rewrite commits B or C while featB
is checked out, then featB
diverges from featA
and I have to go force-update my featA
branch to point to the equivalent rewritten commit.
What I'd really like is a way to ask git-revise
to just deal with this for me.
Non-interactive mode
In non-interactive mode, git-revise
should print a warning to stdout if any local branches contain the rewritten commits but aren't being updated by this command. That way I can decide whether I should undo my change, or update the branch.
It should also support a flag that lets me list additional branches (besides HEAD) that should be rewritten as needed. This flag should take a glob string, so I can pass *
to mean "rewrite any affected branches". I should be able to specify it multiple times. Alternatively it could take a fixed string and have a separate flag to mean "rewrite all branches", but I figure the glob string is a bit simpler.
This is somewhat related to the existing --ref
flag, but that flag only identifies a single ref, and it's also got usability issues (apparently I need to list the entire ref)
With the above example, this would let me say something like git revise --rewrite-additional-local-branches \* $B
while featB
is checked out and it would rewrite both featA
and featB
for me (this flag is too verbose but it's just for illustrative purposes).
Interactive mode
In interactive mode, a new command ref
should be added that lets me create or update a ref. In interactive mode it should behave as though --rewrite-additional-local-branches \*
is implicitly specified if the flag isn't otherwise listed. When constructing the todo list, it should insert a ref
command for every matching branch that points to a commit in the todo list, except of course for the working ref (HEAD
or --ref
) because that will always point to the final result. The --rewrite-additional-local-branches
flag would default to *
because I can always delete refs I don't want to update from the todo list before committing it.
When --autosquash
is specified, any refs that point to a fixup or squash commit will not move with the fixup or squash commit, they will end up pointing to whatever non-fixup/squash commit was behind it. For example, if my initial todo list is
pick 5152786f70f2 b
pick 736a81426962 c
pick c08daa5ef3d5 fixup! b
ref refs/heads/featA
pick ce817c55b54c d
pick e7b6185cdd59 e
then autosquash will turn that into
pick 5152786f70f2 b
fixup c08daa5ef3d5 fixup! b
pick 736a81426962 c
ref refs/heads/featA
pick ce817c55b54c d
pick e7b6185cdd59 e
If the ref
command is used to list the working ref (HEAD
or the --ref
value), this will do nothing because that ref will always be updated with the final result of the revise; listing this should be legal but it may be worth printing a warning about the ref
command being ignored (and why).