{"thread":{"id":"28913","subject":"Git: Unexpected behaviour?","startedAt":"2011-11-11T20:55:04Z","lastAt":"2011-11-14T21:33:51Z","messageCount":14,"participants":["Jvsrvcs","Carlos Martín Nieto","Eugene Sajine","Taylor Hedberg","Gelonida N","Chris Packham","J.V.","Alexey Shumkin","Junio C Hamano","Martin von Zweigbergk","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"179329","messageId":"1321044904175-6986736.post@n2.nabble.com","threadId":"28913","inReplyTo":null,"subject":"Git: Unexpected behaviour?","fromName":"Jvsrvcs","fromEmail":"jvsrvcs@gmail.com","sentAt":"2011-11-11T20:55:04Z","receivedAt":"2011-11-11T20:55:04Z","isPatch":false,"sender":{"key":"jvsrvcs@gmail.com","avatar":null},"body":"Unexpected git behaviour\n\n---\n# First create a local git repo\n\n$mkdir gitexample\n$git config --global user.name \"my name\"\n$git config --global user.email \"me@me.com\"\n$git init\n$git add .\n$git commit -m 'initial commit'\n\n# Create/Edit an empty file\n$vi readme.txt\n\n# add a single line: \"this was added in the master branch.\"\n$git commit -a\n\n# create and checkout a new branch (from master)\n$git branch test\n$git checkout test\n\n# edit the readme.txt file and do not commit\n# add the text:  \"this was added in the test branch.\", save and exit\n$vi readme.txt\n\n#now switch back to master\n$git checkout master\n$cat readme.txt\n\n#You will see both lines in the master.  \n\nQuestion #1:\n\tWhy was this line added in the *master branch?\n\n\n--- even further surprising\nIn the master branch, now do a commit\n$git commit -a\n\ncat readme.txt ( you will see the line in the master now that was added in\nthe test branch )\n\nQuestion #2:\n\tWhy did this happen?\n\n# Now switch back to the test branch\n$git checkout test\n$cat readme.txt\n\nYou will only see the one line: \"This was added in the master branch\"\n\nQuestion #3:\n\tWhy did this happen?\n\nand NOT the line added in that branch: \"this was added in the test branch\"\n<= this line is gone\n\nWhat is the reason for this?\n\n1) Why do I see uncommitted changes in the branches made off master in the\nmaster branch?\n2) Why, if I commit them in the master, do the disappear in the branch in\nwhich they were made?\n\nThis is confusing, I would think the * master branch would be left\nuntouched.  This would solve issue #2.\n\n\n--\nView this message in context: http://git.661346.n2.nabble.com/Git-Unexpected-behaviour-tp6986736p6986736.html\nSent from the git mailing list archive at Nabble.com.\n"},{"id":"179330","messageId":"20111111210352.GA4752@centaur.lab.cmartin.tk","threadId":"28913","inReplyTo":"1321044904175-6986736.post@n2.nabble.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Carlos Martín Nieto","fromEmail":"cmn@elego.de","sentAt":"2011-11-11T21:03:52Z","receivedAt":"2011-11-11T21:03:52Z","isPatch":false,"sender":{"key":"cmn@elego.de","avatar":"https://avatars.githubusercontent.com/u/335443?v=4"},"body":"On Fri, Nov 11, 2011 at 12:55:04PM -0800, Jvsrvcs wrote:\n> Unexpected git behaviour\n> \n[ ... switch branches with local modifications ...]\n> #You will see both lines in the master.  \n> \n> Question #1:\n> \tWhy was this line added in the *master branch?\n> \n\nIt wasn't. that line was added in the working directory. When you\nswitch branches, if the file in the tip of the current branch and the\nfile in the tip of the target branch don't differ, it's safe to keep\nyour local changes, so git does. This is to support the use-case where\nyou start editing a file when the wrong branch is checked out and want\nto change to the right one.\n\n> \n> --- even further surprising\n> In the master branch, now do a commit\n> $git commit -a\n> \n> cat readme.txt ( you will see the line in the master now that was added in\n> the test branch )\n> \n> Question #2:\n> \tWhy did this happen?\n\nBecause you told git to commit the file with that modification in it.\n\n> \n> # Now switch back to the test branch\n> $git checkout test\n> $cat readme.txt\n> \n> You will only see the one line: \"This was added in the master branch\"\n> \n> Question #3:\n> \tWhy did this happen?\n\nBecause the file in the 'test' branch only has that line. As you said\nyourself, you edited the file but didn't commit.\n\n> \n> and NOT the line added in that branch: \"this was added in the test branch\"\n> <= this line is gone\n\nAgain, that line wasn't added in any branch but in the working\ndirectory. The active branch was 'test', but doesn't magically mean\nthat uncommitted changes travel with it.\n\n   cmn\n"},{"id":"179331","messageId":"CAPZPVFakJjNexiTrDh9nQ34Ow9E-XmrVtrEmcnGtGP9kZwwL9g@mail.gmail.com","threadId":"28913","inReplyTo":"CAPZPVFb-VbTfkuyg4KtTsaWiNvd37GHeH7crPtqv1fKRbwuyfQ@mail.gmail.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Eugene Sajine","fromEmail":"euguess@gmail.com","sentAt":"2011-11-11T21:04:03Z","receivedAt":"2011-11-11T21:04:03Z","isPatch":false,"sender":{"key":"euguess@gmail.com","avatar":null},"body":"On Fri, Nov 11, 2011 at 4:01 PM, Eugene Sajine <euguess@gmail.com> wrote:\n>\n>\n> On Friday, November 11, 2011, Jvsrvcs <jvsrvcs@gmail.com> wrote:\n>> Unexpected git behaviour\n>>\n>> ---\n>> # First create a local git repo\n>>\n>> $mkdir gitexample\n>> $git config --global user.name \"my name\"\n>> $git config --global user.email \"me@me.com\"\n>> $git init\n>> $git add .\n>> $git commit -m 'initial commit'\n>>\n>> # Create/Edit an empty file\n>> $vi readme.txt\n>>\n>> # add a single line: \"this was added in the master branch.\"\n>> $git commit -a\n>>\n>> # create and checkout a new branch (from master)\n>> $git branch test\n>> $git checkout test\n>>\n>> # edit the readme.txt file and do not commit\n>> # add the text:  \"this was added in the test branch.\", save and exit\n>> $vi readme.txt\n>>\n>> #now switch back to master\n>> $git checkout master\n>> $cat readme.txt\n>>\n>> #You will see both lines in the master.\n>>\n>> Question #1:\n>>        Why was this line added in the *master branch?\n>>\n>>\n>> --- even further surprising\n>> In the master branch, now do a commit\n>> $git commit -a\n>>\n>> cat readme.txt ( you will see the line in the master now that was added in\n>> the test branch )\n>>\n>> Question #2:\n>>        Why did this happen?\n>>\n>> # Now switch back to the test branch\n>> $git checkout test\n>> $cat readme.txt\n>>\n>> You will only see the one line: \"This was added in the master branch\"\n>>\n>> Question #3:\n>>        Why did this happen?\n>>\n>> and NOT the line added in that branch: \"this was added in the test branch\"\n>> <= this line is gone\n>>\n>> What is the reason for this?\n>>\n>> 1) Why do I see uncommitted changes in the branches made off master in the\n>> master branch?\n>> 2) Why, if I commit them in the master, do the disappear in the branch in\n>> which they were made?\n>>\n>> This is confusing, I would think the * master branch would be left\n>> untouched.  This would solve issue #2.\n>>\n>>\n>> --\n>> View this message in context:\n>> http://git.661346.n2.nabble.com/Git-Unexpected-behaviour-tp6986736p6986736.html\n>> Sent from the git mailing list archive at Nabble.com.\n>> --\n>> To unsubscribe from this list: send the line \"unsubscribe git\" in\n>> the body of a message to majordomo@vger.kernel.org\n>> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>>\n\nPossible dup, thanks to \"smart\" HTML filter:\n\n All described is absolutely expected and normal behavior for git. You just\n need to learn about it a bit more and understand what branch in git is and\n how it works with changes in working directory.\n it is best described in here http://progit.org/book/ch3-0.html\n"},{"id":"179332","messageId":"1321045782702-6986770.post@n2.nabble.com","threadId":"28913","inReplyTo":"1321044904175-6986736.post@n2.nabble.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Jvsrvcs","fromEmail":"jvsrvcs@gmail.com","sentAt":"2011-11-11T21:09:42Z","receivedAt":"2011-11-11T21:09:42Z","isPatch":false,"sender":{"key":"jvsrvcs@gmail.com","avatar":null},"body":"The thing is that I want my 'master' branch' to reflect what is in the\n'master' repo - we are using another versioning control system than git for\nthe master for the moment. \n\nI want to be able to switch to the master at any moment, do an update there\nwith the primary versioning system in use, and get all others commits and\nmerge down to my branch from time to time.\n\nIt seems to me that this behaviour corrupts the master branch, reflecting a\nchange in the master branch that I did not want or expect.\n\nso I suppose the correct work flow would to be *ALWAYS*, commit on the\nbranch you are on before switching to another branch?  I think this would\nsolve the problem.\n\nThis just seems a bit odd.  I did not commit on the branch, I switched and\nit's on the master now.  At any rate, I can work with it, just need to know\nthe correct work flow I should take before switching to another branch, and\nthat seems to be *ALWAYS* commit before switching to get the expected\nbehaviour that seems normal to me.\n\n--\nView this message in context: http://git.661346.n2.nabble.com/Git-Unexpected-behaviour-tp6986736p6986770.html\nSent from the git mailing list archive at Nabble.com.\n"},{"id":"179333","messageId":"20111111211401.GF4495@foodlogiq3-xp-d620","threadId":"28913","inReplyTo":"1321045782702-6986770.post@n2.nabble.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Taylor Hedberg","fromEmail":"tmhedberg@gmail.com","sentAt":"2011-11-11T21:14:02Z","receivedAt":"2011-11-11T21:14:02Z","isPatch":false,"sender":{"key":"tmhedberg@gmail.com","avatar":"https://gravatar.com/avatar/d046da5ea94a7957169aef0fe122771a1f8d9387d39bc68fcfb1332978e11a6c?d=mp&s=160"},"body":"If you don't want to make a new commit on the branch you are leaving,\nyou can use `git stash` to stash away your working directory changes in\na temporary holding place without updating any branch.\n"},{"id":"179334","messageId":"j9k3rg$i72$1@dough.gmane.org","threadId":"28913","inReplyTo":"1321045782702-6986770.post@n2.nabble.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Gelonida N","fromEmail":"gelonida@gmail.com","sentAt":"2011-11-11T21:25:03Z","receivedAt":"2011-11-11T21:25:03Z","isPatch":false,"sender":{"key":"gelonida@gmail.com","avatar":null},"body":"On 11/11/2011 10:09 PM, Jvsrvcs wrote:\n> The thing is that I want my 'master' branch' to reflect what is in the\n> 'master' repo - we are using another versioning control system than git for\n> the master for the moment. \n> \n> I want to be able to switch to the master at any moment, do an update there\n> with the primary versioning system in use, and get all others commits and\n> merge down to my branch from time to time.\n> \n> It seems to me that this behaviour corrupts the master branch, reflecting a\n> change in the master branch that I did not want or expect.\n> \n> so I suppose the correct work flow would to be *ALWAYS*, commit on the\n> branch you are on before switching to another branch?  I think this would\n> solve the problem.\n\nYou can look at\n\ngit stash\n\n> \n> This just seems a bit odd.  I did not commit on the branch, I switched and\n> it's on the master now.  At any rate, I can work with it, just need to know\n> the correct work flow I should take before switching to another branch, and\n> that seems to be *ALWAYS* commit before switching to get the expected\n> behaviour that seems normal to me.\n> \n> --\n> View this message in context: http://git.661346.n2.nabble.com/Git-Unexpected-behaviour-tp6986736p6986770.html\n> Sent from the git mailing list archive at Nabble.com.\n"},{"id":"179335","messageId":"4EBD9428.3030506@gmail.com","threadId":"28913","inReplyTo":"1321044904175-6986736.post@n2.nabble.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Chris Packham","fromEmail":"judge.packham@gmail.com","sentAt":"2011-11-11T21:31:20Z","receivedAt":"2011-11-11T21:31:20Z","isPatch":false,"sender":{"key":"judge.packham@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155667?v=4"},"body":"Hi,\n\nOn 12/11/11 09:55, Jvsrvcs wrote:\n> Unexpected git behaviour\n> \n> ---\n> # First create a local git repo\n> \n> $mkdir gitexample\n> $git config --global user.name \"my name\"\n> $git config --global user.email \"me@me.com\"\n> $git init\n> $git add .\n> $git commit -m 'initial commit'\n> \n> # Create/Edit an empty file\n> $vi readme.txt\n> \n> # add a single line: \"this was added in the master branch.\"\n> $git commit -a\n\nOne thing to remember is that this is the same as \"git add readme.txt\"\nand \"git commit\" (I'll explain why below).\n\n> \n> # create and checkout a new branch (from master)\n> $git branch test\n> $git checkout test\n> \n> # edit the readme.txt file and do not commit\n> # add the text:  \"this was added in the test branch.\", save and exit\n> $vi readme.txt\n\nAt this point the changes are in the work tree. They aren't added to the\ntest branch until you commit them.\n\n> \n> #now switch back to master\n> $git checkout master\n\nWhen you have uncommited changes in the work tree that don't conflict\nwith the contents of the branch you are checking out git will happily\ncarry them along for you. If they did conflict then git would refuse to\nswitch to the new branch.\n\n> $cat readme.txt\n> \n> #You will see both lines in the master.  \n> \n> Question #1:\n> \tWhy was this line added in the *master branch?\n\nBecause the second change hasn't been committed it isn't in either\nbranch. It's in the work tree.\n\n> --- even further surprising\n> In the master branch, now do a commit\n> $git commit -a\n> \n> cat readme.txt ( you will see the line in the master now that was added in\n> the test branch )\n> \n> Question #2:\n> \tWhy did this happen?\n\nBecause you asked for it to happen.\n\n> \n> # Now switch back to the test branch\n> $git checkout test\n> $cat readme.txt\n> \n> You will only see the one line: \"This was added in the master branch\"\n> \n> Question #3:\n> \tWhy did this happen?\n\nBecause the second change was committed (in the master branch) it is\nno-longer floating in the work tree so when you switch branches you get\nthe contents of the file in that branch.\n\n> \n> and NOT the line added in that branch: \"this was added in the test branch\"\n> <= this line is gone\n> \n> What is the reason for this?\n> \n> 1) Why do I see uncommitted changes in the branches made off master in the\n> master branch?\n> 2) Why, if I commit them in the master, do the disappear in the branch in\n> which they were made?\n> \n> This is confusing, I would think the * master branch would be left\n> untouched.  This would solve issue #2.\n> \n\nHopefully this will explain things a little better\n\n[work-tree] -- git add -> [index] -- git commit --> [HEAD]\n\nwork-tree: the area on the file system where your code is checked out.\nindex: also known as the staging area, this is represents what will end\nup in the next commit.\nHEAD: a general term for the current branch.\n\nAs you can see that until a change is committed it isn't in _any_\nbranch. When you type \"git checkout test\" or \"git checkout master\" HEAD\nwill be updated. Changes in the work-tree or the index will be carried\nalong (provided they don't conflict with the new HEAD).\n\nHope that helps.\n"},{"id":"179341","messageId":"4EBDBCA2.7070603@gmail.com","threadId":"28913","inReplyTo":"4EBD9428.3030506@gmail.com","subject":"Re: Git: Unexpected behaviour?","fromName":"J.V.","fromEmail":"jvsrvcs@gmail.com","sentAt":"2011-11-12T00:24:02Z","receivedAt":"2011-11-12T00:24:02Z","isPatch":false,"sender":{"key":"jvsrvcs@gmail.com","avatar":null},"body":"OK so \"work tree\" is a new term for me.  I thought we were in isolated \nsandboxes called \"branches\" and changes made in a branch would stay in \nthat branch regardless.\n\nso anything in the \"work tree\" is over layed on top of my branch if \nthere are no conflicts?\n\nOn 11/11/2011 2:31 PM, Chris Packham wrote:\n> Hi,\n>\n> On 12/11/11 09:55, Jvsrvcs wrote:\n>> Unexpected git behaviour\n>>\n>> ---\n>> # First create a local git repo\n>>\n>> $mkdir gitexample\n>> $git config --global user.name \"my name\"\n>> $git config --global user.email \"me@me.com\"\n>> $git init\n>> $git add .\n>> $git commit -m 'initial commit'\n>>\n>> # Create/Edit an empty file\n>> $vi readme.txt\n>>\n>> # add a single line: \"this was added in the master branch.\"\n>> $git commit -a\n> One thing to remember is that this is the same as \"git add readme.txt\"\n> and \"git commit\" (I'll explain why below).\n>\n>> # create and checkout a new branch (from master)\n>> $git branch test\n>> $git checkout test\n>>\n>> # edit the readme.txt file and do not commit\n>> # add the text:  \"this was added in the test branch.\", save and exit\n>> $vi readme.txt\n> At this point the changes are in the work tree. They aren't added to the\n> test branch until you commit them.\n>\n>> #now switch back to master\n>> $git checkout master\n> When you have uncommited changes in the work tree that don't conflict\n> with the contents of the branch you are checking out git will happily\n> carry them along for you. If they did conflict then git would refuse to\n> switch to the new branch.\n>\n>> $cat readme.txt\n>>\n>> #You will see both lines in the master.\n>>\n>> Question #1:\n>> \tWhy was this line added in the *master branch?\n> Because the second change hasn't been committed it isn't in either\n> branch. It's in the work tree.\n>\n>> --- even further surprising\n>> In the master branch, now do a commit\n>> $git commit -a\n>>\n>> cat readme.txt ( you will see the line in the master now that was added in\n>> the test branch )\n>>\n>> Question #2:\n>> \tWhy did this happen?\n> Because you asked for it to happen.\n>\n>> # Now switch back to the test branch\n>> $git checkout test\n>> $cat readme.txt\n>>\n>> You will only see the one line: \"This was added in the master branch\"\n>>\n>> Question #3:\n>> \tWhy did this happen?\n> Because the second change was committed (in the master branch) it is\n> no-longer floating in the work tree so when you switch branches you get\n> the contents of the file in that branch.\n>\n>> and NOT the line added in that branch: \"this was added in the test branch\"\n>> <= this line is gone\n>>\n>> What is the reason for this?\n>>\n>> 1) Why do I see uncommitted changes in the branches made off master in the\n>> master branch?\n>> 2) Why, if I commit them in the master, do the disappear in the branch in\n>> which they were made?\n>>\n>> This is confusing, I would think the * master branch would be left\n>> untouched.  This would solve issue #2.\n>>\n> Hopefully this will explain things a little better\n>\n> [work-tree] -- git add ->  [index] -- git commit -->  [HEAD]\n>\n> work-tree: the area on the file system where your code is checked out.\n> index: also known as the staging area, this is represents what will end\n> up in the next commit.\n> HEAD: a general term for the current branch.\n>\n> As you can see that until a change is committed it isn't in _any_\n> branch. When you type \"git checkout test\" or \"git checkout master\" HEAD\n> will be updated. Changes in the work-tree or the index will be carried\n> along (provided they don't conflict with the new HEAD).\n>\n> Hope that helps.\n>\n>\n"},{"id":"179349","messageId":"4EBE2D8D.1090206@gmail.com","threadId":"28913","inReplyTo":"4EBDBCA2.7070603@gmail.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Chris Packham","fromEmail":"judge.packham@gmail.com","sentAt":"2011-11-12T08:25:49Z","receivedAt":"2011-11-12T08:25:49Z","isPatch":false,"sender":{"key":"judge.packham@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155667?v=4"},"body":"On 12/11/11 13:24, J.V. wrote:\n> OK so \"work tree\" is a new term for me.  I thought we were in isolated\n> sandboxes called \"branches\" and changes made in a branch would stay in\n> that branch regardless.\n> \n> so anything in the \"work tree\" is over layed on top of my branch if\n> there are no conflicts?\n\nKind of. I'd say that your work tree is updated to match a branch when\nyou run git checkout initially. The branch is updated when you run git\ncommit (after staging changes in the index with git add or using -a).\n"},{"id":"179350","messageId":"20111112123234.17ab4426@zappedws","threadId":"28913","inReplyTo":"1321044904175-6986736.post@n2.nabble.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Alexey Shumkin","fromEmail":"alex.crezoff@gmail.com","sentAt":"2011-11-12T08:32:34Z","receivedAt":"2011-11-12T08:32:34Z","isPatch":false,"sender":{"key":"alex.crezoff@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1183752?v=4"},"body":"the same situation and question were discussed and explained one\nmonth earlier\ntake a look\nhttp://thread.gmane.org/gmane.comp.version-control.git/183464\n\n> Unexpected git behaviour\n> \n> ---\n> # First create a local git repo\n> \n> $mkdir gitexample\n> $git config --global user.name \"my name\"\n> $git config --global user.email \"me@me.com\"\n> $git init\n> $git add .\n> $git commit -m 'initial commit'\n> \n> # Create/Edit an empty file\n> $vi readme.txt\n> \n> # add a single line: \"this was added in the master branch.\"\n> $git commit -a\n> \n> # create and checkout a new branch (from master)\n> $git branch test\n> $git checkout test\n> \n> # edit the readme.txt file and do not commit\n> # add the text:  \"this was added in the test branch.\", save and exit\n> $vi readme.txt\n> \n> #now switch back to master\n> $git checkout master\n> $cat readme.txt\n> \n> #You will see both lines in the master.  \n> \n> Question #1:\n> \tWhy was this line added in the *master branch?\n> \n> \n> --- even further surprising\n> In the master branch, now do a commit\n> $git commit -a\n> \n> cat readme.txt ( you will see the line in the master now that was\n> added in the test branch )\n> \n> Question #2:\n> \tWhy did this happen?\n> \n> # Now switch back to the test branch\n> $git checkout test\n> $cat readme.txt\n> \n> You will only see the one line: \"This was added in the master branch\"\n> \n> Question #3:\n> \tWhy did this happen?\n> \n> and NOT the line added in that branch: \"this was added in the test\n> branch\" <= this line is gone\n> \n> What is the reason for this?\n> \n> 1) Why do I see uncommitted changes in the branches made off master\n> in the master branch?\n> 2) Why, if I commit them in the master, do the disappear in the\n> branch in which they were made?\n> \n> This is confusing, I would think the * master branch would be left\n> untouched.  This would solve issue #2.\n> \n> \n> --\n> View this message in context:\n> http://git.661346.n2.nabble.com/Git-Unexpected-behaviour-tp6986736p6986736.html\n> Sent from the git mailing list archive at Nabble.com.\n"},{"id":"179358","messageId":"7vlirlp1y6.fsf@alter.siamese.dyndns.org","threadId":"28913","inReplyTo":"4EBDBCA2.7070603@gmail.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-12T19:37:05Z","receivedAt":"2011-11-12T19:37:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"J.V.\" <jvsrvcs@gmail.com> writes:\n\n> OK so \"work tree\" is a new term for me.  I thought we were in isolated\n> sandboxes called \"branches\" and changes made in a branch would stay in\n> that branch regardless.\n\nDo not think of \"branches\" as isolated _sandboxes_.\n\nRather, \"branches\" are where the independent states are to be _recorded_.\n\nThe recorded states only exist in the git repository, and to use its\ncontents (e.g. view in the pager or browser, edit in the editor, run the\ncompiler on,...), you need to materialize the contents of the branch\nsomewhere on the filesystem. Such a set of files on the filesystem form\nthe working tree. The act of doing so is called \"checking out a branch\".\n\nAfter you check out a branch, your working tree can be used to record an\nupdated state to the branch, but notice the \"can be\" part. Changes you\nmake to the working tree are _not_ associated to the branch until you make\nthem so by committing. They are floating on top of the branch you have\ncurrently checked out in your working tree, and \"floating\" was the key\npart lacking in your understanding that started this thread. You are\nallowed to check out another branch while you have a local change in the\nworking tree, and this is deliberately so. People often start working on a\nbranch (that is, they want to make a change and check out a branch, or\nthey happen to have a check-out of a branch and then the find something\nthey want to change), and then realize that the change logically does not\nbelong to the currently checked-out branch but some other branch. They\nneed to be able to check out another branch without losing the change they\nalready made in their working tree, and for such usage, the workflow\nshould look like:\n\n    $ git checkout master ;# on master branch\n    $ edit hello.c ;# some feature being added\n    ... realize that this change does not belong to the master\n    ... branch but is part of the \"hello\" branch you have been\n    ... working on for the past few days\n    $ git checkout hello ;# check out the correct branch\n    ... this keeps the local modification in hello.c (as long as\n    ... the file you modified are the same between master and hello\n    ... branches). Keep working on it and then finally...\n    $ git commit ;# on hello branch.\n\nThere is another unrelated use case in which people have local changes in\ntheir working tree, but need to check out a different branch. The most\ncommon is while you are working on a large feature that is not finished\nyet on your \"feature\" branch, you hear from your boss that one trivial fix\nfor an urgent bug must be committed and pushed out on the \"master\" branch.\nThe feature you have in your working tree does not have anything to do\nwith the bug or the fix you are going to make for your boss. In such a\ncase, you would want to save away the changes for the feature, check out\nthe \"master\" branch and commit the fix, i.e.\n\n    $ git checkout feature ;# on feature\n    $ edit foo bar baz ;# some complicated change\n    ... boss comes\n\n    $ git stash ;# stash away the current change\n    or\n    $ git commit -a -m 'wip'\n\n    $ git checkout master ;# emergency\n    $ edit ... ;# quickfix\n    $ git commit -m 'urgent fix...'\n    ... emergency dealt with\n\n    $ git checkout feature\n    ... back to what was being worked on\n\n    $ git stash pop\n    or\n    $ git reset HEAD^\n"},{"id":"179435","messageId":"CAOeW2eEUbvd0eJHjNfbvi9QnDiUO=mFA9rrKsjv8Yu0_QiPgSw@mail.gmail.com","threadId":"28913","inReplyTo":"7vlirlp1y6.fsf@alter.siamese.dyndns.org","subject":"Re: Git: Unexpected behaviour?","fromName":"Martin von Zweigbergk","fromEmail":"martin.von.zweigbergk@gmail.com","sentAt":"2011-11-14T17:20:37Z","receivedAt":"2011-11-14T17:20:37Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Sat, Nov 12, 2011 at 11:37 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> \"J.V.\" <jvsrvcs@gmail.com> writes:\n>\n>> OK so \"work tree\" is a new term for me.  I thought we were in isolated\n>> sandboxes called \"branches\" and changes made in a branch would stay in\n>> that branch regardless.\n>\n> Do not think of \"branches\" as isolated _sandboxes_.\n>\n> Rather, \"branches\" are where the independent states are to be _recorded_.\n\nI think I was confused about this when learning Git too. I friend of\nmine made the following argument, which I agree with and which I haven\nseen on the list before:\n\nEither you want the modifications to stay on the branch, or you want\nthem to carry over to the branch you are checking out. In the former\ncase, you would want Git to fail if there are modifications (that you\nmight have forgotten you made). In the latter case, you would want\n\"git checkout -m\". The current behavior is somewhere in between. It is\nnot clear to me if there is a use case where the current behavior is\nbetter (from the user's point of view) than either failing or\n\"checkout -m\".\n\nIt is obviously too late to change this now, though.\n\nMartin\n"},{"id":"179446","messageId":"7vr51aifug.fsf@alter.siamese.dyndns.org","threadId":"28913","inReplyTo":"CAOeW2eEUbvd0eJHjNfbvi9QnDiUO=mFA9rrKsjv8Yu0_QiPgSw@mail.gmail.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-14T20:55:35Z","receivedAt":"2011-11-14T20:55:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin von Zweigbergk <martin.von.zweigbergk@gmail.com> writes:\n\n> Either you want the modifications to stay on the branch, or you want\n> them to carry over to the branch you are checking out. In the former\n> case, you would want Git to fail if there are modifications (that you\n> might have forgotten you made). In the latter case, you would want\n> \"git checkout -m\". The current behavior is somewhere in between. It is\n> not clear to me if there is a use case where the current behavior is\n> better (from the user's point of view) than either failing or\n> \"checkout -m\".\n\nCurrent behaviour is deliberately made safe because \"checkout -m\" may end\nup forcing you to resolve a 3-way conflict you may not be prepared to do\ncorrectly at your first attempt. Stopping and refusing to check out the\nother branch gives you the choice to create a temporary stash-away commit\neither on a current branch, or a temporary branch you create with \"git\ncheckout -b temp && git commit\" before switching to the target branch to\nattempt to port the change over with \"git cherry-pick @{-1}\", which you\n_can_ redo if you screw up conflict resolution and want to start over.\nIf you are confident that your local changes are trivial that you can\nreproduce it even if you screw up your conflict resolution attempt, then\nyou can choose to run \"checkout -m\". If we made it the default, you will\nlose this safety.\n\nOn the other hand, if you do *not* want to carry over the change when\nchecking out a different branch, you can easily stash-away the changes.\n"},{"id":"179447","messageId":"m3k472mltc.fsf@localhost.localdomain","threadId":"28913","inReplyTo":"CAOeW2eEUbvd0eJHjNfbvi9QnDiUO=mFA9rrKsjv8Yu0_QiPgSw@mail.gmail.com","subject":"Re: Git: Unexpected behaviour?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-11-14T21:33:51Z","receivedAt":"2011-11-14T21:33:51Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Martin von Zweigbergk <martin.von.zweigbergk@gmail.com> writes:\n> On Sat, Nov 12, 2011 at 11:37 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> > \"J.V.\" <jvsrvcs@gmail.com> writes:\n> >\n> > > OK so \"work tree\" is a new term for me.  I thought we were in isolated\n> > > sandboxes called \"branches\" and changes made in a branch would stay in\n> > > that branch regardless.\n\nThat would be the default and only solution if each branch was checked\nout to a separate working directory.\n\nYou can do that in git using git-new-worktree script from contrib.\n\n> > Do not think of \"branches\" as isolated _sandboxes_.\n> >\n> > Rather, \"branches\" are where the independent states are to be _recorded_.\n\nBranches are lines of development, and are about _comitted_ changes.\nThis means that when switching branches \"in place\", un-committed\nchanges are not on any branch.\n\n> I think I was confused about this when learning Git too. I friend of\n> mine made the following argument, which I agree with and which I haven\n> seen on the list before:\n> \n> Either you want the modifications to stay on the branch, or you want\n> them to carry over to the branch you are checking out. In the former\n> case, you would want Git to fail if there are modifications (that you\n> might have forgotten you made). In the latter case, you would want\n> \"git checkout -m\". The current behavior is somewhere in between. It is\n> not clear to me if there is a use case where the current behavior is\n> better (from the user's point of view) than either failing or\n> \"checkout -m\".\n\nThe \"checkout -m\" behavior is unsafe; you can land in a state where it\nwould be difficult to revert, and could lose your changes.  The\ndefault behavior of switching branches is to carry over changes if it\nis safe to do so.\n \n> It is obviously too late to change this now, though.\n\nWell, we could in theory add knob that would stash changes when\nswitching to branch, and unstash when switching to branch.\n\n-- \nJakub Narębski\n"}]}