{"thread":{"id":"1645","subject":"cache status after git pull","startedAt":"2005-08-25T16:08:33Z","lastAt":"2005-08-25T20:26:07Z","messageCount":2,"participants":["tony.luck@intel.com","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"7747","messageId":"200508251608.j7PG8XGq016882@agluck-lia64.sc.intel.com","threadId":"1645","inReplyTo":null,"subject":"cache status after git pull","fromName":"","fromEmail":"tony.luck@intel.com","sentAt":"2005-08-25T16:08:33Z","receivedAt":"2005-08-25T16:08:33Z","isPatch":false,"sender":{"key":"tony.luck@intel.com","avatar":"https://avatars.githubusercontent.com/u/5446021?v=4"},"body":">* When the branch head pointed by $GIT_DIR/HEAD changes while\n> the index file and working tree are looking the other way\n> (e.g. somebody pushed into your repository, or you ran \"git\n> fetch\" to update the ref your working tree is on), \"git\n> checkout\" without -f gets confused.  Figure out a good way to\n> handle this.\n\nAha ... is this the problem that caught me out last week (when\nI ended up with 10 extra files attached to one of my commits)? At\nthe time the blame was placed on a failed merge not being backed\nout correctly.  But I only had the failed merge because \"get checkout\"\nhad failed to switch branches (and not provided an exit code to\nstop my script from trying the merge).\n\nHere's what I did this morning.\n\n1) Updated my \"linus\" branch:\n\n  $ git checkout linus && git pull linus\n\nThis appeared to work just fine ... except that when I\ncheck the status of my tree I see:\n\n  $ git status\n  #\n  # Updated but not checked in:\n  #   (will commit)\n  #\n  #       modified: arch/ia64/pci/pci.c\n  #       modified: arch/ppc64/kernel/setup.c\n  #       modified: arch/sparc64/kernel/pci.c\n  #       modified: arch/x86_64/defconfig\n  #       modified: drivers/block/cfq-iosched.c\n  #       modified: include/asm-m68k/page.h\n  #       modified: kernel/cpuset.c\n  #\n  #\n  # On branch refs/heads/linus\n  \nWhich looks like a set of landmines just waiting for me to\nstep on them!\n\nToday these didn't bite me.  \"git checkout release\" worked\nand switched to my release branch (and git status went back\nto saying \"nothing to commit\").  But in the past I think\nthis is the situation that has caused \"git checkout\" to fail\nwith the \"fatal: Entry 'blah' would be overwritten by merge. Cannot merge.\"\n\n-Tony\n"},{"id":"7756","messageId":"7v4q9dvk4g.fsf@assigned-by-dhcp.cox.net","threadId":"1645","inReplyTo":"200508251608.j7PG8XGq016882@agluck-lia64.sc.intel.com","subject":"Re: cache status after git pull","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-25T20:26:07Z","receivedAt":"2005-08-25T20:26:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"tony.luck@intel.com writes:\n\n> Aha ... is this the problem that caught me out last week (when\n> I ended up with 10 extra files attached to one of my commits)?\n\nPlausible.\n\n> 1) Updated my \"linus\" branch:\n>\n>   $ git checkout linus && git pull linus\n\nI would assume that just after \"git checkout linus\" before \"git\npull linus\", running \"git diff -r linus\" would have said\nnothing.\n\nThe second command, \"git pull linus\", would internally run \"git\nfetch linus\".  It depends on how your shorthand \"linus\" is\ndefined, but if it is set to update (either overwrite or\nfast-forward) the \"linus\" branch head, then your HEAD pointer\nwould be updated without updating the index and working tree.\nThis is bad because now you are telling git that your working\ntree is based on updated \"linus\" branch head, and what you\n_could_ commit on top of it is the same thing as what old\n\"linus\" branch head commit used to have.  That's why \"git\nstatus\" output shows the minefield.\n\nIf I keep copies of foreign brahches in $GIT_DIR/refs/heads/\nsomewhere, I never checkout those branches in my working tree.\nI always stay in my branches to do my work.  I may \"diff\"\nagainst them to see where I am.  Of course I would \"resolve\"\nwith them when I feel I am ready.\n\nSo, assumes that \"linus\" short-hand is set up to update\n$GIT_DIR/refs/heads/linus with the foreign branch head, the\nabove example would have been:\n\n    $ git checkout master && git pull linus\n    : examine diffs and be convinced what Linus does is always right.\n\nIf my \"master\" branch is not ready to merge from Linus but I\nwant to get a feel of what is coming, I would instead do:\n\n    : while staying on my master branch\n    $ git fetch linus\n    $ gitk linus master ;# or git show-branch linus master\n\nand later when my branch is ready, I would merge it into my\nmaster:\n\n    : still staying on my master branch\n    $ git pull . linus\n\nIf you did the pull into your master but it turns out that the\nmerge result is too messy, you could always reset (back to the\nfirst example):\n\n    $ git checkout master && git pull linus\n    : if merge failed...\n    $ git reset --hard master\n\n    $ git checkout master && git pull linus\n    : merge succeeds, but I realize that my tree was not quite\n    : ready to merge from linus -- going back to pre-merge state\n    $ git reset --hard master^1\n\n\nThe rules for updating $GIT_DIR/refs/ when fetch happens have\nbeen extended and clarified in 0.99.5 quite a bit.\n\nTo set up \"linus\" short-hand to be updated with \"master\" branch\nhead from Linus, you would do one of the following:\n\n  * Using old style shorthand\n\n    $ echo >$GIT_DIR/branches/linus \\\n    http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/\n    $ git fetch linus\n\n  * Using new style shorthand\n\n    $ cat >$GIT_DIR/remotes/linus \\\n    URL: http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/\n    Pull: master:linus\n    $ git fetch linus\n\n  * From the command line, having either branches/linus or\n    remotes/linus from the above two examples:\n\n    $ git fetch linus master:linus\n\nTo set up \"linus\" short-hand _not_ to update any local branch\nhead (i.e. you only use \"pull\" to update your local branch,\nwhich can be named \"linus\" branch), you would do one of the\nfollowing:\n\n  * Using old style shorthand\n\n    There is no way to do this using old style shorthand without\n    an explicit command line <refspec>.  See the \"From the\n    command line\" example below how to do this.\n\n  * Using new style shorthand\n\n    $ cat >$GIT_DIR/remotes/linus \\\n    URL: http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/\n    Pull: master:\n    $ git fetch linus\n\n  * From the command line, having either branches/linus or\n    remotes/linus from the above two examples:\n\n    $ git fetch linus master:\n"}]}