2

For example, let's say that there was a conflict during a merge into master, like this.

A --- M <- master
    /
B -

Sometimes I find out that the conflict, or the commit B was too messy (for example, crlf changes on all files) so I decide to reset the file status to A and modify feature specific files only. (i.e. write M from scratch.)

However, if I do git reset --hard ., the files are resetted but also the MERGE_HEAD is deleted afterwards, making it impossible to create a merge commit.(fatal: There is no merge in progress (MERGE_HEAD missing).)

How can I reset all files while perserving MERGE_HEAD?

ik1ne
  • 1,041
  • 15
  • 20

3 Answers3

2

Check if, with Git 2.23+ (August 2019), you can do it with one command: git restore (man page)

git restore --source=HEAD --staged --worktree -- .

I just tested it:

vonc@VONC D:\git\git
> git restore --source=@ --staged --worktree  --ignore-unmerged -- .
warning: path 'mru.h' is unmerged
warning: path 't/t2028-worktree-move.sh' is unmerged

vonc@VONC D:\git\git
> git st
On branch master
Your branch is up to date with 'origin/master'.

All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   sha1collisiondetection (new commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        mru.h
        t/t2028-worktree-move.sh

Still merging:

> dir .git
 Volume in drive D is data
 Volume Serial Number is xxx

 Directory of D:\git\git\.git

10/03/2019  20:04                 2 COMMIT_EDITMSG
10/03/2019  20:06               593 config
19/06/2016  09:15                73 description
27/07/2019  08:55               483 FETCH_HEAD
15/12/2017  07:28         5 324 666 gitk.cache
27/07/2019  08:55                23 HEAD
19/06/2016  09:15    <DIR>          hooks
31/08/2019  13:54           358 360 index
27/04/2019  18:25    <DIR>          info
05/03/2018  23:34    <DIR>          lfs
27/04/2019  18:25    <DIR>          logs
31/08/2019  13:42                41 MERGE_HEAD   <===
31/08/2019  13:42                 0 MERGE_MODE   <===
31/08/2019  13:42             1 295 MERGE_MSG    <===
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

It can't be done with one command, but these two commands will achieve that.

  1. git reset -- . to reset index only.

  2. git checkout -- . to discard working copy changes.

After this MERGE_HEAD exists while file changes are discarded.

ik1ne
  • 1,041
  • 15
  • 20
-1

If you don't have Git 2.23, you can achieve the same thing with git rm -r -- .; git checkout HEAD -- . or (simpler) git read-tree --reset -m -u HEAD.

The initial git rm -r is only required if you have files in commit B that are new since the merge base between A and B and you don't want them in the merge, so:

git checkout HEAD -- .

usually suffices. This has basically the same effect as the new:

git restore --source=HEAD --staged --worktree -- .

(the difference between --no-overlay and --overlay has to do with these new files).

torek
  • 448,244
  • 59
  • 642
  • 775