From: Jon Seymour <jon.seymour@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, j6t@kdbg.org, Jon Seymour <jon.seymour@gmail.com>
Subject: [PATCH v5 1/8] detached-stash: introduce parse_flags_and_revs function
Date: Wed, 18 Aug 2010 23:09:33 +1000 [thread overview]
Message-ID: <1282136980-25793-2-git-send-email-jon.seymour@gmail.com> (raw)
In-Reply-To: <1282136980-25793-1-git-send-email-jon.seymour@gmail.com>
Introduce parse_flags_and_revs. This function requires that
there is at at most one stash-like revision parameter and
sero or more flags.
It knows how to parse -q,--quiet and --index flags, but leaves
other flags unparsed.
Specified revisions are checked to see that they are at least stash-like
(meaning: they look like something created by git stash save or git stash
create).
If this is so, then IS_STASH_LIKE is initialized to a non-empty value.
If the specified revision also looks like a stash log entry reference,
then IS_STASH_REF is initialized to a non-empty value.
References of the form ref@{spec} are required to precisely identify
an individual commit.
If no reference is specified, stash@{0} is assumed.
Once the specified reference is validated to be at least stash_like
a ensemble of derived variables, (w_commit, w_tree, b_commit, etc)
are initialized with a single call to git rev-parse.
Repeated calls to parse_flags_and_rev() avoid repeated calls
to git rev-parse if the specified arguments have already been
parsed.
An ensemble of supporting functions that make use of the state
established by parse_flags_and_rev(). These are describe below.
Subsequent patches in the series modify the existing
git stash subcommands to make use of these functions as appropriate.
The ancillary functions are:
is_stash_like(): which can be used to test
whether a specified commit looks like a commit created with
git stash save or git stash create.
assert_stash_like(): which can be used by
commands that misbehave unless their arguments stash-like.
is_stash_ref(): which checks whether an argument
is valid stash reference(e.g. is of the form
['refs/']stash['@{'something'}])
assert_stash_ref(): which can be used by commands
that misbehave unless their arguments are both stash-like and
refer to valid stash entries.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
git-stash.sh | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 133 insertions(+), 0 deletions(-)
diff --git a/git-stash.sh b/git-stash.sh
index 1d95447..42b0da2 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -225,6 +225,138 @@ show_stash () {
git diff $flags $b_commit $w_commit
}
+#
+# 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
+# w_tree is set to the working tree
+# b_tree is set to the base tree
+# i_tree is set to the index 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
+#
+# 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
+#
+
+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=
+ w_tree=
+ b_tree=
+ i_tree=
+
+ REV=$(git rev-parse --no-flags --symbolic "$@" 2>/dev/null)
+ FLAGS=$(git rev-parse --no-revs -- "$@" 2>/dev/null)
+
+ set -- $FLAGS
+
+ FLAGS=
+ while test $# -ne 0
+ do
+ case "$1" in
+ -q|--quiet)
+ GIT_QUIET=-t
+ ;;
+ --index)
+ INDEX_OPTION=--index
+ ;;
+ --)
+ :
+ ;;
+ *)
+ FLAGS="${FLAGS}${FLAGS:+ }$1"
+ ;;
+ esac
+ shift
+ done
+
+ set -- $REV
+
+ case $# in
+ 0)
+ have_stash || die "No stash found."
+ set -- ${ref_stash}@{0}
+ ;;
+ 1)
+ :
+ ;;
+ *)
+ die "Too many revisions specified: $REV"
+ ;;
+ esac
+
+ REV=$(git rev-parse --quiet --symbolic --verify $1 2>/dev/null) || die "$1 is not valid reference"
+
+ i_commit=$(git rev-parse --quiet --verify $REV^2 2>/dev/null) &&
+ 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
+
+ if test "${REV}" != "${REV%{*\}}"
+ then
+ # maintainers: it would be better if git rev-parse indicated
+ # this condition with a non-zero status code but as of 1.7.2.1 it
+ # it did not. So, we use non-empty stderr output as a proxy for the
+ # condition of interest.
+ test -z "$(git rev-parse "$REV" 2>&1 >/dev/null)" || die "$REV does not exist in the stash log"
+ fi
+
+}
+
+is_stash_like()
+{
+ parse_flags_and_rev "$@"
+ test -n "$IS_STASH_LIKE"
+}
+
+assert_stash_like() {
+ is_stash_like "$@" || die "'$*' is not a stash-like commit"
+}
+
+is_stash_ref() {
+ is_stash_like "$@" && test -n "$IS_STASH_REF"
+}
+
+assert_stash_ref() {
+ is_stash_ref "$@" || die "'$*' is not a stash reference"
+}
+
apply_stash () {
applied_stash=
unstash_index=
@@ -375,6 +507,7 @@ apply_to_branch () {
drop_stash $stash
}
+PARSE_CACHE='--not-parsed'
# The default command is "save" if nothing but options are given
seen_non_option=
for opt
--
1.7.2.1.95.g4fabf
next prev parent reply other threads:[~2010-08-18 13:10 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-18 13:09 [PATCH v5 0/8] detached-stash: regularise handling of stash arguments by git stash Jon Seymour
2010-08-18 13:09 ` Jon Seymour [this message]
2010-08-18 13:09 ` [PATCH v5 2/8] detached-stash: simplify stash_apply Jon Seymour
2010-08-18 13:09 ` [PATCH v5 3/8] detached-stash: simplify stash_drop Jon Seymour
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1282136980-25793-2-git-send-email-jon.seymour@gmail.com \
--to=jon.seymour@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=j6t@kdbg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).