An alternative to git read-tree -m -u is git read-tree --reset -u, which is now documented in Git 2.22 (Q2 2019), and can matter if "state of all files would be set to the same as in commit CommitX" includes merge commits.
See commit b5a0bd6 (01 Apr 2019) by Nguyễn Thái Ngọc Duy (pclouds).
(Merged by Junio C Hamano -- gitster -- in commit 87e20f8, 22 Apr 2019)
read-tree.txt: clarify --reset and worktree changes
The description of --reset stays true to the first implementation in
438195c (git-read-tree: add "--reset" flag, 2005-06-09, Git v0.99).
That is, --reset discards unmerged entries.
Or at least true to the commit message because I can't be sure about read-tree's behavior regarding local changes.
But in fcc387d (read-tree -m -u: do not overwrite or remove untracked
working tree files., 2006-05-17, Git v1.4.0-rc1), it is clear that "-m -u" tries to keep local changes, while --reset is singled out and will keep overwriting
worktree files.
It's not stated in the commit message, but it's obvious from the patch.
I went this far back not because I had a lot of free time, but because I did not trust my reading of unpack-trees.c code. So far I think the
related changes in history agree with my understanding of the current
code, that "--reset" loses local changes.
This behavior is not mentioned in git-read-tree.txt, even though
old-timers probably can just guess it based on the "reset" name.
Update git-read-tree.txt about this.
Side note. There's another change regarding --reset that is not
obviously about local changes, b018ff6 (unpack-trees: fix "read-tree -u --reset A B" with conflicted index, 2012-12-29, Git v1.8.5.2).
But I'm pretty sure this is about the first function of --reset, to discard unmerged entries correctly.
So the documentation now states:
`--reset`:
Same as -m, except that unmerged entries are discarded instead of failing.
When used with -u, updates leading to loss of working tree changes will not abort the operation.