From: Fabian Ruch <bafain@gmail.com>
To: Michael Haggerty <mhagger@alum.mit.edu>, git@vger.kernel.org
Cc: Johannes Schindelin <johannes.schindelin@gmx.de>
Subject: Re: [RFC PATCH 1/7] rebase -i: Make option handling in pick_one more flexible
Date: Sun, 22 Jun 2014 01:21:30 +0200 [thread overview]
Message-ID: <53A6137A.7040803@gmail.com> (raw)
In-Reply-To: <53A439B2.7000106@alum.mit.edu>
Hi Michael,
On 06/20/2014 03:40 PM, Michael Haggerty wrote:
> On 06/19/2014 05:28 AM, Fabian Ruch wrote:
>> `pick_one` and `pick_one_preserving_merges` are wrappers around
>> `cherry-pick` in `rebase --interactive`. They take the hash of a commit
>> and build a `cherry-pick` command line that
>>
>> - respects the user-supplied merge options
>> - disables complaints about empty commits
>> - tries to fast-forward the rebase head unless rebase is forced
>> - suppresses output unless the user requested higher verbosity
>> - rewrites merge commits to point to their rebased parents.
>>
>> `pick_one` is used to implement not only `pick` but also `squash`, which
>> amends the previous commit rather than creating a new one. When
>> `pick_one` is called from `squash`, it receives a second argument `-n`.
>> This tells `pick_one` to apply the changes to the index without
>> committing them. Since the argument is almost directly passed to
>> `cherry-pick`, we might want to do the same with other `cherry-pick`
>> options. Currently, `pick_one` expects `-n` to be the first and only
>> argument except for the commit hash.
>>
>> Prepare `pick_one` for additional `cherry-pick` options by allowing `-n`
>> to appear anywhere before the commit hash in the argument list. Loop
>> over the argument list and pop each handled item until the commit hash
>> is the only parameter left on the list. If an option is not supported,
>> ignore it and issue a warning on the console. Construct a new arguments
>> list `extra_args` of recognized options that shall be passed to
>> `cherry-pick` on the command line.
>>
>> Signed-off-by: Fabian Ruch <bafain@gmail.com>
>> ---
>> git-rebase--interactive.sh | 61 ++++++++++++++++++++++++++++++++++------------
>> 1 file changed, 45 insertions(+), 16 deletions(-)
>>
>> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
>> index f267d8b..ea5514e 100644
>> --- a/git-rebase--interactive.sh
>> +++ b/git-rebase--interactive.sh
>> @@ -237,8 +237,26 @@ git_sequence_editor () {
>>
>> pick_one () {
>> ff=--ff
>> + extra_args=
>> + while test $# -gt 0
>> + do
>> + case "$1" in
>> + -n)
>> + ff=
>> + extra_args="$extra_args -n"
>> + ;;
>> + -*)
>> + warn "pick_one: ignored option -- $1"
>> + ;;
>
> This is an internal interface, right? I.e., user input isn't being
> processed here? If so, then the presence of an unrecognized option is a
> bug and it is preferable to "die" here rather than "warn".
>
> The same below and in at least one later commit.
Ok.
>> + *)
>> + break
>> + ;;
>> + esac
>> + shift
>> + done
>> + test $# -ne 1 && die "pick_one: wrong number of arguments"
>> + sha1=$1
>>
>> - case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac
>> case "$force_rebase" in '') ;; ?*) ff= ;; esac
>> output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
>>
>> @@ -248,24 +266,35 @@ pick_one () {
>> fi
>>
>> test -d "$rewritten" &&
>> - pick_one_preserving_merges "$@" && return
>> + pick_one_preserving_merges $extra_args $sha1 && return
>> output eval git cherry-pick \
>> ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
>> - "$strategy_args" $empty_args $ff "$@"
>> + "$strategy_args" $empty_args $ff $extra_args $sha1
>> }
>
> It might be confusing that extra_args is used both in pick_one and in
> pick_one_preserving_merges. Since these are not local variables, the
> call to the latter changes the value of the variable in the former. I
> don't know if that could be a problem now (can
> pick_one_preserving_merges return with a nonzero exit code?) but even if
> not, it is a trap for future developers. I recommend giving the two
> variables different names.
Please correct me if I missed something. At the moment (786a89d),
pick_one_preserving_merges will not and cannot return with a non-zero
exit code because it doesn't explicitly return and all possibly failing
last statements are guarded with a ... || die "...". Since this can only
be established by carefully looking at the code, I will change the reuse
of extra_args.
Now that we're at it, what I didn't understand when creating this patch
was why the code doesn't explicitly say "one or the other" in the first
place:
> if test -d "$rewritten"
> then
> pick_one_preserving_merges "$@"
> else
> output eval git cherry-pick \
> ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
> "$strategy_args" $empty_args $ff "$@"
> fi
At least that is how I interpreted it. After all, if
pick_one_preserving_merges failed to recreate a merge commit, wouldn't
it be a bug to record the changes in a single-parent commit?
Johannes, I cc'd you this email since you're the author of f09c9b8 -
"Teach rebase -i about --preserve-merges". I hope you don't resent me
digging out this seven-year-old patch.
Fabian
>> pick_one_preserving_merges () {
>> fast_forward=t
>> - case "$1" in
>> - -n)
>> - fast_forward=f
>> - sha1=$2
>> - ;;
>> - *)
>> - sha1=$1
>> - ;;
>> - esac
>> - sha1=$(git rev-parse $sha1)
>> + no_commit=
>> + extra_args=
>> + while test $# -gt 0
>> + do
>> + case "$1" in
>> + -n)
>> + fast_forward=f
>> + extra_args="$extra_args -n"
>> + no_commit=y
>> + ;;
>> + -*)
>> + warn "pick_one_preserving_merges: ignored option -- $1"
>> + ;;
>> + *)
>> + break
>> + ;;
>> + esac
>> + shift
>> + done
>> + test $# -ne 1 && die "pick_one_preserving_merges: wrong number of arguments"
>> + sha1=$(git rev-parse $1)
>>
>> if test -f "$state_dir"/current-commit
>> then
>> @@ -335,7 +364,7 @@ pick_one_preserving_merges () {
>> f)
>> first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
>>
>> - if [ "$1" != "-n" ]
>> + if test -z "$no_commit"
>> then
>> # detach HEAD to current parent
>> output git checkout $first_parent 2> /dev/null ||
>> @@ -344,7 +373,7 @@ pick_one_preserving_merges () {
>>
>> case "$new_parents" in
>> ' '*' '*)
>> - test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
>> + test -n "$no_commit" && die "Refusing to squash a merge: $sha1"
>>
>> # redo merge
>> author_script_content=$(get_author_ident_from_commit $sha1)
>> @@ -365,7 +394,7 @@ pick_one_preserving_merges () {
>> *)
>> output eval git cherry-pick \
>> ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
>> - "$strategy_args" "$@" ||
>> + "$strategy_args" $extra_args $sha1 ||
>> die_with_patch $sha1 "Could not pick $sha1"
>> ;;
>> esac
>>
next prev parent reply other threads:[~2014-06-21 23:21 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1403146774.git.bafain@gmail.com>
2014-06-19 3:28 ` [RFC PATCH 1/7] rebase -i: Make option handling in pick_one more flexible Fabian Ruch
2014-06-20 13:40 ` Michael Haggerty
2014-06-20 19:53 ` Junio C Hamano
2014-06-23 0:04 ` Fabian Ruch
2014-06-21 23:21 ` Fabian Ruch [this message]
2014-06-23 16:09 ` Johannes Schindelin
2014-06-19 3:28 ` [RFC PATCH 2/7] rebase -i: Teach do_pick the option --edit Fabian Ruch
2014-06-20 13:41 ` Michael Haggerty
2014-06-22 0:09 ` Fabian Ruch
2014-06-19 3:28 ` [RFC PATCH 3/7] rebase -i: Stop on root commits with empty log messages Fabian Ruch
2014-06-21 0:33 ` Eric Sunshine
2014-06-22 0:32 ` Fabian Ruch
2014-06-19 3:28 ` [RFC PATCH 4/7] rebase -i: Commit only once when rewriting picks Fabian Ruch
2014-06-19 3:28 ` [RFC PATCH 5/7] rebase -i: Do not die in do_pick Fabian Ruch
2014-06-19 3:28 ` [RFC PATCH 6/7] rebase -i: Prepare for squash in terms of do_pick --amend Fabian Ruch
2014-06-19 3:28 ` [RFC PATCH 7/7] rebase -i: Teach do_pick the options --amend and --file Fabian Ruch
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=53A6137A.7040803@gmail.com \
--to=bafain@gmail.com \
--cc=git@vger.kernel.org \
--cc=johannes.schindelin@gmx.de \
--cc=mhagger@alum.mit.edu \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.