git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* git rebase: retain original head?
@ 2019-01-08 15:06 Markus Wiederkehr
  2019-01-08 17:43 ` Andreas Schwab
  0 siblings, 1 reply; 11+ messages in thread
From: Markus Wiederkehr @ 2019-01-08 15:06 UTC (permalink / raw)
  To: git

Hello,

I frequently run an interactive rebase to change the order of recent
commits, apply fixups, etc. When merge conflicts occur I often want to
compare the result with the original head prior to starting the
rebase.

In the past I used "git diff ORIG_HEAD". This used to work as long as
I did not manually invoke "git reset" during the operation.

Since git version 2.20.1 (not sure, maybe 2.20.0?) this no longer
works because ORIG_HEAD seems to get modified by fixup commits during
rebase. Now I have to search through reflog to find the commit I want
to compare the current head to.

During the rebase operation the original head seems to get stored in
'rebase-merge/orig-head'. Unfortunately this references gets removed
after the rebase operation completes.

Would it be possible to retain this information? Could you set
ORIG_HEAD back to rebase-merge/orig-head after rebase completes?
Alternatively, could something like REBASE_HEAD be added for this
purpose?

Undoing a rebase would be related to this and is a very popular
question on SO [1]. Users recommend using "git reset --hard ORIG_HEAD"
which now no longer works.

Regards,
Markus

[1] https://stackoverflow.com/questions/134882

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-08 15:06 git rebase: retain original head? Markus Wiederkehr
@ 2019-01-08 17:43 ` Andreas Schwab
  2019-01-08 20:38   ` Markus Wiederkehr
  0 siblings, 1 reply; 11+ messages in thread
From: Andreas Schwab @ 2019-01-08 17:43 UTC (permalink / raw)
  To: Markus Wiederkehr; +Cc: git

On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:

> During the rebase operation the original head seems to get stored in
> 'rebase-merge/orig-head'. Unfortunately this references gets removed
> after the rebase operation completes.
>
> Would it be possible to retain this information?

You could use the reflog of the current branch, where it is the second
entry.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-08 17:43 ` Andreas Schwab
@ 2019-01-08 20:38   ` Markus Wiederkehr
  2019-01-08 20:51     ` Andreas Schwab
  2019-01-08 21:22     ` Jacob Keller
  0 siblings, 2 replies; 11+ messages in thread
From: Markus Wiederkehr @ 2019-01-08 20:38 UTC (permalink / raw)
  To: git

On Tue, Jan 8, 2019 at 6:43 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:
>
> > Would it be possible to retain this information?
>
> You could use the reflog of the current branch, where it is the second
> entry.

It is not, depending on what happens in the rebase it could be any
entry. That's why I always have to search for the right one, which is
tedious.

Example:

$ git rebase -i root-tag
... (apply one fixup)
$ git reflog
906caf1c (HEAD -> master) HEAD@{0}: rebase -i (finish): returning to
refs/heads/master
4906caf1c (HEAD -> master) HEAD@{1}: rebase -i (pick): qux
85dab37b4 HEAD@{2}: rebase -i (pick): baz
7de7420d2 HEAD@{3}: rebase -i (fixup): bar
9bc0461c0 HEAD@{4}: rebase -i (start): checkout root-tag
a150b73ca HEAD@{5}: commit: foo

Here I have to use HEAD@{5}.

Markus

On Tue, Jan 8, 2019 at 6:43 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:
>
> > During the rebase operation the original head seems to get stored in
> > 'rebase-merge/orig-head'. Unfortunately this references gets removed
> > after the rebase operation completes.
> >
> > Would it be possible to retain this information?
>
> You could use the reflog of the current branch, where it is the second
> entry.
>
> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-08 20:38   ` Markus Wiederkehr
@ 2019-01-08 20:51     ` Andreas Schwab
  2019-01-09 13:48       ` Markus Wiederkehr
  2019-01-08 21:22     ` Jacob Keller
  1 sibling, 1 reply; 11+ messages in thread
From: Andreas Schwab @ 2019-01-08 20:51 UTC (permalink / raw)
  To: Markus Wiederkehr; +Cc: git

On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:

> On Tue, Jan 8, 2019 at 6:43 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>>
>> On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:
>>
>> > Would it be possible to retain this information?
>>
>> You could use the reflog of the current branch, where it is the second
>> entry.
>
> It is not, depending on what happens in the rebase it could be any
> entry.

Don't look at the HEAD reflog, use the branch reflog, ie. @{1}.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-08 20:38   ` Markus Wiederkehr
  2019-01-08 20:51     ` Andreas Schwab
@ 2019-01-08 21:22     ` Jacob Keller
  2019-01-09 14:05       ` Johannes Schindelin
  1 sibling, 1 reply; 11+ messages in thread
From: Jacob Keller @ 2019-01-08 21:22 UTC (permalink / raw)
  To: Markus Wiederkehr; +Cc: Git mailing list

On Tue, Jan 8, 2019 at 12:47 PM Markus Wiederkehr
<markus.wiederkehr@gmail.com> wrote:
>
> On Tue, Jan 8, 2019 at 6:43 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> >
> > On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:
> >
> > > Would it be possible to retain this information?
> >
> > You could use the reflog of the current branch, where it is the second
> > entry.
>
> It is not, depending on what happens in the rebase it could be any
> entry. That's why I always have to search for the right one, which is
> tedious.
>
> Example:
>
> $ git rebase -i root-tag
> ... (apply one fixup)
> $ git reflog
> 906caf1c (HEAD -> master) HEAD@{0}: rebase -i (finish): returning to
> refs/heads/master
> 4906caf1c (HEAD -> master) HEAD@{1}: rebase -i (pick): qux
> 85dab37b4 HEAD@{2}: rebase -i (pick): baz
> 7de7420d2 HEAD@{3}: rebase -i (fixup): bar
> 9bc0461c0 HEAD@{4}: rebase -i (start): checkout root-tag
> a150b73ca HEAD@{5}: commit: foo
>
> Here I have to use HEAD@{5}.
>

He meant using:

$ git reflog master

which only shows changes directly to the master ref, not to HEAD.
During a git rebase operations don't modify the master ref until after
the rebase finishes. This, of course, assumes you're on a branch.

If so, you should even be able to use master@{1} and be safe in
assuming it always refers to what the branch was before the rebase
started.

Thanks,
Jake

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-08 20:51     ` Andreas Schwab
@ 2019-01-09 13:48       ` Markus Wiederkehr
  0 siblings, 0 replies; 11+ messages in thread
From: Markus Wiederkehr @ 2019-01-09 13:48 UTC (permalink / raw)
  To: git

On Tue, Jan 8, 2019 at 10:29 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:
>
> > It is not, depending on what happens in the rebase it could be any
> > entry.
>
> Don't look at the HEAD reflog, use the branch reflog, ie. @{1}.

That's exactly what I was looking for, thanks!

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-08 21:22     ` Jacob Keller
@ 2019-01-09 14:05       ` Johannes Schindelin
  2019-01-09 15:08         ` Markus Wiederkehr
  2019-02-27  5:45         ` Nazri Ramliy
  0 siblings, 2 replies; 11+ messages in thread
From: Johannes Schindelin @ 2019-01-09 14:05 UTC (permalink / raw)
  To: Jacob Keller; +Cc: Markus Wiederkehr, Git mailing list

Hi Jake,

On Tue, 8 Jan 2019, Jacob Keller wrote:

> On Tue, Jan 8, 2019 at 12:47 PM Markus Wiederkehr
> <markus.wiederkehr@gmail.com> wrote:
> >
> > On Tue, Jan 8, 2019 at 6:43 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> > >
> > > On Jan 08 2019, Markus Wiederkehr <markus.wiederkehr@gmail.com> wrote:
> > >
> > > > Would it be possible to retain this information?
> > >
> > > You could use the reflog of the current branch, where it is the second
> > > entry.
> >
> > It is not, depending on what happens in the rebase it could be any
> > entry. That's why I always have to search for the right one, which is
> > tedious.
> >
> > Example:
> >
> > $ git rebase -i root-tag
> > ... (apply one fixup)
> > $ git reflog
> > 906caf1c (HEAD -> master) HEAD@{0}: rebase -i (finish): returning to
> > refs/heads/master
> > 4906caf1c (HEAD -> master) HEAD@{1}: rebase -i (pick): qux
> > 85dab37b4 HEAD@{2}: rebase -i (pick): baz
> > 7de7420d2 HEAD@{3}: rebase -i (fixup): bar
> > 9bc0461c0 HEAD@{4}: rebase -i (start): checkout root-tag
> > a150b73ca HEAD@{5}: commit: foo
> >
> > Here I have to use HEAD@{5}.
> >
> 
> He meant using:
> 
> $ git reflog master

Indeed. That's why terse answers are often worse than no answers at all:
more often than not, they leave things unclearer than before, in the worst
case they are misleading, as was the very terse first reply. Just don't.
Too short is not beautiful.

> which only shows changes directly to the master ref, not to HEAD.
> During a git rebase operations don't modify the master ref until after
> the rebase finishes. This, of course, assumes you're on a branch.
> 
> If so, you should even be able to use master@{1} and be safe in
> assuming it always refers to what the branch was before the rebase
> started.

There are more tricks up Git's sleeves: @{1} is a shorthand for the
previous state of the current branch (if any). So after you rebase a
branch, @{1} will refer to what previously was ORIG_HEAD.

Having said that, it is an unintended regression in the built-in rebase.
Markus, could you come up with a minimal test case, preferably in the form
of a patch to t/t3415-rebase-autosquash.sh?

Thanks,
Johannes

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-09 14:05       ` Johannes Schindelin
@ 2019-01-09 15:08         ` Markus Wiederkehr
  2019-01-11 10:42           ` Johannes Schindelin
  2019-02-27  5:45         ` Nazri Ramliy
  1 sibling, 1 reply; 11+ messages in thread
From: Markus Wiederkehr @ 2019-01-09 15:08 UTC (permalink / raw)
  To: Git mailing list

On Wed, Jan 9, 2019 at 3:05 PM Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
>
> Having said that, it is an unintended regression in the built-in rebase.
> Markus, could you come up with a minimal test case, preferably in the form
> of a patch to t/t3415-rebase-autosquash.sh?

I don't think I'm familiar enough with the test code to be able to
provide a good patch but the following code should illustrate the
regression.

git init testrepo
cd testrepo
echo 1 > file && git add file && git commit -m "initial"
echo 1 >> file && git commit -am "commit 1"
# rev_commit_1=$(git rev-parse HEAD)
echo 1 >> file && git commit -am "fixup! $(git rev-parse --short HEAD)"
echo 1 >> file && git commit -am "commit 3"
rev_orig_head=$(git rev-parse HEAD)
GIT_EDITOR=: git rebase --autosquash -i HEAD~3
test $(git rev-parse ORIG_HEAD) = $rev_orig_head

In older versions of git this test succeeded, i.e. ORIG_HEAD pointed
to the previous original head, $rev_orig_head. In git version 2.20.1
ORIG_HEAD now points to the commit that got fixuped instead,
$rev_commit_1.

In previous versions ORIG_HEAD only pointed somewhere else if "git
reset" was invoked manually during the rebase operation. I'm not sure
if this is desirable, maybe ORIG_HEAD should always point to the
previous head after rebase completes, no matter what operations were
run in between. What do you think?

Markus

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-09 15:08         ` Markus Wiederkehr
@ 2019-01-11 10:42           ` Johannes Schindelin
  0 siblings, 0 replies; 11+ messages in thread
From: Johannes Schindelin @ 2019-01-11 10:42 UTC (permalink / raw)
  To: Markus Wiederkehr; +Cc: Git mailing list

Hi Markus,

On Wed, 9 Jan 2019, Markus Wiederkehr wrote:

> On Wed, Jan 9, 2019 at 3:05 PM Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> >
> > Having said that, it is an unintended regression in the built-in rebase.
> > Markus, could you come up with a minimal test case, preferably in the form
> > of a patch to t/t3415-rebase-autosquash.sh?
> 
> I don't think I'm familiar enough with the test code to be able to
> provide a good patch but the following code should illustrate the
> regression.

I think that you think you're too unfamiliar with the test code only
because you have not had a look.

> git init testrepo
> cd testrepo
> echo 1 > file && git add file && git commit -m "initial"

test_commit initial

> echo 1 >> file && git commit -am "commit 1"

test_commit 1 initial.t

> # rev_commit_1=$(git rev-parse HEAD)
> echo 1 >> file && git commit -am "fixup! $(git rev-parse --short HEAD)"

test_commit "fixup! 1" initial.t

> echo 1 >> file && git commit -am "commit 3"

test_commit 3 initial.t

> rev_orig_head=$(git rev-parse HEAD)
> GIT_EDITOR=: git rebase --autosquash -i HEAD~3
> test $(git rev-parse ORIG_HEAD) = $rev_orig_head

test_cmp_rev $rev_orig_head ORIG_HEAD

I leave it to you to make the actual patch.

Ciao,
Johannes

> 
> In older versions of git this test succeeded, i.e. ORIG_HEAD pointed
> to the previous original head, $rev_orig_head. In git version 2.20.1
> ORIG_HEAD now points to the commit that got fixuped instead,
> $rev_commit_1.
> 
> In previous versions ORIG_HEAD only pointed somewhere else if "git
> reset" was invoked manually during the rebase operation. I'm not sure
> if this is desirable, maybe ORIG_HEAD should always point to the
> previous head after rebase completes, no matter what operations were
> run in between. What do you think?
> 
> Markus
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-01-09 14:05       ` Johannes Schindelin
  2019-01-09 15:08         ` Markus Wiederkehr
@ 2019-02-27  5:45         ` Nazri Ramliy
  2019-02-28 10:10           ` Johannes Schindelin
  1 sibling, 1 reply; 11+ messages in thread
From: Nazri Ramliy @ 2019-02-27  5:45 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Jacob Keller, Markus Wiederkehr, Git mailing list

On Wed, Jan 9, 2019 at 10:08 PM Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Having said that, it is an unintended regression in the built-in rebase.
> Markus, could you come up with a minimal test case, preferably in the form
> of a patch to t/t3415-rebase-autosquash.sh?

Something like this, perhaps? ("gmail converts tabs to spaces" caveat
applies to the diff formatting):

--8<--
diff --git t/t3400-rebase.sh t/t3400-rebase.sh
index 3e73f7584c..cb55597a8b 100755
--- t/t3400-rebase.sh
+++ t/t3400-rebase.sh
@@ -59,6 +59,13 @@ test_expect_success 'rebase against master' '
  git rebase master
 '

+test_expect_success 'rebase sets ORIG_HEAD' '
+ echo Add B. > expect &&
+ echo Modify A. >> expect &&
+ git log --oneline --format=%s ORIG_HEAD.. > actual &&
+ test_cmp expect actual
+'
+
 test_expect_success 'rebase, with <onto> and <upstream> specified as
:/quuxery' '
  test_when_finished "git branch -D torebase" &&
  git checkout -b torebase my-topic-branch^ &&
-->8--

Bisect shows that the first bad commit is this one:

commit 21853626eac565dd42572d90724b29863f61eb3b
Author: Johannes Schindelin <johannes.schindelin@gmx.de>
Date:   Fri Jan 18 07:09:27 2019 -0800

    built-in rebase: call `git am` directly

I verified that by undoing the crux of that commit, and that fixes the
failing test:

-->8--
diff --git builtin/rebase.c builtin/rebase.c
index 7c7bc13e91..848f6740a0 100644
--- builtin/rebase.c
+++ builtin/rebase.c
@@ -728,11 +728,6 @@ static int run_specific_rebase(struct rebase_options *opts)
  goto finished_rebase;
  }

- if (opts->type == REBASE_AM) {
- status = run_am(opts);
- goto finished_rebase;
- }
-
  add_var(&script_snippet, "GIT_DIR", absolute_path(get_git_dir()));
  add_var(&script_snippet, "state_dir", opts->state_dir);

--8<--

But something seems off by my bisection in that the "bad" commit
happens about 10 days after this email thread :/

nazri

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: git rebase: retain original head?
  2019-02-27  5:45         ` Nazri Ramliy
