From: Junio C Hamano Date: Thu, 18 Jul 2013 19:48:20 +0000 (-0700) Subject: Merge branch 'rr/rebase-reflog-message-reword' X-Git-Tag: v1.8.4-rc0~50 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/afbfcaa98396de66e42dc3c845f396c5ba508ced?ds=inline;hp=-c Merge branch 'rr/rebase-reflog-message-reword' "git rebase [-i]" used to leave just "rebase" as its reflog message for some operations. This rewords them to be more informative. * rr/rebase-reflog-message-reword: rebase -i: use a better reflog message rebase: use a better reflog message --- afbfcaa98396de66e42dc3c845f396c5ba508ced diff --combined git-rebase--interactive.sh index 157690b685,a975529353..83d6d4676b --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@@ -80,18 -80,6 +80,18 @@@ amend="$state_dir"/amen rewritten_list="$state_dir"/rewritten-list rewritten_pending="$state_dir"/rewritten-pending +strategy_args= +if test -n "$do_merge" +then + strategy_args=${strategy:+--strategy=$strategy} + eval ' + for strategy_opt in '"$strategy_opts"' + do + strategy_args="$strategy_args -X$(git rev-parse --sq-quote "${strategy_opt#--}")" + done + ' +fi + GIT_CHERRY_PICK_HELP="$resolvemsg" export GIT_CHERRY_PICK_HELP @@@ -251,7 -239,7 +251,7 @@@ pick_one () test -d "$rewritten" && pick_one_preserving_merges "$@" && return - output git cherry-pick $empty_args $ff "$@" + output eval git cherry-pick "$strategy_args" $empty_args $ff "$@" } pick_one_preserving_merges () { @@@ -352,8 -340,9 +352,8 @@@ msg_content="$(commit_message $sha1)" # No point in merging the first parent, that's HEAD new_parents=${new_parents# $first_parent} - if ! do_with_author output \ - git merge --no-ff ${strategy:+-s $strategy} -m \ - "$msg_content" $new_parents + if ! do_with_author output eval \ + 'git merge --no-ff $strategy_args -m "$msg_content" $new_parents' then printf "%s\n" "$msg_content" > "$GIT_DIR"/MERGE_MSG die_with_patch $sha1 "Error redoing merge $sha1" @@@ -361,7 -350,7 +361,7 @@@ echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list" ;; *) - output git cherry-pick "$@" || + output eval git cherry-pick "$strategy_args" "$@" || die_with_patch $sha1 "Could not pick $sha1" ;; esac @@@ -639,16 -628,17 +639,16 @@@ do_next () "$GIT_DIR"/hooks/post-rewrite rebase < "$rewritten_list" true # we don't care if this hook failed fi && - rm -rf "$state_dir" && - git gc --auto && warn "Successfully rebased and updated $head_name." - exit + return 1 # not failure; just to break the do_rest loop } +# can only return 0, when the infinite loop breaks do_rest () { while : do - do_next + do_next || break done } @@@ -700,22 -690,8 +700,22 @@@ rearrange_squash () case "$message" in "squash! "*|"fixup! "*) action="${message%%!*}" - rest="${message#*! }" - echo "$sha1 $action $rest" + rest=$message + prefix= + # skip all squash! or fixup! (but save for later) + while : + do + case "$rest" in + "squash! "*|"fixup! "*) + prefix="$prefix${rest%%!*}," + rest="${rest#*! }" + ;; + *) + break + ;; + esac + done + echo "$sha1 $action $prefix $rest" # if it's a single word, try to resolve to a full sha1 and # emit a second copy. This allows us to match on both message # and on sha1 prefix @@@ -724,7 -700,7 +724,7 @@@ if test -n "$fullsha"; then # prefix the action to uniquely identify this line as # intended for full sha1 match - echo "$sha1 +$action $fullsha" + echo "$sha1 +$action $prefix $fullsha" fi fi esac @@@ -739,7 -715,7 +739,7 @@@ esac printf '%s\n' "$pick $sha1 $message" used="$used$sha1 " - while read -r squash action msg_content + while read -r squash action msg_prefix msg_content do case " $used" in *" $squash "*) continue ;; @@@ -755,8 -731,7 +755,8 @@@ case "$message" in "$msg_content"*) emit=1;; esac ;; esac if test $emit = 1; then - printf '%s\n' "$action $squash $action! $msg_content" + real_prefix=$(echo "$msg_prefix" | sed "s/,/! /g") + printf '%s\n' "$action $squash ${real_prefix}$msg_content" used="$used$squash " fi done <"$1.sq" @@@ -830,13 -805,11 +830,13 @@@ first and then run 'git rebase --contin require_clean_work_tree "rebase" do_rest + return 0 ;; skip) git rerere clear do_rest + return 0 ;; edit-todo) git stripspace --strip-comments <"$todo" >"$todo".new @@@ -864,12 -837,15 +864,15 @@@ comment_for_reflog star if test ! -z "$switch_to" then + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" output git checkout "$switch_to" -- || - die "Could not checkout $switch_to" + die "Could not checkout $switch_to" + + comment_for_reflog start fi orig_head=$(git rev-parse --verify HEAD) || die "No HEAD?" -mkdir "$state_dir" || die "Could not create temporary $state_dir" +mkdir -p "$state_dir" || die "Could not create temporary $state_dir" : > "$state_dir"/interactive || die "Could not mark as interactive" write_basic_state @@@ -1007,6 -983,7 +1010,7 @@@ has_action "$todo" | test -d "$rewritten" || test -n "$force_rebase" || skip_unnecessary_picks + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" output git checkout $onto || die_abort "could not detach HEAD" git update-ref ORIG_HEAD $orig_head do_rest diff --combined git-rebase.sh index 81b0346a5d,79f526eb9a..0039ecfb40 --- a/git-rebase.sh +++ b/git-rebase.sh @@@ -13,7 -13,6 +13,7 @@@ git-rebase --continue | --abort | --ski Available options are v,verbose! display a diffstat of what changed upstream q,quiet! be quiet. implies --no-stat +autostash! automatically stash/stash pop before and after onto=! rebase onto given branch instead of upstream p,preserve-merges! try to recreate merges instead of ignoring them s,strategy=! use the given merge strategy @@@ -65,7 -64,6 +65,7 @@@ apply_dir="$GIT_DIR"/rebase-appl verbose= diffstat= test "$(git config --bool rebase.stat)" = true && diffstat=t +autostash="$(git config --bool rebase.autostash || echo false)" git_am_opt= rebase_root= force_rebase= @@@ -84,8 -82,6 +84,8 @@@ keep_empty test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t read_basic_state () { + test -f "$state_dir/head-name" && + test -f "$state_dir/onto" && head_name=$(cat "$state_dir"/head-name) && onto=$(cat "$state_dir"/onto) && # We always write to orig-head, but interactive rebase used to write to @@@ -147,26 -143,6 +147,26 @@@ move_to_original_branch () esac } +finish_rebase () { + if test -f "$state_dir/autostash" + then + stash_sha1=$(cat "$state_dir/autostash") + if git stash apply $stash_sha1 2>&1 >/dev/null + then + echo "$(gettext 'Applied autostash.')" + else + git stash store -m "autostash" -q $stash_sha1 || + die "$(eval_gettext "Cannot store \$stash_sha1")" + gettext 'Applying autostash resulted in conflicts. +Your changes are safe in the stash. +You can run "git stash pop" or "git stash drop" it at any time. +' + fi + fi + git gc --auto && + rm -rf "$state_dir" +} + run_specific_rebase () { if [ "$interactive_rebase" = implied ]; then GIT_EDITOR=: @@@ -174,12 -150,6 +174,12 @@@ autosquash= fi . git-rebase--$type + ret=$? + if test $ret -eq 0 + then + finish_rebase + fi + exit $ret } run_pre_rebase_hook () { @@@ -271,9 -241,6 +271,9 @@@ d --stat) diffstat=t ;; + --autostash) + autostash=true + ;; -v) verbose=t diffstat=t @@@ -374,7 -341,7 +374,7 @@@ abort ;; esac output git reset --hard $orig_head - rm -r "$state_dir" + finish_rebase exit ;; edit-todo) @@@ -433,7 -400,7 +433,7 @@@ the shift ;; esac - upstream=`git rev-parse --verify "${upstream_name}^0"` || + upstream=$(peel_committish "${upstream_name}") || die "$(eval_gettext "invalid upstream \$upstream_name")" upstream_arg="$upstream_name" else @@@ -469,7 -436,7 +469,7 @@@ case "$onto_name" i fi ;; *) - onto=$(git rev-parse --verify "${onto_name}^0") || + onto=$(peel_committish "$onto_name") || die "$(eval_gettext "Does not point to a valid commit: \$onto_name")" ;; esac @@@ -513,18 -480,6 +513,18 @@@ case "$#" i ;; esac +if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null +then + stash_sha1=$(git stash create "autostash") || + die "$(gettext 'Cannot autostash')" + + mkdir -p "$state_dir" && + echo $stash_sha1 >"$state_dir/autostash" && + stash_abbrev=$(git rev-parse --short $stash_sha1) && + echo "$(eval_gettext 'Created autostash: $stash_abbrev')" && + git reset --hard +fi + require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")" # Now we are rebasing commits $upstream..$orig_head (or with --root, @@@ -542,9 -497,10 +542,11 @@@ the if test -z "$force_rebase" then # Lazily switch to the target branch if needed... - test -z "$switch_to" || git checkout "$switch_to" -- + test -z "$switch_to" || + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" \ + git checkout "$switch_to" -- say "$(eval_gettext "Current branch \$branch_name is up to date.")" + finish_rebase exit 0 else say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")" @@@ -568,7 -524,9 +570,9 @@@ test "$type" = interactive && run_speci # Detach HEAD and reset the tree say "$(gettext "First, rewinding head to replay your work on top of it...")" - git checkout -q "$onto^0" || die "could not detach HEAD" + + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \ + git checkout -q "$onto^0" || die "could not detach HEAD" git update-ref ORIG_HEAD $orig_head # If the $onto is a proper descendant of the tip of the branch, then @@@ -577,7 -535,6 +581,7 @@@ if test "$mb" = "$orig_head then say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")" move_to_original_branch + finish_rebase exit 0 fi diff --combined t/t3404-rebase-interactive.sh index 8a6ec039fe,971e21414c..49ccb38f88 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@@ -477,11 -477,19 +477,11 @@@ test_expect_success 'interrupted squas test $one = $(git rev-parse HEAD~2) ' -test_expect_success 'ignore patch if in upstream' ' - HEAD=$(git rev-parse HEAD) && - git checkout -b has-cherry-picked HEAD^ && +test_expect_success '--continue tries to commit, even for "edit"' ' echo unrelated > file7 && git add file7 && test_tick && git commit -m "unrelated change" && - git cherry-pick $HEAD && - EXPECT_COUNT=1 git rebase -i $HEAD && - test $HEAD = $(git rev-parse HEAD^) -' - -test_expect_success '--continue tries to commit, even for "edit"' ' parent=$(git rev-parse HEAD^) && test_tick && FAKE_LINES="edit 1" git rebase -i HEAD^ && @@@ -684,7 -692,7 +684,7 @@@ test_expect_success 'rebase -i can cop test_commit n2 && test_commit n3 && git notes add -m"a note" n3 && - git rebase --onto n1 n2 && + git rebase -i --onto n1 n2 && test "a note" = "$(git notes show HEAD)" ' @@@ -926,6 -934,21 +926,21 @@@ test_expect_success 'rebase --edit-tod test L = $(git cat-file commit HEAD | sed -ne \$p) ' + test_expect_success 'rebase -i produces readable reflog' ' + git reset --hard && + git branch -f branch-reflog-test H && + git rebase -i --onto I F branch-reflog-test && + cat >expect <<-\EOF && + rebase -i (start): checkout I + rebase -i (pick): G + rebase -i (pick): H + rebase -i (finish): returning to refs/heads/branch-reflog-test + EOF + tail -n 4 .git/logs/HEAD | + sed -e "s/.* //" >actual && + test_cmp expect actual + ' + test_expect_success 'rebase -i respects core.commentchar' ' git reset --hard && git checkout E^0 && @@@ -939,26 -962,4 +954,26 @@@ test B = $(git cat-file commit HEAD^ | sed -ne \$p) ' +test_expect_success 'rebase -i, with and specified as :/quuxery' ' + test_when_finished "git branch -D torebase" && + git checkout -b torebase branch1 && + upstream=$(git rev-parse ":/J") && + onto=$(git rev-parse ":/A") && + git rebase --onto $onto $upstream && + git reset --hard branch1 && + git rebase --onto ":/A" ":/J" && + git checkout branch1 +' + +test_expect_success 'rebase -i with --strategy and -X' ' + git checkout -b conflict-merge-use-theirs conflict-branch && + git reset --hard HEAD^ && + echo five >conflict && + echo Z >file1 && + git commit -a -m "one file conflict" && + EDITOR=true git rebase -i --strategy=recursive -Xours conflict-branch && + test $(git show conflict-branch:conflict) = $(cat conflict) && + test $(cat file1) = Z +' + test_done