From: Junio C Hamano <gitster@pobox.com>
To: Stephan Beyer <s-beyer@gmx.net>
Cc: git@vger.kernel.org,
Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Daniel Barkalow <barkalow@iabervon.org>,
Christian Couder <chriscool@tuxfamily.org>
Subject: Re: [RFC/PATCH 1/4] Add git-sequencer shell prototype
Date: Wed, 02 Jul 2008 18:45:06 -0700 [thread overview]
Message-ID: <7vbq1f68rh.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: 1214879914-17866-2-git-send-email-s-beyer@gmx.net
Stephan Beyer <s-beyer@gmx.net> writes:
> git sequencer is planned as a backend for user scripts
> that execute a sequence of git instructions and perhaps
> need manual intervention, for example git-rebase or git-am.
...
> +output () {
> + case "$VERBOSE" in
> + 0)
> + "$@" >/dev/null
> + ;;
> + 1)
> + output=$("$@" 2>&1 )
> + status=$?
> + test $status -ne 0 && printf '%s\n' "$output"
> + return $status
> + ;;
> + 2)
> + "$@"
> + ;;
> + esac
> +}
Perhaps misnamed? This feels more like "do" or "perform" or "run".
> +require_clean_work_tree () {
> + # test if working tree is dirty
> + git rev-parse --verify HEAD >/dev/null &&
> + git update-index --ignore-submodules --refresh &&
> + git diff-files --quiet --ignore-submodules &&
> + git diff-index --cached --quiet HEAD --ignore-submodules -- ||
> + die 'Working tree is dirty'
> +}
When is it necessary to ignore submodules and why? Are there cases where
submodules should not be ignored?
> +LAST_COUNT=
> +mark_action_done () {
> + sed -e 1q <"$TODO" >>"$DONE"
> + sed -e 1d <"$TODO" >"$TODO.new"
> + mv -f "$TODO.new" "$TODO"
> + if test "$VERBOSE" -gt 0
> + then
> + count=$(grep -c '^[^#]' <"$DONE")
> + total=$(expr "$count" + "$(grep -c '^[^#]' <"$TODO")")
Here we are not counting lines that are comments as insns (I am not
complaining; just making a mental note).
> + if test "$LAST_COUNT" != "$count"
> + then
> + LAST_COUNT="$count"
> + test "$VERBOSE" -lt 1 ||
> + printf 'Sequencing (%d/%d)\r' "$count" "$total"
> + test "$VERBOSE" -lt 2 || echo
> + fi
> + fi
> +}
> +
> +# Generate message, patch and author script files
> +make_patch () {
> + parent_sha1=$(git rev-parse --verify "$1"^) ||
> + die "Cannot get patch for $1^"
> + git diff-tree -p "$parent_sha1..$1" >"$PATCH"
Could there be a case where we need/want to deal with a root commit
without parents?
> + test -f "$MSG" ||
> + commit_message "$1" >"$MSG"
> + test -f "$AUTHOR_SCRIPT" ||
> + get_author_ident_from_commit "$1" >"$AUTHOR_SCRIPT"
> +}
> +
> +# Generate a patch and die with "conflict" status code
> +die_with_patch () {
> + make_patch "$1"
> + git rerere
> + die_to_continue "$2"
> +}
> +
> +restore () {
> + git rerere clear
> +
> + HEADNAME=$(cat "$SEQ_DIR/head-name")
> + HEAD=$(cat "$SEQ_DIR/head")
Perhaps
read HEADNAME <"$SEQ_DIR/head-name"
provided if these values are $IFS safe?
> + case $HEADNAME in
> + refs/*)
> + git symbolic-ref HEAD "$HEADNAME"
> + ;;
> + esac &&
> + output git reset --hard "$HEAD"
> +}
> +
> +has_action () {
> + grep '^[^#]' "$1" >/dev/null
> +}
> +
> +# Check if text file $1 contains a commit message
> +has_message () {
> + test -n "$(sed -n -e '/^Signed-off-by:/d;/^[^#]/p' <"$1")"
> +}
Makes one wonder if we would want to special case other kinds like
"Acked-by:" as well...
> +# Usage: pick_one (cherry-pick|revert) [-*|--edit] sha1
> +pick_one () {
> + what="$1"
> + # we just assume that this is either cherry-pick or revert
> + shift
> +
> + # check for fast-forward if no options are given
> + if expr "x$1" : 'x[^-]' >/dev/null
> + then
> + test "$(git rev-parse --verify "$1^")" = \
> + "$(git rev-parse --verify HEAD)" &&
> + output git reset --hard "$1" &&
> + return
> + fi
> + test "$1" != '--edit' -a "$what" = 'revert' &&
> + what='revert --no-edit'
This looks somewhat wrong.
When the history looks like ---A---B and we are at A, cherry-picking B can
be optimized to just advancing to B, but that optimization has a slight
difference (or two) in the semantics.
(1) The committer information would not record the user and time of the
sequencer operation, which actually may be a good thing.
(2) When $what is revert, this codepath shouldn't be exercised, should it?
(3) If B is a merge, even if $what is pick, this codepath shouldn't be
exercised, should it?
As to the syntax I tend to prefer
case "$1" in
-*) ... do option thing ... ;;
*) ... do other thing... ;;
esac
So how about...
case "$what,$1" in
revert,--edit)
what='revert --no-edit' ;;
revert,* | cherry-pick,-* )
;;
*)
if ! git rev-parse --verify "$1^2" &&
test "$(git rev-parse --verify "$1^") = \
"$(git rev-parse --verify HEAD)"
then
output git reset --hard "$1"
return
fi
;;
esac
> +make_squash_message () {
> + if test -f "$squash_msg"
> + then
> + count=$(($(sed -n -e 's/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p' \
> + <"$squash_msg" | sed -n -e '$p')+1))
> + echo "# This is a combination of $count commits."
> + sed -e '1d' -e '2,/^./{
> + /^$/d
> + }' <"$squash_msg"
> + else
> + count=2
> + echo '# This is a combination of 2 commits.'
> + echo '# The first commit message is:'
> + echo
> + commit_message HEAD
> + fi
> + echo
> + echo "# This is the $(nth_string "$count") commit message:"
> + echo
> + commit_message "$1"
> +}
> +
> +make_squash_message_multiple () {
> + echo '# This is a dummy to get the 0.' >"$squash_msg"
> + for cur_sha1 in $(git rev-list --reverse "$sha1..HEAD")
> + do
> + make_squash_message "$cur_sha1" >"$MSG"
> + cp "$MSG" "$squash_msg"
> + done
> +}
Hmm, I know this is how rebase-i is written, but we should be able to do
better than writing and flipping temporary times N times, shouldn't we?
> +peek_next_command () {
> + sed -n -e '1s/ .*$//p' <"$TODO"
> +}
... which could respond "the next command is '#' (comment)", so we are
actively counting a comment as a step here. Does this contradict with the
mental note we made earlier, and if so, does the discrepancy hurt us
somewhere in this program?
> +# If $1 is a mark, make a ref from it; otherwise keep it
> +mark_to_ref () {
> + arg="$1"
> + ref=$(expr "x$arg" : 'x:0*\([0-9][0-9]*\)$')
You might want to leave comments to describe constraints that led to this
slightly awkward regexp:
* :0 is allowed
* :01 is the same as :1
> +strategy_check () {
> + case "$1" in
> + resolve|recursive|octopus|ours|subtree|theirs)
> + return
> + ;;
> + esac
> + todo_warn "Strategy '$1' not known."
> +}
Hmm. Do we need to maintain list of available strategies here and then in
git-merge separately?
> +### Author script functions
> +
> +clean_author_script () {
> + cat "$ORIG_AUTHOR_SCRIPT" >"$AUTHOR_SCRIPT"
> +}
> +
> +# Take "Name <e-mail>" in stdin and outputs author script
> +make_author_script_from_string () {
> + sed -e 's/^\(.*\) <\(.*\)>.*$/GIT_AUTHOR_NAME="\1"\
> +GIT_AUTHOR_EMAIL="\2"\
> +GIT_AUTHOR_DATE=/'
> +}
If you are going to "."-source or eval the output from this, you would
need to quote the values a lot more robustly, wouldn't you? Is this safe
against shell metacharacters in names, mails and/or space between unixtime
and the timezone information?
> + if test -z "$AUTHOR"
> + then
> + sed -n -e '
> + s/^Author: \(.*\)$/GIT_AUTHOR_NAME="\1"/p;
> + s/^Email: \(.*\)$/GIT_AUTHOR_EMAIL="\1"/p;
> + s/^Date: \(.*\)$/GIT_AUTHOR_DATE="\1"/p
> + ' <"$infofile" >>"$AUTHOR_SCRIPT"
The same comment on quoting applies here, I think.
> + # If sed's result is empty, we keep the original
> + # author script by appending.
> + fi
> ...
> + failed=
> + with_author git apply $apply_opts --index "$PATCH" || failed=t
> +
> + if test -n "$failed" -a -n "$threeway" && (with_author fallback_3way)
> + then
> + # Applying the patch to an earlier tree and merging the
> + # result may have produced the same tree as ours.
> + git diff-index --quiet --cached HEAD -- && {
> + echo 'No changes -- Patch already applied.'
> + return 0
> + # XXX: do we want that?
> + }
> + # clear apply_status -- we have successfully merged.
> + failed=
> + fi
> +
> + if test -n "$failed"
> + then
> + # XXX: This is just a stupid hack:
> + with_author git apply $apply_opts --reject --index "$PATCH"
Please don't do this without being asked, if you are planning to use this
in "am" when 3-way fallback was not asked. It _may_ make sense to give an
option to the users to ask for .rej if they prefer to work that way better
than working with 3-way merge fallback, but doing this without being asked
is not acceptable.
> + die_to_continue 'Patch failed. See the .rej files.'
> + # XXX: We actually needed a git-apply flag that creates
> + # conflict markers and sets the DIFF_STATUS_UNMERGED flag.
That is what -3way is all about, and this codepath is when the user did
not ask for it, isn't it?
> +# Check the "pick" instruction
> +check_pick () {
> + revert=
> + mainline=
> + while test $# -gt 1
> + do
> ...
> + done
> +
> + if test -n "$mainline"
> + then
> + test -z "$revert" ||
> + todo_error "Cannot use $revert together with --mainline."
Why not? If you have this...
---A---C---D
/
---B
and you are at D, you may want to undo the merge you made at C and go back
to either A or B, which essentially is same as cherry-picking diff between
C and D on top of either A or B. Both are valid operations aren't they?
The remainder of the review will have to be in a separate message..
next prev parent reply other threads:[~2008-07-03 7:00 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-01 2:38 git sequencer prototype Stephan Beyer
2008-07-01 2:38 ` [RFC/PATCH 1/4] Add git-sequencer shell prototype Stephan Beyer
2008-07-01 2:38 ` [RFC/PATCH 2/4] Add git-sequencer prototype documentation Stephan Beyer
2008-07-01 2:38 ` [RFC/PATCH 3/4] Add git-sequencer test suite (t3350) Stephan Beyer
2008-07-01 2:38 ` [RFC/PATCH 4/4] Migrate git-am to use git-sequencer Stephan Beyer
2008-07-01 2:39 ` git-rebase-i migration to sequencer Stephan Beyer
2008-07-01 2:39 ` [PATCH 1/2] Make rebase--interactive use OPTIONS_SPEC Stephan Beyer
2008-07-01 2:39 ` [RFC/PATCH 2/2] Migrate git-rebase--i to use git-sequencer Stephan Beyer
2008-07-05 17:31 ` [RFC/PATCH 3/4] Add git-sequencer test suite (t3350) Stephan Beyer
2008-07-05 18:16 ` Junio C Hamano
2008-07-01 13:02 ` [RFC/PATCH 2/4] Add git-sequencer prototype documentation Jakub Narebski
2008-07-01 16:03 ` Stephan Beyer
2008-07-01 18:04 ` Jakub Narebski
2008-07-01 19:50 ` Stephan Beyer
2008-07-02 0:39 ` Jakub Narebski
2008-07-02 1:20 ` Junio C Hamano
2008-07-02 3:01 ` Stephan Beyer
2008-07-05 17:00 ` [PATCH v2 " Stephan Beyer
2008-07-08 10:37 ` Jakub Narebski
2008-07-08 11:49 ` Stephan Beyer
2008-07-09 5:20 ` Karl Hasselström
2008-07-03 1:45 ` Junio C Hamano [this message]
2008-07-03 11:03 ` [RFC/PATCH 1/4] Add git-sequencer shell prototype Johannes Schindelin
2008-07-03 21:09 ` Stephan Beyer
2008-07-03 22:11 ` Junio C Hamano
2008-07-03 22:34 ` Stephan Beyer
2008-07-03 23:53 ` Johannes Schindelin
2008-07-04 0:38 ` Stephan Beyer
2008-07-04 1:03 ` Johannes Schindelin
2008-07-04 1:53 ` Stephan Beyer
2008-07-04 15:19 ` [PATCH] Allow cherry-picking root commits Johannes Schindelin
2008-07-04 16:41 ` Stephan Beyer
2008-07-06 1:05 ` Junio C Hamano
2008-07-06 1:37 ` Johannes Schindelin
2008-07-06 11:32 ` t3503: Add test case for identical files Stephan Beyer
2008-07-06 11:35 ` [PATCH] Allow cherry-picking root commits Stephan Beyer
2008-07-06 12:48 ` Johannes Schindelin
2008-07-04 1:06 ` [RFC/PATCH 1/4] Add git-sequencer shell prototype Stephan Beyer
2008-07-04 1:11 ` Johannes Schindelin
2008-07-03 22:51 ` Junio C Hamano
2008-07-03 23:33 ` Stephan Beyer
2008-07-03 13:10 ` Jakub Narebski
2008-07-03 21:12 ` Stephan Beyer
2008-07-05 16:58 ` [PATCH v2 " Stephan Beyer
2008-07-01 8:51 ` git sequencer prototype Junio C Hamano
2008-07-01 14:53 ` Stephan Beyer
2008-07-04 21:00 ` Alex Riesen
2008-07-04 22:09 ` Junio C Hamano
2008-07-04 22:23 ` Stephan Beyer
2008-07-05 8:13 ` Alex Riesen
2008-07-05 10:12 ` Thomas Adam
2008-07-05 10:13 ` Johannes Schindelin
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=7vbq1f68rh.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=barkalow@iabervon.org \
--cc=chriscool@tuxfamily.org \
--cc=git@vger.kernel.org \
--cc=s-beyer@gmx.net \
/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).