stash: optionally use the scripted version again
We recently converted the `git stash` command from Unix shell scripts to builtins. Let's end users a way out when they discover a bug in the builtin command: `stash.useBuiltin`. As the file name `git-stash` is already in use, let's rename the scripted backend to `git-legacy-stash`. To make the test suite pass with `stash.useBuiltin=false`, this commit also backports rudimentary support for `-q` (but only *just* enough to appease the test suite), and adds a super-ugly hack to force exit code 129 for `git stash -h`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Feb 25, 2019 at 23:16 UTC
90a462725ef3932a2408e78a47e3dfc1b8d445cf
6 files changed
+75
-4
.gitignore
+1
@@ -82,6 +82,7 @@
82
/git-interpret-trailers
83
/git-instaweb
84
/git-legacy-rebase
85
+/git-legacy-stash
86
/git-log
87
/git-ls-files
88
/git-ls-remote
Makefile
+1
@@ -617,6 +617,7 @@ SCRIPT_SH += git-merge-resolve.sh
617
SCRIPT_SH += git-mergetool.sh
618
SCRIPT_SH += git-quiltimport.sh
619
SCRIPT_SH += git-legacy-rebase.sh
620
+SCRIPT_SH += git-legacy-stash.sh
621
SCRIPT_SH += git-remote-testgit.sh
622
SCRIPT_SH += git-request-pull.sh
623
SCRIPT_SH += git-submodule.sh
builtin/stash.c
+35
@@ -13,6 +13,7 @@
13
#include "revision.h"
14
#include "log-tree.h"
15
#include "diffcore.h"
16
+#include "exec-cmd.h"
17
18
#define INCLUDE_ALL_FILES 2
19
@@ -1510,6 +1511,26 @@ static int save_stash(int argc, const char **argv, const char *prefix)
1511
return ret;
1512
}
1513
1514
+static int use_builtin_stash(void)
1515
+{
1516
+ struct child_process cp = CHILD_PROCESS_INIT;
1517
+ struct strbuf out = STRBUF_INIT;
1518
+ int ret;
1519
+
1520
+ argv_array_pushl(&cp.args,
1521
+ "config", "--bool", "stash.usebuiltin", NULL);
1522
+ cp.git_cmd = 1;
1523
+ if (capture_command(&cp, &out, 6)) {
1524
+ strbuf_release(&out);
1525
+ return 1;
1526
+ }
1527
+
1528
+ strbuf_trim(&out);
1529
+ ret = !strcmp("true", out.buf);
1530
+ strbuf_release(&out);
1531
+ return ret;
1532
+}
1533
+
1534
int cmd_stash(int argc, const char **argv, const char *prefix)
1535
{
1536
int i = -1;
@@ -1521,6 +1542,20 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
1542
OPT_END()
1543
};
1544
1545
+ if (!use_builtin_stash()) {
1546
+ const char *path = mkpath("%s/git-legacy-stash",
1547
+ git_exec_path());
1548
+
1549
+ if (sane_execvp(path, (char **)argv) < 0)
1550
+ die_errno(_("could not exec %s"), path);
1551
+ else
1552
+ BUG("sane_execvp() returned???");
1553
+ }
1554
+
1555
+ prefix = setup_git_directory();
1556
+ trace_repo_setup(prefix);
1557
+ setup_work_tree();
1558
+
1559
git_config(git_diff_basic_config, NULL);
1560
1561
argc = parse_options(argc, argv, prefix, options, git_stash_usage,
git-legacy-stash.sh
renamed
+31
-3
@@ -80,6 +80,28 @@ clear_stash () {
80
fi
81
}
82
83
+maybe_quiet () {
84
+ case "$1" in
85
+ --keep-stdout)
86
+ shift
87
+ if test -n "$GIT_QUIET"
88
+ then
89
+ eval "$@" 2>/dev/null
90
+ else
91
+ eval "$@"
92
+ fi
93
+ ;;
94
+ *)
95
+ if test -n "$GIT_QUIET"
96
+ then
97
+ eval "$@" >/dev/null 2>&1
98
+ else
99
+ eval "$@"
100
+ fi
101
+ ;;
102
+ esac
103
+}
104
+
105
create_stash () {
106
107
prepare_fallback_ident
@@ -112,15 +134,18 @@ create_stash () {
134
done
135
136
git update-index -q --refresh
115
- if no_changes "$@"
137
+ if maybe_quiet no_changes "$@"
138
then
139
exit 0
140
fi
141
142
# state of the base commit
121
- if b_commit=$(git rev-parse --verify HEAD)
143
+ if b_commit=$(maybe_quiet --keep-stdout git rev-parse --verify HEAD)
144
then
145
head=$(git rev-list --oneline -n 1 HEAD --)
146
+ elif test -n "$GIT_QUIET"
147
+ then
148
+ exit 1
149
else
150
die "$(gettext "You do not have the initial commit yet")"
151
fi
@@ -315,7 +340,7 @@ push_stash () {
340
test -n "$untracked" || git ls-files --error-unmatch -- "$@" >/dev/null || exit 1
341
342
git update-index -q --refresh
318
- if no_changes "$@"
343
+ if maybe_quiet no_changes "$@"
344
then
345
say "$(gettext "No local changes to save")"
346
exit 0
@@ -370,6 +395,9 @@ save_stash () {
395
while test $# != 0
396
do
397
case "$1" in
398
+ -q|--quiet)
399
+ GIT_QUIET=t
400
+ ;;
401
--)
402
shift
403
break
git-sh-setup.sh
+1
@@ -101,6 +101,7 @@ $LONG_USAGE")"
101
case "$1" in
102
-h)
103
echo "$LONG_USAGE"
104
+ case "$0" in *git-legacy-stash) exit 129;; esac
105
exit
106
esac
107
fi
git.c
+6
-1
@@ -554,7 +554,12 @@ static struct cmd_struct commands[] = {
554
{ "show-index", cmd_show_index },
555
{ "show-ref", cmd_show_ref, RUN_SETUP },
556
{ "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
557
- { "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
557
+ /*
558
+ * NEEDSWORK: Until the builtin stash is thoroughly robust and no
559
+ * longer needs redirection to the stash shell script this is kept as
560
+ * is, then should be changed to RUN_SETUP | NEED_WORK_TREE
561
+ */
562
+ { "stash", cmd_stash },
563
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
564
{ "stripspace", cmd_stripspace },
565
{ "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },