threads / bug / 38577

Potential Bug: git merge overwrites uncommitted changes

Subject: Potential Bug: git merge overwrites uncommitted changes

## tl;dr

One message between Feb 17, 2015 and Feb 17, 2015.

replies: 0people: 1as markdown or json

Martin Maas· Feb 17, 2015, 04:26 UTC · lore
Hi all,

Teaching a university class using git, we encountered a case of potentially incorrect behavior when students made changes to a file, forgot to commit them, and then pulled a new one-line change from our remote repository. This resulted in the uncommitted changes being overwritten without a warning.

To our understanding, the expected behavior should have been a warning that uncommitted files are being overwritten, or an auto-merge that preserves the changes in the uncommitted files. Instead, git shows the merge as a single-line change, while in reality discarding potentially a large number of uncommitted lines.

I have attached a script that replicates this behavior -- we have been able to replicate the problem with git versions 1.9.1, 1.9.3 and 2.2.2. Please let us know whether this is a bug, or whether this is the intended behavior.

It appears that it is only this specific sequence of commands that causes the behavior. Across a range of small modifications to the sequence of steps, the behavior is as expected:

* using git cp and dropping the add step -> modifications preserved
* not doing commit 2 (or its changes) -> modifications live in new file
* any change in branch use other than test first master second ->
modifications preserved

(Asking colleagues, one of them pointed me to the following article which describes a potentially related problem that appears to have been fixed in 1.7.7: http://benno.id.au/blog/2011/10/01/git-recursive-merge-broken)

Thanks, Martin

---
git-test.sh: Run in a clean directory!
#!/bin/bash

# Replicate the two different states of hw2_starter, before and after our update. git clone git@github.com:cs61c-spring2015/hw2_starter.git cd hw2_starter git checkout f8a2e4418b4c370921790d1dfd1b6f9761262d4a git checkout -b test cd ..

# Set up the cs61c-xx repository, and fetch "first" hw2_starter. mkdir cs61c-test cd cs61c-test git init git remote add hw2_starter ../hw2_starter/ git fetch hw2_starter git merge hw2_starter/test -m "add hw2 changes"

# Perform a series of commits that some students accidentally did. mkdir hw2 git mv hw1 hw2 git commit -a -m "commit 1"

cp hw2/hw1/* hw2/ git add hw2/* git commit -a -m "commit 2"

# Now we make changes to the beargit.c file, but don't commit them. for i in `seq 1 5`; do echo "beargitcode line $i" >> hw2/beargit.c done

echo echo echo " *** SHOULD HAVE A LINE CONTAINING beargitcode IN beargit.c ***" echo echo "CONTENT OF beargit.c | grep beargitcode BEFORE MERGE:" cat hw2/beargit.c | grep beargitcode echo "[EOF]" echo

# Now we fetch the update, as we told students git fetch hw2_starter git merge hw2_starter/master -m "add hw2 changes"

# This should fail, because there are uncommitted changes!!!

echo echo "CONTENT OF beargit.c | grep beargitcode AFTER MERGE:" cat hw2/beargit.c | grep beargitcode echo "[EOF]" echo

← back to recent threads