* Bug Report or Unexpected Feature when "git restore -m ." restores merge conflicted state of a file after a commit
@ 2025-04-30 21:03 Terry Bear
2025-04-30 21:39 ` Junio C Hamano
0 siblings, 1 reply; 2+ messages in thread
From: Terry Bear @ 2025-04-30 21:03 UTC (permalink / raw)
To: git
What did you do before the bug happened? (Steps to reproduce your issue)
Can be replicated on a new repository.
1. Initialize git repo.
git init
2. Create a file
touch test-file
3. Write to the file
"update 1"
4. Stage the changes to the file, create a commit.
git add .
git commit -m "update 1"
5. Copy the branch
git branch -c "main-copy"
6. Write to the file on the same first "main" branch by appending new
content on the second line of the "test-file"
"update 2"
The file looks like:
"update 1"
"update 2"
7. Stage and commit.
git commit -a -m "update 2"
8. Introduce another change to the file but keep it on the work-space
by appending another line
"update 3"
The file looks like:
"update 1"
"update 2"
"update 3"
9. Make a merge switch
git switch --merge main-copy
The file on the "main-copy" branch should look like:
"update 1"
"<<<<<<< main-copy"
"======="
"update 2"
"update 3"
">>>>>>> local"
10. Stage and commit file
git commit -a -m "merge conflict on main-copy"
11. Restore merge-conflicted state
git restore -m .
What did you expect to happen? (Expected behavior)
The "git restore -m ." is not supposed to restore the merge-conflicted
state of the file after it was staged and committed
What happened instead? (Actual behavior)
The "git restore -m ." restored the merge-conflicted state of the file
after it was staged and committed
What's different between what you expected and what actually happened?
The restoration of the merge-conflicted state of the file after it was
staged and committed
Anything else you want to add:
I am not sure whether it is a bug or a feature but the behavior seemed
unexpected and I couldn't find any mentions of it.
[System Info]
git version:
git version 2.34.1
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
uname: Linux 6.8.0-57-generic #59~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC
Wed Mar 19 17:07:41 UTC 2 x86_64
compiler info: gnuc: 11.4
libc info: glibc: 2.35
$SHELL (typically, interactive shell): /bin/bash
[Enabled Hooks]
not run from a git repository - no hooks to show
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: Bug Report or Unexpected Feature when "git restore -m ." restores merge conflicted state of a file after a commit
2025-04-30 21:03 Bug Report or Unexpected Feature when "git restore -m ." restores merge conflicted state of a file after a commit Terry Bear
@ 2025-04-30 21:39 ` Junio C Hamano
0 siblings, 0 replies; 2+ messages in thread
From: Junio C Hamano @ 2025-04-30 21:39 UTC (permalink / raw)
To: Terry Bear; +Cc: git
Terry Bear <terrythebear746@gmail•com> writes:
> 9. Make a merge switch
> git switch --merge main-copy
> The file on the "main-copy" branch should look like:
> "update 1"
> "<<<<<<< main-copy"
> "======="
> "update 2"
> "update 3"
> ">>>>>>> local"
> 10. Stage and commit file
> git commit -a -m "merge conflict on main-copy"
> 11. Restore merge-conflicted state
> git restore -m .
>
> What did you expect to happen? (Expected behavior)
> The "git restore -m ." is not supposed to restore the merge-conflicted
> state of the file after it was staged and committed
Just a quick question. If you did "git reset --hard" between steps
10 and 11, does the outcome change?
I think the behaviour you observed dates back to the very original
implementation of the feature, made in cfc5789a (resolve-undo:
record resolved conflicts in a new index extension section,
2009-12-25).
resolve-undo: record resolved conflicts in a new index extension section
When resolving a conflict using "git add" to create a stage #0 entry, or
"git rm" to remove entries at higher stages, remove_index_entry_at()
function is eventually called to remove unmerged (i.e. higher stage)
entries from the index. Introduce a "resolve_undo_info" structure and
keep track of the removed cache entries, and save it in a new index
extension section in the index_state.
Operations like "read-tree -m", "merge", "checkout [-m] <branch>" and
"reset" are signs that recorded information in the index is no longer
necessary. The data is removed from the index extension when operations
start; they may leave conflicted entries in the index, and later user
actions like "git add" will record their conflicted states afresh.
Notice that "git add" or "git commit -a" are not included in the
operations that are signs that the previous conflicted state no
longer needs to be recreatable? In other words, it is part of the
design that you can take back the conflicted state across "git add"
or "git commit", because you will thank Git later when you realize
that your resolution was broken and you want to redo it after you
finished your step #10.
If you do not want to restore the conflicted state, don't do "git
restore -m ." at that point ;-).
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-04-30 21:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-30 21:03 Bug Report or Unexpected Feature when "git restore -m ." restores merge conflicted state of a file after a commit Terry Bear
2025-04-30 21:39 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox