threads / rfc / 28652

[RFC] teach --edit to git rebase

Subject: [RFC] teach --edit to git rebase

## tl;dr

4 messages between Oct 11, 2011 and Oct 12, 2011.

replies: 3people: 2as markdown or json

Jean Privat· Oct 11, 2011, 21:21 UTC · lore

The idea of this patch is to allow a simple edition of a buggy commit in the history.

## Motivation

The motivation behind the option is that sometime I have to do a simple fixup of a previous commit. Usually the way to do it is just to commit the fix on the top of the branch (git commit --fixup) then doing a 'git rebase --autosquash'. However, the way is often not optimal if the context of commit on the top of the branch is different from the context of the buggy commit, thus the rebase with a fixup will lead to a conflict when git will apply the fixup patch to the buggy commit (and a second conflict later).

An other way is to do a 'git rebase --interactive' with an edit in the todo list (instead of a pick). This is what I propose to simplify.

## Proposal

My idea is to add a --edit option to 'git rebase' in order to automatize the 'git rebase --interactive' workflow.

Currently:
    $ git rebase -i commit-to-fix^
    # replace the first 'pick' with 'edit' then save and quit
    $ hack hack hack...
    $ git commit --amend  # or whatever you want to do like split commit
    $ git rebase --continue  # and resolve possible conflicts
With the --edit option:
    $ git rebase --edit commit_to_fix # note: no caret, no editor ! yeah !
    $ hack hack hack...
    $ git commit --amend  # or what ever like split commit
    $ git rebase --continue  # and resolve possible conflicts

Note that for a more complex history modification, a standard git rebase with reordering, squashing and stuff the way to go is a good old git rebase --interactive.

## Implementation proposal

Yes I know "show me the code" but because I am lazy I prefer ask 1-if the proposal makes sense, and 2-if the following way of doing it makes sense.

The idea is to extend git-rebase and git-rebase-interactive.
* detect and check the option --edit in git-rebase
* automatically prepare the todolist in git-rebase-interactive without
launching the editor.
## Alternative proposals

A weak point of the proposal it that it is a new option to a overloaded git command (git rebase). In fact is is even a new synopsis to git rebase since the --edit option will be incompatible with --interactive (it is an automatic interactive) and with --onto (since there is no real point to ``move'' the base if you want to fixup a single commit). A counter proposal could be to not extend the command 'git rebase' but add a new git command (for instance 'git edit buggy_commit') but since the edit may[1] lead to conflicts the user has to do some 'git edit --continue' to finish the editing (or 'git edit --abort' if bored). It will also require to adapt a lot of tinny things because hint messages, error messages, and prompts will talk about 'rebase' and not 'edit'.

[1] In fact, it is probable that the *may* is in fact a *will* since if no conflict arise, it is likable that a simple 'commit --fixup' (followed by a later 'git rebase --autosquash') will just work and be simpler.

An other alternative is to use a simple git alias for myself (and do not bother the git community) but I do not know how to automatize the command 'git rebase --interactive' I suppose I need more complex infrastructure in the existing 'git rebase' (Maybe I did not look enough and there is a way to do it with a git alias).

A last alternative is do do nothing. What I propose is just a way to 1-do not need a caret ('git rebase --edit commit' instead of 'git rebase --interactive commit^') and 2-avoid launching the editor. Therefore, maybe the itch do not really need a patch.

-- Jean Privat
Jean Privat· Oct 11, 2011, 22:36 UTC · re: Jean Privat · lore

Re: [RFC] teach --edit to git rebase

Show 5 quoted lines
> An other alternative is to use a simple git alias for myself (and do
> not bother the git community) but I do not know how to automatize the
> command 'git rebase --interactive' I suppose I need more complex
> infrastructure in the existing 'git rebase' (Maybe I did not look
> enough and there is a way to do it with a git alias).
Hum. I just found that I can do something like :
[alias]
        edit=!GIT_EDITOR='sed -i -e 1s/pick/edit/ --' git rebase -i
-no-autosquash $1^

The main thing that bothers me is that after the rebase, the head is detached (why?)

The other thing is that the error messages for invalid usages are far for perfect

$ git edit toto fatal: Needed a single revision invalid upstream toto^

$ git edit --root toto error: unknown option `root^' usage: git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>] [...]

-Jean
Junio C Hamano· Oct 12, 2011, 04:44 UTC · re: Jean Privat · lore

Re: [RFC] teach --edit to git rebase

Jean Privat <jean.privat@gmail.com> writes:
> Yes I know "show me the code" but because I am lazy I prefer ask 1-if
> the proposal makes sense, and 2-if the following way of doing it makes
> sense.

No, no, and no we do not necessarily hate talking to lazy people but only as long as what they propose makes some sense.

The only thing you can do with this new option is "update one commit buried in the history, and rebase everything that build on top of it", as far as I can tell. It feels a shame to waste the generic word "--edit" for such a narrow option.

At the UI level, "git commit --amend HEAD~4" might be a more natural way to invoke such an operation, I would think.

Jean Privat· Oct 12, 2011, 13:57 UTC · re: Junio C Hamano · lore

Re: [RFC] teach --edit to git rebase

> The only thing you can do with this new option is "update one commit
> buried in the history, and rebase everything that build on top of it",
It is a good summary indeed.
> as
> far as I can tell. It feels a shame to waste the generic word "--edit" for
> such a narrow option.

I'm bad at bikesheeding. The 'edit' come from the 'edit' command in rebase interactive. I am open to other names. Note that in the following I keep the --edit name, not because I am suborn but because I do not have better to propose yet.

> At the UI level, "git commit --amend HEAD~4" might be a more natural way
> to invoke such an operation, I would think.

As I say in the original email the point of the 'rebase --edit some-commit' is to temporally checkout some-commit so that edits are done in the context of the commit and not in the context of the head of the branch. One has to do a rebase --edit prior to modification (although we can imagine a possibility to bring back the index or the content of the working directory with us either automatically as with a branch checkout or manually with the help of stash).

Unless I misinterpret the 'git commit --amend HEAD~4' you suggest, it means that you have to prepare the commit in the head of the branch. It may be difficult if what was in HEAD~4 is altered by HEAD~2. My argument is that if preparing a patch to HEAD~4 in HEAD is easy, a git commit --fixup will do the tick. If the preparation is difficult because I have to work on (or more insidious, near) change that occurs between HEAD~4 and HEAD, I need something like my proposal. For example I added a line in HEAD~2 but I prefer now to have this line to appears in HEAD~4.

The workflow I propose is :
$ # we are on master
$ git rebase --edit HEAD~4 # workdir is a detached master~4 like with a
                           # git checkout master~4
$ hack hack hack; git add files
$ git commit --amend
$ git rebase --continue # conflict is detected with master~2, resolve it
                        # manually
$ git rebase --continue # workdir is now a rebased master

I do no see what is the workflow with an extend git commit --amend Do you mean something like the following ?

$ git checkout HEAD~4 -- . # bring back the content of master~4 but
                           # HEAD still points master
$ hack hack hack; git add files # And try to now be disturbed by the fact
                                # that diff and status are polluted
                                # with things related to master
$ git commit --amend HEAD~4 # conflict is detected with master~2, resolve it
$ git rebase --continue # Do we really want using "git rebase"?
This last workflow seems so awkward to me that I might miss something.
-- Jean Privat

← back to recent threads