{"thread":{"id":"8777","subject":"[PATCH (2nd try)] Add git-stash script","startedAt":"2007-06-30T01:29:06Z","lastAt":"2007-07-02T23:11:22Z","messageCount":34,"participants":["しらいしななこ","Johannes Schindelin","Jeff King","Junio C Hamano","Frank Lichtenheld"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"46057","messageId":"200706300126.l5U1QPdb021795@mi1.bluebottle.com","threadId":"8777","inReplyTo":null,"subject":"[PATCH (2nd try)] Add git-stash script","fromName":"しらいしななこ","fromEmail":"nanako3@bluebottle.com","sentAt":"2007-06-30T01:29:06Z","receivedAt":"2007-06-30T01:29:06Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"When my boss has something to show me and I have to update, for some\nreason I am always in the middle of doing something else, and git pull\ncommand refuses to work in such a case.\n\nI wrote this little script to save the changes I made, perform the\nupdate, and then come back to where I was, but on top of the updated\ncommit.\n\nThis is how you would use the script:\n\n  $ git stash\n  $ git pull\n  $ git stash apply\n\nSigned-off-by: Nanako Shiraishi <nanako3@bluebottle.com>\n---\n\nHere is an updated script.\n\nUnfortunately I haven't managed to get the suggestion to use\n\"export GITHEAD_xxxx=NicerName\" from Johannes Schindelin working\nyet.\n\n git-stash.sh |  153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 153 insertions(+), 0 deletions(-)\n create mode 100755 git-stash.sh\n\ndiff --git a/git-stash.sh b/git-stash.sh\nnew file mode 100755\nindex 0000000..8bf83c1\n--- /dev/null\n+++ b/git-stash.sh\n@@ -0,0 +1,153 @@\n+#!/bin/sh\n+# Copyright (c) 2007, Nanako Shiraishi\n+\n+USAGE='[ | list | show | apply | clear]'\n+\n+. git-sh-setup\n+require_work_tree\n+\n+TMP=\"$GIT_DIR/.git-stash.$$\"\n+trap 'rm -f \"$TMP-*\"' 0\n+\n+ref_stash=refs/stash\n+\n+no_changes () {\n+\tgit-diff-index --quiet --cached HEAD &&\n+\tgit-diff-files --quiet\n+}\n+\n+clear_stash () {\n+\tlogfile=\"$GIT_DIR/logs/$ref_stash\" &&\n+\tmkdir -p \"$(dirname \"$logfile\")\" &&\n+\t: >\"$logfile\"\n+}\n+\n+save_stash () {\n+\tif no_changes\n+\tthen\n+\t\techo >&2 'No local changes to save'\n+\t\texit 0\n+\tfi\n+\ttest -f \"$GIT_DIR/logs/refs/stash\" ||\n+\t\tclear_stash || die \"Cannot initialize stash\"\n+\n+\t# state of the base commit\n+\tif b_commit=$(git-rev-parse --verify HEAD)\n+\tthen\n+\t\thead=$(git-log --abbrev-commit --pretty=oneline -n 1 HEAD)\n+\telse\n+\t\tdie \"You do not have the initial commit yet\"\n+\tfi\n+\n+\tif branch=$(git-symbolic-ref -q HEAD)\n+\tthen\n+\t\tbranch=${branch#refs/heads/}\n+\telse\n+\t\tbranch='(no branch)'\n+\tfi\n+\tmsg=$(printf '%s: %s' \"$branch\" \"$head\")\n+\n+\t# state of the index\n+\ti_tree=$(git-write-tree) &&\n+\ti_commit=$(printf 'index on %s' \"$msg\" |\n+\t\tgit-commit-tree $i_tree -p $b_commit) ||\n+\t\tdie \"Cannot save the current index state\"\n+\n+\t# state of the working tree\n+\tw_tree=$( (\n+\t\tGIT_INDEX_FILE=\"$TMP-index\" &&\n+\t\texport GIT_INDEX_FILE &&\n+\n+\t\trm -f \"$TMP-index\" &&\n+\t\tgit-read-tree $i_tree &&\n+\t\tgit-add -u &&\n+\t\tgit-write-tree &&\n+\t\trm -f \"$TMP-index\"\n+\t) ) ||\n+\t\tdie \"Cannot save the current worktree state\"\n+\n+\t# create the stash\n+\tw_commit=$(printf 'WIP on %s' \"$msg\" |\n+\t\tgit-commit-tree $w_tree -p $b_commit -p $i_commit) ||\n+\t\tdie \"Cannot record working tree state\"\n+\n+\tgit-update-ref -m \"$msg\" $ref_stash $w_commit ||\n+\t\tdie \"Cannot save the current status\"\n+\tprintf >&2 'Saved WIP on %s\\n' \"$msg\"\n+}\n+\n+list_stash () {\n+\tgit-log --pretty=oneline -g \"$@\" $ref_stash |\n+\tsed -n -e 's/^[.0-9a-f]* refs\\///p'\n+}\n+\n+show_stash () {\n+\tflags=$(git-rev-parse --no-revs --flags \"$@\")\n+\tif test -z \"$flags\"\n+\tthen\n+\t\tflags=--stat\n+\tfi\n+\ts=$(git-rev-parse --revs-only --no-flags --default $ref_stash \"$@\")\n+\n+\tw_commit=$(git-rev-parse --verify \"$s\") &&\n+\tb_commit=$(git-rev-parse --verify \"$s^\") &&\n+\tgit-diff $flags $b_commit $w_commit\n+}\n+\n+apply_stash () {\n+\tgit-diff-files --quiet ||\n+\t\tdie 'Cannot restore on top of a dirty state'\n+\n+\t# current index state\n+\tc_tree=$(git-write-tree) ||\n+\t\tdie 'Cannot apply a stash in the middle of a merge'\n+\n+\ts=$(git-rev-parse --revs-only --no-flags --default $ref_stash \"$@\") &&\n+\tw_tree=$(git-rev-parse --verify \"$s:\") &&\n+\tb_tree=$(git-rev-parse --verify \"$s^:\") ||\n+\t\tdie \"$*: no valid stashed state found\"\n+\n+\tif git-merge-recursive $b_tree -- $c_tree $w_tree\n+\tthen\n+\t\t# No conflict\n+\t\ta=\"$TMP-added\" &&\n+\t\tgit-diff --cached --name-only --diff-filter=A $c_tree >\"$a\" &&\n+\t\tgit-read-tree --reset $c_tree &&\n+\t\tgit-update-index --add --stdin <\"$a\" ||\n+\t\t\tdie \"Cannot unstage modified files\"\n+\t\tgit-status\n+\t\trm -f \"$a\"\n+\telse\n+\t\t# Merge conflict\n+\t\texit 1\n+\tfi\n+}\n+\n+# Main command set\n+case \"$1\" in\n+list)\n+\tshift\n+\tif test $# = 0\n+\tthen\n+\t\tset x -n 10\n+\t\tshift\n+\tfi\n+\tlist_stash \"$@\"\n+\t;;\n+show)\n+\tshift\n+\tshow_stash \"$@\"\n+\t;;\n+apply)\n+\tshift\n+\tapply_stash \"$@\"\n+\t;;\n+clear)\n+\tclear_stash\n+\t;;\n+'')\n+\tsave_stash && git-reset --hard\n+\t;;\n+*)\n+\tusage\n+esac\n-- \n1.5.2\n\n----------------------------------------------------------------------\nFree pop3 email with a spam filter.\nhttp://www.bluebottle.com\n"},{"id":"46058","messageId":"Pine.LNX.4.64.0706300304480.4438@racer.site","threadId":"8777","inReplyTo":"200706300126.l5U1QPdb021795@mi1.bluebottle.com","subject":"Re: [PATCH (2nd try)] Add git-stash script","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-30T02:05:04Z","receivedAt":"2007-06-30T02:05:04Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 30 Jun 2007, しらいしななこ wrote:\n\n> Unfortunately I haven't managed to get the suggestion to use \"export \n> GITHEAD_xxxx=NicerName\" from Johannes Schindelin working yet.\n\nIf you provide a test script (see t/t[0-9]*.sh), I'll gladly provide the \nsupport for GITHEAD_xxxx.\n\nCiao,\nDscho\n"},{"id":"46064","messageId":"200706300539.l5U5dHLh003989@mi1.bluebottle.com","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706300304480.4438@racer.site","subject":"[PATCH (3rd try)] Add git-stash script","fromName":"しらいしななこ","fromEmail":"nanako3@bluebottle.com","sentAt":"2007-06-30T05:37:09Z","receivedAt":"2007-06-30T05:37:09Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"When my boss has something to show me and I have to update, for some\nreason I am always in the middle of doing something else, and git pull\ncommand refuses to work in such a case.\n\nI wrote this little script to save the changes I made, perform the\nupdate, and then come back to where I was, but on top of the updated\ncommit.\n\nThis is how you would use the script:\n\n  $ git stash\n  $ git pull\n  $ git stash apply\n\nSigned-off-by: Nanako Shiraishi <nanako3@bluebottle.com>\n---\n\nThank you for the hint for labeling the conflict blocks.\nI also added an entry to gitignore and Makefile as requested.\n\n .gitignore   |    1 +\n Makefile     |    3 +-\n git-stash.sh |  160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 163 insertions(+), 1 deletions(-)\n create mode 100755 git-stash.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex e8b060c..02d9b04 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -123,6 +123,7 @@ git-ssh-fetch\n git-ssh-pull\n git-ssh-push\n git-ssh-upload\n+git-stash\n git-status\n git-stripspace\n git-submodule\ndiff --git a/Makefile b/Makefile\nindex a98e27a..05b1fc0 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -212,7 +212,8 @@ SCRIPT_SH = \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh \\\n \tgit-lost-found.sh git-quiltimport.sh git-submodule.sh \\\n-\tgit-filter-branch.sh\n+\tgit-filter-branch.sh \\\n+\tgit-stash.sh\n \n SCRIPT_PERL = \\\n \tgit-add--interactive.perl \\\ndiff --git a/git-stash.sh b/git-stash.sh\nnew file mode 100755\nindex 0000000..05ca3a6\n--- /dev/null\n+++ b/git-stash.sh\n@@ -0,0 +1,160 @@\n+#!/bin/sh\n+# Copyright (c) 2007, Nanako Shiraishi\n+\n+USAGE='[ | list | show | apply | clear]'\n+\n+. git-sh-setup\n+require_work_tree\n+\n+TMP=\"$GIT_DIR/.git-stash.$$\"\n+trap 'rm -f \"$TMP-*\"' 0\n+\n+ref_stash=refs/stash\n+\n+no_changes () {\n+\tgit-diff-index --quiet --cached HEAD &&\n+\tgit-diff-files --quiet\n+}\n+\n+clear_stash () {\n+\tlogfile=\"$GIT_DIR/logs/$ref_stash\" &&\n+\tmkdir -p \"$(dirname \"$logfile\")\" &&\n+\t: >\"$logfile\"\n+}\n+\n+save_stash () {\n+\tif no_changes\n+\tthen\n+\t\techo >&2 'No local changes to save'\n+\t\texit 0\n+\tfi\n+\ttest -f \"$GIT_DIR/logs/refs/stash\" ||\n+\t\tclear_stash || die \"Cannot initialize stash\"\n+\n+\t# state of the base commit\n+\tif b_commit=$(git-rev-parse --verify HEAD)\n+\tthen\n+\t\thead=$(git-log --abbrev-commit --pretty=oneline -n 1 HEAD)\n+\telse\n+\t\tdie \"You do not have the initial commit yet\"\n+\tfi\n+\n+\tif branch=$(git-symbolic-ref -q HEAD)\n+\tthen\n+\t\tbranch=${branch#refs/heads/}\n+\telse\n+\t\tbranch='(no branch)'\n+\tfi\n+\tmsg=$(printf '%s: %s' \"$branch\" \"$head\")\n+\n+\t# state of the index\n+\ti_tree=$(git-write-tree) &&\n+\ti_commit=$(printf 'index on %s' \"$msg\" |\n+\t\tgit-commit-tree $i_tree -p $b_commit) ||\n+\t\tdie \"Cannot save the current index state\"\n+\n+\t# state of the working tree\n+\tw_tree=$( (\n+\t\tGIT_INDEX_FILE=\"$TMP-index\" &&\n+\t\texport GIT_INDEX_FILE &&\n+\n+\t\trm -f \"$TMP-index\" &&\n+\t\tgit-read-tree $i_tree &&\n+\t\tgit-add -u &&\n+\t\tgit-write-tree &&\n+\t\trm -f \"$TMP-index\"\n+\t) ) ||\n+\t\tdie \"Cannot save the current worktree state\"\n+\n+\t# create the stash\n+\tw_commit=$(printf 'WIP on %s' \"$msg\" |\n+\t\tgit-commit-tree $w_tree -p $b_commit -p $i_commit) ||\n+\t\tdie \"Cannot record working tree state\"\n+\n+\tgit-update-ref -m \"$msg\" $ref_stash $w_commit ||\n+\t\tdie \"Cannot save the current status\"\n+\tprintf >&2 'Saved WIP on %s\\n' \"$msg\"\n+}\n+\n+list_stash () {\n+\tgit-log --pretty=oneline -g \"$@\" $ref_stash |\n+\tsed -n -e 's/^[.0-9a-f]* refs\\///p'\n+}\n+\n+show_stash () {\n+\tflags=$(git-rev-parse --no-revs --flags \"$@\")\n+\tif test -z \"$flags\"\n+\tthen\n+\t\tflags=--stat\n+\tfi\n+\ts=$(git-rev-parse --revs-only --no-flags --default $ref_stash \"$@\")\n+\n+\tw_commit=$(git-rev-parse --verify \"$s\") &&\n+\tb_commit=$(git-rev-parse --verify \"$s^\") &&\n+\tgit-diff $flags $b_commit $w_commit\n+}\n+\n+apply_stash () {\n+\tgit-diff-files --quiet ||\n+\t\tdie 'Cannot restore on top of a dirty state'\n+\n+\t# current index state\n+\tc_tree=$(git-write-tree) ||\n+\t\tdie 'Cannot apply a stash in the middle of a merge'\n+\n+\ts=$(git-rev-parse --revs-only --no-flags --default $ref_stash \"$@\") &&\n+\tw_tree=$(git-rev-parse --verify \"$s:\") &&\n+\tb_tree=$(git-rev-parse --verify \"$s^:\") ||\n+\t\tdie \"$*: no valid stashed state found\"\n+\n+\teval \"\n+\t\tGITHEAD_$w_tree='Stashed changes' &&\n+\t\tGITHEAD_$c_tree='Updated upstream' &&\n+\t\tGITHEAD_$b_tree='Version stash was based on' &&\n+\t\texport GITHEAD_$w_tree GITHEAD_$c_tree GITHEAD_$b_tree\n+\t\"\n+\n+\tif git-merge-recursive $b_tree -- $c_tree $w_tree\n+\tthen\n+\t\t# No conflict\n+\t\ta=\"$TMP-added\" &&\n+\t\tgit-diff --cached --name-only --diff-filter=A $c_tree >\"$a\" &&\n+\t\tgit-read-tree --reset $c_tree &&\n+\t\tgit-update-index --add --stdin <\"$a\" ||\n+\t\t\tdie \"Cannot unstage modified files\"\n+\t\tgit-status\n+\t\trm -f \"$a\"\n+\telse\n+\t\t# Merge conflict\n+\t\texit 1\n+\tfi\n+}\n+\n+# Main command set\n+case \"$1\" in\n+list)\n+\tshift\n+\tif test $# = 0\n+\tthen\n+\t\tset x -n 10\n+\t\tshift\n+\tfi\n+\tlist_stash \"$@\"\n+\t;;\n+show)\n+\tshift\n+\tshow_stash \"$@\"\n+\t;;\n+apply)\n+\tshift\n+\tapply_stash \"$@\"\n+\t;;\n+clear)\n+\tclear_stash\n+\t;;\n+'')\n+\tsave_stash && git-reset --hard\n+\t;;\n+*)\n+\tusage\n+esac\n-- \n1.5.2\n\n----------------------------------------------------------------------\nFree pop3 email with a spam filter.\nhttp://www.bluebottle.com\n"},{"id":"46066","messageId":"20070630061237.GA14344@coredump.intra.peff.net","threadId":"8777","inReplyTo":"200706300539.l5U5dHLh003989@mi1.bluebottle.com","subject":"Re: [PATCH (3rd try)] Add git-stash script","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-06-30T06:12:37Z","receivedAt":"2007-06-30T06:12:37Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jun 30, 2007 at 02:37:09PM +0900, しらいしななこ wrote:\n\n> +ref_stash=refs/stash\n[...]\n> +save_stash () {\n> +\tif no_changes\n> +\tthen\n> +\t\techo >&2 'No local changes to save'\n> +\t\texit 0\n> +\tfi\n> +\ttest -f \"$GIT_DIR/logs/refs/stash\" ||\n> +\t\tclear_stash || die \"Cannot initialize stash\"\n\nNit: this should be .../logs/$ref_stash\n\n-Peff\n"},{"id":"46067","messageId":"7v7ipmdkme.fsf@assigned-by-dhcp.pobox.com","threadId":"8777","inReplyTo":"20070630061237.GA14344@coredump.intra.peff.net","subject":"Re: [PATCH (3rd try)] Add git-stash script","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-06-30T06:25:29Z","receivedAt":"2007-06-30T06:25:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sat, Jun 30, 2007 at 02:37:09PM +0900, しらいしななこ wrote:\n>\n>> +ref_stash=refs/stash\n> [...]\n>> +save_stash () {\n>> +\tif no_changes\n>> +\tthen\n>> +\t\techo >&2 'No local changes to save'\n>> +\t\texit 0\n>> +\tfi\n>> +\ttest -f \"$GIT_DIR/logs/refs/stash\" ||\n>> +\t\tclear_stash || die \"Cannot initialize stash\"\n>\n> Nit: this should be .../logs/$ref_stash\n\nSharp eyes.\n\nI'll take a look and possibly comment on it later, but from a\ncursory look I do not see major problems, so if I decide to\napply it I'll try to remember fixing this up when I do so...\n"},{"id":"46092","messageId":"Pine.LNX.4.64.0706301641000.4438@racer.site","threadId":"8777","inReplyTo":"200706300539.l5U5dHLh003989@mi1.bluebottle.com","subject":"Re: [PATCH (3rd try)] Add git-stash script","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-30T15:41:11Z","receivedAt":"2007-06-30T15:41:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 30 Jun 2007, しらいしななこ wrote:\n\n> diff --git a/git-stash.sh b/git-stash.sh\n> [...]\n> +\tprintf >&2 'Saved WIP on %s\\n' \"$msg\"\n\nYou have an awful lot of printfs in the code. Why not just use echos?\n\n> +list_stash () {\n> +\tgit-log --pretty=oneline -g \"$@\" $ref_stash |\n\nWouldn't you want \"--default $ref_stash\" here?\n\n> +apply_stash () {\n> +\tgit-diff-files --quiet ||\n> +\t\tdie 'Cannot restore on top of a dirty state'\n\nYou meant \"no_changes\", right? I think you miss changes in the index \notherwise.\n\n> +\t\tgit-diff --cached --name-only --diff-filter=A $c_tree >\"$a\" &&\n> +\t\tgit-read-tree --reset $c_tree &&\n> +\t\tgit-update-index --add --stdin <\"$a\" ||\n> +\t\t\tdie \"Cannot unstage modified files\"\n\nIsn't there a way to avoid the temporary file here?\n\n> +\telse\n> +\t\t# Merge conflict\n> +\t\texit 1\n\nSince $? is already != 0, and it might tell the savvy user what kind of \nerror merge-recursive returned, why not use \"exit\", which is equivalent to \n\"exit $?\"?\n\n> +\t\tset x -n 10\n> +\t\tshift\n\nThis is more elegantly written as \"set -- -n 10\", or in our context even \n\"set -- -10\".\n\nCiao,\nDscho\n"},{"id":"46093","messageId":"Pine.LNX.4.64.0706301644190.4438@racer.site","threadId":"8777","inReplyTo":"200706300539.l5U5dHLh003989@mi1.bluebottle.com","subject":"[PATCH] Add a manual page for git-stash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-30T15:44:39Z","receivedAt":"2007-06-30T15:44:39Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/git-stash.txt |  116 +++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 116 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-stash.txt\n\ndiff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt\nnew file mode 100644\nindex 0000000..b109f6e\n--- /dev/null\n+++ b/Documentation/git-stash.txt\n@@ -0,0 +1,116 @@\n+git-stash(1)\n+=============\n+\n+NAME\n+----\n+git-stash - Stash the changes in a dirty working directory away\n+\n+SYNOPSIS\n+--------\n+[verse]\n+'git-stash' [clear]\n+'git-stash' [list | show | apply] [<stashname>]\n+\n+DESCRIPTION\n+-----------\n+Use 'git stash' when you want to record the current state of the\n+working directory and the index, but want to go back to a clean\n+working directory.\n+\n+For example, if you have to pull, but are in the middle of some\n+interesting work, not yet ready to be committed, use git-stash.\n+\n+The default operation (when called without options), is to save\n+the changes away.\n+\n+\n+OPTIONS\n+-------\n+clear::\n+\tUndo _all_ stashes (dangerous!).\n+\n+list [<stashname>]::\n+\tList all stashed states.\n+\n+show [<stashname>]::\n+\tShow a combined diff of the stashed working directory, index and\n+\tHEAD.\n+\n+apply [<stashname>]::\n+\tTry to apply the stashed changes to the current HEAD. You need\n+\ta clean working directory for that, i.e. you must not have changes\n+\trelative to HEAD in your working directory or index.\n+\n+<stashname>::\n+\tA name of a stashed state. Typically something like 'stash@{2}'\n+\tor 'stash@{2.days.ago}'.\n+\n+\n+EXAMPLES\n+--------\n+\n+Get to a clean working directory, quick:\n+\n+---------------------\n+$ git stash\n+---------------------\n+\n+See what you stashed:\n+\n+---------------------\n+$ git stash list\n+---------------------\n+\n+Inspect the last stashed state:\n+\n+---------------------\n+$ git stash show\n+---------------------\n+\n+Inspect the second last stashed state:\n+\n+--------------------------\n+$ git stash show stash@{1}\n+--------------------------\n+\n+Apply the second last stashed state:\n+\n+---------------------------\n+$ git stash apply stash@{1}\n+---------------------------\n+\n+\n+DISCUSSION\n+----------\n+\n+The state is saved as three commits:\n+\n+- HEAD,\n+- a commit which contains the state of the index, which has HEAD as a\n+  parent, and\n+- a commit which contains the state of the working directory (only the\n+  tracked files, though), which has both HEAD and the second commit\n+  as parents.\n+\n+The third commit holds the complete information of the stash, and is\n+stored as the ref 'refs/stash'.\n+\n+Since that commit does not have any reference to other stashed states,\n+the stash listing relies on the reflog of 'refs/stash'. Therefore,\n+the stashed states are garbage collected like all the other reflogs.\n+\n+\n+SEE ALSO\n+--------\n+gitlink:git-commit[1],\n+gitlink:git-log[1],\n+gitlink:git-reflog[1]\n+\n+Author\n+------\n+Written by Johannes E. Schindelin <johannes.schindelin@gmx.de>\n+\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\n-- \n1.5.2.2.3249.g33841\n"},{"id":"46094","messageId":"Pine.LNX.4.64.0706301705490.4438@racer.site","threadId":"8777","inReplyTo":"200706300539.l5U5dHLh003989@mi1.bluebottle.com","subject":"[PATCH] Add tests for git-stash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-30T16:06:28Z","receivedAt":"2007-06-30T16:06:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tIn the current version of git-stash, the last test fails.\n\tBasically, it tests if different changes to the file \"file\"\n\tin the working directory and the index are reconstructed.\n\tThey are not (index changes are not there), but I think they \n\tshould be.\n\n t/t3903-stash.sh |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 55 insertions(+), 0 deletions(-)\n create mode 100755 t/t3903-stash.sh\n\ndiff --git a/t/t3903-stash.sh b/t/t3903-stash.sh\nnew file mode 100755\nindex 0000000..6d42373\n--- /dev/null\n+++ b/t/t3903-stash.sh\n@@ -0,0 +1,55 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Johannes E Schindelin\n+#\n+\n+test_description='Test git-stash'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'stash some dirty working directory' '\n+\techo 1 > file &&\n+\tgit add file &&\n+\ttest_tick &&\n+\tgit commit -m initial &&\n+\techo 2 > file &&\n+\tgit add file &&\n+\techo 3 > file &&\n+\ttest_tick &&\n+\tgit stash &&\n+\tgit diff-files --quiet &&\n+\tgit diff-index --cached --quiet HEAD\n+'\n+\n+cat > expect << EOF\n+diff --git a/file b/file\n+index 0cfbf08..00750ed 100644\n+--- a/file\n++++ b/file\n+@@ -1 +1 @@\n+-2\n++3\n+EOF\n+\n+test_expect_success 'parents of stash' '\n+\ttest $(git rev-parse stash^) = $(git rev-parse HEAD) &&\n+\tgit diff stash^2..stash > output &&\n+\tdiff -u output expect\n+'\n+\n+test_expect_success 'apply needs clean working directory' '\n+\techo 4 > other-file &&\n+\tgit add other-file &&\n+\t! git stash apply\n+'\n+\n+test_expect_success 'apply stashed changes' '\n+\ttest_tick &&\n+\tgit commit -m other-file &&\n+\tgit stash apply &&\n+\ttest 3 = $(cat file) &&\n+\ttest 2 = $(git show :file) &&\n+\ttest 1 = $(git show HEAD:file)\n+'\n+\n+test_done\n-- \n1.5.2.2.3249.g33841\n"},{"id":"46096","messageId":"20070630163823.GT12721@planck.djpig.de","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301644190.4438@racer.site","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Frank Lichtenheld","fromEmail":"frank@lichtenheld.de","sentAt":"2007-06-30T16:38:23Z","receivedAt":"2007-06-30T16:38:23Z","isPatch":true,"sender":{"key":"frank@lichtenheld.de","avatar":"https://gravatar.com/avatar/b9f1d4b120e138f157c9e480d0818197c474628923786adb98f30017cdb99c3c?d=mp&s=160"},"body":"On Sat, Jun 30, 2007 at 04:44:39PM +0100, Johannes Schindelin wrote:\n> +Author\n> +------\n> +Written by Johannes E. Schindelin <johannes.schindelin@gmx.de>\n\nAFAICT \"Author\" is usually used for the author of the documented program\nand \"Documentation\" for the author of the documentation itself.\n\nGruesse,\n-- \nFrank Lichtenheld <frank@lichtenheld.de>\nwww: http://www.djpig.de/\n"},{"id":"46101","messageId":"7v8xa1e4wo.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301641000.4438@racer.site","subject":"Re: [PATCH (3rd try)] Add git-stash script","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-06-30T17:19:35Z","receivedAt":"2007-06-30T17:19:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> diff --git a/git-stash.sh b/git-stash.sh\n>> [...]\n>> +\tprintf >&2 'Saved WIP on %s\\n' \"$msg\"\n>\n> You have an awful lot of printfs in the code. Why not just use echos?\n\nI had the same impression, but I would say it is Ok (actually\nprintf is even better).  Judging from our recent changes\n(e.g. a23bfae) I think it is prudent to avoid echo when printing\nuser supplied messages.  Not that corrupted backslash sequence\nmatters that much on stderr, though ;-).\n\n>> +list_stash () {\n>> +\tgit-log --pretty=oneline -g \"$@\" $ref_stash |\n>\n> Wouldn't you want \"--default $ref_stash\" here?\n\nBut \"git log --pretty=oneline -g master --default refs/stash\"\nwould not make much sense would it?  The design currently seems\nto follow what I suggested earlier, namely to use a single stash\nref per repository, so $ref_stash is spelled as a variable but\nit is a constant.  IOW, you do not specify \"alternate stash\"\nfrom the command line.\n\nUnfortunately we do not have a good way to reject non-flag rev\nparameters in \"$@\" to error out \"git stash list master\".  What\nwe would want here is a way to allow things like --since=1.hour\nand -20 while rejecting branch/tag names and other parameters.\n\n>> +apply_stash () {\n>> +\tgit-diff-files --quiet ||\n>> +\t\tdie 'Cannot restore on top of a dirty state'\n>\n> You meant \"no_changes\", right? I think you miss changes in the index \n> otherwise.\n\nInterestingly, I think this is actually correct in the sense\nthat the code is internally consistent, as it uses the current\nindex, not the HEAD, as the base of application.  It however is\ndebatable if this sequence (which is allowed because it does not\nuse no_changes here) makes sense:\n\n\t: hack hack hack\n\t: get interrupted\n\t$ git stash\n\t: do something else on a clean slate\n\t$ git commit\n        : hack hack hack\n        $ git add -u\n        $ git unstash\n\n>> +\t\tgit-diff --cached --name-only --diff-filter=A $c_tree >\"$a\" &&\n>> +\t\tgit-read-tree --reset $c_tree &&\n>> +\t\tgit-update-index --add --stdin <\"$a\" ||\n>> +\t\t\tdie \"Cannot unstage modified files\"\n>\n> Isn't there a way to avoid the temporary file here?\n\nWe could obviously do\n\n\tfiles=$(git-diff --cached ...) &&\n        git-read-tree --reset $c_tree &&\n        echo \"$files\" | git-update-index --add --stdin\n\nOops, the last \"echo\" may have to be \"printf '%s'\" ;-)\n\nThere might be quite many files that have been added to make the\n$files variable too big to be given to echo, though.\n\n\tgit-diff --cached ... |\n        (\n        \tgit-read-tree --reset $c_tree &&\n                git-update-index --add --stdin\n\t)\n\nwould not work, unless you copy the index into a temporary file\nand have the upstream git-diff use it.  But then we are using a\ntemporary file anyway.\n\n>> +\t\tset x -n 10\n>> +\t\tshift\n>\n> This is more elegantly written as \"set -- -n 10\", or in our context even \n> \"set -- -10\".\n\nThat is Ok in POSIX only world, but so far we have stayed away\nfrom using \"set -- potentially-dangerous-string\" in any of our\nscripts.  I would feel x + shift is safer and more comfortable\nbut probably that is largely because I am old fashioned.\n"},{"id":"46103","messageId":"7vps3dcp76.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301644190.4438@racer.site","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-06-30T17:44:13Z","receivedAt":"2007-06-30T17:44:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> +DESCRIPTION\n> +-----------\n> +Use 'git stash' when you want to record the current state of the\n> +working directory and the index, but want to go back to a clean\n> +working directory.\n> +\n> +For example, if you have to pull, but are in the middle of some\n> +interesting work, not yet ready to be committed, use git-stash.\n> +\n> +The default operation (when called without options), is to save\n> +the changes away.\n> +\n> +\n> +OPTIONS\n> +-------\n> +clear::\n> +\tUndo _all_ stashes (dangerous!).\n> +\n> +list [<stashname>]::\n> +\tList all stashed states.\n> +\n\nI suspect that is not what the implementation intends to do.\n\"list -n 4\", \"list --since=1.hour\" would make sense, but \"list\nstash@{12}\" would probably not.\n\n> +show [<stashname>]::\n> +\tShow a combined diff of the stashed working directory, index and\n> +\tHEAD.\n\nIs that what it does?  I had an impression that \"show stash@{2}\"\nshows a regular diff between the base and the stashed working\ntree state.\n\n> +apply [<stashname>]::\n> +\tTry to apply the stashed changes to the current HEAD. You need\n> +\ta clean working directory for that, i.e. you must not have changes\n> +\trelative to HEAD in your working directory or index.\n\nThe implementation appears to apply on a clean index without\nrestriction to where the HEAD is.  I hinted that that behaviour\nis fine in my previous message, but on the other hand haven't\nconvinced myself enough to say that it would not confuse end\nusers.  Maybe insisting on not just clean index but no changes\nfrom the HEAD would reduce confusion?  I dunno.\n\n> +<stashname>::\n> +\tA name of a stashed state. Typically something like 'stash@{2}'\n> +\tor 'stash@{2.days.ago}'.\n\nProbably this should be defined in DESCRIPTION, along with the\ndefinition of what a stash is (\"records the difference between\nthe HEAD when the stash was created and the working tree state\nin such a way that it can be applied to a different state\nlater\").\n\n> +DISCUSSION\n> +----------\n> +\n> +The state is saved as three commits:\n> +\n> +- HEAD,\n> +- a commit which contains the state of the index, which has HEAD as a\n> +  parent, and\n> +- a commit which contains the state of the working directory (only the\n> +  tracked files, though), which has both HEAD and the second commit\n> +  as parents.\n> +\n> +The third commit holds the complete information of the stash, and is\n> +stored as the ref 'refs/stash'.\n> +\n> +Since that commit does not have any reference to other stashed states,\n> +the stash listing relies on the reflog of 'refs/stash'. Therefore,\n> +the stashed states are garbage collected like all the other reflogs.\n\nNit; s/the other reflogs/the other reflog entries/\n\n> +Author\n> +------\n> +Written by Johannes E. Schindelin <johannes.schindelin@gmx.de>\n\nYou wrote that ;-)?\n"},{"id":"46105","messageId":"Pine.LNX.4.64.0706301847370.4438@racer.site","threadId":"8777","inReplyTo":"20070630163823.GT12721@planck.djpig.de","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-30T17:48:27Z","receivedAt":"2007-06-30T17:48:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 30 Jun 2007, Frank Lichtenheld wrote:\n\n> On Sat, Jun 30, 2007 at 04:44:39PM +0100, Johannes Schindelin wrote:\n> > +Author\n> > +------\n> > +Written by Johannes E. Schindelin <johannes.schindelin@gmx.de>\n> \n> AFAICT \"Author\" is usually used for the author of the documented program\n> and \"Documentation\" for the author of the documentation itself.\n\nOh? If that is so, please disregard this hunk.\n\nAlthough in that case, git-bundle.txt is misattributed.\n\nCiao,\nDscho\n"},{"id":"46107","messageId":"Pine.LNX.4.64.0706301853400.4438@racer.site","threadId":"8777","inReplyTo":"7vps3dcp76.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-30T17:56:02Z","receivedAt":"2007-06-30T17:56:02Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 30 Jun 2007, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > +DESCRIPTION\n> > +-----------\n> > +Use 'git stash' when you want to record the current state of the\n> > +working directory and the index, but want to go back to a clean\n> > +working directory.\n> > +\n> > +For example, if you have to pull, but are in the middle of some\n> > +interesting work, not yet ready to be committed, use git-stash.\n> > +\n> > +The default operation (when called without options), is to save\n> > +the changes away.\n> > +\n> > +\n> > +OPTIONS\n> > +-------\n> > +clear::\n> > +\tUndo _all_ stashes (dangerous!).\n> > +\n> > +list [<stashname>]::\n> > +\tList all stashed states.\n> > +\n> \n> I suspect that is not what the implementation intends to do.\n> \"list -n 4\", \"list --since=1.hour\" would make sense, but \"list\n> stash@{12}\" would probably not.\n\nOkay, I misunderstood the _intention_ of the code, then.\n\n> > +show [<stashname>]::\n> > +\tShow a combined diff of the stashed working directory, index and\n> > +\tHEAD.\n> \n> Is that what it does?  I had an impression that \"show stash@{2}\"\n> shows a regular diff between the base and the stashed working\n> tree state.\n\nAh, you're completely right! Somehow my tired eyes read what I expected to \nfind there.\n\n> > +apply [<stashname>]::\n> > +\tTry to apply the stashed changes to the current HEAD. You need\n> > +\ta clean working directory for that, i.e. you must not have changes\n> > +\trelative to HEAD in your working directory or index.\n> \n> The implementation appears to apply on a clean index without\n> restriction to where the HEAD is.  I hinted that that behaviour\n> is fine in my previous message, but on the other hand haven't\n> convinced myself enough to say that it would not confuse end\n> users.  Maybe insisting on not just clean index but no changes\n> from the HEAD would reduce confusion?  I dunno.\n\nI am sure confused why the index state is stashed away when it is not \nused...\n\n> > +<stashname>::\n> > +\tA name of a stashed state. Typically something like 'stash@{2}'\n> > +\tor 'stash@{2.days.ago}'.\n> \n> Probably this should be defined in DESCRIPTION, along with the\n> definition of what a stash is (\"records the difference between\n> the HEAD when the stash was created and the working tree state\n> in such a way that it can be applied to a different state\n> later\").\n\nOkay.\n\n> > +DISCUSSION\n> > +----------\n> > +\n> > +The state is saved as three commits:\n> > +\n> > +- HEAD,\n> > +- a commit which contains the state of the index, which has HEAD as a\n> > +  parent, and\n> > +- a commit which contains the state of the working directory (only the\n> > +  tracked files, though), which has both HEAD and the second commit\n> > +  as parents.\n> > +\n> > +The third commit holds the complete information of the stash, and is\n> > +stored as the ref 'refs/stash'.\n> > +\n> > +Since that commit does not have any reference to other stashed states,\n> > +the stash listing relies on the reflog of 'refs/stash'. Therefore,\n> > +the stashed states are garbage collected like all the other reflogs.\n> \n> Nit; s/the other reflogs/the other reflog entries/\n\nOkay.\n\n> > +Author\n> > +------\n> > +Written by Johannes E. Schindelin <johannes.schindelin@gmx.de>\n> \n> You wrote that ;-)?\n\nNo. ;-)\n\nHey, be nice. It's a new role for me, usually others document what _I_ \nwrote, not vice versa :-)\n\nCiao,\nDscho\n"},{"id":"46109","messageId":"7vk5tlcnuq.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301853400.4438@racer.site","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-06-30T18:13:17Z","receivedAt":"2007-06-30T18:13:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> > +apply [<stashname>]::\n>> > +\tTry to apply the stashed changes to the current HEAD. You need\n>> > +\ta clean working directory for that, i.e. you must not have changes\n>> > +\trelative to HEAD in your working directory or index.\n>> \n>> The implementation appears to apply on a clean index without\n>> restriction to where the HEAD is.  I hinted that that behaviour\n>> is fine in my previous message, but on the other hand haven't\n>> convinced myself enough to say that it would not confuse end\n>> users.  Maybe insisting on not just clean index but no changes\n>> from the HEAD would reduce confusion?  I dunno.\n>\n> I am sure confused why the index state is stashed away when it is not \n> used...\n\nYeah, I think Nanako kept this from her previous round because I\nmentioned that \"git show stash\" (not \"git stash show\") is\ninteresting in that it gives stashed (HEAD, index, working tree)\nin --cc fashion.  I also mentioned that it might make sense to\nstash untracked files in the working tree portion of the commit,\nand if we do that then we would need to record what was known to\ngit by the index tree so that we can discard them from the index\nupon applying, but (1) I no longer think it is useful to try\ncarrying forward the untracked file states, and (2) it would\nmake \"git show stash\" uninteresting (too much cruft).\n\nSo perhaps we would want to drop the index tree portion from the\nstash.\n\n>> > +Author\n>> > +------\n>> > +Written by Johannes E. Schindelin <johannes.schindelin@gmx.de>\n>> \n>> You wrote that ;-)?\n>\n> No. ;-)\n>\n> Hey, be nice. It's a new role for me, usually others document what _I_ \n> wrote, not vice versa :-)\n\nActually I have been wondering if it is a good idea to start\ndropping the Author section.  Perhaps replace it by list of\nstakeholders or people who have been active in the area recently\nand who are likely to be able to help when an end-user has\ntroubles with the command.\n"},{"id":"46114","messageId":"Pine.LNX.4.64.0706301943040.4438@racer.site","threadId":"8777","inReplyTo":"7vk5tlcnuq.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-30T18:44:17Z","receivedAt":"2007-06-30T18:44:17Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 30 Jun 2007, Junio C Hamano wrote:\n\n> So perhaps we would want to drop the index tree portion from the stash.\n\nThat was actually the only reason I found it useful to write a script for \nit. Otherwise, the revised alias would do just fine.\n\nCiao,\nDscho\n"},{"id":"46115","messageId":"20070630184536.GW12721@planck.djpig.de","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301847370.4438@racer.site","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Frank Lichtenheld","fromEmail":"frank@lichtenheld.de","sentAt":"2007-06-30T18:45:36Z","receivedAt":"2007-06-30T18:45:36Z","isPatch":true,"sender":{"key":"frank@lichtenheld.de","avatar":"https://gravatar.com/avatar/b9f1d4b120e138f157c9e480d0818197c474628923786adb98f30017cdb99c3c?d=mp&s=160"},"body":"On Sat, Jun 30, 2007 at 06:48:27PM +0100, Johannes Schindelin wrote:\n> On Sat, 30 Jun 2007, Frank Lichtenheld wrote:\n> > On Sat, Jun 30, 2007 at 04:44:39PM +0100, Johannes Schindelin wrote:\n> > > +Author\n> > > +------\n> > > +Written by Johannes E. Schindelin <johannes.schindelin@gmx.de>\n> > \n> > AFAICT \"Author\" is usually used for the author of the documented program\n> > and \"Documentation\" for the author of the documentation itself.\n> \n> Oh? If that is so, please disregard this hunk.\n\nDocumentation$ grep -B2 -i \"\\(written\\|documentation\\) by\" *.txt\n\nseems to suggest that I'm right.\n\n> Although in that case, git-bundle.txt is misattributed.\n\nIndeed.\n\nGruesse,\n-- \nFrank Lichtenheld <frank@lichtenheld.de>\nwww: http://www.djpig.de/\n"},{"id":"46134","messageId":"200706302327.l5UNRMta027974@mi0.bluebottle.com","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301641000.4438@racer.site","subject":"Re: [PATCH (3rd try)] Add git-stash script","fromName":"しらいしななこ","fromEmail":"nanako3@bluebottle.com","sentAt":"2007-06-30T23:27:10Z","receivedAt":"2007-06-30T23:27:10Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting Johannes Schindelin <Johannes.Schindelin@gmx.de>:\n\n> Hi,\n\nHello.\n\n> On Sat, 30 Jun 2007, しらいしななこ wrote:\n>\n>> diff --git a/git-stash.sh b/git-stash.sh\n>> [...]\n>> +\tprintf >&2 'Saved WIP on %s\\n' \"$msg\"\n>\n> You have an awful lot of printfs in the code. Why not just use echos?\n\nI just imitated other scripts.  I can change it to\n\necho >&2 \"Saved WIP on $msg\"\n\nbut after reading Junio's comments, I think I probably should not.\n\n>> +list_stash () {\n>> +\tgit-log --pretty=oneline -g \"$@\" $ref_stash |\n>\n> Wouldn't you want \"--default $ref_stash\" here?\n\nI do not know, and I'm sorry I do not understand Junio's comments.\n\nWhat does --default do in this case?\n\n>> +apply_stash () {\n>> +\tgit-diff-files --quiet ||\n>> +\t\tdie 'Cannot restore on top of a dirty state'\n>\n> You meant \"no_changes\", right? I think you miss changes in the index \n> otherwise.\n\nAfter I read exchanges between you and Junio I do not know which way\nis preferred.  Using no_changes does not forbid me from doing that,\nbut I think Junio's example will be forbidden.  The original scenario\nwas that I apply a stashed change to an unmodified state, and there is\nno problem either way.\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n\n----------------------------------------------------------------------\nFree pop3 email with a spam filter.\nhttp://www.bluebottle.com\n"},{"id":"46146","messageId":"7vabug8ztr.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301644190.4438@racer.site","subject":"Re: [PATCH] Add a manual page for git-stash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-01T05:20:32Z","receivedAt":"2007-07-01T05:20:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  Documentation/git-stash.txt |  116 +++++++++++++++++++++++++++++++++++++++++++\n>  1 files changed, 116 insertions(+), 0 deletions(-)\n>  create mode 100644 Documentation/git-stash.txt\n\nBy the way, whoever does the documentation needs to list it in\nthe command list (Documentation/cmd-list.perl).\n"},{"id":"46148","messageId":"200707010533.l615XiH6006728@mi1.bluebottle.com","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0706301853400.4438@racer.site","subject":"[PATCH] Document git-stash","fromName":"しらいしななこ","fromEmail":"nanako3@bluebottle.com","sentAt":"2007-07-01T05:26:08Z","receivedAt":"2007-07-01T05:26:08Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"This describes the git-stash command.\n\nI borrowed a few paragraphs from Johannes's version, and added a few\nexamples.\n\nSigned-off-by: Nanako Shiraishi <nanako3@bluebottle.com>\n---\n Documentation/cmd-list.perl |    1 +\n Documentation/git-stash.txt |  162 +++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 163 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-stash.txt\n\ndiff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl\nindex fcea1d7..8ee8122 100755\n--- a/Documentation/cmd-list.perl\n+++ b/Documentation/cmd-list.perl\n@@ -178,6 +178,7 @@ git-show-ref                            plumbinginterrogators\n git-sh-setup                            purehelpers\n git-ssh-fetch                           synchingrepositories\n git-ssh-upload                          synchingrepositories\n+git-stash                               mainporcelain\n git-status                              mainporcelain\n git-stripspace                          purehelpers\n git-submodule                           mainporcelain\ndiff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt\nnew file mode 100644\nindex 0000000..17ebc83\n--- /dev/null\n+++ b/Documentation/git-stash.txt\n@@ -0,0 +1,162 @@\n+git-stash(1)\n+============\n+\n+NAME\n+----\n+git-stash - Stash the changes in a dirty working directory away\n+\n+SYNOPSIS\n+--------\n+[verse]\n+'git-stash'\n+'git-stash' [list | show [<stash>] | apply [<stash>] | clear]\n+\n+DESCRIPTION\n+-----------\n+\n+Use 'git-stash' when you want to record the current state of the\n+working directory and the index, but want to go back to a clean\n+working directory.  The command saves your local modifications away\n+and reverts the working directory to match the `HEAD` commit.\n+\n+The modifications stashed away by this command can be listed with\n+`git-stash list`, inspected with `git-stash show`, and restored\n+(potentially on top of a different commit) with `git-stash apply`\n+commands.  The default operation when called without options is to\n+save the changes away.\n+\n+The latest stash you created is stored in `$GIT_DIR/refs/stash`; older\n+stashes are found in the reflog of this refererence and can be named using\n+the usual reflog syntax (e.g. `stash@{1}` is the stash one previously made,\n+`stash@{2}` is the one before it, `stash@{2.hours.ago}` is also possible).\n+\n+OPTIONS\n+-------\n+\n+(no subcommand)::\n+\n+\tSave your local modifications to a new 'stash', and run `git-reset\n+\t--hard` to revert them.\n+\n+list::\n+\n+\tList the stashes that you currently have.  Each 'stash' is listed\n+\twith its name (e.g. `stash@{0}` is the latest stash, `stash@{1} is\n+\tthe one before), the name of the branch that was current when the\n+\tstash was made, and a short description of the commit the stash was\n+\tbased on.\n++\n+----------------------------------------------------------------\n+stash@{0}: submit: 6ebd0e2... Add git-stash\n+stash@{1}: master: 9cc0589... Merge branch 'master' of gfi\n+----------------------------------------------------------------\n+\n+show [<stash>]::\n+\n+\tShow the changes recorded in the stash.  When no `<stash>` is given,\n+\tshows the latest one.  By default, the command shows diffstat, but\n+\tyou can add `-p` option (i.e. `git stash show -p stash@{2}`) to view\n+\tit in patch form.\n+\n+apply [<stash>]::\n+\n+\tRestores the changes recorded in the stash on top of the current\n+\tworking tree state.  When no `<stash>` is given, applies the latest\n+\tone.  The working directory must match the index.  When the changes\n+\tconflict, you need to resolve them by hand and mark the result with\n+\t`git add` as usual.  When the changes are cleanly merged, your\n+\tearlier local changes stored in the stash becomes the differences\n+\tbetween the index and the working tree (i.e. `git diff`), except\n+\tthat newly created files are registered in the index (i.e. `git diff\n+\t--cached` is necessary to review the newly added files).\n+\n+clear::\n+\tRemoves all the stashed states.\n+\n+\n+DISCUSSION\n+----------\n+\n+A stash is represented as a commit whose tree records the state of the\n+working directory, and its first parent is the commit at `HEAD` when\n+the stash was created.  The tree of the second parent records the\n+state of the index when the stash is made, and it is made a child of\n+the `HEAD` commit.  The ancestry graph looks like this:\n+\n+            .----W\n+           /    /\n+     ...--H----I\n+\n+where `H` is the `HEAD` commit, `I` is a commit that records the state\n+of the index, and `W` is a commit that records the state of the working\n+tree.\n+\n+\n+EXAMPLES\n+--------\n+\n+Pulling into a dirty tree::\n+\n+When you are in the middle of something, you learn that there are\n+changes that possibly are relevant to what you are doing in the\n+upstream.  When your local changes do not conflict with the changes in\n+the upstream, a simple `git pull` will let you move forward.\n++\n+However, there are cases in which your local changes do conflict with\n+the upstream changes, and `git pull` refuses to overwrite your\n+changes.  In such a case, you can first stash your changes away,\n+perform a pull, and then unstash, like this:\n++\n+----------------------------------------------------------------\n+$ git pull\n+...\n+file foobar not up to date, cannot merge.\n+$ git stash\n+$ git pull\n+$ git stash apply\n+----------------------------------------------------------------\n+\n+Interrupted workflow::\n+\n+When you are in the middle of something, your boss comes in and\n+demands you to fix something immediately.  Traditionally, you would\n+make a commit to a temporary branch to store your changes away, and\n+come back to make the emergency fix, like this:\n++\n+----------------------------------------------------------------\n+... hack hack hack ...\n+$ git checkout -b my_wip\n+$ git commit -a -m \"WIP\"\n+$ git checkout master\n+$ edit emergency fix\n+$ git commit -a -m \"Fix in a hurry\"\n+$ git checkout my_wip\n+$ git reset --soft HEAD^\n+... continue hacking ...\n+----------------------------------------------------------------\n++\n+You can use `git-stash` to simplify the above, like this:\n++\n+----------------------------------------------------------------\n+... hack hack hack ...\n+$ git stash\n+$ edit emergency fix\n+$ git commit -a -m \"Fix in a hurry\"\n+$ git stash apply\n+... continue hacking ...\n+----------------------------------------------------------------\n+\n+SEE ALSO\n+--------\n+gitlink:git-checkout[1],\n+gitlink:git-commit[1],\n+gitlink:git-reflog[1],\n+gitlink:git-reset[1]\n+\n+AUTHOR\n+------\n+Written by Nanako Shiraishi <nanako3@bluebottle.com>\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\n-- \n1.5.2.2\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n\n----------------------------------------------------------------------\nGet a free email account with anti spam protection.\nhttp://www.bluebottle.com\n"},{"id":"46152","messageId":"7v1wfs8vr9.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"200707010533.l615XiH6006728@mi1.bluebottle.com","subject":"Re: [PATCH] Document git-stash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-01T06:48:26Z","receivedAt":"2007-07-01T06:48:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks.\n"},{"id":"46154","messageId":"20070701080757.GA6093@coredump.intra.peff.net","threadId":"8777","inReplyTo":"200707010533.l615XiH6006728@mi1.bluebottle.com","subject":"Re: [PATCH] Document git-stash","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-07-01T08:07:57Z","receivedAt":"2007-07-01T08:07:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jul 01, 2007 at 02:26:08PM +0900, しらいしななこ wrote:\n\n> This describes the git-stash command.\n\nA few minor language nits follow (Junio, I can provide a patch, but if\nyou haven't pushed it out, it might be simpler to just --amend). Some\nare obviously correct, and some are minor or matters of taste. Feel free\nto ignore the latter. :)\n\n> +The modifications stashed away by this command can be listed with\n> +`git-stash list`, inspected with `git-stash show`, and restored\n> +(potentially on top of a different commit) with `git-stash apply`\n> +commands.  The default operation when called without options is to\n> +save the changes away.\n\nThe 'commands' at the end of the first sentence doesn't quite work. It\nneeds to be either \"with the `foo` command\" or \"with `foo`\" (I think the\nlatter is preferable, since the list structure makes the article sound\nawkward).\n\n> +The latest stash you created is stored in `$GIT_DIR/refs/stash`; older\n> +stashes are found in the reflog of this refererence and can be named using\n\ns/refererence/reference/\n\n> +the usual reflog syntax (e.g. `stash@{1}` is the stash one previously made,\n> +`stash@{2}` is the one before it, `stash@{2.hours.ago}` is also possible).\n\n\"the stash one previously made\" is a bit ambiguous (they've all been\npreviously made!). How about \"is the most recently created stash\"?\n\n> +(no subcommand)::\n> +\n> +\tSave your local modifications to a new 'stash', and run `git-reset\n> +\t--hard` to revert them.\n\nFor orthogonality's sake, should this be 'git-stash save', aliased to\njust 'git-stash'? It would make this heading a little more intuitive,\nand the very first paragraph (describing all of the modes) a little more\nclear.\n\nI can work up a patch if there's agreement.\n\n> +list::\n> +\n> +\tList the stashes that you currently have.  Each 'stash' is listed\n> +\twith its name (e.g. `stash@{0}` is the latest stash, `stash@{1} is\n> +\tthe one before),\n\n\"...the one before, etc.)\" is slightly more clear to me.\n\n>   the name of the branch that was current when the\n> +\tstash was made, and a short description of the commit the stash was\n> +\tbased on.\n\n\"the name of the branch that was current when the stash was made\" seems\na bit awkward, but it's actually quite accurate.\n\n> +\tShow the changes recorded in the stash.  When no `<stash>` is given,\n> +\tshows the latest one.  By default, the command shows diffstat, but\n> +\tyou can add `-p` option (i.e. `git stash show -p stash@{2}`) to view\n> +\tit in patch form.\n\ns/shows diffstat/shows the diffstat of the changes/\n\ns/i.e./e.g./\n\nAlso, you can use any diff options. So maybe the whole thing would be\nbetter written as (Is there a better term for \"original parent\" here?):\n\n  Show the changes recorded in the stash as a diff between the the\n  stashed state and its original parent. When no `<stash>` is given,\n  shows the latest one. By default, the command shows the diffstat, but\n  it will accept any format known to `git-diff` (e.g., `git-stash show\n  -p stash@{2}` to view the second most recent stash in patch form).\n\nWe refer to \"the changes\" a lot...maybe it would be better to introduce\nand define a term like \"stash changes\" early on and then use it. But\nwithout that, I'm not sure it's clear that the stash can really be\nthought of as a diff (since, after all, git stores states, stashes\nincluded). I guess we talk about that later, but at this point in the\nmanual I think it's a little confusing.\n\n> +apply [<stash>]::\n> +\n> +\tRestores the changes recorded in the stash on top of the current\n\ns/Restores/Restore/ to match the imperative of the other command\ndescriptions.\n\n> +\tworking tree state.  When no `<stash>` is given, applies the latest\n> +\tone.  The working directory must match the index.  When the changes\n> +\tconflict, you need to resolve them by hand and mark the result with\n> +\t`git add` as usual.  When the changes are cleanly merged, your\n> +\tearlier local changes stored in the stash becomes the differences\n> +\tbetween the index and the working tree (i.e. `git diff`), except\n> +\tthat newly created files are registered in the index (i.e. `git diff\n> +\t--cached` is necessary to review the newly added files).\n\nI'm not quite sure I understand what this is saying.\n\n> +clear::\n> +\tRemoves all the stashed states.\n\nMaybe a note to indicate that this can lose data? Something like:\n\n  ...stashed states. Note that those states will then be subject to\n  pruning, and may be difficult or impossible to recover.\n\n> +When you are in the middle of something, you learn that there are\n> +changes that possibly are relevant to what you are doing in the\n> +upstream.  When your local changes do not conflict with the changes in\n> +the upstream, a simple `git pull` will let you move forward.\n\nThe first sentence would be more clear if we moved the prepositional\nphrase \"in the upstream\":\n\n  When you are in the middle of something, you learn that there are\n  changes in the upstream that are possibly relevant to what you are\n  doing.\n\nor even:\n\n  When you are in the middle of something, you learn that there are\n  upstream changes that are possibly relevant to what you are doing.\n\n> ++\n> +However, there are cases in which your local changes do conflict with\n> +the upstream changes, and `git pull` refuses to overwrite your\n> +changes.  In such a case, you can first stash your changes away,\n> +perform a pull, and then unstash, like this:\n\nI think the \"first\" in the last sentence is confusing, since we don't\nuse a \"then\" in the second step (\"perform a pull\") to indicate that we\nhave gone on to the second step.\n\n> +When you are in the middle of something, your boss comes in and\n> +demands you to fix something immediately.  Traditionally, you would\n\ns/demands you to fix/demands that you fix/\n\n> +make a commit to a temporary branch to store your changes away, and\n> +come back to make the emergency fix, like this:\n\n\"come back\" is pretty vague here. Maybe \"return to your original\nbranch\"?\n\nOtherwise, I think the page is very well written, and the examples are\nvery clear.\n\n-Peff\n"},{"id":"46157","messageId":"7vps3c7c38.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"20070701080757.GA6093@coredump.intra.peff.net","subject":"Re: [PATCH] Document git-stash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-01T08:38:35Z","receivedAt":"2007-07-01T08:38:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sun, Jul 01, 2007 at 02:26:08PM +0900, しらいしななこ wrote:\n>\n>> This describes the git-stash command.\n>\n> A few minor language nits follow (Junio, I can provide a patch, but if\n> you haven't pushed it out, it might be simpler to just --amend).\n\nAlthough I sent out a Thanks already, I haven't even applied it\nyet.  Language nits are very much appreciated in the\nDocumentation area.  Will take a look but it is getting late\nhere in California, so it has to wait for about 8 to 10 hours.\n"},{"id":"46158","messageId":"200707010910.l619A23b027837@mi0.bluebottle.com","threadId":"8777","inReplyTo":"20070701080757.GA6093@coredump.intra.peff.net","subject":"Re: [PATCH] Document git-stash","fromName":"しらいしななこ","fromEmail":"nanako3@bluebottle.com","sentAt":"2007-07-01T09:06:29Z","receivedAt":"2007-07-01T09:06:29Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Hi,\n\nQuoting Jeff King <peff@peff.net>:\n\n>> +(no subcommand)::\n>> +\n>> +\tSave your local modifications to a new 'stash', and run `git-reset\n>> +\t--hard` to revert them.\n>\n> For orthogonality's sake, should this be 'git-stash save', aliased to\n> just 'git-stash'? It would make this heading a little more intuitive,\n> and the very first paragraph (describing all of the modes) a little more\n> clear.\n\nJohannes earlier asked for the same thing, and I think it is a good change.\n\n>> +apply [<stash>]::\n>> +\n>> +\tRestores the changes recorded in the stash on top of the current\n>\n> s/Restores/Restore/ to match the imperative of the other command\n> descriptions.\n>\n>> +\tworking tree state.  When no `<stash>` is given, applies the latest\n>> +\tone.  The working directory must match the index.  When the changes\n>> +\tconflict, you need to resolve them by hand and mark the result with\n>> +\t`git add` as usual.  When the changes are cleanly merged, your\n>> +\tearlier local changes stored in the stash becomes the differences\n>> +\tbetween the index and the working tree (i.e. `git diff`), except\n>> +\tthat newly created files are registered in the index (i.e. `git diff\n>> +\t--cached` is necessary to review the newly added files).\n>\n> I'm not quite sure I understand what this is saying.\n\nI don't understand myself anymore, either (^_^;) I just tried to follow\nJnio's earlier suggestion in his message.  He said this.\n\n| The three-way merge is done correctly here, and I would imagine\n| the users would feel the UI quite natural _if_ this merge\n| conflicts.  \"git diff\" would show only the conflicted paths\n| (because the updates coming from the old working tree is placed\n| in the index for cleanly merged paths), editing a conflicted\n| file and \"git add $that_path\" would resolve.  That's exactly the\n| same workflow for a conflicted merge.\n|\n| However, I think it is a bit counterintuitive to update the\n| working tree change to the index if the merge did not conflict.\n| It might be better to run an equivalent of \"git reset\", so that\n| after \"git save restore\", the user can say \"git diff\" (not \"git\n| diff HEAD\") to view the local changes.  Perhaps...\n\n>> +clear::\n>> +\tRemoves all the stashed states.\n>\n> Maybe a note to indicate that this can lose data? Something like:\n>\n>   ...stashed states. Note that those states will then be subject to\n>   pruning, and may be difficult or impossible to recover.\n\nI see.  When I wrote it, I thought that saying \"removes\" was enough.  It\nseemed obvious to me that you would lose it when you remove it.\n\nThanks for fixing my language.  I am not very good at writing English,\nbut you probably have already found it out (^_^;).\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n\n----------------------------------------------------------------------\nFinally - A spam blocker that actually works.\nhttp://www.bluebottle.com\n"},{"id":"46159","messageId":"20070701091905.GA13559@coredump.intra.peff.net","threadId":"8777","inReplyTo":"200707010910.l619A23c027837@mi0.bluebottle.com","subject":"Re: [PATCH] Document git-stash","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-07-01T09:19:05Z","receivedAt":"2007-07-01T09:19:05Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jul 01, 2007 at 06:06:29PM +0900, しらいしななこ wrote:\n\n> I don't understand myself anymore, either (^_^;) I just tried to follow\n> Jnio's earlier suggestion in his message.  He said this.\n\nOK, we will wait for Junio to clarify tomorrow. :)\n\n> >> +\tRemoves all the stashed states.\n> >\n> > Maybe a note to indicate that this can lose data? Something like:\n> >\n> >   ...stashed states. Note that those states will then be subject to\n> >   pruning, and may be difficult or impossible to recover.\n> \n> I see.  When I wrote it, I thought that saying \"removes\" was enough.  It\n> seemed obvious to me that you would lose it when you remove it.\n\nIt is \"enough\" in the sense that the meaning is clear, but in general it\nis very hard to convince git to forget things, and I think that is a\nfeature. There are so few commands in git where you can \"lose\" data that\nI think it is worth marking them with a big X.\n\nReally, I don't see the need to use 'clear' in general. The reflog works\nas a stack, so old stashes will get out of the \"top 10\" eventually\nanyway. In the long run, they will be cleaned up by \"git reflog expire\"\n(or indirectly by \"git gc\").\n\n> Thanks for fixing my language.  I am not very good at writing English,\n> but you probably have already found it out (^_^;).\n\nQuite the contrary. If it had been very badly written, it would have\njust been easier to rewrite it than to point out the few mistakes. :)\n\n-Peff\n"},{"id":"46195","messageId":"7vps3b4xcj.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"20070701091905.GA13559@coredump.intra.peff.net","subject":"Re: [PATCH] Document git-stash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-01T21:39:56Z","receivedAt":"2007-07-01T21:39:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sun, Jul 01, 2007 at 06:06:29PM +0900, しらいしななこ wrote:\n>\n>> I don't understand myself anymore, either (^_^;) I just tried to follow\n>> Jnio's earlier suggestion in his message.  He said this.\n>\n> OK, we will wait for Junio to clarify tomorrow. :)\n\nJeez.  I tried to stay lazy and have all the work done by\nsomebody else (and taking the credit at the end, as I was\nmentored by you-know-who ;-), but you guys managed to suck me\ninto this.\n\nThere are a few issues when you replay a stash on a state that\nis different from the state the stash was created on.\n\nStash records the then-current HEAD, index and the working tree\n(I'll call them H, I and W for brevity from now on).  Ideally,\nwe would want to have the difference between the resulting index\nand working tree to be similar to the difference between I and\nW.\n\nReplaying the stash is done on a clean working tree.  That is,\nwe require that at least the index and working tree match (we\ncould also require that the index and HEAD match, but I do not\nthink it changes anything in this discussion).  And we apply the\nchange between H and W with three-way merge.\n\nFor paths that are cleanly merged with this three-way merge,\nmerge-recursive updates the working tree and the index.  That\nmeans if you do \"git diff\", you would not see the local changes\nthat were carried forward would not be visible, and you would\nneed \"git diff HEAD\" to view them.  I found it confusing, and\nthat was the suggestion I sent was about.  Nana's \"3rd try\", which\nI applied and pushed to 'next', addresses this issue by running\n\"read-tree --reset $c_tree\" (where $c_tree is the contents of\nthe index before replaying the stash).\n\nThis is not ideal.  We would want to see \"git diff\" for such a\npath show difference similar to difference between I and W.\n\nThere is a little glitch, though.  Such an operation can also be\ndone with a three-way merge (git-merge-file would most likely be\nuseful), but what would we do when this second merge conflicts?\nIf we insist on making the \"git diff\" output to match the diff\nbetween I and W for the path, somebody needs to resolve the\nconflict and put the result in the index, but if git-merge-file\ncouldn't, the user is left to do that.  I strongly suspect that\nwe would not want that aggravation (besides, the working tree\ncannot be used anymore as it contains what we would want to\nleave there as the result of unstashing).  The second best thing\nis probably to leave the index as it was before the stash was\napplied for such a path (in other words, for such a path, we\ndiscard the difference between I and W, favoring to use W).\n\nWe could still attempt to carry the difference between I and W\nfor paths that the second merge cleanly resolves, but then \"git\ndiff\" will show full diff between H and W for some paths (that\nis, the ones the second merge did not cleanly resolve) while\ndiff between I and W for others (the ones that resolved\ncleanly).  That is not what the current code does, though.\n\nI am hoping that the \"best effort\" would make it more convenient\nto use, but I also suspect that it might make things more\nconfusing to the end user and certainly more difficult to explain.\n\nSo that's about the cleanly-merged case.\n\nWhat we should do about the paths that the first merge (i.e. the\none that updates the working tree) does not resolve cleanly?  We\nwould want to keep the index the way merge-recursive left, for\nconflicting paths at least.  We would have higher stages for\nthem, so that the user will not accidentally commit things that\nhave not been merged, and can use usual conflict resolution\ntechniques like \"git diff\" to view the combined diff between\nthree versions.\n"},{"id":"46197","messageId":"7vlkdz4wp3.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"20070701080757.GA6093@coredump.intra.peff.net","subject":"Re: [PATCH] Document git-stash","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-01T21:54:00Z","receivedAt":"2007-07-01T21:54:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n>> +(no subcommand)::\n>> +\n>> +\tSave your local modifications to a new 'stash', and run `git-reset\n>> +\t--hard` to revert them.\n>\n> For orthogonality's sake, should this be 'git-stash save', aliased to\n> just 'git-stash'? It would make this heading a little more intuitive,\n> and the very first paragraph (describing all of the modes) a little more\n> clear.\n\nI would further suggest that we _require_ 'git stash save' to\ncreate a new one and perhaps make the non-subcommand case run\n'git stash list'.  While I was trying the code out I\naccidentally created a new stash when I did not mean to, which\npushed the stash I wanted to apply down in the list every time I\nmade such a mistake.\n"},{"id":"46200","messageId":"Pine.LNX.4.64.0707012355150.4438@racer.site","threadId":"8777","inReplyTo":"7vlkdz4wp3.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Document git-stash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-07-01T22:57:20Z","receivedAt":"2007-07-01T22:57:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 1 Jul 2007, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> >> +(no subcommand)::\n> >> +\n> >> +\tSave your local modifications to a new 'stash', and run `git-reset\n> >> +\t--hard` to revert them.\n> >\n> > For orthogonality's sake, should this be 'git-stash save', aliased to\n> > just 'git-stash'? It would make this heading a little more intuitive,\n> > and the very first paragraph (describing all of the modes) a little more\n> > clear.\n> \n> I would further suggest that we _require_ 'git stash save' to\n> create a new one and perhaps make the non-subcommand case run\n> 'git stash list'.  While I was trying the code out I\n> accidentally created a new stash when I did not mean to, which\n> pushed the stash I wanted to apply down in the list every time I\n> made such a mistake.\n\nWell, the normal thing you want to do if you say \"git stash\" is best \ndescribed by \"Git, stash!\".\n\nHowever, unstash would by a nice feature. Not easy, but nice. Not easy, \nbecause we would be actively outsmarting the reflog machinery we use for \nthe stash.\n\nCiao,\nDscho\n"},{"id":"46210","messageId":"20070702040800.GA17384@coredump.intra.peff.net","threadId":"8777","inReplyTo":"7vps3b4xcj.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Document git-stash","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-07-02T04:08:00Z","receivedAt":"2007-07-02T04:08:00Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jul 01, 2007 at 02:39:56PM -0700, Junio C Hamano wrote:\n\n> For paths that are cleanly merged with this three-way merge,\n> merge-recursive updates the working tree and the index.  That\n> means if you do \"git diff\", you would not see the local changes\n> that were carried forward would not be visible, and you would\n> need \"git diff HEAD\" to view them.  I found it confusing, and\n> that was the suggestion I sent was about.  Nana's \"3rd try\", which\n> I applied and pushed to 'next', addresses this issue by running\n> \"read-tree --reset $c_tree\" (where $c_tree is the contents of\n> the index before replaying the stash).\n> \n> This is not ideal.  We would want to see \"git diff\" for such a\n> path show difference similar to difference between I and W.\n\nAh, I get it now. Thanks for the explanation.\n\nI see you gutted the confusing text from the manpage...I think what you\nhave now is conceptually much simpler, and it won't bite anyone unless\nthey are trying to do something clever with the index. In which case I\nhope they will be able to use the description of how the stash is stored\nto poke around.\n\n-Peff\n"},{"id":"46211","messageId":"20070702041046.GB17384@coredump.intra.peff.net","threadId":"8777","inReplyTo":"7vlkdz4wp3.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Document git-stash","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-07-02T04:10:46Z","receivedAt":"2007-07-02T04:10:46Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jul 01, 2007 at 02:54:00PM -0700, Junio C Hamano wrote:\n\n> I would further suggest that we _require_ 'git stash save' to\n> create a new one and perhaps make the non-subcommand case run\n> 'git stash list'.  While I was trying the code out I\n> accidentally created a new stash when I did not mean to, which\n> pushed the stash I wanted to apply down in the list every time I\n> made such a mistake.\n\nI think that makes sense...it's somehow cleaner to me if the\nnon-subcommand case doesn't make any changes (maybe just because I like\nto explore commands by running them).\n\nI see you have already applied this change. However, you missed a spot\nin the documentation. Patch will follow, along with a couple of minor\ncleanups for the script.\n\n-Peff\n"},{"id":"46221","messageId":"Pine.LNX.4.64.0707021129540.4438@racer.site","threadId":"8777","inReplyTo":"20070702041046.GB17384@coredump.intra.peff.net","subject":"Re: [PATCH] Document git-stash","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-07-02T10:33:09Z","receivedAt":"2007-07-02T10:33:09Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 2 Jul 2007, Jeff King wrote:\n\n> On Sun, Jul 01, 2007 at 02:54:00PM -0700, Junio C Hamano wrote:\n> \n> > I would further suggest that we _require_ 'git stash save' to create a \n> > new one and perhaps make the non-subcommand case run 'git stash list'.  \n> > While I was trying the code out I accidentally created a new stash \n> > when I did not mean to, which pushed the stash I wanted to apply down \n> > in the list every time I made such a mistake.\n> \n> I think that makes sense...it's somehow cleaner to me if the \n> non-subcommand case doesn't make any changes (maybe just because I like \n> to explore commands by running them).\n\nI disagree entirely.\n\nThe _only_ default subcommand for git-stash, which makes _any_ sense, is \n\"save\". I have run my own version of it several times, and it _literally_ \nwas in those circumstances \"hack, hack, hack, aargh, stash that, I'll need \nit later\". \"git cherry-pick stash\" and \"git reflog show stash\" were needed \nfar less.\n\nI am utterly uninterested in the stash list.\n\nCiao,\nDscho\n"},{"id":"46222","messageId":"Pine.LNX.4.64.0707021141280.4438@racer.site","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0707021129540.4438@racer.site","subject":"[PATCH] git-stash: Make \"save\" the default operation again","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-07-02T10:44:29Z","receivedAt":"2007-07-02T10:44:29Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nThe default operation really should be that which you are most likely\nto use. And that _is_ to stash the current changes away. Indeed, quite\noften you will want it to stash away changes you never plan to commit,\nlike extensive debugging output.\n\nSometimes you will stash away changes that you realize only later will\nnever be needed.\n\nSo, neither \"list\" nor \"apply\" are ase often used in practice as \"save\".\nThe manpage already reflects that, so change the script to the better.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tThink about it again. You tested git-stash. That is not the normal \n\tmodus operandi. You needed to inspect the stashed changes. In the\n\texamples given in the manpage, you usually want to work with the\n\tlast stashed changes, if at all. So you _rarely_ inspect the \n\tstashed changes. From my experience I agree.\n\n\tIf you make \"list\" the default, people will get used to _that_, \n\teven if it means more typing, and quite a few \"Aargh, I just \n\twanted to stash the current state, and I get a list instead!\" \n\tmoments.\n\n\tThen there is no way to change it back to some sane default \n\toperation.\n\n git-stash.sh |    4 ++--\n 1 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/git-stash.sh b/git-stash.sh\nindex ec18ef6..04ce30a 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -132,7 +132,7 @@ apply_stash () {\n \n # Main command set\n case \"$1\" in\n-list | '')\n+list)\n \tshift\n \tif test $# = 0\n \tthen\n@@ -152,7 +152,7 @@ apply)\n clear)\n \tclear_stash\n \t;;\n-save)\n+save|'')\n \tsave_stash && git-reset --hard\n \t;;\n *)\n-- \n1.5.2.2.3293.gad30\n"},{"id":"46223","messageId":"20070702110014.GA6490@sigill.intra.peff.net","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0707021141280.4438@racer.site","subject":"Re: [PATCH] git-stash: Make \"save\" the default operation again","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-07-02T11:00:14Z","receivedAt":"2007-07-02T11:00:14Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jul 02, 2007 at 11:44:29AM +0100, Johannes Schindelin wrote:\n\n> So, neither \"list\" nor \"apply\" are ase often used in practice as \"save\".\n> The manpage already reflects that, so change the script to the better.\n\nI have to admit that I don't really care all that much, so I'll let you\nguys duke it out.\n\n-Peff\n"},{"id":"46225","messageId":"Pine.LNX.4.64.0707021215120.4438@racer.site","threadId":"8777","inReplyTo":"20070702110014.GA6490@sigill.intra.peff.net","subject":"Re: [PATCH] git-stash: Make \"save\" the default operation again","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-07-02T11:15:57Z","receivedAt":"2007-07-02T11:15:57Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 2 Jul 2007, Jeff King wrote:\n\n> On Mon, Jul 02, 2007 at 11:44:29AM +0100, Johannes Schindelin wrote:\n> \n> > So, neither \"list\" nor \"apply\" are ase often used in practice as \n> > \"save\". The manpage already reflects that, so change the script to the \n> > better.\n> \n> I have to admit that I don't really care all that much, so I'll let you \n> guys duke it out.\n\nI do have to admit that I do care. Especially since my alias is no longer \nworking (having the same name as a git program).\n\nCiao,\nDscho\n"},{"id":"46298","messageId":"7vlkdywgdh.fsf@assigned-by-dhcp.cox.net","threadId":"8777","inReplyTo":"Pine.LNX.4.64.0707021215120.4438@racer.site","subject":"Re: [PATCH] git-stash: Make \"save\" the default operation again","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-02T23:11:22Z","receivedAt":"2007-07-02T23:11:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> On Mon, Jul 02, 2007 at 11:44:29AM +0100, Johannes Schindelin wrote:\n>> \n>> > So, neither \"list\" nor \"apply\" are ase often used in practice as \n>> > \"save\". The manpage already reflects that, so change the script to the \n>> > better.\n>> \n>> I have to admit that I don't really care all that much, so I'll let you \n>> guys duke it out.\n>\n> I do have to admit that I do care. Especially since my alias is no longer \n> working (having the same name as a git program).\n\nOk, two votes from long-timer Dscho and original poster Nana are\nsufficient for me to change my mind.\n\nThanks.\n"}]}