{"thread":{"id":"19240","subject":"I want \"fast forward my workdir to upstream if it's safe\"","startedAt":"2009-05-07T21:40:00Z","lastAt":"2009-05-11T20:11:31Z","messageCount":12,"participants":["Randal L. Schwartz","Wincent Colaiuta","Jeff King","Andreas Ericsson","Eyvind Bernhardsen","Junio C Hamano","Jakub Narebski","Miles Bader"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"113270","messageId":"86prekfv7z.fsf@blue.stonehenge.com","threadId":"19240","inReplyTo":null,"subject":"I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2009-05-07T21:40:00Z","receivedAt":"2009-05-07T21:40:00Z","isPatch":false,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":"\nFor the past few years, within any given 12 hour period, at least\none person on #git would come up with the use case with which I'm\nreally familiar (having needed it many times myself):\n\n  I have a workdir tracking a remote.\n  I may or may not have made local edits... I can't remember.\n  I may or may not have made local commits... I can't remember.\n  But the upstream might now have changed... please update me *safely*.\n\nSeriously, this comes up, a lot.  Typically, from a cron job updater,\nbut often just \"what can I do to make sure I'm up to date\".\n\nSo, what I need is a command, likely an option to \"git merge\" that says \"do\neverything that a git merge would do except abort if it would have been a\nmerge commit\".  In other words, abort if the workdir is dirty or is not a\nfast-forward update to the upstream.  Bonus if it exits non-zero if\nsomething went wrong.\n\nPlease don't tell me \"use these three commands in this script\".\nI want a *command* I can tell people in #git.\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nSmalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.\nSee http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion\n"},{"id":"113278","messageId":"FC9BF880-D69F-4A56-B9FA-EF5BDBF73437@wincent.com","threadId":"19240","inReplyTo":"86prekfv7z.fsf@blue.stonehenge.com","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2009-05-07T23:18:32Z","receivedAt":"2009-05-07T23:18:32Z","isPatch":false,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 7/5/2009, a las 23:40, Randal L. Schwartz escribió:\n\n> For the past few years, within any given 12 hour period, at least\n> one person on #git would come up with the use case with which I'm\n> really familiar (having needed it many times myself):\n>\n>  I have a workdir tracking a remote.\n>  I may or may not have made local edits... I can't remember.\n>  I may or may not have made local commits... I can't remember.\n>  But the upstream might now have changed... please update me *safely*.\n>\n> Seriously, this comes up, a lot.  Typically, from a cron job updater,\n> but often just \"what can I do to make sure I'm up to date\".\n>\n> So, what I need is a command, likely an option to \"git merge\" that  \n> says \"do\n> everything that a git merge would do except abort if it would have  \n> been a\n> merge commit\".  In other words, abort if the workdir is dirty or is  \n> not a\n> fast-forward update to the upstream.  Bonus if it exits non-zero if\n> something went wrong.\n>\n> Please don't tell me \"use these three commands in this script\".\n> I want a *command* I can tell people in #git.\n\n\"git status\"?\n\n# On branch master\n# Your branch is ahead of 'origin/master' by 46 commits.\n#\n# Changed but not updated:\n#   (use \"git add <file>...\" to update what will be committed)\n#   (use \"git checkout -- <file>...\" to discard changes in working  \ndirectory)\n#\n#       modified:   foo\n#\n# Untracked files:\n#   (use \"git add <file>...\" to include in what will be committed)\n#\n#       bar\n"},{"id":"113279","messageId":"86ljp8fqkp.fsf@blue.stonehenge.com","threadId":"19240","inReplyTo":"FC9BF880-D69F-4A56-B9FA-EF5BDBF73437@wincent.com","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2009-05-07T23:20:22Z","receivedAt":"2009-05-07T23:20:22Z","isPatch":false,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"Wincent\" == Wincent Colaiuta <win@wincent.com> writes:\n\n>> I want a *command* I can tell people in #git.\n\nWincent> \"git status\"?\n\nWincent> # On branch master\nWincent> # Your branch is ahead of 'origin/master' by 46 commits.\nWincent> #\nWincent> # Changed but not updated:\nWincent> #   (use \"git add <file>...\" to update what will be committed)\nWincent> #   (use \"git checkout -- <file>...\" to discard changes in working  directory)\nWincent> #\nWincent> #       modified:   foo\nWincent> #\nWincent> # Untracked files:\nWincent> #   (use \"git add <file>...\" to include in what will be committed)\nWincent> #\nWincent> #       bar\n\nNow, you expect them to parse that in a script?  \"git status\" is porcelain,\nnot plumbing, and can change from version to version, and has.\n\nI want a command I can put in a cron job that Does The Right Thing.\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nSmalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.\nSee http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion\n"},{"id":"113300","messageId":"20090508023028.GA1218@coredump.intra.peff.net","threadId":"19240","inReplyTo":"86prekfv7z.fsf@blue.stonehenge.com","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-05-08T02:30:28Z","receivedAt":"2009-05-08T02:30:28Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, May 07, 2009 at 02:40:00PM -0700, Randal L. Schwartz wrote:\n\n> So, what I need is a command, likely an option to \"git merge\" that says \"do\n> everything that a git merge would do except abort if it would have been a\n> merge commit\".  In other words, abort if the workdir is dirty or is not a\n> fast-forward update to the upstream.  Bonus if it exits non-zero if\n> something went wrong.\n\nCan you define more clearly what you want, because you are asking for\nconflicting things. \"abort if it would have been a merge commit\" is\npurely about fast forward. But it sounds like you also care about \"would\nmerge have succeeded\". So I think you are asking for:\n\n  1. There are no local commits on the branch.\n\nand one of:\n\n  2a. There are no local edits.\n\n  2b. There are no local edits in the same files as those that are\n      affected by any new commits from upstream.\n\n  2c. Any local edits you have done would not cause a conflict if merged\n      with what's in upstream.\n\nAnd before I discuss those further, let me address:\n\n> Please don't tell me \"use these three commands in this script\".\n> I want a *command* I can tell people in #git.\n\nby saying that I don't think there is currently a single command to\ncover both (1) and (2) (any of the (2) options). So we need to talk\nabout \"use these three commands in a script\" for a moment to figure out\nwhat such a command _should_ do, and then we can talk about putting it\ninto a single command (and presumably making that command part of the\ngit distribution) that you can tell people about in #git.\n\nBoth (1) and (2) involve finding out who your upstream is. As of 1.6.3,\nthis is easy to do as:\n\n  upstream=`git for-each-ref --format='%(upstream)' `git symbolic-ref HEAD`\n\nOne you have that, (1) is easy:\n\n  test -z \"`git rev-list -1 $upstream..HEAD`\"\n\n(2a) is also pretty easy:\n\n  git diff-files --quiet && git diff-index --quiet\n\n(2b) is a bit harder, but do-able:\n\n  git diff-tree --name-only HEAD $upstream | sort >them\n  (git diff-files --name-only; git diff-index --name-only) | sort >us\n  test -z \"`comm -12 us them`\"\n\n(2c) is the trickiest (and of course, therefore probably the one you\nwant ;) ).  I'm not sure there is a simple way to do it short of hacking\ngit-merge to actually try the merge and roll it back. Because you really\nhave to deal not just with merging actual text file content but with\ncustom merge drivers.\n\nSo what is it that you're looking for?\n\n-Peff\n\nPS I took your request at face value, but I actually think this question\nshows that the asker is not using git as it was intended. Unless you are\nvery clueful (i.e., willing to sort out any mess caused by a failed\nmerge), you should almost certainly be merging with a clean working\ntree. In other words, you should not be afraid of making a commit, and\n_then_ merging, as you might be in a non-distributed VCS.\n"},{"id":"113310","messageId":"4A03D6E2.2050708@op5.se","threadId":"19240","inReplyTo":"20090508023028.GA1218@coredump.intra.peff.net","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2009-05-08T06:53:22Z","receivedAt":"2009-05-08T06:53:22Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Jeff King wrote:\n> On Thu, May 07, 2009 at 02:40:00PM -0700, Randal L. Schwartz wrote:\n> \n>> So, what I need is a command, likely an option to \"git merge\" that says \"do\n>> everything that a git merge would do except abort if it would have been a\n>> merge commit\".  In other words, abort if the workdir is dirty or is not a\n>> fast-forward update to the upstream.  Bonus if it exits non-zero if\n>> something went wrong.\n> \n> Can you define more clearly what you want, because you are asking for\n> conflicting things. \"abort if it would have been a merge commit\" is\n> purely about fast forward. But it sounds like you also care about \"would\n> merge have succeeded\". So I think you are asking for:\n> \n>   1. There are no local commits on the branch.\n> \n> and one of:\n> \n>   2a. There are no local edits.\n> \n>   2b. There are no local edits in the same files as those that are\n>       affected by any new commits from upstream.\n> \n>   2c. Any local edits you have done would not cause a conflict if merged\n>       with what's in upstream.\n> \n> And before I discuss those further, let me address:\n> \n>> Please don't tell me \"use these three commands in this script\".\n>> I want a *command* I can tell people in #git.\n> \n> by saying that I don't think there is currently a single command to\n> cover both (1) and (2) (any of the (2) options). So we need to talk\n> about \"use these three commands in a script\" for a moment to figure out\n> what such a command _should_ do, and then we can talk about putting it\n> into a single command (and presumably making that command part of the\n> git distribution) that you can tell people about in #git.\n> \n> Both (1) and (2) involve finding out who your upstream is. As of 1.6.3,\n> this is easy to do as:\n> \n>   upstream=`git for-each-ref --format='%(upstream)' `git symbolic-ref HEAD`\n> \n> One you have that, (1) is easy:\n> \n>   test -z \"`git rev-list -1 $upstream..HEAD`\"\n> \n> (2a) is also pretty easy:\n> \n>   git diff-files --quiet && git diff-index --quiet\n> \n> (2b) is a bit harder, but do-able:\n> \n>   git diff-tree --name-only HEAD $upstream | sort >them\n>   (git diff-files --name-only; git diff-index --name-only) | sort >us\n>   test -z \"`comm -12 us them`\"\n> \n> (2c) is the trickiest (and of course, therefore probably the one you\n> want ;) ).  I'm not sure there is a simple way to do it short of hacking\n> git-merge to actually try the merge and roll it back. Because you really\n> have to deal not just with merging actual text file content but with\n> custom merge drivers.\n> \n\nThe \"rolling back\" part is about as simple as\n* never touch the worktree (only use in-index merge)\n* preserve the last HEAD commit object name\n* preserve the index\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n\nRegister now for Nordic Meet on Nagios, June 3-4 in Stockholm\n http://nordicmeetonnagios.op5.org/\n\nConsidering the successes of the wars on alcohol, poverty, drugs and\nterror, I think we should give some serious thought to declaring war\non peace.\n"},{"id":"113312","messageId":"20090508070119.GA12989@coredump.intra.peff.net","threadId":"19240","inReplyTo":"4A03D6E2.2050708@op5.se","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-05-08T07:01:19Z","receivedAt":"2009-05-08T07:01:19Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, May 08, 2009 at 08:53:22AM +0200, Andreas Ericsson wrote:\n\n>> (2b) is a bit harder, but do-able:\n>>\n>>   git diff-tree --name-only HEAD $upstream | sort >them\n>>   (git diff-files --name-only; git diff-index --name-only) | sort >us\n>>   test -z \"`comm -12 us them`\"\n>>\n>> (2c) is the trickiest (and of course, therefore probably the one you\n>> want ;) ).  I'm not sure there is a simple way to do it short of hacking\n>> git-merge to actually try the merge and roll it back. Because you really\n>> have to deal not just with merging actual text file content but with\n>> custom merge drivers.\n>>\n>\n> The \"rolling back\" part is about as simple as\n> * never touch the worktree (only use in-index merge)\n> * preserve the last HEAD commit object name\n> * preserve the index\n\nIf you are just doing in-index merge, then (2b) works fine. You know you\naren't doing any file-level merging. The advantage of (2c) is that\nnon-conflicting merges in files would are \"safe\".\n\n-Peff\n"},{"id":"113344","messageId":"F871F2A1-DFCF-4642-BB53-7BE483A93271@orakel.ntnu.no","threadId":"19240","inReplyTo":"20090508023028.GA1218@coredump.intra.peff.net","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Eyvind Bernhardsen","fromEmail":"eyvind-git@orakel.ntnu.no","sentAt":"2009-05-08T12:34:12Z","receivedAt":"2009-05-08T12:34:12Z","isPatch":false,"sender":{"key":"eyvind.bernhardsen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/106762?v=4"},"body":"On 8. mai. 2009, at 04.30, Jeff King wrote:\n\n> On Thu, May 07, 2009 at 02:40:00PM -0700, Randal L. Schwartz wrote:\n>\n>> So, what I need is a command, likely an option to \"git merge\" that  \n>> says \"do\n>> everything that a git merge would do except abort if it would have  \n>> been a\n>> merge commit\".  In other words, abort if the workdir is dirty or is  \n>> not a\n>> fast-forward update to the upstream.  Bonus if it exits non-zero if\n>> something went wrong.\n>\n> Can you define more clearly what you want, because you are asking for\n> conflicting things. \"abort if it would have been a merge commit\" is\n> purely about fast forward. But it sounds like you also care about  \n> \"would\n> merge have succeeded\". So I think you are asking for:\n>\n>  1. There are no local commits on the branch.\n>\n> and one of:\n>\n>  2a. There are no local edits.\n>\n>  2b. There are no local edits in the same files as those that are\n>      affected by any new commits from upstream.\n>\n>  2c. Any local edits you have done would not cause a conflict if  \n> merged\n>      with what's in upstream.\n\nI read it as a request for pull/merge --ff-only (based on \"abort if  \nthe workdir is dirty or is not a fast-forward update\").  This feature  \nhas been implemented twice, but never included:\n\nhttp://article.gmane.org/gmane.comp.version-control.git/76787\nhttp://article.gmane.org/gmane.comp.version-control.git/107768\nhttp://article.gmane.org/gmane.comp.version-control.git/80284\n-- \nEyvind Bernhardsen\n"},{"id":"113345","messageId":"867i0rg0b6.fsf@blue.stonehenge.com","threadId":"19240","inReplyTo":"F871F2A1-DFCF-4642-BB53-7BE483A93271@orakel.ntnu.no","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2009-05-08T14:02:21Z","receivedAt":"2009-05-08T14:02:21Z","isPatch":false,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"Eyvind\" == Eyvind Bernhardsen <eyvind-git@orakel.ntnu.no> writes:\n\nEyvind> http://article.gmane.org/gmane.comp.version-control.git/76787\nEyvind> http://article.gmane.org/gmane.comp.version-control.git/107768\nEyvind> http://article.gmane.org/gmane.comp.version-control.git/80284\n\nYes. Precisely.\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nSmalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.\nSee http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion\n"},{"id":"113354","messageId":"7vk54rvb8x.fsf@alter.siamese.dyndns.org","threadId":"19240","inReplyTo":"F871F2A1-DFCF-4642-BB53-7BE483A93271@orakel.ntnu.no","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-08T15:57:02Z","receivedAt":"2009-05-08T15:57:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eyvind Bernhardsen <eyvind-git@orakel.ntnu.no> writes:\n\n> I read it as a request for pull/merge --ff-only (based on \"abort if\n> the workdir is dirty or is not a fast-forward update\").  This feature\n> has been implemented twice, but never included:\n\nInteresting.  Do you mean twice they were both found lacking, substandard,\nuseless, uninteresting, buggy, incorrect, or all of the above?  Or was it\njust somebody simply forgot to apply a perfect patchset twice?\n"},{"id":"113355","messageId":"m3prejmv2f.fsf@localhost.localdomain","threadId":"19240","inReplyTo":"7vk54rvb8x.fsf@alter.siamese.dyndns.org","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-05-08T16:15:31Z","receivedAt":"2009-05-08T16:15:31Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n> Eyvind Bernhardsen <eyvind-git@orakel.ntnu.no> writes:\n> \n> > I read it as a request for pull/merge --ff-only (based on \"abort if\n> > the workdir is dirty or is not a fast-forward update\").  This feature\n> > has been implemented twice, but never included:\n> \n> Interesting.  Do you mean twice they were both found lacking, substandard,\n> useless, uninteresting, buggy, incorrect, or all of the above?  Or was it\n> just somebody simply forgot to apply a perfect patchset twice?\n\nI think (if I remember correctly) that they were once to be split into\njust --ff-only and --ff=<strategy>, and once there were almost ready,\nand either feature freeze happened, or the author didn't have time to\nresend corrected patches, or both.\n\nI cc-ed authors of both versions (longer by Sverre, only --ff-only by\nYuval)\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"113371","messageId":"87iqkbth1c.fsf@catnip.gol.com","threadId":"19240","inReplyTo":"F871F2A1-DFCF-4642-BB53-7BE483A93271@orakel.ntnu.no","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Miles Bader","fromEmail":"miles@gnu.org","sentAt":"2009-05-08T21:34:55Z","receivedAt":"2009-05-08T21:34:55Z","isPatch":false,"sender":{"key":"miles@gnu.org","avatar":"https://gravatar.com/avatar/01069b69593af7bff28e2f97afeb3644ae6fe2f5f56cb3a8cf34c5fb8c36efe5?d=mp&s=160"},"body":"Eyvind Bernhardsen <eyvind-git@orakel.ntnu.no> writes:\n> I read it as a request for pull/merge --ff-only (based on \"abort if the\n> workdir is dirty or is not a fast-forward update\").  This feature  has\n> been implemented twice, but never included:\n\nI'd also like such a feature.\n\n[It seems like such an obvious partner to \"--no-ff\" (etc), that it's\nkind of surprising it isn't there already -- I think there have been\nmultiple times in the past where I've spent time grovelling the\npull/merge documentation looking for the right option name to do this,\nonly to give up in confusion when I couldn't find it...]\n\n-Miles\n\n-- \nLove is the difficult realization that something other than oneself is real.\n[Iris Murdoch]\n"},{"id":"113581","messageId":"EDAB1A7F-628A-47F6-BAEB-89935E86546A@orakel.ntnu.no","threadId":"19240","inReplyTo":"7vk54rvb8x.fsf@alter.siamese.dyndns.org","subject":"Re: I want \"fast forward my workdir to upstream if it's safe\"","fromName":"Eyvind Bernhardsen","fromEmail":"eyvind-git@orakel.ntnu.no","sentAt":"2009-05-11T20:11:31Z","receivedAt":"2009-05-11T20:11:31Z","isPatch":false,"sender":{"key":"eyvind.bernhardsen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/106762?v=4"},"body":"On 8. mai. 2009, at 17.57, Junio C Hamano wrote:\n\n> Eyvind Bernhardsen <eyvind-git@orakel.ntnu.no> writes:\n>\n>> I read it as a request for pull/merge --ff-only (based on \"abort if\n>> the workdir is dirty or is not a fast-forward update\").  This feature\n>> has been implemented twice, but never included:\n>\n> Interesting.  Do you mean twice they were both found lacking,  \n> substandard,\n> useless, uninteresting, buggy, incorrect, or all of the above?  Or  \n> was it\n> just somebody simply forgot to apply a perfect patchset twice?\n\nSorry, I should have summarised.\n\nI guess Yuval explained what happened to his patch himself.  Sverre's  \nwas dropped after a fair amount of discussion and several rounds, but  \nhis series added multiple fast-forward strategies, not just \"ff-only\".\n\nThe last reference I can find to it in the archives is Dscho asking  \nfor the feature to be held off pending the builtinification of git- \nmerge (http://article.gmane.org/gmane.comp.version-control.git/ \n82623).  Sverre probably lost interest in following up after that.\n\nIt looks like there's some interest behind the \"--ff=only\" feature  \nnow, at least.  I remembered the thread because of it; I wanted to  \nreplace a \"git reset --hard\" in my workflow with something slightly  \nsafer, and --ff=only would have fit.\n-- \nEyvind Bernhardsen\n"}]}