15

When in the middle of an interactive rebase, e.g. git rebase -i HEAD~12 and adding/editing some commits, I'm often confused as to which commit I'm editing, especially when there's a merge conflict:

> git status
rebase in progress; onto 55d9292
You are currently rebasing branch 'master' on '55d9292'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

        both modified:   file

no changes added to commit (use "git add" and/or "git commit -a")

How can I get a clear idea of all the patches involved in the current state? For example, what is the base patch, what patch I'm "picking", which patch the merge conflicts are coming from?

jozxyqk
  • 16,424
  • 12
  • 91
  • 180
  • Does `git log` provide the information you are looking for> – Code-Apprentice Jul 20 '17 at 20:33
  • 1
    Also, when you open `file` in an editor, the conflicts are clearly marked to show where each edit comes from. – Code-Apprentice Jul 20 '17 at 20:34
  • While `git status` knows how to fish this information out of the `.git` state files, their actual format has changed over time and there is no single way to get it. – torek Jul 20 '17 at 20:44
  • For those complex rebases, you now can (Git 2.17, Q2 2018) add the option `--show-current-patch`. See [my answer below](https://stackoverflow.com/a/49215221/6309). – VonC Mar 10 '18 at 23:53
  • Related: https://stackoverflow.com/q/2118364/10095231 – kelvin Apr 05 '19 at 14:10

2 Answers2

11

When in the middle of an interactive rebase, e.g. git rebase -i HEAD~12 and adding/editing some commits, I'm often confused as to which commit I'm editing

With Git 2.17 (Q2 2018), the new "--show-current-patch" option gives an end-user facing way to get the diff being applied when "git rebase" (and "git am") stops with a conflict.

See commit fbd7a23, commit 6633529, commit 984913a (11 Feb 2018) by Nguyễn Thái Ngọc Duy (pclouds).
Helped-by: Tim Landscheidt (scfc).
(Merged by Junio C Hamano -- gitster -- in commit 9ca488c, 06 Mar 2018)

rebase: introduce and use pseudo-ref REBASE_HEAD

The new command git rebase --show-current-patch is useful for seeing the commit related to the current rebase state.
Some, however, may find the "git show" command behind it too limiting.
You may want to increase context lines, do a diff that ignores whitespaces...

For these advanced use cases, the user can execute any command they want with the new pseudo ref REBASE_HEAD.

This also helps show where the stopped commit is from, which is hard to see from the previous patch which implements --show-current-patch.

See also, with Git 2.26 (Q2 2020), the new git rebase/am --show-current-patchd=diff mode.


Git 2.42 (Q3 2023) documents more pseudo-refs, including REBASE_HEAD.

See commit 982ff3a, commit 4fa1edb, commit b7dd54a, commit 1ef3c61, commit 6ec5f46, commit bc11bac (22 May 2023) by Philippe Blain (phil-blain).
(Merged by Junio C Hamano -- gitster -- in commit 0899beb, 20 Jun 2023)

revisions.txt: document more special refs

Signed-off-by: Philippe Blain

Some special refs, namely HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD, are mentioned and described in 'gitrevisions', but some others, namely REBASE_HEAD, REVERT_HEAD, and BISECT_HEAD, are not.

Add a small description of these special refs.

revisions now includes in its man page:

useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD, REBASE_HEAD, REVERT_HEAD, CHERRY_PICK_HEAD and BISECT_HEAD);

revisions now includes in its man page:

REBASE_HEAD:

during a rebase, records the commit at which the operation is currently stopped, either because of conflicts or an edit command in an interactive rebase.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
2

If you have a conflict, you can run git show to see the last applied commit.

Then when opening your conflicting file, the conflict will show in one hand the state of the file at the last applied commit, and on the other hand the state of the file at the commit currently being applied.

Example:

I created a repo with a file "a". My first commit was to create the file:

John@debian-John: ~/tmp/test (master #) ✖ (1)
> touch a
John@debian-John: ~/tmp/test (master #) ✔
> git add a
John@debian-John: ~/tmp/test (master +) ✔
> git commit -m initial
[master (root-commit) 298299e] initial
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

Then, I modified the file and commited it as "commit1":

John@debian-John: ~/tmp/test (master) ✔
> echo aaa >a
John@debian-John: ~/tmp/test (master *) ✔
> git add a
John@debian-John: ~/tmp/test (master +) ✔
> git commit -m commit1
[master 90b49f8] commit1
 1 file changed, 1 insertion(+)

Then, done it again for a commit "commit2":

John@debian-John: ~/tmp/test (master) ✔
> echo bbb >>a
John@debian-John: ~/tmp/test (master *) ✔
> git add a
John@debian-John: ~/tmp/test (master +) ✔
> git commit -m commit2
[master 14d798e] commit2
 1 file changed, 1 insertion(+)

Then I rebased to remove commit1:

John@debian-John: ~/tmp/test (master) ✔
> git rebase -i HEAD^^
Auto-merging a
CONFLICT (content): Merge conflict in a
error: could not apply 14d798e... commit2

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Recorded preimage for 'a'
Could not apply 14d798e... commit2

Commit2 could not be applied because its context changed (commit1 missing). Please note the error: could not apply 14d798e... commit2 which has the hash of commit2. While in the conflict, if I run git show, I get:

John@debian-John: ~/tmp/test (master *+|REBASE-i 1/1) ✖ (1)
> git show
commit 298299e3fb4e75c50aaa346c9f57c3b8885726f7 (HEAD)
Author: John Doe <john@doe>
Date:   Fri Jul 21 15:59:01 2017 +0100

    initial

diff --git a/a b/a
new file mode 100644
index 0000000..e69de29
John@debian-John: ~/tmp/test (master *+|REBASE-i 1/1) ✔
> git status
interactive rebase in progress; onto 298299e
Last command done (1 command done):
   pick 14d798e commit2
No commands remaining.
You are currently rebasing branch 'master' on '298299e'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

    both modified:   a

no changes added to commit (use "git add" and/or "git commit -a")

And the content of a is:

John@debian-John: ~/tmp/test (master +|REBASE-i 1/1) ✔
> cat a
<<<<<<< HEAD
=======
aaa
bbb
>>>>>>> 14d798e... commit2

Where HEAD is the last commit applied (initial) and the second part is the commit which failed to be applied.

I hope it will help.

padawin
  • 4,230
  • 15
  • 19