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