{"thread":{"id":"43286","subject":"[PATCH 2/2] Optionally check for uncommitted changes before switching branches.","startedAt":"2006-12-07T10:02:24Z","lastAt":"2006-12-07T23:01:12Z","messageCount":4,"participants":["Shawn O. Pearce","Junio C Hamano","Shawn Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"294225","messageId":"20061207100224.GB12966@spearce.org","threadId":"43286","inReplyTo":"6ed9774cb95e873e76a4ac406dd740caf954bd3b.1165485618.git.spearce@spearce.org","subject":"[PATCH 2/2] Optionally check for uncommitted changes before switching branches.","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-12-07T10:02:24Z","receivedAt":"2006-12-07T10:02:24Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Lately I have noticed a number of users are forgetting that they\nhave uncommitted changes in their working directory when they switch\nto another branch.  This causes the user to accidentally carry those\nchanges into the new branch, which is usually not where they wanted\nto commit them.  A correlation does appear to exist between the user\nbeing interrupted in the middle of their task and the branch switch,\nindicating they simply got distracted and forgot what was going on.\n\nGit shouldn't cause the user to make mistakes when it can help to\nprevent them.  So now users may set checkout.requireCleanDirectory\nto true in their config file to have git-checkout verify the working\ndirectory is clean before switching branches.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n Documentation/config.txt |    8 ++++++++\n git-checkout.sh          |   10 ++++++++++\n t/t3200-branch.sh        |   11 +++++++++++\n 3 files changed, 29 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 9d754c8..f10e8ac 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -136,6 +136,14 @@ checkout.requireSourceBranch::\n \tbe the source version if only one argument is supplied.\n \tDefault is false, to stay compatible with prior behavior.\n \n+checkout.requireCleanDirectory::\n+\tIf true tells git-checkout to verify there are no uncommitted\n+\tchanges still in the index or working directory before\n+\tswitching branches.  If uncommitted changes exist the -m\n+\tflag can be used to skip the check if the user really wanted\n+\tto carry those onto the new branch.  Default is false,\n+\tto stay compatible with prior behavior.\n+\n pager.color::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-checkout.sh b/git-checkout.sh\nindex 5f9fb6e..c04b8c1 100755\n--- a/git-checkout.sh\n+++ b/git-checkout.sh\n@@ -171,6 +171,16 @@ then\n     git-read-tree --reset -u $new\n else\n     git-update-index --refresh >/dev/null\n+\tif [ -n \"$old\" ] &&\n+\t   [ -z \"$merge\" ] &&\n+\t   [ Xtrue = \"X`git-repo-config --bool checkout.requireCleanDirectory`\" ]\n+\tthen\n+\t\tif [ `git-diff-index --cached $old | wc -l` -gt 0 ] ||\n+\t\t   [ `git-diff-files | wc -l` -gt 0 ]\n+\t\tthen\n+\t\t\tdie \"Working directory has uncommitted changes; commit, reset or use -m\"\n+\t\tfi\n+\tfi\n     merge_error=$(git-read-tree -m -u $old $new 2>&1) || (\n \tcase \"$merge\" in\n \t'')\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex 7e0c48b..9429827 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -84,4 +84,15 @@ test_expect_success \\\n \t'git-repo-config checkout.requireSourceBranch false\n \t git-checkout -b N'\n \n+test_expect_failure \\\n+\t'git checkout -b O works only if tree is clean' \\\n+\t'git-repo-config checkout.requireCleanDirectory true\n+\t echo atest >atest\n+\t git add atest\n+\t git-checkout -b O'\n+\n+test_expect_success \\\n+\t'git checkout -m -b O works' \\\n+\t'git-checkout -m -b O'\n+\n test_done\n-- \n"},{"id":"297409","messageId":"7vu007sdhp.fsf@assigned-by-dhcp.cox.net","threadId":"43286","inReplyTo":"20061207100224.GB12966@spearce.org","subject":"Re: [PATCH 2/2] Optionally check for uncommitted changes before switching branches.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-07T19:38:26Z","receivedAt":"2006-12-07T19:38:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> Git shouldn't cause the user to make mistakes when it can help to\n> prevent them.  So now users may set checkout.requireCleanDirectory\n> to true in their config file to have git-checkout verify the working\n> directory is clean before switching branches.\n\nA lot of times the reason to switch branches is because the user\nstarts to make a trivial change in the worktree and realizes\nthat the change belongs to another branch.  Other times it is\ndone by mistake and making it easier to notice that mistake is a\nlaudable goal.\n\nYour patch allows -m to override this, but that destroys one\nvery useful feature of -m.  In the above \"ah, this trivial thing\nbelongs to the other branch, so let's switch to the branch to\ncommit only that trivial piece and come back to the current\nbranch to continue what I'm doing\" workflow, I usually first say\n\"git checkout\" without -m to switch, and if it does not allow me\nto switch, it is an indication that \"the trivial thing\" I\nthought was trivial was not trivial.  I take it as a cue that I\nshould instead do it \"the right way\" (i.e. finish or stash away\nwhat I am doing, switch to the branch in a clean state and fix\nit properly).\n\nOther times, when all (or most of) the changes in the work tree\nlogically should have started on a different branch, I do force\nit with -m (and take the conflict markers in my worktree), but\nbeing able to forbid the worktree merge by not giving -m is\nimportant.\n\nPeople with this new configuration set and has to override it\nwith a command line switch will lose this ability if you\noverload that on '-m'.\n"},{"id":"296043","messageId":"20061207194358.GF12143@spearce.org","threadId":"43286","inReplyTo":"7vu007sdhp.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 2/2] Optionally check for uncommitted changes before switching branches.","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-12-07T19:43:58Z","receivedAt":"2006-12-07T19:43:58Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> \n> > Git shouldn't cause the user to make mistakes when it can help to\n> > prevent them.  So now users may set checkout.requireCleanDirectory\n> > to true in their config file to have git-checkout verify the working\n> > directory is clean before switching branches.\n[...snip...]\n> People with this new configuration set and has to override it\n> with a command line switch will lose this ability if you\n> overload that on '-m'.\n\nYes.  That's a problem with this patch.\n\nWhat about when this option is enabled then -m means do what we\ndid before, and -m -m (or -mm, or -m2) does what -m does when the\noption is false?\n\n-- \n"},{"id":"294396","messageId":"7vejrbqpjb.fsf@assigned-by-dhcp.cox.net","threadId":"43286","inReplyTo":"20061207194358.GF12143@spearce.org","subject":"Re: [PATCH 2/2] Optionally check for uncommitted changes before switching branches.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-07T23:01:12Z","receivedAt":"2006-12-07T23:01:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Shawn Pearce <spearce@spearce.org> writes:\n\n> What about when this option is enabled then -m means do what we\n> did before, and -m -m (or -mm, or -m2) does what -m does when the\n> option is false?\n\nWouldn't --force be more appropriate?\n"}]}