diff mbox series

[RFC] git stash --snapshot

Message ID 002101d4e039$a7cd8a10$f7689e30$@nexbridge.com (mailing list archive)
State New, archived
Headers show
Series [RFC] git stash --snapshot | expand

Commit Message

Randall S. Becker March 21, 2019, 10:58 p.m. UTC
About two weeks ago there was a discussion about building an undo stack. 
https://public-inbox.org/git/000401d4d6c8$f68bb020$e3a31060$@nexbridge.com/

it had me thinking about whether a stash --snapshot might be useful. Below
is a conceptual change - by no means even close to complete. This would
allow scripting to wrap critical commands with a "git stash push --snapshot"
without changing the working directory. For symmetry, a "git stash pop
--force" is needed if --include-untracked were used to stash everything in
the first place. It might be more useful also to wait until stash is
converted to C, I suppose. I'm wondering whether to pursue this or drop it.
Thoughts? (and I beg forgiveness for what my mailer might do to the wrapping
of this patch, and I already know the indent is wrong between 329 and 370,
and that the granularity of the --force option is wrong).


@@ -252,6 +253,7 @@ push_stash () {
        patch_mode=
        untracked=
        stash_msg=
+       snapshot=
        while test $# != 0
        do
                case "$1" in
@@ -286,6 +288,9 @@ push_stash () {
                --message=*)
                        stash_msg=${1#--message=}
                        ;;
+               --snapshot)
+                       snapshot=t
+                       ;;
                --help)
                        show_help
                        ;;
@@ -329,6 +334,8 @@ push_stash () {
        die "$(gettext "Cannot save the current status")"
        say "$(eval_gettext "Saved working directory and index state
\$stash_msg")"

+       if test -z "$snapshot"
+       then
        if test -z "$patch_mode"
        then
                test "$untracked" = "all" && CLEAN_X_OPTION=-x ||
CLEAN_X_OPTION=
@@ -363,6 +370,7 @@ push_stash () {
                        git reset -q -- "$@"
                fi
        fi
+       fi
 }

 save_stash () {
@@ -490,6 +498,7 @@ parse_flags_and_rev()

        FLAGS=
        REV=
+       FORCE_OPTION=
        for opt
        do
                case "$opt" in
@@ -499,6 +508,9 @@ parse_flags_and_rev()
                        --index)
                                INDEX_OPTION=--index
                        ;;
+                       -f|--force)
+                               FORCE_OPTION=--force
+                       ;;
                        --help)
                                show_help
                        ;;
