{"thread":{"id":"44268","subject":"git merge deletes my changes","startedAt":"2016-10-10T09:56:02Z","lastAt":"2016-10-11T07:45:50Z","messageCount":3,"participants":["Eduard Egorov","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"303701","messageId":"AM4PR03MB1636D18D727968F332F16021DBDB0@AM4PR03MB1636.eurprd03.prod.outlook.com","threadId":"44268","inReplyTo":null,"subject":"git merge deletes my changes","fromName":"Eduard Egorov","fromEmail":"eduard.egorov@icl-services.com","sentAt":"2016-10-10T09:39:13Z","receivedAt":"2016-10-10T09:56:02Z","isPatch":false,"sender":{"key":"eduard.egorov@icl-services.com","avatar":null},"body":"Hello Git experts,\n\nA week ago, I've reset a state of 'ceph-ansible' folder in %current% branch with code from corresponding branch (that tracks an upstream from github):\n\n# git read-tree --prefix=ceph-ansible/ -u ceph_ansible\n\nThen I've committed several changes, including:\n\n1. Renamed file and commited:\n# git mv site.yml.sample site.yml\n\n2. Made some changes and committed\n\n3. Pulled updates from original branch by:\n# git merge -s subtree --squash ceph_ansible\n\nIt said:\n    Auto-merging ceph-ansible/site.yml.sample\n    blablabla\n    Squash commit -- not updating HEAD\n    Automatic merge went well; stopped before committing as requested\n\nI can see that \"my\" ceph-ansible/site.yml is deleted (as well as few new files added by me), ceph-ansible/site.yml.sample is restored and doesn't contain my changes (it's just restored to the state before my changes).\n`git log ceph_ansible site.yml.sample` shows the latest change on ceph_ansible branch done from 26th of August, 2016, my changes in %current% branch was this October, so it shouldn't be any conflict either (even if it was).\nI believe there is some obvious explanation for this behavior. Could you help me please? What information can  I provide in order to troubleshoot this issue? \n\nA post on SO: http://stackoverflow.com/questions/39954265/git-merge-deletes-my-changes\n\nWith best regards\nEduard Egorov\n\n\n"},{"id":"303726","messageId":"20161010152626.frc3ypflwnhzidea@sigill.intra.peff.net","threadId":"44268","inReplyTo":"AM4PR03MB1636D18D727968F332F16021DBDB0@AM4PR03MB1636.eurprd03.prod.outlook.com","subject":"Re: git merge deletes my changes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-10-10T15:26:26Z","receivedAt":"2016-10-10T15:26:57Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Oct 10, 2016 at 09:39:13AM +0000, Eduard Egorov wrote:\n\n> A week ago, I've reset a state of 'ceph-ansible' folder in %current%\n> branch with code from corresponding branch (that tracks an upstream\n> from github):\n> \n> # git read-tree --prefix=ceph-ansible/ -u ceph_ansible\n\nThis pulls in the subtree files, but there's no actual relationship with\nthe commit history in ceph_ansible.\n\nSo later...\n\n> Then I've committed several changes, including:\n> \n> 1. Renamed file and commited:\n> # git mv site.yml.sample site.yml\n> \n> 2. Made some changes and committed\n> \n> 3. Pulled updates from original branch by:\n> # git merge -s subtree --squash ceph_ansible\n> \n> It said:\n>     Auto-merging ceph-ansible/site.yml.sample\n>     blablabla\n>     Squash commit -- not updating HEAD\n>     Automatic merge went well; stopped before committing as requested\n\nWhen you merge from ceph_ansible, there is no shared history, and git\nuses the empty tree as a common ancestor. It looks like the other side\nadded site.yml.sample, for instance, because that is a change from the\nempty tree.\n\n> A post on SO: http://stackoverflow.com/questions/39954265/git-merge-deletes-my-changes\n\nAs you noted on SO, modern git disallows merges of unrelated history by\ndefault, because it's usually a mistake to do so.\n\nIf you are doing repeated merges into the subtree, you need to somehow\ntell git how the histories are related. The obvious answer is to do a\n\"git merge -s ours ceph_ansible\" after your initial read-tree, so that\ngit knows you've pulled in the changes up to that point. But I'd guess\nfrom your use of \"--squash\" that you don't want to carry the\nceph_ansible history in your project.\n\nSo you need to record the original upstream commit somewhere (probably\nin the commit message when you commit the read-tree result), and then\nask git to use that as the merge-base during subsequent merges (which\nwill require using plumbing codes, as git-merge wants to compute the\nmerge base itself).  I believe the git-subtree command (in\ncontrib/subtree of git.git) handles this use case, but I haven't used it\nmyself.\n\n-Peff\n"},{"id":"303856","messageId":"AM4PR03MB163637D73077F3DDEDCF21A9DBDA0@AM4PR03MB1636.eurprd03.prod.outlook.com","threadId":"44268","inReplyTo":"20161010152626.frc3ypflwnhzidea@sigill.intra.peff.net","subject":"RE: git merge deletes my changes","fromName":"Eduard Egorov","fromEmail":"eduard.egorov@icl-services.com","sentAt":"2016-10-11T07:11:19Z","receivedAt":"2016-10-11T07:45:50Z","isPatch":false,"sender":{"key":"eduard.egorov@icl-services.com","avatar":null},"body":"Hello Jeff, Paul\n\nThanks a lot for sharing your time!\n\nAs you correctly stated, I used  \"--squash\" for preventing my project history being flooded with the ceph_ansible's commits and  I didn't really understand that this is critical for having relationship history with other repository.\n\nAlso I realized that made another big mistake - I should use another branch (that is directly branched from 'ceph-ansible' one) for storing my ceph-ansible's code updates. And, periodically, this branch will be merged into my main repo with '-s subtree --squash' without worrying about merge conflicts since this folder would never be changed in main repo's branches.\n\nAgain - thank you very much for your help!\n\nP.S. Please feel free to copy-paste this thread as an answer on SO (http://stackoverflow.com/questions/39954265/git-merge-s-subtree-works-incorrectly ) - I will accept it with great pleasure ;-)\n\nWith best regards\nEduard Egorov\n\n-----Original Message-----\nFrom: Paul Smith [mailto:paul@mad-scientist.net] \nSent: Monday, October 10, 2016 8:52 PM\nTo: Eduard Egorov <Eduard.Egorov@icl-services.com>; 'git@vger.kernel.org' <git@vger.kernel.org>\nSubject: Re: git merge deletes my changes\n\nOn Mon, 2016-10-10 at 10:19 +0000, Eduard Egorov wrote:\n> # ~/gitbuild/git-2.10.1/git merge -s subtree --squash ceph_ansible\n> \n> Can somebody confirm this please? Doesn't \"merge -s subtree\" really \n> merges branches?\n\nI think possibly you're not fully understanding what the --squash flag does... that's what's causing your issue here, not the \"-s\" option.\n\nA squash merge takes the commits that would be merged from the origin branch and squashes them into a single patch and applies them to the current branch as a new commit... but this new commit is not a merge commit (that is, when you look at it with \"git show\" etc. the commit will have only one parent, not two--or more--parents like a normal merge commit).\n\nBasically, it's syntactic sugar for a diff plus patch operation plus some Git goodness wrapped around it to make it easier to use.\n\nBut ultimately once you're done, Git has no idea that this new commit has any relationship whatsoever to the origin branch.  So the next time you merge, Git doesn't know that there was a previous merge and it will try to merge everything from scratch rather than starting at the previous common merge point.\n\nSo either you'll have to use a normal, non-squash merge, or else you'll have to tell Git by hand what the previous common merge point was (as Jeff King's excellent email suggests).  Or else, you'll have to live with this behavior.\n\n-----Original Message-----\nFrom: Jeff King [mailto:peff@peff.net] \nSent: Monday, October 10, 2016 6:26 PM\nTo: Eduard Egorov <Eduard.Egorov@icl-services.com>\nCc: 'git@vger.kernel.org' <git@vger.kernel.org>\nSubject: Re: git merge deletes my changes\n\nOn Mon, Oct 10, 2016 at 09:39:13AM +0000, Eduard Egorov wrote:\n\n> A week ago, I've reset a state of 'ceph-ansible' folder in %current% \n> branch with code from corresponding branch (that tracks an upstream \n> from github):\n> \n> # git read-tree --prefix=ceph-ansible/ -u ceph_ansible\n\nThis pulls in the subtree files, but there's no actual relationship with the commit history in ceph_ansible.\n\nSo later...\n\n> Then I've committed several changes, including:\n> \n> 1. Renamed file and commited:\n> # git mv site.yml.sample site.yml\n> \n> 2. Made some changes and committed\n> \n> 3. Pulled updates from original branch by:\n> # git merge -s subtree --squash ceph_ansible\n> \n> It said:\n>     Auto-merging ceph-ansible/site.yml.sample\n>     blablabla\n>     Squash commit -- not updating HEAD\n>     Automatic merge went well; stopped before committing as requested\n\nWhen you merge from ceph_ansible, there is no shared history, and git uses the empty tree as a common ancestor. It looks like the other side added site.yml.sample, for instance, because that is a change from the empty tree.\n\n> A post on SO: \n> http://stackoverflow.com/questions/39954265/git-merge-deletes-my-chang\n> es\n\nAs you noted on SO, modern git disallows merges of unrelated history by default, because it's usually a mistake to do so.\n\nIf you are doing repeated merges into the subtree, you need to somehow tell git how the histories are related. The obvious answer is to do a \"git merge -s ours ceph_ansible\" after your initial read-tree, so that git knows you've pulled in the changes up to that point. But I'd guess from your use of \"--squash\" that you don't want to carry the ceph_ansible history in your project.\n\nSo you need to record the original upstream commit somewhere (probably in the commit message when you commit the read-tree result), and then ask git to use that as the merge-base during subsequent merges (which will require using plumbing codes, as git-merge wants to compute the merge base itself).  I believe the git-subtree command (in contrib/subtree of git.git) handles this use case, but I haven't used it myself.\n\n-Peff\n"}]}