{"thread":{"id":"23377","subject":"git pull suggestion","startedAt":"2010-04-07T23:17:35Z","lastAt":"2010-04-12T21:35:23Z","messageCount":15,"participants":["Aghiles","Thomas Rast","Nicolas Sebrecht","Jeff King","Junio C Hamano","Matthieu Moy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"138905","messageId":"r2x3abd05a91004071617z9ffd6e02v83d825405bb6ef1@mail.gmail.com","threadId":"23377","inReplyTo":null,"subject":"git pull suggestion","fromName":"Aghiles","fromEmail":"aghilesk@gmail.com","sentAt":"2010-04-07T23:17:35Z","receivedAt":"2010-04-07T23:17:35Z","isPatch":false,"sender":{"key":"aghilesk@gmail.com","avatar":null},"body":"Hello,\n\nIt would be nice to have _all_ the WIP conflicts listed when pulling.\nAs of now, one has to fix the currently showed conflict to see the next one.\n\nIf there is a way to do that, please advise.\n\nThanks,\n\n  -- aghiles\n"},{"id":"138962","messageId":"201004081754.24954.trast@student.ethz.ch","threadId":"23377","inReplyTo":"r2x3abd05a91004071617z9ffd6e02v83d825405bb6ef1@mail.gmail.com","subject":"Re: git pull suggestion","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-04-08T15:54:24Z","receivedAt":"2010-04-08T15:54:24Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Aghiles wrote:\n> \n> It would be nice to have _all_ the WIP conflicts listed when pulling.\n> As of now, one has to fix the currently showed conflict to see the next one.\n\nAre you using 'git pull --rebase' or the equivalent\nbranch.<name>.rebase setting?\n\nIf so, note that git-rebase (which does all the hard work) can't know\nthe later conflicts once it hits the first one: your resolution of the\nfirst conflict constitutes the base onto which the further patches are\napplied.  So depending on what changes you make during the resolution,\nthere may be more or fewer conflicts in the rest of the rebase.\n\nIf not, I can't see how your question makes sense as ordinary 'git\npull' does a merge, and during a 'git merge' there can only ever be\none conflict resolution phase.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"138979","messageId":"p2x3abd05a91004081233j77b7177bm5928913a64de0e57@mail.gmail.com","threadId":"23377","inReplyTo":"201004081754.24954.trast@student.ethz.ch","subject":"Re: git pull suggestion","fromName":"Aghiles","fromEmail":"aghilesk@gmail.com","sentAt":"2010-04-08T19:33:59Z","receivedAt":"2010-04-08T19:33:59Z","isPatch":false,"sender":{"key":"aghilesk@gmail.com","avatar":null},"body":">>\n>> It would be nice to have _all_ the WIP conflicts listed when pulling.\n>> As of now, one has to fix the currently showed conflict to see the next one.\n>\n> Are you using 'git pull --rebase' or the equivalent\n> branch.<name>.rebase setting?\n>\n> If so, note that git-rebase (which does all the hard work) can't know\n> the later conflicts once it hits the first one: your resolution of the\n> first conflict constitutes the base onto which the further patches are\n> applied.  So depending on what changes you make during the resolution,\n> there may be more or fewer conflicts in the rest of the rebase.\n>\n> If not, I can't see how your question makes sense as ordinary 'git\n> pull' does a merge, and during a 'git merge' there can only ever be\n> one conflict resolution phase.\n>\n\nSorry, my explanation was not clear. I am talking about changes in the\nworking directory that are not in the index. So my working directory is\n\"dirty\" and I just issue a 'git pull'. Because some files are not \"up to date\"\ngit would abort the pull, saying that a certain file is not \"up to date\".\nSo I was suggesting to list all the \"problematic\" files in one go instead.\nNot a biggie of course.\n\n  -- aghiles\n"},{"id":"138993","messageId":"20100408231154.GB13704@vidovic","threadId":"23377","inReplyTo":"p2x3abd05a91004081233j77b7177bm5928913a64de0e57@mail.gmail.com","subject":"Re: git pull suggestion","fromName":"Nicolas Sebrecht","fromEmail":"nicolas.s.dev@gmx.fr","sentAt":"2010-04-08T23:11:54Z","receivedAt":"2010-04-08T23:11:54Z","isPatch":false,"sender":{"key":"nicolas.s.dev@gmx.fr","avatar":null},"body":"The 08/04/10, Aghiles wrote:\n> >>\n> >> It would be nice to have _all_ the WIP conflicts listed when pulling.\n> >> As of now, one has to fix the currently showed conflict to see the next one.\n> >\n> > Are you using 'git pull --rebase' or the equivalent\n> > branch.<name>.rebase setting?\n> >\n> > If so, note that git-rebase (which does all the hard work) can't know\n> > the later conflicts once it hits the first one: your resolution of the\n> > first conflict constitutes the base onto which the further patches are\n> > applied.  So depending on what changes you make during the resolution,\n> > there may be more or fewer conflicts in the rest of the rebase.\n> >\n> > If not, I can't see how your question makes sense as ordinary 'git\n> > pull' does a merge, and during a 'git merge' there can only ever be\n> > one conflict resolution phase.\n> \n> Sorry, my explanation was not clear. I am talking about changes in the\n> working directory that are not in the index. So my working directory is\n> \"dirty\" and I just issue a 'git pull'. Because some files are not \"up to date\"\n> git would abort the pull, saying that a certain file is not \"up to date\".\n> So I was suggesting to list all the \"problematic\" files in one go instead.\n\nDoesn't 'git status' ouput what you want ? Or am I out of the scope ?\n\n-- \nNicolas Sebrecht\n"},{"id":"138997","messageId":"v2r3abd05a91004082006v74e243f2x33b500f2f6dadc9f@mail.gmail.com","threadId":"23377","inReplyTo":"20100408231154.GB13704@vidovic","subject":"Re: git pull suggestion","fromName":"Aghiles","fromEmail":"aghilesk@gmail.com","sentAt":"2010-04-09T03:06:42Z","receivedAt":"2010-04-09T03:06:42Z","isPatch":false,"sender":{"key":"aghilesk@gmail.com","avatar":null},"body":"Nicolas wrote:\n>>\n>> Sorry, my explanation was not clear. I am talking about changes in the\n>> working directory that are not in the index. So my working directory is\n>> \"dirty\" and I just issue a 'git pull'. Because some files are not \"up to date\"\n>> git would abort the pull, saying that a certain file is not \"up to date\".\n>> So I was suggesting to list all the \"problematic\" files in one go instead.\n>\n> Doesn't 'git status' ouput what you want ? Or am I out of the scope ?\n>\n\nKind of ! 'git status' will effectively tell you what files are modified but not\nin the index. The problem is that there is no way to know what files are\nin potential conflict with what is coming from 'git pull'. So basically, you can\nhave as many dirty files as you want in your working directory as long as\nthey are not conflicting with what's coming.\nIf dirty files are in conflict, then 'git pull' will complain, but slowly ... :)\n\nAnother way of looking at it: do we have a command to know if some files\nthat are _not_ in the index are in a conflict with some upstream repository.\nI guess this would imply fetching and then doing some work but I am not a\ngit expert, not by a  stretch of the word!\n\n  -- aghiles\n"},{"id":"138999","messageId":"20100409034911.GA4020@coredump.intra.peff.net","threadId":"23377","inReplyTo":"v2r3abd05a91004082006v74e243f2x33b500f2f6dadc9f@mail.gmail.com","subject":"Re: git pull suggestion","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-04-09T03:49:11Z","receivedAt":"2010-04-09T03:49:11Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Apr 08, 2010 at 11:06:42PM -0400, Aghiles wrote:\n\n> Kind of ! 'git status' will effectively tell you what files are\n> modified but not in the index. The problem is that there is no way to\n> know what files are in potential conflict with what is coming from\n> 'git pull'. So basically, you can have as many dirty files as you want\n> in your working directory as long as they are not conflicting with\n> what's coming.\n> If dirty files are in conflict, then 'git pull' will complain, but\n> slowly ... :)\n\nI think I get what you are talking about now. Consider the following\nexample script, and let me know if it illustrates your problem:\n\n  # define some handy functions\n  content() {\n    echo 1 $1 >file1\n    echo 2 $1 >file2\n  }\n  commit() {\n    git add file1 file2\n    git commit -m \"$1\"\n  }\n\n  # make a new repo\n  mkdir repo && cd repo && git init\n\n  # make two diverged branches\n  content one; commit one\n  git checkout -b other\n  content two; commit two\n  git checkout master\n  content three; commit three\n\n  # now give us dirty working tree state on both files\n  content four\n\n  # and try to merge\n  git merge other\n\nI get:\n\n  $ git merge other\n  error: Your local changes to 'file1' would be overwritten by merge. Aborting.\n  Please, commit your changes or stash them before you can merge.\n\nBut that's not the whole story. Once you fix that, you will see that\nyour local changes to 'file2' would be overwritten by the merge:\n\n  $ git commit -m \"commit file1\" file1\n  $ git merge other\n  error: Your local changes to 'file2' would be overwritten by merge. Aborting.\n  Please, commit your changes or stash them before you can merge.\n\nAnd so on.\n\nNotice that I didn't use \"pull\", but pull should invoke git-merge after\nfetching from the remote. I assume this is the same message you are\ntalking about?\n\nI agree it would be nicer if, on the error case, we kept going through\nthe index to find all of the other error cases, and printed them all.\nThe code for that is a bit tricky, though, as the unpack-trees merging\ncode which produces that message is a callback, and only sees one cache\nentry at a time.\n\nIt is possible to manually get the answer you want, or close to it. You\nare looking for the intersection of files modified by you and files\nmodified by the upstream. So:\n\n  # unique list of modified working tree files and index entries\n  $ (git diff-files --name-only;\n     git diff-index --name-only HEAD\n    ) | sort -u >us\n  # files that will be changing as part of merge\n  $ git diff-tree --name-only $HEAD_TO_MERGE_FROM | sort >them\n  $ comm -12 us them\n\nwhere $HEAD_TO_MERGE_FROM in my example would be \"other\", but in the\ncase of a pull, would probably be FETCH_HEAD.\n\nIt isn't 100% accurate, as there are some special cases that the merging\ncode handles (e.g., I think if the remote changed a file and we have the\nsame uncommitted change in our working tree, we may still allow that.\nThere are probably others, too). But it should give a general idea of\nwhat is in conflict.\n\nIn practice, I have never actually wanted to this. The workflow goes\nsomething like:\n\n  (1) Run git merge foo (or git pull)\n\n  (2) Oops, I have cruft in my working tree. What was it? Run git\n      status.\n\n  (3a) Oh, that cruft should have been committed. Make a commit (or\n       commits). Go to (1), possibly still with some changes in\n       the working tree.\n\n       or\n\n  (3b) Oh, that cruft is some change I want to carry forward in the\n       working directory. Run git stash, repeat the pull, fix any\n       merge conflicts, and then git stash apply.\n\nSo it doesn't really matter to me if there is 1 conflicting file or 100.\nIn most cases, the commits in (3a) will clean up all of it in one go.\nOtherwise, I'll just stash it all and come back to it.\n\n-Peff\n"},{"id":"139067","messageId":"i2y3abd05a91004091233nc11ee5f8m4f40e7451e02518a@mail.gmail.com","threadId":"23377","inReplyTo":"20100409034911.GA4020@coredump.intra.peff.net","subject":"Re: git pull suggestion","fromName":"Aghiles","fromEmail":"aghilesk@gmail.com","sentAt":"2010-04-09T19:33:35Z","receivedAt":"2010-04-09T19:33:35Z","isPatch":false,"sender":{"key":"aghilesk@gmail.com","avatar":null},"body":"Jeff King <peff@peff.net> wrote:\n>\n> ...\n>\n> I get:\n>\n>  $ git merge other\n>  error: Your local changes to 'file1' would be overwritten by merge. Aborting.\n>  Please, commit your changes or stash them before you can merge.\n>\n> But that's not the whole story. Once you fix that, you will see that\n> your local changes to 'file2' would be overwritten by the merge:\n>\n>  $ git commit -m \"commit file1\" file1\n>  $ git merge other\n>  error: Your local changes to 'file2' would be overwritten by merge. Aborting.\n>  Please, commit your changes or stash them before you can merge.\n>\n> And so on.\n>\n> Notice that I didn't use \"pull\", but pull should invoke git-merge after\n> fetching from the remote. I assume this is the same message you are\n> talking about?\n\nExactly.\n\n> It is possible to manually get the answer you want, or close to it. You\n> are looking for the intersection of files modified by you and files\n> modified by the upstream. So:\n>\n>  # unique list of modified working tree files and index entries\n>  $ (git diff-files --name-only;\n>     git diff-index --name-only HEAD\n>    ) | sort -u >us\n>  # files that will be changing as part of merge\n>  $ git diff-tree --name-only $HEAD_TO_MERGE_FROM | sort >them\n>  $ comm -12 us them\n>\n> where $HEAD_TO_MERGE_FROM in my example would be \"other\", but in the\n> case of a pull, would probably be FETCH_HEAD.\n\nThanks a lot for this, I will try it.\n\n> In practice, I have never actually wanted to this. The workflow goes\n> something like:\n>\n>  (1) Run git merge foo (or git pull)\n>\n>  (2) Oops, I have cruft in my working tree. What was it? Run git\n>      status.\n>\n>  (3a) Oh, that cruft should have been committed. Make a commit (or\n>       commits). Go to (1), possibly still with some changes in\n>       the working tree.\n>\n>       or\n>\n>  (3b) Oh, that cruft is some change I want to carry forward in the\n>       working directory. Run git stash, repeat the pull, fix any\n>       merge conflicts, and then git stash apply.\n>\n> So it doesn't really matter to me if there is 1 conflicting file or 100.\n> In most cases, the commits in (3a) will clean up all of it in one go.\n> Otherwise, I'll just stash it all and come back to it.\n>\n\nThat is exactly my workflow and I am perfectly happy with that. The\nproblem is that I am putting git in the hands of svnites and\nsometimes I have to address some usability issues like these.\n\nIt is another issue, but I feel that the 'dirty working directory' is\none of the major usability hurdles for people migrating from svn\nand CVS (a git pull --merge-using-stash could address it, maybe).\n\n  -- aghiles\n"},{"id":"139075","messageId":"h2m3abd05a91004091354t1b1de4aag48816d7e47cc766@mail.gmail.com","threadId":"23377","inReplyTo":"20100409034911.GA4020@coredump.intra.peff.net","subject":"Re: git pull suggestion","fromName":"Aghiles","fromEmail":"aghilesk@gmail.com","sentAt":"2010-04-09T20:54:41Z","receivedAt":"2010-04-09T20:54:41Z","isPatch":false,"sender":{"key":"aghilesk@gmail.com","avatar":null},"body":"Jeff King <peff@peff.net> wrote:\n> It is possible to manually get the answer you want, or close to it. You\n> are looking for the intersection of files modified by you and files\n> modified by the upstream. So:\n>\n>  # unique list of modified working tree files and index entries\n>  $ (git diff-files --name-only;\n>     git diff-index --name-only HEAD\n>    ) | sort -u >us\n>  # files that will be changing as part of merge\n>  $ git diff-tree --name-only $HEAD_TO_MERGE_FROM | sort >them\n>  $ comm -12 us them\n>\n> where $HEAD_TO_MERGE_FROM in my example would be \"other\", but in the\n> case of a pull, would probably be FETCH_HEAD.\n\nIt works. You actually need the -r flag to 'git diff-tree' (recursive) in order\nto list the actual files and not only their parent directories. So it becomes:\n\n$ (git diff-files --name-only; git diff-index --name-only HEAD ) | sort -u>us\n$ git diff-tree -r --name-only $HEAD_TO_MERGE_FROM | sort > them\n$ comm -12 us them\n\nThank you very much,\n\n  -- aghiles\n"},{"id":"139106","messageId":"20100410043535.GA22481@coredump.intra.peff.net","threadId":"23377","inReplyTo":"i2y3abd05a91004091233nc11ee5f8m4f40e7451e02518a@mail.gmail.com","subject":"Re: git pull suggestion","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-04-10T04:35:35Z","receivedAt":"2010-04-10T04:35:35Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Apr 09, 2010 at 03:33:35PM -0400, Aghiles wrote:\n\n> It is another issue, but I feel that the 'dirty working directory' is\n> one of the major usability hurdles for people migrating from svn\n> and CVS (a git pull --merge-using-stash could address it, maybe).\n\nI think this has been discussed before, but I couldn't find it in the\narchives.\n\nIt is probably a little bit confusing because your pull will not\nnecessarily complete immediately. It may have conflicts, which you may\nfix up, or you may \"git reset --hard\" to abort. But either way, you need\nto remember that your dirty state was stashed and that you need to pull\nit out after it's all done.\n\nI think we would do better to tell the user about stash there, so they\ncan do it themselves. Then they know where their changes went and how to\nget them back. Since v1.6.5.5, this error message now says:\n\n  Your local changes to '%s' would be overwritten by merge.  Aborting.\n  Please, commit your changes or stash them before you can merge.\n\nWhat version of git are you using? If you (or others you are helping)\nsaw that message and it wasn't helpful, do you have any suggestions for\nhow to improve it?\n\n-Peff\n"},{"id":"139108","messageId":"7vochrzzqc.fsf@alter.siamese.dyndns.org","threadId":"23377","inReplyTo":"20100410043535.GA22481@coredump.intra.peff.net","subject":"Re: git pull suggestion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-10T04:40:59Z","receivedAt":"2010-04-10T04:40:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n>   Your local changes to '%s' would be overwritten by merge.  Aborting.\n>   Please, commit your changes or stash them before you can merge.\n>\n> What version of git are you using? If you (or others you are helping)\n> saw that message and it wasn't helpful, do you have any suggestions for\n> how to improve it?\n\nI use 1.7.1-rc0 myself, but dropping comma after \"Please\" may make it a\nbit easier to read IMHO ;-).\n"},{"id":"139234","messageId":"m2v3abd05a91004102301i95bf7091ib2bd9da5e8a208c1@mail.gmail.com","threadId":"23377","inReplyTo":"20100410043535.GA22481@coredump.intra.peff.net","subject":"Re: git pull suggestion","fromName":"Aghiles","fromEmail":"aghilesk@gmail.com","sentAt":"2010-04-11T06:01:18Z","receivedAt":"2010-04-11T06:01:18Z","isPatch":false,"sender":{"key":"aghilesk@gmail.com","avatar":null},"body":"King <peff@peff.net> writes:\n> I think we would do better to tell the user about stash there, so they\n> can do it themselves. Then they know where their changes went and how to\n> get them back. Since v1.6.5.5, this error message now says:\n>\n>  Your local changes to '%s' would be overwritten by merge.  Aborting.\n>  Please, commit your changes or stash them before you can merge.\n>\n> What version of git are you using? If you (or others you are helping)\n> saw that message and it wasn't helpful, do you have any suggestions for\n> how to improve it?\n\nYes we have the latest version and we do see this message. This helps\na bit. Although for people used to CVS/CVN the \"stash\" is yet another thing\nto learn. There is also a high probability for new users to see this message\nvery early when using git and the question is always the same: why can't git\njust merge with my files and show me the conflict?\n\n(There was also some usability issues with the \"stash\", I remember people\nloosing _untracked_ files but I am not sure if that was PEBKAC. First versions\nof stash had a very friendly syntax that punished you by obliterating your files\nif you made a typo and some are still traumatized.)\n\nSimply put: in git, your working directory is a second class citizen and git\ndoesn't want to deal with it. Fundamentally, this is in a collision course with\nwhat some users think about their work in progress.\n\nI started a similar discussion had a couple years ago:\nhttp://lists-archives.org/git/635926-git-pull-opinion.html\n\nBack then, I was certain that 'git pull' should have an option to mix with a\ndirty tree but now, after a couple years of using the tool, I am not certain\nanymore. I am just reporting the biggest frustrations I see with new users.\n\nThanks,\n\n  -- aghiles\n"},{"id":"139235","messageId":"7vaataphi7.fsf@alter.siamese.dyndns.org","threadId":"23377","inReplyTo":"m2v3abd05a91004102301i95bf7091ib2bd9da5e8a208c1@mail.gmail.com","subject":"Re: git pull suggestion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-11T07:37:04Z","receivedAt":"2010-04-11T07:37:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Aghiles <aghilesk@gmail.com> writes:\n\n> Although for people used to CVS/CVN the \"stash\" is yet another thing\n> to learn. There is also a high probability for new users to see this message\n> very early when using git and the question is always the same: why can't git\n> just merge with my files and show me the conflict?\n\nThere actually are two answers to this question.\n\nOne is that it is not necessarily \"can't\", but rather \"chooses not to\".\nIf you are limiting yourself to CVS/SVN style of development, then we\ncertainly could do that.\n\nLet's review what happens in CVS/SVN world when you \"update\" with dirty\nworking tree.  As you are familiar with CVS/SVN, you should be able to\nfollow this part quite easily.\n\nYou \"updated\" and were in sync with the central repository at some point,\nlet's call it O, and have some uncommitted changes in the work tree since\nthen.  In the meantime, other people worked on the project and made more\ncommits in the central repository.  The tip of the central repository is\nat commit A.\n\n         x\n        / \n    ---O---X---X---X---A\n\nYou would want your \"cvs update\" to end up with a topology like this:\n\n                         x'\n                        / \n    ---O---X---X---X---A\n\nwhere\n\n        x' = merge-three-way(O, x, A)\n\nThat is, the files in the work tree are updated to contain whatever\nwas done by other people between O and A.\n\ngit does _not_ implement a handy Porcelain to do this, but we could script\nit like this (I am only illustrating that it can be done, but I am leaving\nthe reason why git chooses not to to a later part of this message).\n\n\t#!/bin/sh\n        # Usage: git-cvs-pull remote [refspec]\n\n        # Fetch from the other\n        git fetch \"$@\"\n\t# Figure out \"A\", i.e. the updated commit\n\tmerge_head=$(sed -e '/\tnot-for-merge\t/d' \\\n\t\t-e 's/\t.*//' .git/FETCH_HEAD | \\\n\t\ttr '\\012' ' ')\n\t# cvs/svn style pull will never have an octopus\n        case \"$merge_head\" in\n        ?*' '?*)\tdie \"cannot merge more than one\" ;;\n        ?*)\t\t;;\n        *)\t\tdie \"nothing to merge\" ;;\n        esac\n\n\t# Make sure it is cvs/svn-style pull.  That is, our commit must\n        # be an ancestor of the updated commit\n\ttest 0 = (git rev-list $merge_head..HEAD | wc -l) || die \"you forked\"\n\n        # At this point, we know the topology is like this.\n        #\n        #         x\n        #        / \n        #    ---O---X---X---X---A\n\n\t# Figure out the current branch\n\tbranch=$(git symbolic-ref HEAD)\n\n\t# Checkout and detach to \"A\" while carrying the local changes.\n        # This may leave conflicts but that is what the user is asking for.\n        git checkout -m \"$merge_head^0\"\n\n        # At this point, topology has become:\n        #\n        #                         x'\n        #                        / \n        #    ---O---X---X---X---A\n        #\n        # We have detached HEAD at A but haven't updated the branch yet.\n\n        case \"$branch\" in\n        '')\t;; # detached from the beginning\n        ?*)\tgit update-ref -m \"cvs-pull\" \"$branch\" \"$merge_head\" ;;\n\tesac\n\nNote that this was written in my MUA and is obviously untested ;-) but I\nthink you have also been around here long enough to understand the idea.\n\nSo that was one of the answers.  It's not \"we can't do it\", but is \"in a\nworld with cvs/svn limitation, we could\".\n\nThe other answer would initially appear a bit sad, but after you think\nabout it, it would turn into an enlightenment, especially for people whose\nbrains have rotten from years and years of CVS/SVN use.\n\nIf you are not limited to CVS/SVN style of development and have made\ncommits since you updated from the central repository the last time,\nCVS/SVN style \"update\" is fundamentally impossible.\n\nAgain, you \"updated\" and were in sync with the central repository at some\npoint, let's call it O, and this time, made a few commits, ending with\ncommit B.  You further have some uncommitted changes in the work tree\nsince then.  In the meantime, other people worked on the project and made\nmore commits in the central repository.  Again, the tip of the central\nrepository is at commit A.\n\n                   x\n                  /\n         Y---Y---B\n        / \n    ---O---X---X---X---A\n\nFirst, a simple question.\n\nWhat kind of topology would you want to end up with?\n\nThink.\n\n\t... you think for five minutes ...\n\n\t(page break)\n\n\t... and then you look at the answer ...\n\nYes, you want to have a merge between A and B, and then have your local\nchange relative to M in your working tree.  In other words, the topology\nshould look like this:\n\n                           x'\n                          /\n         Y---Y---B-------M\n        /               /  \n    ---O---X---X---X---A\n\nwhere\n\n\tM = merge-three-way(O, B, A)\n        x' = merge-three-way(B, x, M)\n\nAgain, think.  How would you deal with conflicts while coming up with M?\n\nYou cannot leave files with conflict markers in the work tree and have the\nuser fix them up to record M.  Quite contrary to what you insinuated, your\nworking directory is not a second class citizen but is a very valuable\nentity, and it already has important changes between B and x.  We cannot\nafford to overwrite it with a half-merge result between A and B for the\npurpose of conflict resolution between A and B.\n\nWorse yet, even if we _could_ keep the changes between B and x in the same\nfile while showing conflicts between A and B (perhaps the changes you made\nbetween B and x did not overlap the region conflicted between A and B), we\ncannot still write such a thing out to the working tree.  Why?  Because\nthen you have to sift through the changes in that file and commit _only_\nthe parts that are relevant to the merge between A and B while finishing\nthe merge to produce M, while leaving the change between B and x (which is\ngoing to become the difference between M and x' and left in the working\ntree) alone.  And that is actually the best case.  What would you do if\nthe conflicted region between A and B were something that you changed in\nthe working tree between B and x?\n\nSo the \"enlightenment\" part is that once you have an ability to \"fork\" the\nhistory, CVS/SVN style \"edit, update, commit\" cycle _fundamentally_ would\nnot work.  That is why \"commit first and then merge\" is the norm in DVCS\nworld.\n\nNow how would one deal with this then?  The answer is actually quite\nsimple.  Let's go back to the first picture:\n\n                   x\n                  /\n         Y---Y---B\n        / \n    ---O---X---X---X---A\n\nWe want to come up with a merge between A and B first to produce M, and\nwhile we do that, we do not want to lose the valuable change between B and\nx, so we _stash it away_.  Then we can use the working tree to deal with\npotential conflicts while finishing the merge to produce M.  In other\nwords, after stashing, we can safely run \"git pull\" to produce M.\n\n                   (x) --- the change is stashed away\n                  /\n         Y---Y---B-------M\n        /               /  \n    ---O---X---X---X---A\n\nAnd then we can replay the stash on top of M to produce x'\n\n                           x'\n                          /\n         Y---Y---B-------M\n        /               /  \n    ---O---X---X---X---A\n\n\nAnd the final answer (yes, I said there are two answers to the original\nquestion, and I already gave two answers, but I let the above description\nto raise another question \"why does git choose not to implement the logic\nof the first answer in a fast-forward case, aka cvs/svn style?\") is that\nit simply is not worth it to special case the \"I didn't commit and ran\npull again\".  The workflow to result in such a case would look like this:\n\n\t$ git pull\n        ... you are in sync with the other end ...\n        $ edit\n        $ edit\n        $ edit\n        $ edit\n        $ edit\n        $ edit\n        ... keep working forever _without ever committing_ ...\n        $ git pull\n\nwhich goes against the distributed nature of the system you are using.\n\nWorse yet, once you have committed between these pulls, even once, then\nthe simple-minded \"cvs/svn update\" style will not fundamentally work.\nRather than training the users with \"If you didn't commit, then you can do\n\"pull\" many many times, but once you commit, then you have to do something\ndifferent\", which is not very useful anyway, it is better to teach the\nmore general \"forked\" case, because the general case solution will also\nwork in the fast-forward case.\n\nNow, the above inevitably solicits \"then why doesn't 'pull' automatically\nstash and then unstash?\" question.  I think the answer is obvious if you\nthink about it, and it is getting late, so I'll leave that as an exercise\nto the readers but will leave a pictorial hint.\n\n                   C-------M\n                  /       /\n         Y---Y---B       / \n        /               /\n    ---O---X---X---X---A\n"},{"id":"139259","messageId":"vpq4ojit0dp.fsf@bauges.imag.fr","threadId":"23377","inReplyTo":"7vaataphi7.fsf@alter.siamese.dyndns.org","subject":"Re: git pull suggestion","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2010-04-11T16:33:22Z","receivedAt":"2010-04-11T16:33:22Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> git does _not_ implement a handy Porcelain to do this, but we could script\n> it like this (I am only illustrating that it can be done, but I am leaving\n> the reason why git chooses not to to a later part of this message).\n\nActually, another way to do this is\n\ngit commit -a\ngit rebase origin/where-you-want-to-merge-from\ngit reset HEAD^\n\nThat would not necessarily be a good way to implement a command, but I\noften use variants of this interactively.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"139369","messageId":"s2m3abd05a91004121318x22b1f712tdd5600ad656c6b13@mail.gmail.com","threadId":"23377","inReplyTo":"7vaataphi7.fsf@alter.siamese.dyndns.org","subject":"Re: git pull suggestion","fromName":"Aghiles","fromEmail":"aghilesk@gmail.com","sentAt":"2010-04-12T20:18:23Z","receivedAt":"2010-04-12T20:18:23Z","isPatch":false,"sender":{"key":"aghilesk@gmail.com","avatar":null},"body":"On Sun, Apr 11, Junio C Hamano <gitster@pobox.com> wrote:\n> ...\n>\n> The other answer would initially appear a bit sad, but after you think\n> about it, it would turn into an enlightenment, especially for people whose\n> brains have rotten from years and years of CVS/SVN use.\n\nMy brain was rotten even _before_ CVS/SVN use, so you can picture\nthe damage.\n\nNow, thank you very much for taking the time to explain everything. I had\na vague understanding but now things are clearer.\n\nI think that there was a document back in the day, that was giving a\nrelationship between CVS/SVN commands and git. A posteriori, that\ndocument did more harm than good: it made you believe that you could\nuse git as CVS/SVN. In practice, that is very difficult and error prone.\n\n> Now, the above inevitably solicits \"then why doesn't 'pull' automatically\n> stash and then unstash?\" question.  I think the answer is obvious if you\n> think about it, and it is getting late, so I'll leave that as an exercise\n> to the readers but will leave a pictorial hint.\n\nBefore I start thinking I already have a question (which says a lot about\nmy thinking capacity): can't git detect this  problematic case ? My feeling\nis that an automatic stash/unstash will  work in most cases and could be\ntriggered by a --dirty flag.\n\n  -- aghiles\n"},{"id":"139372","messageId":"7vpr24jqw4.fsf@alter.siamese.dyndns.org","threadId":"23377","inReplyTo":"s2m3abd05a91004121318x22b1f712tdd5600ad656c6b13@mail.gmail.com","subject":"Re: git pull suggestion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-12T21:35:23Z","receivedAt":"2010-04-12T21:35:23Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Aghiles <aghilesk@gmail.com> writes:\n\n> On Sun, Apr 11, Junio C Hamano <gitster@pobox.com> wrote:\n>> ...\n>>\n>> The other answer would initially appear a bit sad, but after you think\n>> about it, it would turn into an enlightenment, especially for people whose\n>> brains have rotten from years and years of CVS/SVN use.\n>\n> My brain was rotten even _before_ CVS/SVN use, so you can picture\n> the damage.\n\nPlease don't take that too seriously; it was just me imitating these:\n\n    http://www.youtube.com/watch?v=4XpnKHJAok8\n    https://git.wiki.kernel.org/index.php/LinusTalk200705Transcript\n\n;-)\n\n>> ... so I'll leave that as an exercise\n>> to the readers but will leave a pictorial hint.\n>\n> Before I start thinking I already have a question (which says a lot about\n> my thinking capacity): can't git detect this problematic case?\n\nThe pictorial hint is to illustrate that the case is not necessarily\nproblematic.\n"}]}