{"thread":{"id":"50801","subject":"[RFC] git stash --snapshot","startedAt":"2019-03-21T22:59:00Z","lastAt":"2019-03-31T22:07:09Z","messageCount":2,"participants":["Randall S. Becker","Thomas Gummerer"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"372191","messageId":"002101d4e039$a7cd8a10$f7689e30$@nexbridge.com","threadId":"50801","inReplyTo":null,"subject":"[RFC] git stash --snapshot","fromName":"Randall S. Becker","fromEmail":"rsbecker@nexbridge.com","sentAt":"2019-03-21T22:58:47Z","receivedAt":"2019-03-21T22:59:00Z","isPatch":false,"sender":{"key":"randall.becker@nexbridge.ca","avatar":"https://avatars.githubusercontent.com/u/28956764?v=4"},"body":"About two weeks ago there was a discussion about building an undo stack. \nhttps://public-inbox.org/git/000401d4d6c8$f68bb020$e3a31060$@nexbridge.com/\n\nit had me thinking about whether a stash --snapshot might be useful. Below\nis a conceptual change - by no means even close to complete. This would\nallow scripting to wrap critical commands with a \"git stash push --snapshot\"\nwithout changing the working directory. For symmetry, a \"git stash pop\n--force\" is needed if --include-untracked were used to stash everything in\nthe first place. It might be more useful also to wait until stash is\nconverted to C, I suppose. I'm wondering whether to pursue this or drop it.\nThoughts? (and I beg forgiveness for what my mailer might do to the wrapping\nof this patch, and I already know the indent is wrong between 329 and 370,\nand that the granularity of the --force option is wrong).\n\ndiff --git a/git-stash.sh b/git-stash.sh\nindex 789ce2f41d..7741192980 100755\n--- a/git-stash.sh\n+++ b/git-stash.sh\n@@ -5,12 +5,13 @@ dashless=$(basename \"$0\" | sed -e 's/-/ /')\n USAGE=\"list [<options>]\n    or: $dashless show [<stash>]\n    or: $dashless drop [-q|--quiet] [<stash>]\n-   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]\n+   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [-f|--force]\n[<stash>]\n    or: $dashless branch <branchname> [<stash>]\n    or: $dashless save [--patch] [-k|--[no-]keep-index] [-q|--quiet]\n                      [-u|--include-untracked] [-a|--all] [<message>]\n    or: $dashless [push [--patch] [-k|--[no-]keep-index] [-q|--quiet]\n                       [-u|--include-untracked] [-a|--all] [-m <message>]\n+                      [--snapshot]\n                       [-- <pathspec>...]]\n    or: $dashless clear\"\n\n@@ -252,6 +253,7 @@ push_stash () {\n        patch_mode=\n        untracked=\n        stash_msg=\n+       snapshot=\n        while test $# != 0\n        do\n                case \"$1\" in\n@@ -286,6 +288,9 @@ push_stash () {\n                --message=*)\n                        stash_msg=${1#--message=}\n                        ;;\n+               --snapshot)\n+                       snapshot=t\n+                       ;;\n                --help)\n                        show_help\n                        ;;\n@@ -329,6 +334,8 @@ push_stash () {\n        die \"$(gettext \"Cannot save the current status\")\"\n        say \"$(eval_gettext \"Saved working directory and index state\n\\$stash_msg\")\"\n\n+       if test -z \"$snapshot\"\n+       then\n        if test -z \"$patch_mode\"\n        then\n                test \"$untracked\" = \"all\" && CLEAN_X_OPTION=-x ||\nCLEAN_X_OPTION=\n@@ -363,6 +370,7 @@ push_stash () {\n                        git reset -q -- \"$@\"\n                fi\n        fi\n+       fi\n }\n\n save_stash () {\n@@ -490,6 +498,7 @@ parse_flags_and_rev()\n\n        FLAGS=\n        REV=\n+       FORCE_OPTION=\n        for opt\n        do\n                case \"$opt\" in\n@@ -499,6 +508,9 @@ parse_flags_and_rev()\n                        --index)\n                                INDEX_OPTION=--index\n                        ;;\n+                       -f|--force)\n+                               FORCE_OPTION=--force\n+                       ;;\n                        --help)\n                                show_help\n                        ;;\n@@ -607,7 +619,7 @@ apply_stash () {\n        if test -n \"$u_tree\"\n        then\n                GIT_INDEX_FILE=\"$TMPindex\" git read-tree \"$u_tree\" &&\n-               GIT_INDEX_FILE=\"$TMPindex\" git checkout-index --all &&\n+               GIT_INDEX_FILE=\"$TMPindex\" git checkout-index --all\n$FORCE_OPTION &&\n                rm -f \"$TMPindex\" ||\n                die \"$(gettext \"Could not restore untracked files from stash\nentry\")\"\n        fi\n@@ -688,7 +700,7 @@ apply_to_branch () {\n        set -- --index \"$@\"\n        assert_stash_like \"$@\"\n\n-       git checkout -b $branch $REV^ &&\n+       git checkout -b $branch $FORCE_OPTION $REV^ &&\n        apply_stash \"$@\" && {\n                test -z \"$IS_STASH_REF\" || drop_stash \"$@\"\n        }\n\nRegards,\nRandall\n\n-- Brief whoami:\n NonStop developer since approximately 211288444200000000\n UNIX developer since approximately 421664400\n-- In my real life, I talk too much.\n\n\n\n"},{"id":"372847","messageId":"20190331220703.GY32487@hank.intra.tgummerer.com","threadId":"50801","inReplyTo":"002101d4e039$a7cd8a10$f7689e30$@nexbridge.com","subject":"Re: [RFC] git stash --snapshot","fromName":"Thomas Gummerer","fromEmail":"t.gummerer@gmail.com","sentAt":"2019-03-31T22:07:03Z","receivedAt":"2019-03-31T22:07:09Z","isPatch":false,"sender":{"key":"t.gummerer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/191004?v=4"},"body":"On 03/21, Randall S. Becker wrote:\n> About two weeks ago there was a discussion about building an undo stack. \n> https://public-inbox.org/git/000401d4d6c8$f68bb020$e3a31060$@nexbridge.com/\n> \n> it had me thinking about whether a stash --snapshot might be useful. Below\n> is a conceptual change - by no means even close to complete. This would\n> allow scripting to wrap critical commands with a \"git stash push --snapshot\"\n> without changing the working directory.\n\nI'm not sure I understand this proposal correctly.  Since you mention\nthis being used in scripting, would it be any different than using\n'git stash push && git stash apply'?  The former is a bit more\nexpensive of course, but conceptually it would do the same thing, I\nthink.\n\nI could see this as somewhat useful, but I don't think stash supports\nall the necessary operations yet.  E.g. what if you are in the middle\nof resolving a merge conflict.  But maybe a bit more of a description of your problem would\nhelp convince me.\n\nFor the undo stack discussion, I think I prefer something like Duy's\nbackup-log [*1*] proposal, that is built into git, rather than\nscripting my own solution, even if it's supported by 'git stash'.\n\nI meant to review those patches, but unfortunately never got around to\nthat.  But if it's something that interests you as well, reviewing the\npatches is probably the best way to get support for this into git.\n\n*1*: https://public-inbox.org/git/20181209104419.12639-1-pclouds@gmail.com/\n\n>                                          For symmetry, a \"git stash pop\n> --force\" is needed if --include-untracked were used to stash everything in\n> the first place.\n\nWhat exactly is the force option meant to do?  Apply the stash anyway,\nand discard current changes?  Wouldn't that lead to loosing data\nagain, just in a different way?\n\n>                   It might be more useful also to wait until stash is\n> converted to C, I suppose.\n\nYes please, any changes should ideally also apply to the stash-in-C\ntopic, unless they are actual bug fixes.\n\n>                            I'm wondering whether to pursue this or drop it.\n> Thoughts? (and I beg forgiveness for what my mailer might do to the wrapping\n> of this patch, and I already know the indent is wrong between 329 and 370,\n> and that the granularity of the --force option is wrong).\n> \n> diff --git a/git-stash.sh b/git-stash.sh\n> index 789ce2f41d..7741192980 100755\n> --- a/git-stash.sh\n> +++ b/git-stash.sh\n> @@ -5,12 +5,13 @@ dashless=$(basename \"$0\" | sed -e 's/-/ /')\n>  USAGE=\"list [<options>]\n>     or: $dashless show [<stash>]\n>     or: $dashless drop [-q|--quiet] [<stash>]\n> -   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]\n> +   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [-f|--force]\n> [<stash>]\n>     or: $dashless branch <branchname> [<stash>]\n>     or: $dashless save [--patch] [-k|--[no-]keep-index] [-q|--quiet]\n>                       [-u|--include-untracked] [-a|--all] [<message>]\n>     or: $dashless [push [--patch] [-k|--[no-]keep-index] [-q|--quiet]\n>                        [-u|--include-untracked] [-a|--all] [-m <message>]\n> +                      [--snapshot]\n>                        [-- <pathspec>...]]\n>     or: $dashless clear\"\n> \n> @@ -252,6 +253,7 @@ push_stash () {\n>         patch_mode=\n>         untracked=\n>         stash_msg=\n> +       snapshot=\n>         while test $# != 0\n>         do\n>                 case \"$1\" in\n> @@ -286,6 +288,9 @@ push_stash () {\n>                 --message=*)\n>                         stash_msg=${1#--message=}\n>                         ;;\n> +               --snapshot)\n> +                       snapshot=t\n> +                       ;;\n>                 --help)\n>                         show_help\n>                         ;;\n> @@ -329,6 +334,8 @@ push_stash () {\n>         die \"$(gettext \"Cannot save the current status\")\"\n>         say \"$(eval_gettext \"Saved working directory and index state\n> \\$stash_msg\")\"\n> \n> +       if test -z \"$snapshot\"\n> +       then\n>         if test -z \"$patch_mode\"\n>         then\n>                 test \"$untracked\" = \"all\" && CLEAN_X_OPTION=-x ||\n> CLEAN_X_OPTION=\n> @@ -363,6 +370,7 @@ push_stash () {\n>                         git reset -q -- \"$@\"\n>                 fi\n>         fi\n> +       fi\n>  }\n> \n>  save_stash () {\n> @@ -490,6 +498,7 @@ parse_flags_and_rev()\n> \n>         FLAGS=\n>         REV=\n> +       FORCE_OPTION=\n>         for opt\n>         do\n>                 case \"$opt\" in\n> @@ -499,6 +508,9 @@ parse_flags_and_rev()\n>                         --index)\n>                                 INDEX_OPTION=--index\n>                         ;;\n> +                       -f|--force)\n> +                               FORCE_OPTION=--force\n> +                       ;;\n>                         --help)\n>                                 show_help\n>                         ;;\n> @@ -607,7 +619,7 @@ apply_stash () {\n>         if test -n \"$u_tree\"\n>         then\n>                 GIT_INDEX_FILE=\"$TMPindex\" git read-tree \"$u_tree\" &&\n> -               GIT_INDEX_FILE=\"$TMPindex\" git checkout-index --all &&\n> +               GIT_INDEX_FILE=\"$TMPindex\" git checkout-index --all\n> $FORCE_OPTION &&\n>                 rm -f \"$TMPindex\" ||\n>                 die \"$(gettext \"Could not restore untracked files from stash\n> entry\")\"\n>         fi\n> @@ -688,7 +700,7 @@ apply_to_branch () {\n>         set -- --index \"$@\"\n>         assert_stash_like \"$@\"\n> \n> -       git checkout -b $branch $REV^ &&\n> +       git checkout -b $branch $FORCE_OPTION $REV^ &&\n>         apply_stash \"$@\" && {\n>                 test -z \"$IS_STASH_REF\" || drop_stash \"$@\"\n>         }\n> \n> Regards,\n> Randall\n> \n> -- Brief whoami:\n>  NonStop developer since approximately 211288444200000000\n>  UNIX developer since approximately 421664400\n> -- In my real life, I talk too much.\n> \n> \n> \n"}]}