{"thread":{"id":"38577","subject":"Potential Bug: git merge overwrites uncommitted changes","startedAt":"2015-02-17T04:26:38Z","lastAt":"2015-02-17T04:26:38Z","messageCount":1,"participants":["Martin Maas"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"256182","messageId":"CAHBpcCZMqFyFga4hyGQA3Sum3Lsn=knR1i9PAHr8G+Zyx8FepA@mail.gmail.com","threadId":"38577","inReplyTo":null,"subject":"Potential Bug: git merge overwrites uncommitted changes","fromName":"Martin Maas","fromEmail":"maas@eecs.berkeley.edu","sentAt":"2015-02-17T04:26:38Z","receivedAt":"2015-02-17T04:26:38Z","isPatch":false,"sender":{"key":"maas@eecs.berkeley.edu","avatar":null},"body":"Hi all,\n\nTeaching a university class using git, we encountered a case of\npotentially incorrect behavior when students made changes to a file,\nforgot to commit them, and then pulled a new one-line change from our\nremote repository. This resulted in the uncommitted changes being\noverwritten without a warning.\n\nTo our understanding, the expected behavior should have been a warning\nthat uncommitted files are being overwritten, or an auto-merge that\npreserves the changes in the uncommitted files. Instead, git shows the\nmerge as a single-line change, while in reality discarding potentially\na large number of uncommitted lines.\n\nI have attached a script that replicates this behavior -- we have been\nable to replicate the problem with git versions 1.9.1, 1.9.3 and\n2.2.2. Please let us know whether this is a bug, or whether this is\nthe intended behavior.\n\nIt appears that it is only this specific sequence of commands that\ncauses the behavior. Across a range of small modifications to the\nsequence of steps, the behavior is as expected:\n\n* using git cp and dropping the add step -> modifications preserved\n* not doing commit 2 (or its changes) -> modifications live in new file\n* any change in branch use other than test first master second ->\nmodifications preserved\n\n(Asking colleagues, one of them pointed me to the following article\nwhich describes a potentially related problem that appears to have\nbeen fixed in 1.7.7:\nhttp://benno.id.au/blog/2011/10/01/git-recursive-merge-broken)\n\nThanks,\nMartin\n\n---\n\ngit-test.sh: Run in a clean directory!\n\n#!/bin/bash\n\n# Replicate the two different states of hw2_starter, before and after\nour update.\ngit clone git@github.com:cs61c-spring2015/hw2_starter.git\ncd hw2_starter\ngit checkout f8a2e4418b4c370921790d1dfd1b6f9761262d4a\ngit checkout -b test\ncd ..\n\n# Set up the cs61c-xx repository, and fetch \"first\" hw2_starter.\nmkdir cs61c-test\ncd cs61c-test\ngit init\ngit remote add hw2_starter ../hw2_starter/\ngit fetch hw2_starter\ngit merge hw2_starter/test -m \"add hw2 changes\"\n\n# Perform a series of commits that some students accidentally did.\nmkdir hw2\ngit mv hw1 hw2\ngit commit -a -m \"commit 1\"\n\ncp hw2/hw1/* hw2/\ngit add hw2/*\ngit commit -a -m \"commit 2\"\n\n# Now we make changes to the beargit.c file, but don't commit them.\nfor i in `seq 1 5`; do\necho \"beargitcode line $i\" >> hw2/beargit.c\ndone\n\necho\necho\necho \" *** SHOULD HAVE A LINE CONTAINING beargitcode IN beargit.c ***\"\necho\necho \"CONTENT OF beargit.c | grep beargitcode BEFORE MERGE:\"\ncat hw2/beargit.c | grep beargitcode\necho \"[EOF]\"\necho\n\n# Now we fetch the update, as we told students\ngit fetch hw2_starter\ngit merge hw2_starter/master -m \"add hw2 changes\"\n\n# This should fail, because there are uncommitted changes!!!\n\necho\necho \"CONTENT OF beargit.c | grep beargitcode AFTER MERGE:\"\ncat hw2/beargit.c | grep beargitcode\necho \"[EOF]\"\necho\n"}]}