@@ -607,7 +619,7 @@ apply_stash () {
        if test -n "$u_tree"
        then
                GIT_INDEX_FILE="$TMPindex" git read-tree "$u_tree" &&
-               GIT_INDEX_FILE="$TMPindex" git checkout-index --all &&
+               GIT_INDEX_FILE="$TMPindex" git checkout-index --all
$FORCE_OPTION &&
                rm -f "$TMPindex" ||
                die "$(gettext "Could not restore untracked files from stash
entry")"
        fi
@@ -688,7 +700,7 @@ apply_to_branch () {
        set -- --index "$@"
        assert_stash_like "$@"

-       git checkout -b $branch $REV^ &&
+       git checkout -b $branch $FORCE_OPTION $REV^ &&
        apply_stash "$@" && {
                test -z "$IS_STASH_REF" || drop_stash "$@"
        }

Regards,
Randall

-- Brief whoami:
 NonStop developer since approximately 211288444200000000
 UNIX developer since approximately 421664400
-- In my real life, I talk too much.

Comments

Thomas Gummerer March 31, 2019, 10:07 p.m. UTC | #1
On 03/21, Randall S. Becker wrote:
> About two weeks ago there was a discussion about building an undo stack. 
> https://public-inbox.org/git/000401d4d6c8$f68bb020$e3a31060$@nexbridge.com/
> 
> it had me thinking about whether a stash --snapshot might be useful. Below
> is a conceptual change - by no means even close to complete. This would
> allow scripting to wrap critical commands with a "git stash push --snapshot"
> without changing the working directory.

I'm not sure I understand this proposal correctly.  Since you mention
this being used in scripting, would it be any different than using
'git stash push && git stash apply'?  The former is a bit more
expensive of course, but conceptually it would do the same thing, I
think.

I could see this as somewhat useful, but I don't think stash supports
all the necessary operations yet.  E.g. what if you are in the middle
of resolving a merge conflict.  But maybe a bit more of a description of your problem would
help convince me.

For the undo stack discussion, I think I prefer something like Duy's
backup-log [*1*] proposal, that is built into git, rather than
scripting my own solution, even if it's supported by 'git stash'.

I meant to review those patches, but unfortunately never got around to
that.  But if it's something that interests you as well, reviewing the
patches is probably the best way to get support for this into git.

*1*: https://public-inbox.org/git/20181209104419.12639-1-pclouds@gmail.com/

>                                          For symmetry, a "git stash pop
> --force" is needed if --include-untracked were used to stash everything in
> the first place.

What exactly is the force option meant to do?  Apply the stash anyway,
and discard current changes?  Wouldn't that lead to loosing data
again, just in a different way?

>                   It might be more useful also to wait until stash is
> converted to C, I suppose.

Yes please, any changes should ideally also apply to the stash-in-C
topic, unless they are actual bug fixes.

>                            I'm wondering whether to pursue this or drop it.
> Thoughts? (and I beg forgiveness for what my mailer might do to the wrapping
> of this patch, and I already know the indent is wrong between 329 and 370,
> and that the granularity of the --force option is wrong).
> 
> diff --git a/git-stash.sh b/git-stash.sh
> index 789ce2f41d..7741192980 100755
> --- a/git-stash.sh
> +++ b/git-stash.sh
> @@ -5,12 +5,13 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
>  USAGE="list [<options>]
>     or: $dashless show [<stash>]
>     or: $dashless drop [-q|--quiet] [<stash>]
> -   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
> +   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [-f|--force]
> [<stash>]
>     or: $dashless branch <branchname> [<stash>]
>     or: $dashless save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
>                       [-u|--include-untracked] [-a|--all] [<message>]
>     or: $dashless [push [--patch] [-k|--[no-]keep-index] [-q|--quiet]
>                        [-u|--include-untracked] [-a|--all] [-m <message>]
> +                      [--snapshot]
>                        [-- <pathspec>...]]
>     or: $dashless clear"
> 
> @@ -252,6 +253,7 @@ push_stash () {
>         patch_mode=
>         untracked=
>         stash_msg=
> +       snapshot=
>         while test $# != 0
>         do
>                 case "$1" in
> @@ -286,6 +288,9 @@ push_stash () {
>                 --message=*)
>                         stash_msg=${1#--message=}
>                         ;;
> +               --snapshot)
> +                       snapshot=t
> +                       ;;
>                 --help)
>                         show_help
>                         ;;
> @@ -329,6 +334,8 @@ push_stash () {
>         die "$(gettext "Cannot save the current status")"
>         say "$(eval_gettext "Saved working directory and index state
> \$stash_msg")"
> 
> +       if test -z "$snapshot"
> +       then
>         if test -z "$patch_mode"
>         then
>                 test "$untracked" = "all" && CLEAN_X_OPTION=-x ||
> CLEAN_X_OPTION=
> @@ -363,6 +370,7 @@ push_stash () {
>                         git reset -q -- "$@"
>                 fi
>         fi
> +       fi
>  }
> 
>  save_stash () {
> @@ -490,6 +498,7 @@ parse_flags_and_rev()
> 
>         FLAGS=
>         REV=
> +       FORCE_OPTION=
>         for opt
>         do
>                 case "$opt" in
> @@ -499,6 +508,9 @@ parse_flags_and_rev()
>                         --index)
>                                 INDEX_OPTION=--index
>                         ;;
> +                       -f|--force)
> +                               FORCE_OPTION=--force
> +                       ;;
>                         --help)
>                                 show_help
>                         ;;
> @@ -607,7 +619,7 @@ apply_stash () {
>         if test -n "$u_tree"
>         then
>                 GIT_INDEX_FILE="$TMPindex" git read-tree "$u_tree" &&
> -               GIT_INDEX_FILE="$TMPindex" git checkout-index --all &&
> +               GIT_INDEX_FILE="$TMPindex" git checkout-index --all
> $FORCE_OPTION &&
>                 rm -f "$TMPindex" ||
>                 die "$(gettext "Could not restore untracked files from stash
> entry")"
>         fi
> @@ -688,7 +700,7 @@ apply_to_branch () {
>         set -- --index "$@"
>         assert_stash_like "$@"
> 
> -       git checkout -b $branch $REV^ &&
> +       git checkout -b $branch $FORCE_OPTION $REV^ &&
>         apply_stash "$@" && {
>                 test -z "$IS_STASH_REF" || drop_stash "$@"
>         }
> 
> Regards,
> Randall
> 
> -- Brief whoami:
>  NonStop developer since approximately 211288444200000000
>  UNIX developer since approximately 421664400
> -- In my real life, I talk too much.
> 
> 
>
diff mbox series

Patch

diff --git a/git-stash.sh b/git-stash.sh
index 789ce2f41d..7741192980 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -5,12 +5,13 @@  dashless=$(basename "$0" | sed -e 's/-/ /')
 USAGE="list [<options>]
    or: $dashless show [<stash>]
    or: $dashless drop [-q|--quiet] [<stash>]
-   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
+   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [-f|--force]
[<stash>]
    or: $dashless branch <branchname> [<stash>]
    or: $dashless save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
                      [-u|--include-untracked] [-a|--all] [<message>]
    or: $dashless [push [--patch] [-k|--[no-]keep-index] [-q|--quiet]
                       [-u|--include-untracked] [-a|--all] [-m <message>]
+                      [--snapshot]
                       [-- <pathspec>...]]
    or: $dashless clear"