mirror of
https://github.com/git/git.git
synced 2026-01-18 14:44:28 +00:00
Merge branch 'make-builtin-stash-and-rebase-opt-ins'
This branch adds back the scripted versions, then adds the option to use the builtin versions of `stash` and `rebase` by setting `stash.useBuiltin=true` and `rebase.useBuiltin=true`, respectively, (the latter already worked for the top-level `git rebase` command and the `--am` backend, and now it also works for the interactive backend). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -79,6 +79,8 @@
|
||||
/git-interpret-trailers
|
||||
/git-instaweb
|
||||
/git-legacy-rebase
|
||||
/git-legacy-rebase--interactive
|
||||
/git-legacy-stash
|
||||
/git-log
|
||||
/git-ls-files
|
||||
/git-ls-remote
|
||||
|
||||
2
Makefile
2
Makefile
@@ -615,11 +615,13 @@ SCRIPT_SH += git-merge-resolve.sh
|
||||
SCRIPT_SH += git-mergetool.sh
|
||||
SCRIPT_SH += git-quiltimport.sh
|
||||
SCRIPT_SH += git-legacy-rebase.sh
|
||||
SCRIPT_SH += git-legacy-stash.sh
|
||||
SCRIPT_SH += git-remote-testgit.sh
|
||||
SCRIPT_SH += git-request-pull.sh
|
||||
SCRIPT_SH += git-submodule.sh
|
||||
SCRIPT_SH += git-web--browse.sh
|
||||
|
||||
SCRIPT_LIB += git-legacy-rebase--interactive
|
||||
SCRIPT_LIB += git-mergetool--lib
|
||||
SCRIPT_LIB += git-parse-remote
|
||||
SCRIPT_LIB += git-rebase--am
|
||||
|
||||
@@ -141,7 +141,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
|
||||
char *raw_strategies = NULL;
|
||||
enum {
|
||||
NONE = 0, CONTINUE, SKIP, EDIT_TODO, SHOW_CURRENT_PATCH,
|
||||
SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, REARRANGE_SQUASH, ADD_EXEC
|
||||
SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, REARRANGE_SQUASH, ADD_EXEC,
|
||||
MAKE_SCRIPT, SKIP_UNNECESSARY_PICKS,
|
||||
} command = 0;
|
||||
struct option options[] = {
|
||||
OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
|
||||
@@ -192,6 +193,10 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
|
||||
OPT_STRING(0, "onto-name", &onto_name, N_("onto-name"), N_("onto name")),
|
||||
OPT_STRING(0, "cmd", &cmd, N_("cmd"), N_("the command to run")),
|
||||
OPT_RERERE_AUTOUPDATE(&opts.allow_rerere_auto),
|
||||
OPT_CMDMODE(0, "make-script", &command,
|
||||
N_("make rebase script"), MAKE_SCRIPT),
|
||||
OPT_CMDMODE(0, "skip-unnecessary-picks", &command,
|
||||
N_("skip unnecessary picks"), SKIP_UNNECESSARY_PICKS),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
@@ -263,6 +268,17 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
|
||||
case ADD_EXEC:
|
||||
ret = sequencer_add_exec_commands(cmd);
|
||||
break;
|
||||
case MAKE_SCRIPT:
|
||||
ret = sequencer_make_script(stdout, argc, argv, flags);
|
||||
break;
|
||||
case SKIP_UNNECESSARY_PICKS: {
|
||||
struct object_id oid;
|
||||
|
||||
ret = skip_unnecessary_picks(&oid);
|
||||
if (!ret)
|
||||
printf("%s\n", oid_to_hex(&oid));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BUG("invalid command '%d'", command);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ static int use_builtin_rebase(void)
|
||||
cp.git_cmd = 1;
|
||||
if (capture_command(&cp, &out, 6)) {
|
||||
strbuf_release(&out);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strbuf_trim(&out);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "revision.h"
|
||||
#include "log-tree.h"
|
||||
#include "diffcore.h"
|
||||
#include "exec-cmd.h"
|
||||
|
||||
static const char * const git_stash_usage[] = {
|
||||
N_("git stash list [<options>]"),
|
||||
@@ -1477,6 +1478,26 @@ static int save_stash(int argc, const char **argv, const char *prefix)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int use_builtin_stash(void)
|
||||
{
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
struct strbuf out = STRBUF_INIT;
|
||||
int ret;
|
||||
|
||||
argv_array_pushl(&cp.args,
|
||||
"config", "--bool", "stash.usebuiltin", NULL);
|
||||
cp.git_cmd = 1;
|
||||
if (capture_command(&cp, &out, 6)) {
|
||||
strbuf_release(&out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strbuf_trim(&out);
|
||||
ret = !strcmp("true", out.buf);
|
||||
strbuf_release(&out);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cmd_stash(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i = -1;
|
||||
@@ -1488,6 +1509,20 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
if (!use_builtin_stash()) {
|
||||
const char *path = mkpath("%s/git-legacy-stash",
|
||||
git_exec_path());
|
||||
|
||||
if (sane_execvp(path, (char **)argv) < 0)
|
||||
die_errno(_("could not exec %s"), path);
|
||||
else
|
||||
BUG("sane_execvp() returned???");
|
||||
}
|
||||
|
||||
prefix = setup_git_directory();
|
||||
trace_repo_setup(prefix);
|
||||
setup_work_tree();
|
||||
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options, git_stash_usage,
|
||||
|
||||
283
git-legacy-rebase--interactive.sh
Normal file
283
git-legacy-rebase--interactive.sh
Normal file
@@ -0,0 +1,283 @@
|
||||
# This shell script fragment is sourced by git-rebase to implement
|
||||
# its interactive mode. "git rebase --interactive" makes it easy
|
||||
# to fix up commits in the middle of a series and rearrange commits.
|
||||
#
|
||||
# Copyright (c) 2006 Johannes E. Schindelin
|
||||
#
|
||||
# The original idea comes from Eric W. Biederman, in
|
||||
# https://public-inbox.org/git/m1odwkyuf5.fsf_-_@ebiederm.dsl.xmission.com/
|
||||
#
|
||||
# The file containing rebase commands, comments, and empty lines.
|
||||
# This file is created by "git rebase -i" then edited by the user. As
|
||||
# the lines are processed, they are removed from the front of this
|
||||
# file and written to the tail of $done.
|
||||
todo="$state_dir"/git-rebase-todo
|
||||
|
||||
GIT_CHERRY_PICK_HELP="$resolvemsg"
|
||||
export GIT_CHERRY_PICK_HELP
|
||||
|
||||
comment_char=$(git config --get core.commentchar 2>/dev/null)
|
||||
case "$comment_char" in
|
||||
'' | auto)
|
||||
comment_char="#"
|
||||
;;
|
||||
?)
|
||||
;;
|
||||
*)
|
||||
comment_char=$(echo "$comment_char" | cut -c1)
|
||||
;;
|
||||
esac
|
||||
|
||||
orig_reflog_action="$GIT_REFLOG_ACTION"
|
||||
|
||||
comment_for_reflog () {
|
||||
case "$orig_reflog_action" in
|
||||
''|rebase*)
|
||||
GIT_REFLOG_ACTION="rebase -i ($1)"
|
||||
export GIT_REFLOG_ACTION
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
append_todo_help () {
|
||||
gettext "
|
||||
Commands:
|
||||
p, pick <commit> = use commit
|
||||
r, reword <commit> = use commit, but edit the commit message
|
||||
e, edit <commit> = use commit, but stop for amending
|
||||
s, squash <commit> = use commit, but meld into previous commit
|
||||
f, fixup <commit> = like \"squash\", but discard this commit's log message
|
||||
x, exec <command> = run command (the rest of the line) using shell
|
||||
d, drop <commit> = remove commit
|
||||
l, label <label> = label current HEAD with a name
|
||||
t, reset <label> = reset HEAD to a label
|
||||
m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
|
||||
. create a merge commit using the original merge commit's
|
||||
. message (or the oneline, if no original merge commit was
|
||||
. specified). Use -c <commit> to reword the commit message.
|
||||
|
||||
These lines can be re-ordered; they are executed from top to bottom.
|
||||
" | git stripspace --comment-lines >>"$todo"
|
||||
|
||||
if test $(get_missing_commit_check_level) = error
|
||||
then
|
||||
gettext "
|
||||
Do not remove any line. Use 'drop' explicitly to remove a commit.
|
||||
" | git stripspace --comment-lines >>"$todo"
|
||||
else
|
||||
gettext "
|
||||
If you remove a line here THAT COMMIT WILL BE LOST.
|
||||
" | git stripspace --comment-lines >>"$todo"
|
||||
fi
|
||||
}
|
||||
|
||||
die_abort () {
|
||||
apply_autostash
|
||||
rm -rf "$state_dir"
|
||||
die "$1"
|
||||
}
|
||||
|
||||
has_action () {
|
||||
test -n "$(git stripspace --strip-comments <"$1")"
|
||||
}
|
||||
|
||||
git_sequence_editor () {
|
||||
if test -z "$GIT_SEQUENCE_EDITOR"
|
||||
then
|
||||
GIT_SEQUENCE_EDITOR="$(git config sequence.editor)"
|
||||
if [ -z "$GIT_SEQUENCE_EDITOR" ]
|
||||
then
|
||||
GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $?
|
||||
fi
|
||||
fi
|
||||
|
||||
eval "$GIT_SEQUENCE_EDITOR" '"$@"'
|
||||
}
|
||||
|
||||
expand_todo_ids() {
|
||||
git rebase--interactive --expand-ids
|
||||
}
|
||||
|
||||
collapse_todo_ids() {
|
||||
git rebase--interactive --shorten-ids
|
||||
}
|
||||
|
||||
# Switch to the branch in $into and notify it in the reflog
|
||||
checkout_onto () {
|
||||
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
|
||||
output git checkout $onto || die_abort "$(gettext "could not detach HEAD")"
|
||||
git update-ref ORIG_HEAD $orig_head
|
||||
}
|
||||
|
||||
get_missing_commit_check_level () {
|
||||
check_level=$(git config --get rebase.missingCommitsCheck)
|
||||
check_level=${check_level:-ignore}
|
||||
# Don't be case sensitive
|
||||
printf '%s' "$check_level" | tr 'A-Z' 'a-z'
|
||||
}
|
||||
|
||||
# Initiate an action. If the cannot be any
|
||||
# further action it may exec a command
|
||||
# or exit and not return.
|
||||
#
|
||||
# TODO: Consider a cleaner return model so it
|
||||
# never exits and always return 0 if process
|
||||
# is complete.
|
||||
#
|
||||
# Parameter 1 is the action to initiate.
|
||||
#
|
||||
# Returns 0 if the action was able to complete
|
||||
# and if 1 if further processing is required.
|
||||
initiate_action () {
|
||||
case "$1" in
|
||||
continue)
|
||||
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
|
||||
--continue
|
||||
;;
|
||||
skip)
|
||||
git rerere clear
|
||||
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
|
||||
--continue
|
||||
;;
|
||||
edit-todo)
|
||||
git stripspace --strip-comments <"$todo" >"$todo".new
|
||||
mv -f "$todo".new "$todo"
|
||||
collapse_todo_ids
|
||||
append_todo_help
|
||||
gettext "
|
||||
You are editing the todo file of an ongoing interactive rebase.
|
||||
To continue rebase after editing, run:
|
||||
git rebase --continue
|
||||
|
||||
" | git stripspace --comment-lines >>"$todo"
|
||||
|
||||
git_sequence_editor "$todo" ||
|
||||
die "$(gettext "Could not execute editor")"
|
||||
expand_todo_ids
|
||||
|
||||
exit
|
||||
;;
|
||||
show-current-patch)
|
||||
exec git show REBASE_HEAD --
|
||||
;;
|
||||
*)
|
||||
return 1 # continue
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
setup_reflog_action () {
|
||||
comment_for_reflog start
|
||||
|
||||
if test ! -z "$switch_to"
|
||||
then
|
||||
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
|
||||
output git checkout "$switch_to" -- ||
|
||||
die "$(eval_gettext "Could not checkout \$switch_to")"
|
||||
|
||||
comment_for_reflog start
|
||||
fi
|
||||
}
|
||||
|
||||
init_basic_state () {
|
||||
orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
|
||||
mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
|
||||
rm -f "$(git rev-parse --git-path REBASE_HEAD)"
|
||||
|
||||
: > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
|
||||
write_basic_state
|
||||
}
|
||||
|
||||
init_revisions_and_shortrevisions () {
|
||||
shorthead=$(git rev-parse --short $orig_head)
|
||||
shortonto=$(git rev-parse --short $onto)
|
||||
if test -z "$rebase_root"
|
||||
# this is now equivalent to ! -z "$upstream"
|
||||
then
|
||||
shortupstream=$(git rev-parse --short $upstream)
|
||||
revisions=$upstream...$orig_head
|
||||
shortrevisions=$shortupstream..$shorthead
|
||||
else
|
||||
revisions=$onto...$orig_head
|
||||
shortrevisions=$shorthead
|
||||
test -z "$squash_onto" ||
|
||||
echo "$squash_onto" >"$state_dir"/squash-onto
|
||||
fi
|
||||
}
|
||||
|
||||
complete_action() {
|
||||
test -s "$todo" || echo noop >> "$todo"
|
||||
test -z "$autosquash" || git rebase--interactive --rearrange-squash || exit
|
||||
test -n "$cmd" && git rebase--interactive --add-exec-commands --cmd "$cmd"
|
||||
|
||||
todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
|
||||
todocount=${todocount##* }
|
||||
|
||||
cat >>"$todo" <<EOF
|
||||
|
||||
$comment_char $(eval_ngettext \
|
||||
"Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
|
||||
"Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
|
||||
"$todocount")
|
||||
EOF
|
||||
append_todo_help
|
||||
gettext "
|
||||
However, if you remove everything, the rebase will be aborted.
|
||||
|
||||
" | git stripspace --comment-lines >>"$todo"
|
||||
|
||||
if test -z "$keep_empty"
|
||||
then
|
||||
printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
|
||||
fi
|
||||
|
||||
|
||||
has_action "$todo" ||
|
||||
return 2
|
||||
|
||||
cp "$todo" "$todo".backup
|
||||
collapse_todo_ids
|
||||
git_sequence_editor "$todo" ||
|
||||
die_abort "$(gettext "Could not execute editor")"
|
||||
|
||||
has_action "$todo" ||
|
||||
return 2
|
||||
|
||||
git rebase--interactive --check-todo-list || {
|
||||
ret=$?
|
||||
checkout_onto
|
||||
exit $ret
|
||||
}
|
||||
|
||||
expand_todo_ids
|
||||
|
||||
test -n "$force_rebase" ||
|
||||
onto="$(git rebase--interactive --skip-unnecessary-picks)" ||
|
||||
die "Could not skip unnecessary pick commands"
|
||||
|
||||
checkout_onto
|
||||
require_clean_work_tree "rebase"
|
||||
exec git rebase--interactive ${force_rebase:+--no-ff} $allow_empty_message \
|
||||
--continue
|
||||
}
|
||||
|
||||
git_rebase__interactive () {
|
||||
initiate_action "$action"
|
||||
ret=$?
|
||||
if test $ret = 0; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
setup_reflog_action
|
||||
init_basic_state
|
||||
|
||||
init_revisions_and_shortrevisions
|
||||
|
||||
git rebase--interactive --make-script ${keep_empty:+--keep-empty} \
|
||||
${rebase_merges:+--rebase-merges} \
|
||||
${rebase_cousins:+--rebase-cousins} \
|
||||
$revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
|
||||
die "$(gettext "Could not generate todo list")"
|
||||
|
||||
complete_action
|
||||
}
|
||||
@@ -135,37 +135,6 @@ finish_rebase () {
|
||||
rm -rf "$state_dir"
|
||||
}
|
||||
|
||||
run_interactive () {
|
||||
GIT_CHERRY_PICK_HELP="$resolvemsg"
|
||||
export GIT_CHERRY_PICK_HELP
|
||||
|
||||
test -n "$keep_empty" && keep_empty="--keep-empty"
|
||||
test -n "$rebase_merges" && rebase_merges="--rebase-merges"
|
||||
test -n "$rebase_cousins" && rebase_cousins="--rebase-cousins"
|
||||
test -n "$autosquash" && autosquash="--autosquash"
|
||||
test -n "$verbose" && verbose="--verbose"
|
||||
test -n "$force_rebase" && force_rebase="--no-ff"
|
||||
test -n "$restrict_revision" && \
|
||||
restrict_revision="--restrict-revision=^$restrict_revision"
|
||||
test -n "$upstream" && upstream="--upstream=$upstream"
|
||||
test -n "$onto" && onto="--onto=$onto"
|
||||
test -n "$squash_onto" && squash_onto="--squash-onto=$squash_onto"
|
||||
test -n "$onto_name" && onto_name="--onto-name=$onto_name"
|
||||
test -n "$head_name" && head_name="--head-name=$head_name"
|
||||
test -n "$strategy" && strategy="--strategy=$strategy"
|
||||
test -n "$strategy_opts" && strategy_opts="--strategy-opts=$strategy_opts"
|
||||
test -n "$switch_to" && switch_to="--switch-to=$switch_to"
|
||||
test -n "$cmd" && cmd="--cmd=$cmd"
|
||||
test -n "$action" && action="--$action"
|
||||
|
||||
exec git rebase--interactive "$action" "$keep_empty" "$rebase_merges" "$rebase_cousins" \
|
||||
"$upstream" "$onto" "$squash_onto" "$restrict_revision" \
|
||||
"$allow_empty_message" "$autosquash" "$verbose" \
|
||||
"$force_rebase" "$onto_name" "$head_name" "$strategy" \
|
||||
"$strategy_opts" "$cmd" "$switch_to" \
|
||||
"$allow_rerere_autoupdate" "$gpg_sign_opt" "$signoff"
|
||||
}
|
||||
|
||||
run_specific_rebase () {
|
||||
if [ "$interactive_rebase" = implied ]; then
|
||||
GIT_EDITOR=:
|
||||
@@ -175,7 +144,9 @@ run_specific_rebase () {
|
||||
|
||||
if test -n "$interactive_rebase" -a -z "$preserve_merges"
|
||||
then
|
||||
run_interactive
|
||||
. git-legacy-rebase--$type
|
||||
|
||||
git_rebase__$type
|
||||
else
|
||||
. git-rebase--$type
|
||||
|
||||
@@ -195,7 +166,12 @@ run_specific_rebase () {
|
||||
then
|
||||
apply_autostash &&
|
||||
rm -rf "$state_dir" &&
|
||||
die "Nothing to do"
|
||||
if test -n "$interactive_rebase" -a -z "$preserve_merges"
|
||||
then
|
||||
die "error: nothing to do"
|
||||
else
|
||||
die "Nothing to do"
|
||||
fi
|
||||
fi
|
||||
exit $ret
|
||||
}
|
||||
|
||||
780
git-legacy-stash.sh
Executable file
780
git-legacy-stash.sh
Executable file
@@ -0,0 +1,780 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2007, Nanako Shiraishi
|
||||
|
||||
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 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>]
|
||||
[-- <pathspec>...]]
|
||||
or: $dashless clear"
|
||||
|
||||
SUBDIRECTORY_OK=Yes
|
||||
OPTIONS_SPEC=
|
||||
START_DIR=$(pwd)
|
||||
. git-sh-setup
|
||||
require_work_tree
|
||||
prefix=$(git rev-parse --show-prefix) || exit 1
|
||||
cd_to_toplevel
|
||||
|
||||
TMP="$GIT_DIR/.git-stash.$$"
|
||||
TMPindex=${GIT_INDEX_FILE-"$(git rev-parse --git-path index)"}.stash.$$
|
||||
trap 'rm -f "$TMP-"* "$TMPindex"' 0
|
||||
|
||||
ref_stash=refs/stash
|
||||
|
||||
if git config --get-colorbool color.interactive; then
|
||||
help_color="$(git config --get-color color.interactive.help 'red bold')"
|
||||
reset_color="$(git config --get-color '' reset)"
|
||||
else
|
||||
help_color=
|
||||
reset_color=
|
||||
fi
|
||||
|
||||
no_changes () {
|
||||
git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" &&
|
||||
git diff-files --quiet --ignore-submodules -- "$@" &&
|
||||
(test -z "$untracked" || test -z "$(untracked_files "$@")")
|
||||
}
|
||||
|
||||
untracked_files () {
|
||||
if test "$1" = "-z"
|
||||
then
|
||||
shift
|
||||
z=-z
|
||||
else
|
||||
z=
|
||||
fi
|
||||
excl_opt=--exclude-standard
|
||||
test "$untracked" = "all" && excl_opt=
|
||||
git ls-files -o $z $excl_opt -- "$@"
|
||||
}
|
||||
|
||||
clear_stash () {
|
||||
if test $# != 0
|
||||
then
|
||||
die "$(gettext "git stash clear with parameters is unimplemented")"
|
||||
fi
|
||||
if current=$(git rev-parse --verify --quiet $ref_stash)
|
||||
then
|
||||
git update-ref -d $ref_stash $current
|
||||
fi
|
||||
}
|
||||
|
||||
maybe_quiet () {
|
||||
case "$1" in
|
||||
--keep-stdout)
|
||||
shift
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
eval "$@" 2>/dev/null
|
||||
else
|
||||
eval "$@"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
eval "$@" >/dev/null 2>&1
|
||||
else
|
||||
eval "$@"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
create_stash () {
|
||||
stash_msg=
|
||||
untracked=
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
-m|--message)
|
||||
shift
|
||||
stash_msg=${1?"BUG: create_stash () -m requires an argument"}
|
||||
;;
|
||||
-m*)
|
||||
stash_msg=${1#-m}
|
||||
;;
|
||||
--message=*)
|
||||
stash_msg=${1#--message=}
|
||||
;;
|
||||
-u|--include-untracked)
|
||||
shift
|
||||
untracked=${1?"BUG: create_stash () -u requires an argument"}
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
git update-index -q --refresh
|
||||
if maybe_quiet no_changes "$@"
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# state of the base commit
|
||||
if b_commit=$(maybe_quiet --keep-stdout git rev-parse --verify HEAD)
|
||||
then
|
||||
head=$(git rev-list --oneline -n 1 HEAD --)
|
||||
elif test -n "$GIT_QUIET"
|
||||
then
|
||||
exit 1
|
||||
else
|
||||
die "$(gettext "You do not have the initial commit yet")"
|
||||
fi
|
||||
|
||||
if branch=$(git symbolic-ref -q HEAD)
|
||||
then
|
||||
branch=${branch#refs/heads/}
|
||||
else
|
||||
branch='(no branch)'
|
||||
fi
|
||||
msg=$(printf '%s: %s' "$branch" "$head")
|
||||
|
||||
# state of the index
|
||||
i_tree=$(git write-tree) &&
|
||||
i_commit=$(printf 'index on %s\n' "$msg" |
|
||||
git commit-tree $i_tree -p $b_commit) ||
|
||||
die "$(gettext "Cannot save the current index state")"
|
||||
|
||||
if test -n "$untracked"
|
||||
then
|
||||
# Untracked files are stored by themselves in a parentless commit, for
|
||||
# ease of unpacking later.
|
||||
u_commit=$(
|
||||
untracked_files -z "$@" | (
|
||||
GIT_INDEX_FILE="$TMPindex" &&
|
||||
export GIT_INDEX_FILE &&
|
||||
rm -f "$TMPindex" &&
|
||||
git update-index -z --add --remove --stdin &&
|
||||
u_tree=$(git write-tree) &&
|
||||
printf 'untracked files on %s\n' "$msg" | git commit-tree $u_tree &&
|
||||
rm -f "$TMPindex"
|
||||
) ) || die "$(gettext "Cannot save the untracked files")"
|
||||
|
||||
untracked_commit_option="-p $u_commit";
|
||||
else
|
||||
untracked_commit_option=
|
||||
fi
|
||||
|
||||
if test -z "$patch_mode"
|
||||
then
|
||||
|
||||
# state of the working tree
|
||||
w_tree=$( (
|
||||
git read-tree --index-output="$TMPindex" -m $i_tree &&
|
||||
GIT_INDEX_FILE="$TMPindex" &&
|
||||
export GIT_INDEX_FILE &&
|
||||
git diff-index --name-only -z HEAD -- "$@" >"$TMP-stagenames" &&
|
||||
git update-index -z --add --remove --stdin <"$TMP-stagenames" &&
|
||||
git write-tree &&
|
||||
rm -f "$TMPindex"
|
||||
) ) ||
|
||||
die "$(gettext "Cannot save the current worktree state")"
|
||||
|
||||
else
|
||||
|
||||
rm -f "$TMP-index" &&
|
||||
GIT_INDEX_FILE="$TMP-index" git read-tree HEAD &&
|
||||
|
||||
# find out what the user wants
|
||||
GIT_INDEX_FILE="$TMP-index" \
|
||||
git add--interactive --patch=stash -- "$@" &&
|
||||
|
||||
# state of the working tree
|
||||
w_tree=$(GIT_INDEX_FILE="$TMP-index" git write-tree) ||
|
||||
die "$(gettext "Cannot save the current worktree state")"
|
||||
|
||||
git diff-tree -p HEAD $w_tree -- >"$TMP-patch" &&
|
||||
test -s "$TMP-patch" ||
|
||||
die "$(gettext "No changes selected")"
|
||||
|
||||
rm -f "$TMP-index" ||
|
||||
die "$(gettext "Cannot remove temporary index (can't happen)")"
|
||||
|
||||
fi
|
||||
|
||||
# create the stash
|
||||
if test -z "$stash_msg"
|
||||
then
|
||||
stash_msg=$(printf 'WIP on %s' "$msg")
|
||||
else
|
||||
stash_msg=$(printf 'On %s: %s' "$branch" "$stash_msg")
|
||||
fi
|
||||
w_commit=$(printf '%s\n' "$stash_msg" |
|
||||
git commit-tree $w_tree -p $b_commit -p $i_commit $untracked_commit_option) ||
|
||||
die "$(gettext "Cannot record working tree state")"
|
||||
}
|
||||
|
||||
store_stash () {
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
-m|--message)
|
||||
shift
|
||||
stash_msg="$1"
|
||||
;;
|
||||
-m*)
|
||||
stash_msg=${1#-m}
|
||||
;;
|
||||
--message=*)
|
||||
stash_msg=${1#--message=}
|
||||
;;
|
||||
-q|--quiet)
|
||||
quiet=t
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
test $# = 1 ||
|
||||
die "$(eval_gettext "\"$dashless store\" requires one <commit> argument")"
|
||||
|
||||
w_commit="$1"
|
||||
if test -z "$stash_msg"
|
||||
then
|
||||
stash_msg="Created via \"git stash store\"."
|
||||
fi
|
||||
|
||||
git update-ref --create-reflog -m "$stash_msg" $ref_stash $w_commit
|
||||
ret=$?
|
||||
test $ret != 0 && test -z "$quiet" &&
|
||||
die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")"
|
||||
return $ret
|
||||
}
|
||||
|
||||
push_stash () {
|
||||
keep_index=
|
||||
patch_mode=
|
||||
untracked=
|
||||
stash_msg=
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
-k|--keep-index)
|
||||
keep_index=t
|
||||
;;
|
||||
--no-keep-index)
|
||||
keep_index=n
|
||||
;;
|
||||
-p|--patch)
|
||||
patch_mode=t
|
||||
# only default to keep if we don't already have an override
|
||||
test -z "$keep_index" && keep_index=t
|
||||
;;
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t
|
||||
;;
|
||||
-u|--include-untracked)
|
||||
untracked=untracked
|
||||
;;
|
||||
-a|--all)
|
||||
untracked=all
|
||||
;;
|
||||
-m|--message)
|
||||
shift
|
||||
test -z ${1+x} && usage
|
||||
stash_msg=$1
|
||||
;;
|
||||
-m*)
|
||||
stash_msg=${1#-m}
|
||||
;;
|
||||
--message=*)
|
||||
stash_msg=${1#--message=}
|
||||
;;
|
||||
--help)
|
||||
show_help
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
option="$1"
|
||||
eval_gettextln "error: unknown option for 'stash push': \$option"
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
eval "set $(git rev-parse --sq --prefix "$prefix" -- "$@")"
|
||||
|
||||
if test -n "$patch_mode" && test -n "$untracked"
|
||||
then
|
||||
die "$(gettext "Can't use --patch and --include-untracked or --all at the same time")"
|
||||
fi
|
||||
|
||||
test -n "$untracked" || git ls-files --error-unmatch -- "$@" >/dev/null || exit 1
|
||||
|
||||
git update-index -q --refresh
|
||||
if maybe_quiet no_changes "$@"
|
||||
then
|
||||
say "$(gettext "No local changes to save")"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git reflog exists $ref_stash ||
|
||||
clear_stash || die "$(gettext "Cannot initialize stash")"
|
||||
|
||||
create_stash -m "$stash_msg" -u "$untracked" -- "$@"
|
||||
store_stash -m "$stash_msg" -q $w_commit ||
|
||||
die "$(gettext "Cannot save the current status")"
|
||||
say "$(eval_gettext "Saved working directory and index state \$stash_msg")"
|
||||
|
||||
if test -z "$patch_mode"
|
||||
then
|
||||
test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION=
|
||||
if test -n "$untracked" && test $# = 0
|
||||
then
|
||||
git clean --force --quiet -d $CLEAN_X_OPTION
|
||||
fi
|
||||
|
||||
if test $# != 0
|
||||
then
|
||||
test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION=
|
||||
test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION=
|
||||
git add $UPDATE_OPTION $FORCE_OPTION -- "$@"
|
||||
git diff-index -p --cached --binary HEAD -- "$@" |
|
||||
git apply --index -R
|
||||
else
|
||||
git reset --hard -q
|
||||
fi
|
||||
|
||||
if test "$keep_index" = "t" && test -n "$i_tree"
|
||||
then
|
||||
git read-tree --reset $i_tree
|
||||
git ls-files -z --modified -- "$@" |
|
||||
git checkout-index -z --force --stdin
|
||||
fi
|
||||
else
|
||||
git apply -R < "$TMP-patch" ||
|
||||
die "$(gettext "Cannot remove worktree changes")"
|
||||
|
||||
if test "$keep_index" != "t"
|
||||
then
|
||||
git reset -q -- "$@"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
save_stash () {
|
||||
push_options=
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
# pass all options through to push_stash
|
||||
push_options="$push_options $1"
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
stash_msg="$*"
|
||||
|
||||
if test -z "$stash_msg"
|
||||
then
|
||||
push_stash $push_options
|
||||
else
|
||||
push_stash $push_options -m "$stash_msg"
|
||||
fi
|
||||
}
|
||||
|
||||
have_stash () {
|
||||
git rev-parse --verify --quiet $ref_stash >/dev/null
|
||||
}
|
||||
|
||||
list_stash () {
|
||||
have_stash || return 0
|
||||
git log --format="%gd: %gs" -g --first-parent -m "$@" $ref_stash --
|
||||
}
|
||||
|
||||
show_stash () {
|
||||
ALLOW_UNKNOWN_FLAGS=t
|
||||
assert_stash_like "$@"
|
||||
|
||||
if test -z "$FLAGS"
|
||||
then
|
||||
if test "$(git config --bool stash.showStat || echo true)" = "true"
|
||||
then
|
||||
FLAGS=--stat
|
||||
fi
|
||||
|
||||
if test "$(git config --bool stash.showPatch || echo false)" = "true"
|
||||
then
|
||||
FLAGS=${FLAGS}${FLAGS:+ }-p
|
||||
fi
|
||||
|
||||
if test -z "$FLAGS"
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
git diff ${FLAGS} $b_commit $w_commit
|
||||
}
|
||||
|
||||
show_help () {
|
||||
exec git help stash
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Parses the remaining options looking for flags and
|
||||
# at most one revision defaulting to ${ref_stash}@{0}
|
||||
# if none found.
|
||||
#
|
||||
# Derives related tree and commit objects from the
|
||||
# revision, if one is found.
|
||||
#
|
||||
# stash records the work tree, and is a merge between the
|
||||
# base commit (first parent) and the index tree (second parent).
|
||||
#
|
||||
# REV is set to the symbolic version of the specified stash-like commit
|
||||
# IS_STASH_LIKE is non-blank if ${REV} looks like a stash
|
||||
# IS_STASH_REF is non-blank if the ${REV} looks like a stash ref
|
||||
# s is set to the SHA1 of the stash commit
|
||||
# w_commit is set to the commit containing the working tree
|
||||
# b_commit is set to the base commit
|
||||
# i_commit is set to the commit containing the index tree
|
||||
# u_commit is set to the commit containing the untracked files tree
|
||||
# w_tree is set to the working tree
|
||||
# b_tree is set to the base tree
|
||||
# i_tree is set to the index tree
|
||||
# u_tree is set to the untracked files tree
|
||||
#
|
||||
# GIT_QUIET is set to t if -q is specified
|
||||
# INDEX_OPTION is set to --index if --index is specified.
|
||||
# FLAGS is set to the remaining flags (if allowed)
|
||||
#
|
||||
# dies if:
|
||||
# * too many revisions specified
|
||||
# * no revision is specified and there is no stash stack
|
||||
# * a revision is specified which cannot be resolve to a SHA1
|
||||
# * a non-existent stash reference is specified
|
||||
# * unknown flags were set and ALLOW_UNKNOWN_FLAGS is not "t"
|
||||
#
|
||||
|
||||
parse_flags_and_rev()
|
||||
{
|
||||
test "$PARSE_CACHE" = "$*" && return 0 # optimisation
|
||||
PARSE_CACHE="$*"
|
||||
|
||||
IS_STASH_LIKE=
|
||||
IS_STASH_REF=
|
||||
INDEX_OPTION=
|
||||
s=
|
||||
w_commit=
|
||||
b_commit=
|
||||
i_commit=
|
||||
u_commit=
|
||||
w_tree=
|
||||
b_tree=
|
||||
i_tree=
|
||||
u_tree=
|
||||
|
||||
FLAGS=
|
||||
REV=
|
||||
for opt
|
||||
do
|
||||
case "$opt" in
|
||||
-q|--quiet)
|
||||
GIT_QUIET=-t
|
||||
;;
|
||||
--index)
|
||||
INDEX_OPTION=--index
|
||||
;;
|
||||
--help)
|
||||
show_help
|
||||
;;
|
||||
-*)
|
||||
test "$ALLOW_UNKNOWN_FLAGS" = t ||
|
||||
die "$(eval_gettext "unknown option: \$opt")"
|
||||
FLAGS="${FLAGS}${FLAGS:+ }$opt"
|
||||
;;
|
||||
*)
|
||||
REV="${REV}${REV:+ }'$opt'"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
eval set -- $REV
|
||||
|
||||
case $# in
|
||||
0)
|
||||
have_stash || die "$(gettext "No stash entries found.")"
|
||||
set -- ${ref_stash}@{0}
|
||||
;;
|
||||
1)
|
||||
:
|
||||
;;
|
||||
*)
|
||||
die "$(eval_gettext "Too many revisions specified: \$REV")"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
*[!0-9]*)
|
||||
:
|
||||
;;
|
||||
*)
|
||||
set -- "${ref_stash}@{$1}"
|
||||
;;
|
||||
esac
|
||||
|
||||
REV=$(git rev-parse --symbolic --verify --quiet "$1") || {
|
||||
reference="$1"
|
||||
die "$(eval_gettext "\$reference is not a valid reference")"
|
||||
}
|
||||
|
||||
i_commit=$(git rev-parse --verify --quiet "$REV^2") &&
|
||||
set -- $(git rev-parse "$REV" "$REV^1" "$REV:" "$REV^1:" "$REV^2:" 2>/dev/null) &&
|
||||
s=$1 &&
|
||||
w_commit=$1 &&
|
||||
b_commit=$2 &&
|
||||
w_tree=$3 &&
|
||||
b_tree=$4 &&
|
||||
i_tree=$5 &&
|
||||
IS_STASH_LIKE=t &&
|
||||
test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
|
||||
IS_STASH_REF=t
|
||||
|
||||
u_commit=$(git rev-parse --verify --quiet "$REV^3") &&
|
||||
u_tree=$(git rev-parse "$REV^3:" 2>/dev/null)
|
||||
}
|
||||
|
||||
is_stash_like()
|
||||
{
|
||||
parse_flags_and_rev "$@"
|
||||
test -n "$IS_STASH_LIKE"
|
||||
}
|
||||
|
||||
assert_stash_like() {
|
||||
is_stash_like "$@" || {
|
||||
args="$*"
|
||||
die "$(eval_gettext "'\$args' is not a stash-like commit")"
|
||||
}
|
||||
}
|
||||
|
||||
is_stash_ref() {
|
||||
is_stash_like "$@" && test -n "$IS_STASH_REF"
|
||||
}
|
||||
|
||||
assert_stash_ref() {
|
||||
is_stash_ref "$@" || {
|
||||
args="$*"
|
||||
die "$(eval_gettext "'\$args' is not a stash reference")"
|
||||
}
|
||||
}
|
||||
|
||||
apply_stash () {
|
||||
|
||||
assert_stash_like "$@"
|
||||
|
||||
git update-index -q --refresh || die "$(gettext "unable to refresh index")"
|
||||
|
||||
# current index state
|
||||
c_tree=$(git write-tree) ||
|
||||
die "$(gettext "Cannot apply a stash in the middle of a merge")"
|
||||
|
||||
unstashed_index_tree=
|
||||
if test -n "$INDEX_OPTION" && test "$b_tree" != "$i_tree" &&
|
||||
test "$c_tree" != "$i_tree"
|
||||
then
|
||||
git diff-tree --binary $s^2^..$s^2 | git apply --cached
|
||||
test $? -ne 0 &&
|
||||
die "$(gettext "Conflicts in index. Try without --index.")"
|
||||
unstashed_index_tree=$(git write-tree) ||
|
||||
die "$(gettext "Could not save index tree")"
|
||||
git reset
|
||||
fi
|
||||
|
||||
if test -n "$u_tree"
|
||||
then
|
||||
GIT_INDEX_FILE="$TMPindex" git read-tree "$u_tree" &&
|
||||
GIT_INDEX_FILE="$TMPindex" git checkout-index --all &&
|
||||
rm -f "$TMPindex" ||
|
||||
die "$(gettext "Could not restore untracked files from stash entry")"
|
||||
fi
|
||||
|
||||
eval "
|
||||
GITHEAD_$w_tree='Stashed changes' &&
|
||||
GITHEAD_$c_tree='Updated upstream' &&
|
||||
GITHEAD_$b_tree='Version stash was based on' &&
|
||||
export GITHEAD_$w_tree GITHEAD_$c_tree GITHEAD_$b_tree
|
||||
"
|
||||
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
|
||||
fi
|
||||
if git merge-recursive $b_tree -- $c_tree $w_tree
|
||||
then
|
||||
# No conflict
|
||||
if test -n "$unstashed_index_tree"
|
||||
then
|
||||
git read-tree "$unstashed_index_tree"
|
||||
else
|
||||
a="$TMP-added" &&
|
||||
git diff-index --cached --name-only --diff-filter=A $c_tree >"$a" &&
|
||||
git read-tree --reset $c_tree &&
|
||||
git update-index --add --stdin <"$a" ||
|
||||
die "$(gettext "Cannot unstage modified files")"
|
||||
rm -f "$a"
|
||||
fi
|
||||
squelch=
|
||||
if test -n "$GIT_QUIET"
|
||||
then
|
||||
squelch='>/dev/null 2>&1'
|
||||
fi
|
||||
(cd "$START_DIR" && eval "git status $squelch") || :
|
||||
else
|
||||
# Merge conflict; keep the exit status from merge-recursive
|
||||
status=$?
|
||||
git rerere
|
||||
if test -n "$INDEX_OPTION"
|
||||
then
|
||||
gettextln "Index was not unstashed." >&2
|
||||
fi
|
||||
exit $status
|
||||
fi
|
||||
}
|
||||
|
||||
pop_stash() {
|
||||
assert_stash_ref "$@"
|
||||
|
||||
if apply_stash "$@"
|
||||
then
|
||||
drop_stash "$@"
|
||||
else
|
||||
status=$?
|
||||
say "$(gettext "The stash entry is kept in case you need it again.")"
|
||||
exit $status
|
||||
fi
|
||||
}
|
||||
|
||||
drop_stash () {
|
||||
assert_stash_ref "$@"
|
||||
|
||||
git reflog delete --updateref --rewrite "${REV}" &&
|
||||
say "$(eval_gettext "Dropped \${REV} (\$s)")" ||
|
||||
die "$(eval_gettext "\${REV}: Could not drop stash entry")"
|
||||
|
||||
# clear_stash if we just dropped the last stash entry
|
||||
git rev-parse --verify --quiet "$ref_stash@{0}" >/dev/null ||
|
||||
clear_stash
|
||||
}
|
||||
|
||||
apply_to_branch () {
|
||||
test -n "$1" || die "$(gettext "No branch name specified")"
|
||||
branch=$1
|
||||
shift 1
|
||||
|
||||
set -- --index "$@"
|
||||
assert_stash_like "$@"
|
||||
|
||||
git checkout -b $branch $REV^ &&
|
||||
apply_stash "$@" && {
|
||||
test -z "$IS_STASH_REF" || drop_stash "$@"
|
||||
}
|
||||
}
|
||||
|
||||
test "$1" = "-p" && set "push" "$@"
|
||||
|
||||
PARSE_CACHE='--not-parsed'
|
||||
# The default command is "push" if nothing but options are given
|
||||
seen_non_option=
|
||||
for opt
|
||||
do
|
||||
case "$opt" in
|
||||
--) break ;;
|
||||
-*) ;;
|
||||
*) seen_non_option=t; break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -n "$seen_non_option" || set "push" "$@"
|
||||
|
||||
# Main command set
|
||||
case "$1" in
|
||||
list)
|
||||
shift
|
||||
list_stash "$@"
|
||||
;;
|
||||
show)
|
||||
shift
|
||||
show_stash "$@"
|
||||
;;
|
||||
save)
|
||||
shift
|
||||
save_stash "$@"
|
||||
;;
|
||||
push)
|
||||
shift
|
||||
push_stash "$@"
|
||||
;;
|
||||
apply)
|
||||
shift
|
||||
apply_stash "$@"
|
||||
;;
|
||||
clear)
|
||||
shift
|
||||
clear_stash "$@"
|
||||
;;
|
||||
create)
|
||||
shift
|
||||
create_stash -m "$*" && echo "$w_commit"
|
||||
;;
|
||||
store)
|
||||
shift
|
||||
store_stash "$@"
|
||||
;;
|
||||
drop)
|
||||
shift
|
||||
drop_stash "$@"
|
||||
;;
|
||||
pop)
|
||||
shift
|
||||
pop_stash "$@"
|
||||
;;
|
||||
branch)
|
||||
shift
|
||||
apply_to_branch "$@"
|
||||
;;
|
||||
*)
|
||||
case $# in
|
||||
0)
|
||||
push_stash &&
|
||||
say "$(gettext "(To restore them type \"git stash apply\")")"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@@ -101,6 +101,7 @@ $LONG_USAGE")"
|
||||
case "$1" in
|
||||
-h)
|
||||
echo "$LONG_USAGE"
|
||||
case "$0" in *git-legacy-stash) exit 129;; esac
|
||||
exit
|
||||
esac
|
||||
fi
|
||||
|
||||
7
git.c
7
git.c
@@ -550,7 +550,12 @@ static struct cmd_struct commands[] = {
|
||||
{ "show-index", cmd_show_index },
|
||||
{ "show-ref", cmd_show_ref, RUN_SETUP },
|
||||
{ "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
|
||||
/*
|
||||
* NEEDSWORK: Until the builtin stash is thoroughly robust and no
|
||||
* longer needs redirection to the stash shell script this is kept as
|
||||
* is, then should be changed to RUN_SETUP | NEED_WORK_TREE
|
||||
*/
|
||||
{ "stash", cmd_stash },
|
||||
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "stripspace", cmd_stripspace },
|
||||
{ "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
|
||||
|
||||
@@ -4637,7 +4637,7 @@ static int rewrite_file(const char *path, const char *buf, size_t len)
|
||||
}
|
||||
|
||||
/* skip picking commits whose parents are unchanged */
|
||||
static int skip_unnecessary_picks(struct object_id *output_oid)
|
||||
int skip_unnecessary_picks(struct object_id *output_oid)
|
||||
{
|
||||
const char *todo_file = rebase_path_todo();
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
@@ -128,3 +128,5 @@ void print_commit_summary(const char *prefix, const struct object_id *oid,
|
||||
void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);
|
||||
int write_basic_state(struct replay_opts *opts, const char *head_name,
|
||||
const char *onto, const char *orig_head);
|
||||
|
||||
int skip_unnecessary_picks(struct object_id *output_oid);
|
||||
Reference in New Issue
Block a user