{"thread":{"id":"35412","subject":"How to pre-empt git pull merge error?","startedAt":"2013-11-27T15:17:27Z","lastAt":"2013-11-28T08:25:39Z","messageCount":7,"participants":["Pete Forman","Konstantin Khomoutov","Matthieu Moy","Antoine Pelisse","Thomas Rast","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"231193","messageId":"86d2llc1rs.fsf@gmail.com","threadId":"35412","inReplyTo":null,"subject":"How to pre-empt git pull merge error?","fromName":"Pete Forman","fromEmail":"petef4+usenet@gmail.com","sentAt":"2013-11-27T15:17:27Z","receivedAt":"2013-11-27T15:17:27Z","isPatch":false,"sender":{"key":"petef4+usenet@gmail.com","avatar":null},"body":"I am looking for a way of detecting up front whether a git pull or git\nmerge would fail. The sort of script I want to perform is to update a\nserver.\n\n    git fetch\n    git okay\n    stop server\n    backup data\n    git merge\n    start server\n\nHere git okay is a place holder for the command I am asking for.\n\nIf a file has been changed outside of a commit then git pull fails with\nthe following error.\n\nerror: Your local changes to '...' would be overwritten by merge.\nAborting. Please, commit your changes or stash them before you can\nmerge.\n\nI would like git okay to perform the pre-merge checks described in git\nmerge and return non-zero status so that the script aborts before the\nserver is stopped.\n\nPossibilities I have looked for and not found include git merge\n--dry-run. My best line of thought is git status --porcelain |\npre-merge-okay. That seems like a lot of work to make a pre-merge-okay\nthat deals with things like benign untracked files.\n\nI have also asked this question on Stack Overflow but received no\nanswers.\n\nhttp://stackoverflow.com/questions/20221383/\n\n-- \nPete Forman\n"},{"id":"231194","messageId":"20131127194240.2abaff5575961b3d73e1970f@domain007.com","threadId":"35412","inReplyTo":"86d2llc1rs.fsf@gmail.com","subject":"Re: How to pre-empt git pull merge error?","fromName":"Konstantin Khomoutov","fromEmail":"flatworm@users.sourceforge.net","sentAt":"2013-11-27T15:42:40Z","receivedAt":"2013-11-27T15:42:40Z","isPatch":false,"sender":{"key":"flatworm@users.sourceforge.net","avatar":null},"body":"On Wed, 27 Nov 2013 15:17:27 +0000\nPete Forman <petef4+usenet@gmail.com> wrote:\n\n> I am looking for a way of detecting up front whether a git pull or git\n> merge would fail. The sort of script I want to perform is to update a\n> server.\n> \n>     git fetch\n>     git okay\n>     stop server\n>     backup data\n>     git merge\n>     start server\n> \n> Here git okay is a place holder for the command I am asking for.\n> \n> If a file has been changed outside of a commit then git pull fails\n> with the following error.\n> \n> error: Your local changes to '...' would be overwritten by merge.\n> Aborting. Please, commit your changes or stash them before you can\n> merge.\n\nWhat's wrong with \"git okay\" being\n\nif git merge whatever 2>/dev/null; then\n  ... OK path\nelse\n  ... \"merge failed\" path\nfi\n\n?\n"},{"id":"231195","messageId":"vpq8uw9q1r4.fsf@anie.imag.fr","threadId":"35412","inReplyTo":"20131127194240.2abaff5575961b3d73e1970f@domain007.com","subject":"Re: How to pre-empt git pull merge error?","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2013-11-27T15:54:07Z","receivedAt":"2013-11-27T15:54:07Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Konstantin Khomoutov <flatworm@users.sourceforge.net> writes:\n\n> On Wed, 27 Nov 2013 15:17:27 +0000\n> Pete Forman <petef4+usenet@gmail.com> wrote:\n>\n>> I am looking for a way of detecting up front whether a git pull or git\n>> merge would fail. The sort of script I want to perform is to update a\n>> server.\n>> \n>>     git fetch\n>>     git okay\n>>     stop server\n>>     backup data\n>>     git merge\n>>     start server\n>> \n>> Here git okay is a place holder for the command I am asking for.\n>> \n>> If a file has been changed outside of a commit then git pull fails\n>> with the following error.\n>> \n>> error: Your local changes to '...' would be overwritten by merge.\n>> Aborting. Please, commit your changes or stash them before you can\n>> merge.\n>\n> What's wrong with \"git okay\" being\n>\n> if git merge whatever 2>/dev/null; then\n>   ... OK path\n> else\n>   ... \"merge failed\" path\n> fi\n\nThe idea seems to be to stop the server before actually doing the merge\n(and avoid doing so if the merge is bound to fail).\n\nI don't know a simple way to do the pre-merge check without actually\ndoing the merge (other than patching git merge to add a --dry-run\noption), but you can do a pessimistic check by using the\nrequire_work_tree_exists shell function defined in git-sh-setup (copied\nbelow, but you can call it from a shell script after doing\n. \"$(git --exec-path)/git-sh-setup\"):\n\nrequire_clean_work_tree () {\n\tgit rev-parse --verify HEAD >/dev/null || exit 1\n\tgit update-index -q --ignore-submodules --refresh\n\terr=0\n\n\tif ! git diff-files --quiet --ignore-submodules\n\tthen\n\t\techo >&2 \"Cannot $1: You have unstaged changes.\"\n\t\terr=1\n\tfi\n\n\tif ! git diff-index --cached --quiet --ignore-submodules HEAD --\n\tthen\n\t\tif [ $err = 0 ]\n\t\tthen\n\t\t    echo >&2 \"Cannot $1: Your index contains uncommitted changes.\"\n\t\telse\n\t\t    echo >&2 \"Additionally, your index contains uncommitted changes.\"\n\t\tfi\n\t\terr=1\n\tfi\n\n\tif [ $err = 1 ]\n\tthen\n\t\ttest -n \"$2\" && echo >&2 \"$2\"\n\t\texit 1\n\tfi\n}\n\nAdditionally, you may want to check that the merge is a fast-forward\n(hence can't result in merge conflict), e.g. by checking that the\ncurrent commit is the merge base between itself and the commit to merge\n(git merge-base HEAD $commit).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"231198","messageId":"CALWbr2wNODeLSmQ5ztQmKVxBSguNJ1bbSbvY66sdsP09dSUUgA@mail.gmail.com","threadId":"35412","inReplyTo":"vpq8uw9q1r4.fsf@anie.imag.fr","subject":"Re: How to pre-empt git pull merge error?","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2013-11-27T16:38:46Z","receivedAt":"2013-11-27T16:38:46Z","isPatch":false,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":">> On Wed, 27 Nov 2013 15:17:27 +0000\n>> Pete Forman <petef4+usenet@gmail.com> wrote:\n>>\n>>> I am looking for a way of detecting up front whether a git pull or git\n>>> merge would fail. The sort of script I want to perform is to update a\n>>> server.\n>>>\n>>>     git fetch\n>>>     git okay\n>>>     stop server\n>>>     backup data\n>>>     git merge\n>>>     start server\n>>>\n> I don't know a simple way to do the pre-merge check without actually\n> doing the merge (other than patching git merge to add a --dry-run\n> option)\n\nWouldn't that be a nice use-case for git-recursive-merge --index-only\n($gmane/236753) ?\n"},{"id":"231205","messageId":"878uw9hdf0.fsf@thomasrast.ch","threadId":"35412","inReplyTo":"CALWbr2wNODeLSmQ5ztQmKVxBSguNJ1bbSbvY66sdsP09dSUUgA@mail.gmail.com","subject":"Re: How to pre-empt git pull merge error?","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-27T19:06:59Z","receivedAt":"2013-11-27T19:06:59Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Antoine Pelisse <apelisse@gmail.com> writes:\n\n>>> On Wed, 27 Nov 2013 15:17:27 +0000\n>>> Pete Forman <petef4+usenet@gmail.com> wrote:\n>>>\n>>>> I am looking for a way of detecting up front whether a git pull or git\n>>>> merge would fail. The sort of script I want to perform is to update a\n>>>> server.\n>>>>\n>>>>     git fetch\n>>>>     git okay\n>>>>     stop server\n>>>>     backup data\n>>>>     git merge\n>>>>     start server\n>>>>\n>> I don't know a simple way to do the pre-merge check without actually\n>> doing the merge (other than patching git merge to add a --dry-run\n>> option)\n>\n> Wouldn't that be a nice use-case for git-recursive-merge --index-only\n> ($gmane/236753) ?\n\nPossibly, but most of the use-cases for merge --dry-run are better\nanswered by the XY Problem question:\n\nCan you step back and explain what the *underlying* goal is?\n\nThe above sounds a lot like a deployment script, and such scripts are\nalmost always better served by using an actual deployment tool, or\nfailing that, by using some form of checkout -f instead, to ensure that\nthey get whatever they are supposed to deploy.\n\n(Using a merge to update is really terrible in the face of\nnon-fast-forward updates, especially when caused by rewriting history to\nnot include some commits.)\n\n-- \nThomas Rast\ntr@thomasrast.ch\n"},{"id":"231209","messageId":"xmqqvbzdsj2s.fsf@gitster.dls.corp.google.com","threadId":"35412","inReplyTo":"CALWbr2wNODeLSmQ5ztQmKVxBSguNJ1bbSbvY66sdsP09dSUUgA@mail.gmail.com","subject":"Re: How to pre-empt git pull merge error?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-27T20:09:15Z","receivedAt":"2013-11-27T20:09:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Antoine Pelisse <apelisse@gmail.com> writes:\n\n>>> On Wed, 27 Nov 2013 15:17:27 +0000\n>>> Pete Forman <petef4+usenet@gmail.com> wrote:\n>>>\n>>>> I am looking for a way of detecting up front whether a git pull or git\n>>>> merge would fail. The sort of script I want to perform is to update a\n>>>> server.\n>>>>\n>>>>     git fetch\n>>>>     git okay\n>>>>     stop server\n>>>>     backup data\n>>>>     git merge\n>>>>     start server\n>>>>\n>> I don't know a simple way to do the pre-merge check without actually\n>> doing the merge (other than patching git merge to add a --dry-run\n>> option)\n>\n> Wouldn't that be a nice use-case for git-recursive-merge --index-only\n> ($gmane/236753) ?\n\nAs the original mentions \"error: Your local changes to ...\", I do\nnot think it would be a good fit.\n\nI have to say that the safest and sanest way may be to:\n\n (1) Commit any such local change(s);\n\n     server$ git commit -a\n\n (2) Pull that down to a pre-deploy repository from the \"server\";\n\n     prepare$ git pull ...to grab the \"local changes\" above...\n\n (3) Merge in whatever the update you want to have on the \"server\";\n\n     prepare$ git merge ...whatever...\n\n (4) and then stop the server, fast-forward to the result of (3),\n     and then restart.\n\n     server$ stop server\n     server$ git pull --ff-only ...the prepared result of (3)...\n     server$ start server\n"},{"id":"231226","messageId":"864n6x2arg.fsf@gmail.com","threadId":"35412","inReplyTo":"878uw9hdf0.fsf@thomasrast.ch","subject":"Re: How to pre-empt git pull merge error?","fromName":"Pete Forman","fromEmail":"petef4+usenet@gmail.com","sentAt":"2013-11-28T08:25:39Z","receivedAt":"2013-11-28T08:25:39Z","isPatch":false,"sender":{"key":"petef4+usenet@gmail.com","avatar":null},"body":"Thomas Rast <tr@thomasrast.ch> writes:\n\n> Antoine Pelisse <apelisse@gmail.com> writes:\n>\n>>>> On Wed, 27 Nov 2013 15:17:27 +0000\n>>>> Pete Forman <petef4+usenet@gmail.com> wrote:\n>>>>\n>>>>> I am looking for a way of detecting up front whether a git pull or\n>>>>> git merge would fail. The sort of script I want to perform is to\n>>>>> update a server.\n>>>>>\n>>>>>     git fetch\n>>>>>     git okay\n>>>>>     stop server\n>>>>>     backup data\n>>>>>     git merge\n>>>>>     start server\n>>>>>\n>>> I don't know a simple way to do the pre-merge check without actually\n>>> doing the merge (other than patching git merge to add a --dry-run\n>>> option)\n>>\n>> Wouldn't that be a nice use-case for git-recursive-merge --index-only\n>> ($gmane/236753) ?\n>\n> Possibly, but most of the use-cases for merge --dry-run are better\n> answered by the XY Problem question:\n>\n> Can you step back and explain what the *underlying* goal is?\n>\n> The above sounds a lot like a deployment script, and such scripts are\n> almost always better served by using an actual deployment tool, or\n> failing that, by using some form of checkout -f instead, to ensure\n> that they get whatever they are supposed to deploy.\n>\n> (Using a merge to update is really terrible in the face of\n> non-fast-forward updates, especially when caused by rewriting history\n> to not include some commits.)\n\nIt is a deployment script and updates are fast-forward. There was a\nproblem on a test server where a file had been hacked to investigate an\nissue. The next deploy failed with the merge error.\n\nThere are three approaches, which might all be done with git or an\nactual deployment tool.\n\n1. test early, bail out if deploy would fail\n2. set target to good state before applying the merge\n2a. discard changes\n2b. stash changes\n\nI intend to use (1). First I will need to clean up the stray files or add\nmore entries into .gitignore.\n\n  test -z \"$(git status --porcelain)\"\n\n\n-- \nPete Forman\nhttp://petef.22web.org/payg.html\n"}]}