0

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

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 that 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 rollout of <commit> into the 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?

avenir
  • 149
  • 7
  • 2
    "the index" actually means : "the complete content of `HEAD`, plus the files that are staged for commit" (as opposed to : "only the file that are staged for commit"). Does that shed some light on your understanding ? – LeGEC Sep 08 '22 at 15:20
  • @legec I draw my understanding of the definition of the command in the documentation based solely on its specification of the files that are subject to being updated in the working tree: " updates the files in the working tree that are different between and HEAD". And despite the answers that were provided so far, I fail to see how the file "a" (that got updated) in my example is different between and HEAD. – avenir Sep 09 '22 at 09:24
  • ah, see @LeonardoDagnino's answer : the paragraph for [`--merge`](https://git-scm.com/docs/git-reset#Documentation/git-reset.txt---merge) starts with "Resets the index and ..." : it first discards all staged change. Now that I re-read in details this parahraph, I completely agree with the "the description is quite confusing" part. – LeGEC Sep 09 '22 at 11:11
  • @LeGEC, confusing or not confusing, the definition is either conform with the results produced by the program or not. My example is a simple and straightforward, nevertheless it seems I still cannot convey that my only question, is the definition conform with the results on a toy example. The command itself does what it does, and may be has its own justifications in the git infrastructure, but that doesn't change the fact that documentation is incorrect. – avenir Sep 09 '22 at 11:42
  • By the way, definition of all other modes of `git reset` starts with that they reset the index (except `--soft`), so I don’t understand how does it justify the incorrect definition. – avenir Sep 09 '22 at 11:46

1 Answers1

2

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 the index, otherwise you get the fail condition.

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

Leonardo Dagnino
  • 2,914
  • 7
  • 28
  • You say that "Only files which are altered in your working tree and not staged will be kept". But the documentation states otherwise "but keeps those which are different between the index and working tree (i.e. which have changes that have not been added)". I underline, the documentation states that to be kept as they are in the working tree it suffices that they are different in the index and tree, not that index be the same as HEAD for those files. I don't even mention that the file "a" in my example must not be even concerned by this, because it doesn't differ between HEAD and . – avenir Sep 09 '22 at 09:34
  • My question is not about how the command works, it is about the correctness of the definition given in the documentation, and whether we should file a bug report. – avenir Sep 09 '22 at 09:34
  • Since the files are staged, they are in the index. As such, they are equal to the working tree (the current state of the file). If you also changed them on the working tree (i.e. by having an `echo 4 > a` before the merge), then you'd get the error condition. "changes that have not been added" means "unstaged changes", as such my phrasing and the documentation's are equivalent. – Leonardo Dagnino Sep 09 '22 at 19:35
  • I wrote it wrong: I meant they must not have changes between `` and the index, which will give you the case where reset is aborted. I was just mentioning that for completeness's sake, and to have a hopefully better wording. I'll edit it to be correct. – Leonardo Dagnino Sep 09 '22 at 19:43
  • Okay, after thinking for a while, I actually think you are correct. The text should probably say "updates the files in the working tree that are different between and the index", and it would be correct. Searching about this sent me down a rabbit hole trying to reason about why `--merge` exists; seems like it acts differently when there is an ongoing merge (https://stackoverflow.com/questions/24728543/git-reset-merge-vs-git-reset-keep). Also see this which has interesting info: https://stackoverflow.com/questions/25553175/what-are-typical-use-cases-of-git-resets-merge-and-keep-flags – Leonardo Dagnino Sep 09 '22 at 23:14