@ 2019-02-28 10:10           ` Johannes Schindelin
  0 siblings, 0 replies; 11+ messages in thread
From: Johannes Schindelin @ 2019-02-28 10:10 UTC (permalink / raw)
  To: Nazri Ramliy; +Cc: Jacob Keller, Markus Wiederkehr, Git mailing list

Hi Nazri,

On Wed, 27 Feb 2019, Nazri Ramliy wrote:

> On Wed, Jan 9, 2019 at 10:08 PM Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:

Oh wow. Better late than never, eh?

> > Having said that, it is an unintended regression in the built-in
> > rebase. Markus, could you come up with a minimal test case, preferably
> > in the form of a patch to t/t3415-rebase-autosquash.sh?
> 
> Something like this, perhaps? ("gmail converts tabs to spaces" caveat
> applies to the diff formatting):
> 
> --8<--
> diff --git t/t3400-rebase.sh t/t3400-rebase.sh
> index 3e73f7584c..cb55597a8b 100755
> --- t/t3400-rebase.sh
> +++ t/t3400-rebase.sh
> @@ -59,6 +59,13 @@ test_expect_success 'rebase against master' '
>   git rebase master
>  '
> 
> +test_expect_success 'rebase sets ORIG_HEAD' '
> + echo Add B. > expect &&
> + echo Modify A. >> expect &&
> + git log --oneline --format=%s ORIG_HEAD.. > actual &&
> + test_cmp expect actual
> +'
> +
>  test_expect_success 'rebase, with <onto> and <upstream> specified as
> :/quuxery' '
>   test_when_finished "git branch -D torebase" &&
>   git checkout -b torebase my-topic-branch^ &&
> -->8--

I made it a little more stand-alone, and can confirm that this is now
safely a regression in v2.21.0.

> Bisect shows that the first bad commit is this one:
> 
> commit 21853626eac565dd42572d90724b29863f61eb3b
> Author: Johannes Schindelin <johannes.schindelin@gmx.de>
> Date:   Fri Jan 18 07:09:27 2019 -0800
> 
>     built-in rebase: call `git am` directly
> 
> I verified that by undoing the crux of that commit, and that fixes the
> failing test:
> 
> -->8--
> diff --git builtin/rebase.c builtin/rebase.c
> index 7c7bc13e91..848f6740a0 100644
> --- builtin/rebase.c
> +++ builtin/rebase.c
> @@ -728,11 +728,6 @@ static int run_specific_rebase(struct rebase_options *opts)
>   goto finished_rebase;
>   }
> 
> - if (opts->type == REBASE_AM) {
> - status = run_am(opts);
> - goto finished_rebase;
> - }
> -
>   add_var(&script_snippet, "GIT_DIR", absolute_path(get_git_dir()));
>   add_var(&script_snippet, "state_dir", opts->state_dir);
> 
> --8<--
> 
> But something seems off by my bisection in that the "bad" commit
> happens about 10 days after this email thread :/

Yep, I had fixed the issue before this commit, and a regression test would
have come in handy to prevent that regression from creeping in *again*.

Anyway, I'm on it.
Johannes

P.S.: If you want to follow my progress, I'll push updates to the
rebase-am-and-orig-head branch at https://github.com/dscho/git.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-02-28 10:10 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-08 15:06 git rebase: retain original head? Markus Wiederkehr
2019-01-08 17:43 ` Andreas Schwab
2019-01-08 20:38   ` Markus Wiederkehr
2019-01-08 20:51     ` Andreas Schwab
2019-01-09 13:48       ` Markus Wiederkehr
2019-01-08 21:22     ` Jacob Keller
2019-01-09 14:05       ` Johannes Schindelin
2019-01-09 15:08         ` Markus Wiederkehr
2019-01-11 10:42           ` Johannes Schindelin
2019-02-27  5:45         ` Nazri Ramliy
2019-02-28 10:10           ` Johannes Schindelin

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).