Home > Software engineering >  git reset --merge discrepancy with documentation
git reset --merge discrepancy with documentation

Time:09-09

Is it me or is the documentation for the --merge option of git reset formulated poorly or even incorectly?

I cite the documentation:

Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added). If a file that is different between <commit> and the index has unstaged changes, reset is aborted.

Not speaking about the fail condition of the command and speaking only of the first sentence. Does it mean that the files that don’t differ between <commit> and HEAD are not subject to the roll out of <commit> into working directory?

I try the following script that doesn't change the file a between HEAD and HEAD~1:

#!/bin/bash
git init
echo 1 > a
echo 1 > b
git add .
git commit -m 1
echo 2 > b
git add .
git commit -m 2
echo 3 > a
echo 3 > b
git add .
git reset --merge HEAD~1
cat a
cat b
rm -rf .git

Why do the contents of the file a still get reset when they are supposed to stay unchanged?

CodePudding user response:

The key here is the start of the description:

Resets the index,

Resetting the index means that it will become the same as the referred commit, with the specified exceptions. The index is the HEAD including staged files; as such resetting it will also remove any staged files.

Only files which are altered in your working tree and not staged will be kept. They must also not have changed between <commit> and HEAD, otherwise you get the fail condition.

I do agree the description is quite confusing, maybe it could be better.

CodePudding user response:

The doc says that only files with no diff with their index version will be preserved. A file with modifications but which has been git added will be reverted.

In your example : both a and b are staged, they will both get reset.

Here is a modified version of your script, hoping to highlight this point :

#!/bin/bash

# warning: don't run this script in a place where you would have a 'foo'
# directory with relevant data in it ...

mkdir foo
cd foo

git init
echo 1 > a
echo 1 > b
echo 1 > c
git add .
git commit -m 1

echo 2 > b
git add .
git commit -m 2

echo 3 > a # a now has modifications wrt the index (the index version is the one from HEAD, with '1')
echo 3 > b 
git add b  # b now has staged modifications, but no modification in the worktree
## uncomment the 3 lines below to see what happens: having a file with modifications in the index and modification in the worktree
## prevents git reset --merge from working
# echo 2 > c
# git add c
# echo 3 > c # c now has modifications wrt the index (the index version is the 'git add' one, with '2')
echo "
# before reset:"

echo "\$ git status"
git status
echo "\$ cat a"
cat a
echo "\$ cat b"
cat b
echo "\$ cat c"
cat c
git reset --merge HEAD~1

echo "
# after reset:"
echo "\$ git status"
git status
echo "\$ cat a"  # a on disk is unchanged
cat a
echo "\$ cat b"  # b has been reverted to its content in HEAD~1
cat b
echo "\$ cat c"
cat c

cd ..

rm -rf foo
  •  Tags:  
  • git
  • Related