threads / discuss / 26600

Revert a single commit in a single file

Subject: Revert a single commit in a single file

## tl;dr

13 messages between Feb 25, 2011 and Feb 26, 2011.

replies: 12people: 6as markdown or json

Thomas Ferris Nicolaisen· Feb 25, 2011, 10:34 UTC · lore
I tried asking the same question on the "newbie" list some time ago:
http://groups.google.com/group/git-users/browse_thread/thread/d562b4eeac016711
Basically, when I go
> git revert <commit> <path>

.. my expectation was that a new commit would be made reverting the changes from the old commit, but only for specified path/file.

Maybe it's a bit of a corner-case, but still would be nice to have once in a while. What do you think?

Ævar Arnfjörð Bjarmason· Feb 25, 2011, 11:17 UTC · re: Thomas Ferris Nicolaisen · lore

Re: Revert a single commit in a single file

On Fri, Feb 25, 2011 at 11:34, Thomas Ferris Nicolaisen <tfnico@gmail.com> wrote:

Show 12 quoted lines
> I tried asking the same question on the "newbie" list some time ago:
>
> http://groups.google.com/group/git-users/browse_thread/thread/d562b4eeac016711
>
> Basically, when I go
>> git revert <commit> <path>
>
> .. my expectation was that a new commit would be made reverting the
> changes from the old commit, but only for specified path/file.
>
> Maybe it's a bit of a corner-case, but still would be nice to have
> once in a while. What do you think?
It would. What you can do in the meantime is:
    git revert <commit>
    git reset
    git add <path>
    git commit ...
    git reset --hard # making sure you didn't have uncommited changes earlier
Michael J Gruber· Feb 25, 2011, 12:37 UTC · re: Ævar Arnfjörð Bjarmason · lore

Re: Revert a single commit in a single file

Ævar Arnfjörð Bjarmason venit, vidit, dixit 25.02.2011 12:17:
Show 18 quoted lines
> On Fri, Feb 25, 2011 at 11:34, Thomas Ferris Nicolaisen
> <tfnico@gmail.com> wrote:
>> I tried asking the same question on the "newbie" list some time ago:
>>
>> http://groups.google.com/group/git-users/browse_thread/thread/d562b4eeac016711
>>
>> Basically, when I go
>>> git revert <commit> <path>
>>
>> .. my expectation was that a new commit would be made reverting the
>> changes from the old commit, but only for specified path/file.
>>
>> Maybe it's a bit of a corner-case, but still would be nice to have
>> once in a while. What do you think?
> 
> It would. What you can do in the meantime is:
> 
>     git revert <commit>

