support -i flag as per git

Bug #243150 reported by Robert Collins
136
This bug affects 23 people
Affects Status Importance Assigned to Milestone
bzr-rewrite
Wishlist
Kirill Müller

Bug Description

git-rebase -i has nice capabilities for editing commits done in a hurry. While rewriting shared history is problematic, editing local history isn't, and there is no reason not to support that.

Changed in bzr-rebase:
assignee: nobody → lifeless
Jelmer Vernooij (jelmer)
Changed in bzr-rebase:
importance: Undecided → Wishlist
status: New → Triaged
Revision history for this message
Robert Collins (lifeless) wrote : Re: [Bug 243150] [NEW] support -i flag as per git

18:03 < lifeless> so it sounds like my plan is:
18:03 < lifeless> -i should generate the plan and not execure
18:03 < lifeless> there should be some sort of edit-plan call
18:03 < lifeless> after which the plan is adjusted as needed to
accomodate
18:04 < lifeless> refactor stuff so there is an 'execute_plan' method
18:04 < lifeless> which will know how to drop commits, and return to the
shell to edit commits that are selected to edit
18:04 < lifeless> does that sound complete/sufficient?
18:06 < jelmer> yeah

Revision history for this message
Ulrik Mikaelsson (rawler) wrote :

Is there any progress made in this? This is the _one_ thing I really miss from git, when working on feature-branches, wanting to collapse/fix bug-revisions to make it easier for the reviewers later.

Revision history for this message
Ulrik Mikaelsson (rawler) wrote :

I've been investigating this a little, and I see one thing that haven't explicitly mentioned, namely changing commit-messages.

I think adding extra commands, edit-plan and execute-plan would only make it unnecessarily complex, and also less usable, since -i would always be invoked right before editing and executing the plan.

One approach would be to change the persistent merge formats slightly, so that there is a $checkout/rebase-orig, containing only the reference to the original rebased revisiong.

Then there would be a $checkout/rebase-todo, containing only the actions left to do, looking something like:
# Bazaar rebase plan 2
# valid actions are:
# checkout <orig>
# commit <message>
# edit
# merge <revspec>
checkout <orig revid>
merge <first_revision>
commit "Some nice message"
merge <second_revision>
commit "Some other nice message"
merge <third_revision>

So, if the user specifies rebase -i, bzr would generate a todo/plan, drop to $EDITOR and let the user edit the plan (including introducing edit-points, edit commit-messages, squashing commits, etc...)

Then on successful editor-exit, rebase would execute pretty much as before, performing all actions in the order they appear. One thing that could use some special mention would be splitting revisions, which could simply be done by an edit-action, letting the user manually commit some of the desired stuff, and then rebase-continue.

This workflow, and changing the plan-formats, would have a few advantages over what's suggested before:
 * In the normal case, the user does only have to add -i, and do minimal editing for a trivial re-write.
 * If a rebase-merge fails (even when not -i were specified), one could have a rebase_edit command, editing $checkout/rebase-todo, so that the user is given the option to skip this particular revision and continue. (An example would be a revision that were submitted upstream, but were changed a lot to make the merge fail.)
 * Most users looking for interactive rebase to change history are probably coming from git. This would make them feel pretty much at home, closely resembling the git workflow.

I miss this feature enough to have a go at it, unless someone else is willing (or have already worked on it). So please, if you have ideas/work done, please tell me soon, to avoid duplicate efforts.

Revision history for this message
Charles Duffy (M1) (cduffy-messageone) wrote :

Ulrik,

How would multiline commit messages be formatted under this proposal?

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Another option would perhaps be to have a separate command for this sort of stuff. I don't particularly see what all of this has to do with rebasing, it's mainly about changing the revision graph and commit messages. It could potentially even do more than that, such as e.g. filtering out data.

Revision history for this message
Xavier (Open ERP) (xmo-deactivatedaccount) wrote :

I think Jelmer's suggestion is a good one. In Mercurial, the two concepts are split into two different commands (and extensions, but they could be bundled as a single general-purpose hsitory-rewriting extension) are split into different commands: one is rebase (http://mercurial.selenic.com/wiki/RebaseExtension), and the other one is histedit (http://mercurial.selenic.com/wiki/HisteditExtension).

There is also the older (than histedit) Mercurial Queues (http://mercurial.selenic.com/wiki/MqExtension) which lets users edit history by importing existing revision into the queues, manipulating them and then re-serializing them into regular hg revisions, but it's much more complex to approach (which is probably why Histedit was created).

> It could potentially even do more than that, such as e.g. filtering out data.

Depends on the UI used, git's rebase -i UI (which was reused by hg's histedit) doesn't really work for branch filtering. Branch filtering could also, probably, be a third command of the rewrite extension.

Revision history for this message
Ulrik Mikaelsson (rawler) wrote :

Yeah, just thought I might add, if that's not apparent by my complete lack of updates for over a year, that I got stuck in my attempts.

Got lost in the jungle of internal BZR-api:s, and finally other things called for my attention. Sorry, but I don't really have the time for a proper implementation.

Changed in bzr-rewrite:
assignee: Robert Collins (lifeless) → nobody
Revision history for this message
Kirill Müller (krlmlr) wrote :

I'm missing rebase -i from git enough that I want to try to implement an alternative in bzr. I am planning to implement a histedit command that would allow reordering the last n commits (using a --revision parameter). Rewording commit messages, editing commits and squashing commits will follow, although I'm not certain that squashing will be easy to implement.

The UI would be just like in git rebase -i. A human-readable git-style 'todo' list like

pick 1 added file a
pick 2 added file b
pick 3 edited file a

would be opened in $EDITOR (the same way like commit without -m opens one), the result will then be formatted as a .bzr/checkout/rebase-plan file, and the existing machinery will perform the heavy lifting. The numbers will be the numeric revno-s, which are unique within the branch. Users can reorder or leave out commits, later changing the command to "reword", "edit", "squash" or "fixup" with git semantics will be supported, too.

Suggestions and comments are welcome.

I have a technical question. Using the class collections.OrderedDict would simplify the implementation; however, it's available in Python 2.7 only. Does bzrlib already have a substitute for this functionality?

Changed in bzr-rewrite:
assignee: nobody → Kirill Müller (mail-kirill-mueller)
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

FWIW I think your analysis is spot on what I am looking for as well Kirill.

With regards to collections.OrderedDict I am not sure of the conventions for the bzr project code, but definitely Ubuntu 11.10 will ship both Python 2 and 3 versions with the desired class, and since this is in an extension any rules may be laxed? Otherwise look at http://stackoverflow.com/questions/1617078/ordereddict-for-older-versions-of-python

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers