threads / bug / 33567

[BUG] Silent data loss on merge with uncommited changes + renames

Subject: [BUG] Silent data loss on merge with uncommited changes + renames

## tl;dr

4 messages between Apr 22, 2013 and Apr 22, 2013.

replies: 3people: 3as markdown or json

Matthieu Moy· Apr 22, 2013, 09:24 UTC · lore
Hi,

Following the discussion on "merge with uncommited changes" inside the "git pull --autostash" thread, I did a bit of testing, and encountered a case with silent data loss. In short: merge a branch introducing changes to a file. If the file has been renamed in the current branch, then "git merge" follows the rename and brings changes to the renamed file, but uncommited changes in this file are overriden silently.

I could have expected "git merge --abort" to fail, but the problem is really more serious here: data loss is done silently before giving me an opportunity to do or abort anything.

Reproduction script below:
#! /bin/sh

# Create repo git init git.$$ cd git.$$ echo init > test.txt git add test.txt git commit -m init

# Make a branch changing test.txt git checkout -b branch echo new > test.txt git commit -am new

# Move test.txt on master git checkout master git mv test.txt moved.txt git commit -m move

# Make uncommited changes to moved.txt echo precious > moved.txt

# Merge loses uncommited content "precious" in "moved.txt" silently git merge --no-edit branch ls # lists just moved.txt git status # nothing to commit, working directory clean cat moved.txt # Says "new".

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Johannes Sixt· Apr 22, 2013, 14:23 UTC · re: Matthieu Moy · lore

Re: [BUG] Silent data loss on merge with uncommited changes + renames

Am 4/22/2013 11:24, schrieb Matthieu Moy:
Show 6 quoted lines
> Following the discussion on "merge with uncommited changes" inside the
> "git pull --autostash" thread, I did a bit of testing, and encountered a
> case with silent data loss. In short: merge a branch introducing changes
> to a file. If the file has been renamed in the current branch, then "git
> merge" follows the rename and brings changes to the renamed file, but
> uncommited changes in this file are overriden silently.
Can you check whether your case is already covered by one of:
  git grep expect_failure t/*merge*
and if not, contribute a test case?
-- Hannes
Matthieu Moy· Apr 22, 2013, 14:43 UTC · re: Johannes Sixt · lore

Re: [BUG] Silent data loss on merge with uncommited changes + renames

Johannes Sixt <j.sixt@viscovery.net> writes:
Show 11 quoted lines
> Am 4/22/2013 11:24, schrieb Matthieu Moy:
>> Following the discussion on "merge with uncommited changes" inside the
>> "git pull --autostash" thread, I did a bit of testing, and encountered a
>> case with silent data loss. In short: merge a branch introducing changes
>> to a file. If the file has been renamed in the current branch, then "git
>> merge" follows the rename and brings changes to the renamed file, but
>> uncommited changes in this file are overriden silently.
>
> Can you check whether your case is already covered by one of:
>
>   git grep expect_failure t/*merge*
Indeed, it's already here:
test_expect_failure 'will not overwrite unstaged changes in renamed file' '
	git reset --hard c1 &&
	git mv c1.c other.c &&
	git commit -m rename &&
	cp important other.c &&
	git merge c1a &&
	test_cmp important other.c
'
-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Junio C Hamano· Apr 22, 2013, 15:19 UTC · re: Matthieu Moy · lore

Re: [BUG] Silent data loss on merge with uncommited changes + renames

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
> I could have expected "git merge --abort" to fail, but the problem is
> really more serious here: data loss is done silently before giving me an
> opportunity to do or abort anything.

I think this is a well known and longstanding failure case in the recursive merge. As it does not perform its internal operation while handling renames in clean and distinct steps (i.e. figure out what goes to where before touching any index entry or working tree, then check if a proposed change to the index or the working tree conflicts with local changes, and finally carry out the proposed change), it is somewhat hard to fix it correctly in the current implementation, even though you probably could patch these up case by case basis.

← back to recent threads