27
abort abort rebasing process and restore original branch
28
skip skip current patch and continue rebasing process
29
no-verify override pre-rebase hook from stopping the operation
30
+root rebase all reachable commmits up to the root(s)
31
"
32
33
. git-sh-setup
45
ONTO=
46
VERBOSE=
47
OK_TO_SKIP_PRE_REBASE=
48
+REBASE_ROOT=
49
50
GIT_CHERRY_PICK_HELP=" After resolving the conflicts,
51
mark the corrected paths with 'git add <paths>', and
156
output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
157
test -d "$REWRITTEN" &&
158
pick_one_preserving_merges "$@" && return
159
+ if test ! -z "$REBASE_ROOT"
160
+ then
161
+ output git cherry-pick "$@"
162
+ return
163
+ fi
164
parent_sha1=$(git rev-parse --verify $sha1^) ||
165
die "Could not get the parent of $sha1"
166
current_sha1=$(git rev-parse --verify HEAD)
204
205
# rewrite parents; if none were rewritten, we can fast-forward.
206
new_parents=
200
- pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)"
207
+ pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)"
208
+ if test "$pend" = " "
209
+ then
210
+ pend=" root"
211
+ fi
212
while [ "$pend" != "" ]
213
do
214
p=$(expr "$pend" : ' \([^ ]*\)')
238
if test -f "$DROPPED"/$p
239
then
240
fast_forward=f
230
- pend=" $(cat "$DROPPED"/$p)$pend"
241
+ replacement="$(cat "$DROPPED"/$p)"
242
+ test -z "$replacement" && replacement=root
243
+ pend=" $replacement$pend"
244
else
245
new_parents="$new_parents $p"
246
fi
456
test -d "$REWRITTEN" && PRESERVE_MERGES=t
457
test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
458
test -f "$DOTEST"/verbose && VERBOSE=t
459
+ test ! -s "$DOTEST"/upstream && REBASE_ROOT=t
460
}
461
462
while test $# != 0
561
-i)
562
# yeah, we know
563
;;
564
+ --root)
565
+ REBASE_ROOT=t
566
+ ;;
567
--onto)
568
shift
569
ONTO=$(git rev-parse --verify "$1") ||
571
;;
572
--)
573
shift
557
- test $# -eq 1 -o $# -eq 2 || usage
574
+ test ! -z "$REBASE_ROOT" -o $# -eq 1 -o $# -eq 2 || usage
575
test -d "$DOTEST" &&
576
die "Interactive rebase already started"
577
578
git var GIT_COMMITTER_IDENT >/dev/null ||
579
die "You need to set your committer info first"
580
564
- UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
565
- run_pre_rebase_hook ${1+"$@"}
581
+ if test -z "$REBASE_ROOT"
582
+ then
583
+ UPSTREAM_ARG="$1"
584
+ UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
585
+ test -z "$ONTO" && ONTO=$UPSTREAM
586
+ shift
587
+ else
588
+ UPSTREAM_ARG=--root
589
+ test -z "$ONTO" &&
590
+ die "You must specify --onto when using --root"
591
+ fi
592
+ run_pre_rebase_hook "$UPSTREAM_ARG" "$@"
593
594
comment_for_reflog start
595
596
require_clean_work_tree
597
571
- test -z "$ONTO" && ONTO=$UPSTREAM
572
-
573
- if test ! -z "$2"
598
+ if test ! -z "$1"
599
then
575
- output git show-ref --verify --quiet "refs/heads/$2" ||
576
- die "Invalid branchname: $2"
577
- output git checkout "$2" ||
578
- die "Could not checkout $2"
600
+ output git show-ref --verify --quiet "refs/heads/$1" ||
601
+ die "Invalid branchname: $1"
602
+ output git checkout "$1" ||
603
+ die "Could not checkout $1"
604
fi
605
606
HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
624
# This ensures that commits on merged, but otherwise
625
# unrelated side branches are left alone. (Think "X"
626
# in the man page's example.)
602
- mkdir "$REWRITTEN" &&
603
- for c in $(git merge-base --all $HEAD $UPSTREAM)
604
- do
605
- echo $ONTO > "$REWRITTEN"/$c ||
627
+ if test -z "$REBASE_ROOT"
628
+ then
629
+ mkdir "$REWRITTEN" &&
630
+ for c in $(git merge-base --all $HEAD $UPSTREAM)
631
+ do
632
+ echo $ONTO > "$REWRITTEN"/$c ||
633
+ die "Could not init rewritten commits"
634
+ done
635
+ else
636
+ mkdir "$REWRITTEN" &&
637
+ echo $ONTO > "$REWRITTEN"/root ||
638
die "Could not init rewritten commits"
607
- done
639
+ fi
640
# No cherry-pick because our first pass is to determine
641
# parents to rewrite and skipping dropped commits would
642
# prematurely end our probe
646
MERGES_OPTION="--no-merges --cherry-pick"
647
fi
648
617
- SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
649
SHORTHEAD=$(git rev-parse --short $HEAD)
650
SHORTONTO=$(git rev-parse --short $ONTO)
651
+ if test -z "$REBASE_ROOT"
652
+ # this is now equivalent to ! -z "$UPSTREAM"
653
+ then
654
+ SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
655
+ REVISIONS=$UPSTREAM...$HEAD
656
+ SHORTREVISIONS=$SHORTUPSTREAM..$SHORTHEAD
657
+ else
658
+ REVISIONS=$ONTO...$HEAD
659
+ SHORTREVISIONS=$SHORTHEAD
660
+ fi
661
git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
662
--abbrev=7 --reverse --left-right --topo-order \
622
- $UPSTREAM...$HEAD | \
663
+ $REVISIONS | \
664
sed -n "s/^>//p" | while read shortsha1 rest
665
do
666
if test t != "$PRESERVE_MERGES"
668
echo "pick $shortsha1 $rest" >> "$TODO"
669
else
670
sha1=$(git rev-parse $shortsha1)
630
- preserve=t
631
- for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
632
- do
633
- if test -f "$REWRITTEN"/$p -a \( $p != $UPSTREAM -o $sha1 = $first_after_upstream \)
634
- then
635
- preserve=f
636
- fi
637
- done
671
+ if test -z "$REBASE_ROOT"
672
+ then
673
+ preserve=t
674
+ for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
675
+ do
676
+ if test -f "$REWRITTEN"/$p -a \( $p != $UPSTREAM -o $sha1 = $first_after_upstream \)
677
+ then
678
+ preserve=f
679
+ fi
680
+ done
681
+ else
682
+ preserve=f
683
+ fi
684
if test f = "$preserve"
685
then
686
touch "$REWRITTEN"/$sha1
694
then
695
mkdir "$DROPPED"
696
# Save all non-cherry-picked changes
651
- git rev-list $UPSTREAM...$HEAD --left-right --cherry-pick | \
697
+ git rev-list $REVISIONS --left-right --cherry-pick | \
698
sed -n "s/^>//p" > "$DOTEST"/not-cherry-picks
699
# Now all commits and note which ones are missing in
700
# not-cherry-picks and hence being dropped
655
- git rev-list $UPSTREAM..$HEAD |
701
+ git rev-list $REVISIONS |
702
while read rev
703
do
704
if test -f "$REWRITTEN"/$rev -a "$(grep "$rev" "$DOTEST"/not-cherry-picks)" = ""
707
# not worthwhile, we don't want to track its multiple heads,
708
# just the history of its first-parent for others that will
709
# be rebasing on top of it
664
- git rev-list --parents -1 $rev | cut -d' ' -f2 > "$DROPPED"/$rev
710
+ git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$DROPPED"/$rev
711
short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
712
grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
713
rm "$REWRITTEN"/$rev
714
fi
715
done
716
fi
717
+
718
test -s "$TODO" || echo noop >> "$TODO"
719
cat >> "$TODO" << EOF
720
674
-# Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
721
+# Rebase $SHORTREVISIONS onto $SHORTONTO
722
#
723
# Commands:
724
# p, pick = use commit