Ævar meant to write "git revert --no-commit <commit>" here. (Or there wouldn't be anything to reset and add.)

>     git reset
>     git add <path>
>     git commit ...
>     git reset --hard # making sure you didn't have uncommited changes earlier

If you want to revert changes to all files but a few, you can do it the other way round (revert, checkout HEAD^ -- <path>, commit --amend).

Cheers, Michael

Dario Rodriguez· Feb 25, 2011, 12:48 UTC · re: Michael J Gruber · lore

Re: Revert a single commit in a single file

The most sensible way to do this seems to be:
 git checkout HEAD~2 file.c

And your index will show file.c modified, as it will have it's content reverted 2 commits.

The behavior of 'revert' is to revert commits, not files, so it's not expected to work if you say 'git revert <commit> <path>'

Cheers, Dario

On Fri, Feb 25, 2011 at 9:37 AM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

Show 38 quoted lines
> Ævar Arnfjörð Bjarmason venit, vidit, dixit 25.02.2011 12:17:
>> On Fri, Feb 25, 2011 at 11:34, Thomas Ferris Nicolaisen
>> <tfnico@gmail.com> wrote:
>>> I tried asking the same question on the "newbie" list some time ago:
>>>
>>> http://groups.google.com/group/git-users/browse_thread/thread/d562b4eeac016711
>>>
>>> Basically, when I go
>>>> git revert <commit> <path>
>>>
>>> .. my expectation was that a new commit would be made reverting the
>>> changes from the old commit, but only for specified path/file.
>>>
>>> Maybe it's a bit of a corner-case, but still would be nice to have
>>> once in a while. What do you think?
>>
>> It would. What you can do in the meantime is:
>>
>>     git revert <commit>
>
> Ævar meant to write "git revert --no-commit <commit>" here. (Or there
> wouldn't be anything to reset and add.)
>
>>     git reset
>>     git add <path>
>>     git commit ...
>>     git reset --hard # making sure you didn't have uncommited changes earlier
>
> If you want to revert changes to all files but a few, you can do it the
> other way round (revert, checkout HEAD^ -- <path>, commit --amend).
>
> Cheers,
> Michael
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
Michael J Gruber· Feb 25, 2011, 13:05 UTC · re: Dario Rodriguez · lore

Re: Revert a single commit in a single file

Dario Rodriguez venit, vidit, dixit 25.02.2011 13:48:
> The most sensible way to do this seems to be:
To do what? I you hadn't top posted we would know what "this" referred to.
>  git checkout HEAD~2 file.c
> 
> And your index will show file.c modified, as it will have it's content
> reverted 2 commits.

It will have its content reset to what it was in HEAD~2. This is very different from reverting the change made in HEAD~2:

> The behavior of 'revert' is to revert commits, not files, so it's not
> expected to work if you say 'git revert <commit> <path>'
It makes perfect sense, it's just not implemented.
Note that you can also
git show <commit> -- <path> | git apply -R
to achieve a partial revert. That might be the easiest route to take.
Michael
[Cutting the bottom copy - what is it good for there?]
Thomas Ferris Nicolaisen· Feb 25, 2011, 14:38 UTC · re: Michael J Gruber · lore

Re: Revert a single commit in a single file

Ævar, Michael, thanks for the tips.
Dario: Yes, I understand the reasoning. It's not often a problem, and
when it occurs there are ways to do it. I just thought I'd bring it up
on the list cause it feels like expected behavior (other git commands
behave correspondingly).

On Fri, Feb 25, 2011 at 2:05 PM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

Show 5 quoted lines
> Note that you can also
>
> git show <commit> -- <path> | git apply -R
>
> to achieve a partial revert. That might be the easiest route to take.
Indeed it is. Neat command, thanks again!
Dario Rodriguez· Feb 25, 2011, 15:19 UTC · re: Thomas Ferris Nicolaisen · lore

Re: Revert a single commit in a single file

Michael, my comment was about "reverting the changes from the old commit, but only for specified path/file", sorry about non quoting it.

I think that ''the old commit" is HEAD~1, so reverting it is about checking out HEAD~2, and commiting the results. The same is for a given file.

On Fri, Feb 25, 2011 at 11:38 AM, Thomas Ferris Nicolaisen <tfnico@gmail.com> wrote:

> Dario: Yes, I understand the reasoning. It's not often a problem, and
> when it occurs there are ways to do it. I just thought I'd bring it up
> on the list cause it feels like expected behavior (other git commands
> behave correspondingly).
Yeah, and may be your reasoning is better for the principle of least surprise.

Cheers, Dario

Junio C Hamano· Feb 25, 2011, 18:53 UTC · re: Thomas Ferris Nicolaisen · lore

Re: Revert a single commit in a single file

Thomas Ferris Nicolaisen <tfnico@gmail.com> writes:
Show 12 quoted lines
> I tried asking the same question on the "newbie" list some time ago:
>
> http://groups.google.com/group/git-users/browse_thread/thread/d562b4eeac016711
>
> Basically, when I go
>> git revert <commit> <path>
>
> .. my expectation was that a new commit would be made reverting the
> changes from the old commit, but only for specified path/file.
>
> Maybe it's a bit of a corner-case, but still would be nice to have
> once in a while. What do you think?

I am afraid that it would lead to encouraging people to record a horribly broken history, unless you think carefully about what the resulting commit log message should describe. It would look _as if_ you negated the effect of the original commit as a whole, but in reality you are only reverting just a part of what you chose to revert with <path>.

We do encourage people to record the _reason_ why the particular commit was removed by not supporting "-m <message>" option to "git revert" command, but the commit template in the editor given to the user should make it absolutely clear that the particular partial revert is reverting only a part of the original commit, and need additional words to strongly encourage to record why only that part and not other parts are reverted.

Ævar Arnfjörð Bjarmason· Feb 25, 2011, 19:43 UTC · re: Junio C Hamano · lore

Re: Revert a single commit in a single file

On Fri, Feb 25, 2011 at 19:53, Junio C Hamano <gitster@pobox.com> wrote:
Show 27 quoted lines
> Thomas Ferris Nicolaisen <tfnico@gmail.com> writes:
>
>> I tried asking the same question on the "newbie" list some time ago:
>>
>> http://groups.google.com/group/git-users/browse_thread/thread/d562b4eeac016711
>>
>> Basically, when I go
>>> git revert <commit> <path>
>>
>> .. my expectation was that a new commit would be made reverting the
>> changes from the old commit, but only for specified path/file.
>>
>> Maybe it's a bit of a corner-case, but still would be nice to have
>> once in a while. What do you think?
>
> I am afraid that it would lead to encouraging people to record a horribly
> broken history, unless you think carefully about what the resulting commit
> log message should describe.  It would look _as if_ you negated the effect
> of the original commit as a whole, but in reality you are only reverting
> just a part of what you chose to revert with <path>.
>
> We do encourage people to record the _reason_ why the particular commit
> was removed by not supporting "-m <message>" option to "git revert"
> command, but the commit template in the editor given to the user should
> make it absolutely clear that the particular partial revert is reverting
> only a part of the original commit, and need additional words to strongly
> encourage to record why only that part and not other parts are reverted.

Agreed, but FWIW where I work I've seen people record "horribly broken history" already because git-revert doesn't support this, and they don't know the trick I described.

I also don't agree that the history would be horribly broken. The message is just an advisory template, it's always the content that changed that we care about, and we can analyze the history and see that this chunk is the reverse of a chunk in a previous commit.

But just like we now have:
    Revert "some commit"
    This partially reverts commit <sha1>.
We could have with <path>:
    Revert "some commit"
    This partially reverts commit <sha1>. Only the path <path> has
    been reverted, which is X out of Y files changed in the original
    commit.
Or something like that.
Junio C Hamano· Feb 25, 2011, 19:54 UTC · re: Ævar Arnfjörð Bjarmason · lore

Re: Revert a single commit in a single file

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
Show 15 quoted lines
> But just like we now have:
>
>     Revert "some commit"
>
>     This partially reverts commit <sha1>.
>
> We could have with <path>:
>
>     Revert "some commit"
>
>     This partially reverts commit <sha1>. Only the path <path> has
>     been reverted, which is X out of Y files changed in the original
>     commit.
>
> Or something like that.
Yes, that is exactly what I was suggesting, no?

On the similar line of thought, it might be a good idea to update the commit template we give slightly perhaps like...

     Revert "some commit"
     This partially reverts commit <sha1>.
    +#
    +# DESCRBE HERE how the change in <sha1>
    +# was a wrong thing to do.
Ævar Arnfjörð Bjarmason· Feb 25, 2011, 20:05 UTC · re: Junio C Hamano · lore

Re: Revert a single commit in a single file

On Fri, Feb 25, 2011 at 20:54, Junio C Hamano <gitster@pobox.com> wrote:
Show 19 quoted lines
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> But just like we now have:
>>
>>     Revert "some commit"
>>
>>     This partially reverts commit <sha1>.
>>
>> We could have with <path>:
>>
>>     Revert "some commit"
>>
>>     This partially reverts commit <sha1>. Only the path <path> has
>>     been reverted, which is X out of Y files changed in the original
>>     commit.
>>
>> Or something like that.
>
> Yes, that is exactly what I was suggesting, no?

Yes in the second paragraph, I was mainly just going to expand on it and provide a suggestion.

But I mainly wanted to point out that not having this feature means that people do completely manual reverts. So I think we'd have less "broken" history (message), not more as a result of this sort of thing.

Show 9 quoted lines
> On the similar line of thought, it might be a good idea to update the
> commit template we give slightly perhaps like...
>
>     Revert "some commit"
>
>     This partially reverts commit <sha1>.
>    +#
>    +# DESCRBE HERE how the change in <sha1>
>    +# was a wrong thing to do.

Yes this looks very good. Aside from the UI issue of someone expanding on why they did that *inside the comment* because that's what it suggests :)

    This partially reverts commit <sha1>.
    # DESCRIBE ABOVE ...
Would probably be better.
Jay Soffian· Feb 25, 2011, 20:22 UTC · re: Junio C Hamano · lore

Re: Revert a single commit in a single file

On Fri, Feb 25, 2011 at 2:54 PM, Junio C Hamano <gitster@pobox.com> wrote:
> On the similar line of thought, it might be a good idea to update the
> commit template we give slightly perhaps like...
>
>     Revert "some commit"

<bikeshed> Maybe:

      Partially revert "some commit"

to make it easier to notice in summaries. </bikeshed>

j.
Dario Rodriguez· Feb 26, 2011, 00:27 UTC · re: Jay Soffian · lore

Re: Revert a single commit in a single file

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
Show 7 quoted lines
> We could have with <path>:
>
>     Revert "some commit"
>
>     This partially reverts commit <sha1>. Only the path <path> has
>     been reverted, which is X out of Y files changed in the original
>     commit.
Perhaps you want to do something like:
     git revert <commit> <path1> <path2> ...

In such case the text "Only de path <path>..." makes no sense. I think something like:

     Partial Revert (x/y) "some commit"
     This partially reverts commit <sha1>

...whould be a better choice. Summaries will show that 'x' of the 'y' files committed in <sha1> have been reverted.

Cheers

← back to recent threads