PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/libexec/git-core/git-rebase--interactive

https://bitbucket.org/tgunr/usr
Shell | 937 lines | 751 code | 80 blank | 106 comment | 86 complexity | fb920ed24153bbd6ed6a427bae5782bc MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, Apache-2.0, BSD-3-Clause, AGPL-1.0, GPL-2.0
  1. #!/bin/sh
  2. #
  3. # Copyright (c) 2006 Johannes E. Schindelin
  4. # SHORT DESCRIPTION
  5. #
  6. # This script makes it easy to fix up commits in the middle of a series,
  7. # and rearrange commits.
  8. #
  9. # The original idea comes from Eric W. Biederman, in
  10. # http://article.gmane.org/gmane.comp.version-control.git/22407
  11. OPTIONS_KEEPDASHDASH=
  12. OPTIONS_SPEC="\
  13. git-rebase [-i] [options] [--] <upstream> [<branch>]
  14. git-rebase [-i] (--continue | --abort | --skip)
  15. --
  16. Available options are
  17. v,verbose display a diffstat of what changed upstream
  18. onto= rebase onto given branch instead of upstream
  19. p,preserve-merges try to recreate merges instead of ignoring them
  20. s,strategy= use the given merge strategy
  21. m,merge always used (no-op)
  22. i,interactive always used (no-op)
  23. Actions:
  24. continue continue rebasing process
  25. abort abort rebasing process and restore original branch
  26. skip skip current patch and continue rebasing process
  27. no-verify override pre-rebase hook from stopping the operation
  28. root rebase all reachable commmits up to the root(s)
  29. autosquash move commits that begin with squash!/fixup! under -i
  30. "
  31. . git-sh-setup
  32. require_work_tree
  33. DOTEST="$GIT_DIR/rebase-merge"
  34. # The file containing rebase commands, comments, and empty lines.
  35. # This file is created by "git rebase -i" then edited by the user. As
  36. # the lines are processed, they are removed from the front of this
  37. # file and written to the tail of $DONE.
  38. TODO="$DOTEST"/git-rebase-todo
  39. # The rebase command lines that have already been processed. A line
  40. # is moved here when it is first handled, before any associated user
  41. # actions.
  42. DONE="$DOTEST"/done
  43. # The commit message that is planned to be used for any changes that
  44. # need to be committed following a user interaction.
  45. MSG="$DOTEST"/message
  46. # The file into which is accumulated the suggested commit message for
  47. # squash/fixup commands. When the first of a series of squash/fixups
  48. # is seen, the file is created and the commit message from the
  49. # previous commit and from the first squash/fixup commit are written
  50. # to it. The commit message for each subsequent squash/fixup commit
  51. # is appended to the file as it is processed.
  52. #
  53. # The first line of the file is of the form
  54. # # This is a combination of $COUNT commits.
  55. # where $COUNT is the number of commits whose messages have been
  56. # written to the file so far (including the initial "pick" commit).
  57. # Each time that a commit message is processed, this line is read and
  58. # updated. It is deleted just before the combined commit is made.
  59. SQUASH_MSG="$DOTEST"/message-squash
  60. # If the current series of squash/fixups has not yet included a squash
  61. # command, then this file exists and holds the commit message of the
  62. # original "pick" commit. (If the series ends without a "squash"
  63. # command, then this can be used as the commit message of the combined
  64. # commit without opening the editor.)
  65. FIXUP_MSG="$DOTEST"/message-fixup
  66. # $REWRITTEN is the name of a directory containing files for each
  67. # commit that is reachable by at least one merge base of $HEAD and
  68. # $UPSTREAM. They are not necessarily rewritten, but their children
  69. # might be. This ensures that commits on merged, but otherwise
  70. # unrelated side branches are left alone. (Think "X" in the man page's
  71. # example.)
  72. REWRITTEN="$DOTEST"/rewritten
  73. DROPPED="$DOTEST"/dropped
  74. # A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
  75. # GIT_AUTHOR_DATE that will be used for the commit that is currently
  76. # being rebased.
  77. AUTHOR_SCRIPT="$DOTEST"/author-script
  78. # When an "edit" rebase command is being processed, the SHA1 of the
  79. # commit to be edited is recorded in this file. When "git rebase
  80. # --continue" is executed, if there are any staged changes then they
  81. # will be amended to the HEAD commit, but only provided the HEAD
  82. # commit is still the commit to be edited. When any other rebase
  83. # command is processed, this file is deleted.
  84. AMEND="$DOTEST"/amend
  85. PRESERVE_MERGES=
  86. STRATEGY=
  87. ONTO=
  88. VERBOSE=
  89. OK_TO_SKIP_PRE_REBASE=
  90. REBASE_ROOT=
  91. AUTOSQUASH=
  92. GIT_CHERRY_PICK_HELP=" After resolving the conflicts,
  93. mark the corrected paths with 'git add <paths>', and
  94. run 'git rebase --continue'"
  95. export GIT_CHERRY_PICK_HELP
  96. warn () {
  97. echo "$*" >&2
  98. }
  99. output () {
  100. case "$VERBOSE" in
  101. '')
  102. output=$("$@" 2>&1 )
  103. status=$?
  104. test $status != 0 && printf "%s\n" "$output"
  105. return $status
  106. ;;
  107. *)
  108. "$@"
  109. ;;
  110. esac
  111. }
  112. # Output the commit message for the specified commit.
  113. commit_message () {
  114. git cat-file commit "$1" | sed "1,/^$/d"
  115. }
  116. run_pre_rebase_hook () {
  117. if test -z "$OK_TO_SKIP_PRE_REBASE" &&
  118. test -x "$GIT_DIR/hooks/pre-rebase"
  119. then
  120. "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
  121. echo >&2 "The pre-rebase hook refused to rebase."
  122. exit 1
  123. }
  124. fi
  125. }
  126. require_clean_work_tree () {
  127. # test if working tree is dirty
  128. git rev-parse --verify HEAD > /dev/null &&
  129. git update-index --ignore-submodules --refresh &&
  130. git diff-files --quiet --ignore-submodules &&
  131. git diff-index --cached --quiet HEAD --ignore-submodules -- ||
  132. die "Working tree is dirty"
  133. }
  134. ORIG_REFLOG_ACTION="$GIT_REFLOG_ACTION"
  135. comment_for_reflog () {
  136. case "$ORIG_REFLOG_ACTION" in
  137. ''|rebase*)
  138. GIT_REFLOG_ACTION="rebase -i ($1)"
  139. export GIT_REFLOG_ACTION
  140. ;;
  141. esac
  142. }
  143. last_count=
  144. mark_action_done () {
  145. sed -e 1q < "$TODO" >> "$DONE"
  146. sed -e 1d < "$TODO" >> "$TODO".new
  147. mv -f "$TODO".new "$TODO"
  148. count=$(sane_grep -c '^[^#]' < "$DONE")
  149. total=$(($count+$(sane_grep -c '^[^#]' < "$TODO")))
  150. if test "$last_count" != "$count"
  151. then
  152. last_count=$count
  153. printf "Rebasing (%d/%d)\r" $count $total
  154. test -z "$VERBOSE" || echo
  155. fi
  156. }
  157. make_patch () {
  158. sha1_and_parents="$(git rev-list --parents -1 "$1")"
  159. case "$sha1_and_parents" in
  160. ?*' '?*' '?*)
  161. git diff --cc $sha1_and_parents
  162. ;;
  163. ?*' '?*)
  164. git diff-tree -p "$1^!"
  165. ;;
  166. *)
  167. echo "Root commit"
  168. ;;
  169. esac > "$DOTEST"/patch
  170. test -f "$MSG" ||
  171. commit_message "$1" > "$MSG"
  172. test -f "$AUTHOR_SCRIPT" ||
  173. get_author_ident_from_commit "$1" > "$AUTHOR_SCRIPT"
  174. }
  175. die_with_patch () {
  176. make_patch "$1"
  177. git rerere
  178. die "$2"
  179. }
  180. die_abort () {
  181. rm -rf "$DOTEST"
  182. die "$1"
  183. }
  184. has_action () {
  185. sane_grep '^[^#]' "$1" >/dev/null
  186. }
  187. # Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
  188. # GIT_AUTHOR_DATE exported from the current environment.
  189. do_with_author () {
  190. (
  191. export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
  192. "$@"
  193. )
  194. }
  195. pick_one () {
  196. no_ff=
  197. case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
  198. output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
  199. test -d "$REWRITTEN" &&
  200. pick_one_preserving_merges "$@" && return
  201. if test -n "$REBASE_ROOT"
  202. then
  203. output git cherry-pick "$@"
  204. return
  205. fi
  206. parent_sha1=$(git rev-parse --verify $sha1^) ||
  207. die "Could not get the parent of $sha1"
  208. current_sha1=$(git rev-parse --verify HEAD)
  209. if test -z "$no_ff" && test "$current_sha1" = "$parent_sha1"
  210. then
  211. output git reset --hard $sha1
  212. output warn Fast-forward to $(git rev-parse --short $sha1)
  213. else
  214. output git cherry-pick "$@"
  215. fi
  216. }
  217. pick_one_preserving_merges () {
  218. fast_forward=t
  219. case "$1" in
  220. -n)
  221. fast_forward=f
  222. sha1=$2
  223. ;;
  224. *)
  225. sha1=$1
  226. ;;
  227. esac
  228. sha1=$(git rev-parse $sha1)
  229. if test -f "$DOTEST"/current-commit
  230. then
  231. if test "$fast_forward" = t
  232. then
  233. cat "$DOTEST"/current-commit | while read current_commit
  234. do
  235. git rev-parse HEAD > "$REWRITTEN"/$current_commit
  236. done
  237. rm "$DOTEST"/current-commit ||
  238. die "Cannot write current commit's replacement sha1"
  239. fi
  240. fi
  241. echo $sha1 >> "$DOTEST"/current-commit
  242. # rewrite parents; if none were rewritten, we can fast-forward.
  243. new_parents=
  244. pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)"
  245. if test "$pend" = " "
  246. then
  247. pend=" root"
  248. fi
  249. while [ "$pend" != "" ]
  250. do
  251. p=$(expr "$pend" : ' \([^ ]*\)')
  252. pend="${pend# $p}"
  253. if test -f "$REWRITTEN"/$p
  254. then
  255. new_p=$(cat "$REWRITTEN"/$p)
  256. # If the todo reordered commits, and our parent is marked for
  257. # rewriting, but hasn't been gotten to yet, assume the user meant to
  258. # drop it on top of the current HEAD
  259. if test -z "$new_p"
  260. then
  261. new_p=$(git rev-parse HEAD)
  262. fi
  263. test $p != $new_p && fast_forward=f
  264. case "$new_parents" in
  265. *$new_p*)
  266. ;; # do nothing; that parent is already there
  267. *)
  268. new_parents="$new_parents $new_p"
  269. ;;
  270. esac
  271. else
  272. if test -f "$DROPPED"/$p
  273. then
  274. fast_forward=f
  275. replacement="$(cat "$DROPPED"/$p)"
  276. test -z "$replacement" && replacement=root
  277. pend=" $replacement$pend"
  278. else
  279. new_parents="$new_parents $p"
  280. fi
  281. fi
  282. done
  283. case $fast_forward in
  284. t)
  285. output warn "Fast-forward to $sha1"
  286. output git reset --hard $sha1 ||
  287. die "Cannot fast-forward to $sha1"
  288. ;;
  289. f)
  290. first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
  291. if [ "$1" != "-n" ]
  292. then
  293. # detach HEAD to current parent
  294. output git checkout $first_parent 2> /dev/null ||
  295. die "Cannot move HEAD to $first_parent"
  296. fi
  297. case "$new_parents" in
  298. ' '*' '*)
  299. test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
  300. # redo merge
  301. author_script=$(get_author_ident_from_commit $sha1)
  302. eval "$author_script"
  303. msg="$(commit_message $sha1)"
  304. # No point in merging the first parent, that's HEAD
  305. new_parents=${new_parents# $first_parent}
  306. if ! do_with_author output \
  307. git merge $STRATEGY -m "$msg" $new_parents
  308. then
  309. printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG
  310. die_with_patch $sha1 "Error redoing merge $sha1"
  311. fi
  312. ;;
  313. *)
  314. output git cherry-pick "$@" ||
  315. die_with_patch $sha1 "Could not pick $sha1"
  316. ;;
  317. esac
  318. ;;
  319. esac
  320. }
  321. nth_string () {
  322. case "$1" in
  323. *1[0-9]|*[04-9]) echo "$1"th;;
  324. *1) echo "$1"st;;
  325. *2) echo "$1"nd;;
  326. *3) echo "$1"rd;;
  327. esac
  328. }
  329. update_squash_messages () {
  330. if test -f "$SQUASH_MSG"; then
  331. mv "$SQUASH_MSG" "$SQUASH_MSG".bak || exit
  332. COUNT=$(($(sed -n \
  333. -e "1s/^# This is a combination of \(.*\) commits\./\1/p" \
  334. -e "q" < "$SQUASH_MSG".bak)+1))
  335. {
  336. echo "# This is a combination of $COUNT commits."
  337. sed -e 1d -e '2,/^./{
  338. /^$/d
  339. }' <"$SQUASH_MSG".bak
  340. } >"$SQUASH_MSG"
  341. else
  342. commit_message HEAD > "$FIXUP_MSG" || die "Cannot write $FIXUP_MSG"
  343. COUNT=2
  344. {
  345. echo "# This is a combination of 2 commits."
  346. echo "# The first commit's message is:"
  347. echo
  348. cat "$FIXUP_MSG"
  349. } >"$SQUASH_MSG"
  350. fi
  351. case $1 in
  352. squash)
  353. rm -f "$FIXUP_MSG"
  354. echo
  355. echo "# This is the $(nth_string $COUNT) commit message:"
  356. echo
  357. commit_message $2
  358. ;;
  359. fixup)
  360. echo
  361. echo "# The $(nth_string $COUNT) commit message will be skipped:"
  362. echo
  363. commit_message $2 | sed -e 's/^/# /'
  364. ;;
  365. esac >>"$SQUASH_MSG"
  366. }
  367. peek_next_command () {
  368. sed -n -e "/^#/d" -e '/^$/d' -e "s/ .*//p" -e "q" < "$TODO"
  369. }
  370. # A squash/fixup has failed. Prepare the long version of the squash
  371. # commit message, then die_with_patch. This code path requires the
  372. # user to edit the combined commit message for all commits that have
  373. # been squashed/fixedup so far. So also erase the old squash
  374. # messages, effectively causing the combined commit to be used as the
  375. # new basis for any further squash/fixups. Args: sha1 rest
  376. die_failed_squash() {
  377. mv "$SQUASH_MSG" "$MSG" || exit
  378. rm -f "$FIXUP_MSG"
  379. cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit
  380. warn
  381. warn "Could not apply $1... $2"
  382. die_with_patch $1 ""
  383. }
  384. do_next () {
  385. rm -f "$MSG" "$AUTHOR_SCRIPT" "$AMEND" || exit
  386. read command sha1 rest < "$TODO"
  387. case "$command" in
  388. '#'*|''|noop)
  389. mark_action_done
  390. ;;
  391. pick|p)
  392. comment_for_reflog pick
  393. mark_action_done
  394. pick_one $sha1 ||
  395. die_with_patch $sha1 "Could not apply $sha1... $rest"
  396. ;;
  397. reword|r)
  398. comment_for_reflog reword
  399. mark_action_done
  400. pick_one $sha1 ||
  401. die_with_patch $sha1 "Could not apply $sha1... $rest"
  402. git commit --amend
  403. ;;
  404. edit|e)
  405. comment_for_reflog edit
  406. mark_action_done
  407. pick_one $sha1 ||
  408. die_with_patch $sha1 "Could not apply $sha1... $rest"
  409. make_patch $sha1
  410. git rev-parse --verify HEAD > "$AMEND"
  411. warn "Stopped at $sha1... $rest"
  412. warn "You can amend the commit now, with"
  413. warn
  414. warn " git commit --amend"
  415. warn
  416. warn "Once you are satisfied with your changes, run"
  417. warn
  418. warn " git rebase --continue"
  419. warn
  420. exit 0
  421. ;;
  422. squash|s|fixup|f)
  423. case "$command" in
  424. squash|s)
  425. squash_style=squash
  426. ;;
  427. fixup|f)
  428. squash_style=fixup
  429. ;;
  430. esac
  431. comment_for_reflog $squash_style
  432. test -f "$DONE" && has_action "$DONE" ||
  433. die "Cannot '$squash_style' without a previous commit"
  434. mark_action_done
  435. update_squash_messages $squash_style $sha1
  436. author_script=$(get_author_ident_from_commit HEAD)
  437. echo "$author_script" > "$AUTHOR_SCRIPT"
  438. eval "$author_script"
  439. output git reset --soft HEAD^
  440. pick_one -n $sha1 || die_failed_squash $sha1 "$rest"
  441. case "$(peek_next_command)" in
  442. squash|s|fixup|f)
  443. # This is an intermediate commit; its message will only be
  444. # used in case of trouble. So use the long version:
  445. do_with_author output git commit --no-verify -F "$SQUASH_MSG" ||
  446. die_failed_squash $sha1 "$rest"
  447. ;;
  448. *)
  449. # This is the final command of this squash/fixup group
  450. if test -f "$FIXUP_MSG"
  451. then
  452. do_with_author git commit --no-verify -F "$FIXUP_MSG" ||
  453. die_failed_squash $sha1 "$rest"
  454. else
  455. cp "$SQUASH_MSG" "$GIT_DIR"/SQUASH_MSG || exit
  456. rm -f "$GIT_DIR"/MERGE_MSG
  457. do_with_author git commit --no-verify -e ||
  458. die_failed_squash $sha1 "$rest"
  459. fi
  460. rm -f "$SQUASH_MSG" "$FIXUP_MSG"
  461. ;;
  462. esac
  463. ;;
  464. *)
  465. warn "Unknown command: $command $sha1 $rest"
  466. if git rev-parse --verify -q "$sha1" >/dev/null
  467. then
  468. die_with_patch $sha1 "Please fix this in the file $TODO."
  469. else
  470. die "Please fix this in the file $TODO."
  471. fi
  472. ;;
  473. esac
  474. test -s "$TODO" && return
  475. comment_for_reflog finish &&
  476. HEADNAME=$(cat "$DOTEST"/head-name) &&
  477. OLDHEAD=$(cat "$DOTEST"/head) &&
  478. SHORTONTO=$(git rev-parse --short $(cat "$DOTEST"/onto)) &&
  479. NEWHEAD=$(git rev-parse HEAD) &&
  480. case $HEADNAME in
  481. refs/*)
  482. message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO" &&
  483. git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD &&
  484. git symbolic-ref HEAD $HEADNAME
  485. ;;
  486. esac && {
  487. test ! -f "$DOTEST"/verbose ||
  488. git diff-tree --stat $(cat "$DOTEST"/head)..HEAD
  489. } &&
  490. rm -rf "$DOTEST" &&
  491. git gc --auto &&
  492. warn "Successfully rebased and updated $HEADNAME."
  493. exit
  494. }
  495. do_rest () {
  496. while :
  497. do
  498. do_next
  499. done
  500. }
  501. # skip picking commits whose parents are unchanged
  502. skip_unnecessary_picks () {
  503. fd=3
  504. while read command sha1 rest
  505. do
  506. # fd=3 means we skip the command
  507. case "$fd,$command,$(git rev-parse --verify --quiet $sha1^)" in
  508. 3,pick,"$ONTO"*|3,p,"$ONTO"*)
  509. # pick a commit whose parent is current $ONTO -> skip
  510. ONTO=$sha1
  511. ;;
  512. 3,#*|3,,*)
  513. # copy comments
  514. ;;
  515. *)
  516. fd=1
  517. ;;
  518. esac
  519. echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd
  520. done <"$TODO" >"$TODO.new" 3>>"$DONE" &&
  521. mv -f "$TODO".new "$TODO" ||
  522. die "Could not skip unnecessary pick commands"
  523. }
  524. # check if no other options are set
  525. is_standalone () {
  526. test $# -eq 2 -a "$2" = '--' &&
  527. test -z "$ONTO" &&
  528. test -z "$PRESERVE_MERGES" &&
  529. test -z "$STRATEGY" &&
  530. test -z "$VERBOSE"
  531. }
  532. get_saved_options () {
  533. test -d "$REWRITTEN" && PRESERVE_MERGES=t
  534. test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
  535. test -f "$DOTEST"/verbose && VERBOSE=t
  536. test -f "$DOTEST"/rebase-root && REBASE_ROOT=t
  537. }
  538. # Rearrange the todo list that has both "pick sha1 msg" and
  539. # "pick sha1 fixup!/squash! msg" appears in it so that the latter
  540. # comes immediately after the former, and change "pick" to
  541. # "fixup"/"squash".
  542. rearrange_squash () {
  543. sed -n -e 's/^pick \([0-9a-f]*\) \(squash\)! /\1 \2 /p' \
  544. -e 's/^pick \([0-9a-f]*\) \(fixup\)! /\1 \2 /p' \
  545. "$1" >"$1.sq"
  546. test -s "$1.sq" || return
  547. used=
  548. while read pick sha1 message
  549. do
  550. case " $used" in
  551. *" $sha1 "*) continue ;;
  552. esac
  553. echo "$pick $sha1 $message"
  554. while read squash action msg
  555. do
  556. case "$message" in
  557. "$msg"*)
  558. echo "$action $squash $action! $msg"
  559. used="$used$squash "
  560. ;;
  561. esac
  562. done <"$1.sq"
  563. done >"$1.rearranged" <"$1"
  564. cat "$1.rearranged" >"$1"
  565. rm -f "$1.sq" "$1.rearranged"
  566. }
  567. LF='
  568. '
  569. parse_onto () {
  570. case "$1" in
  571. *...*)
  572. if left=${1%...*} right=${1#*...} &&
  573. onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
  574. then
  575. case "$onto" in
  576. ?*"$LF"?* | '')
  577. exit 1 ;;
  578. esac
  579. echo "$onto"
  580. exit 0
  581. fi
  582. esac
  583. git rev-parse --verify "$1^0"
  584. }
  585. while test $# != 0
  586. do
  587. case "$1" in
  588. --no-verify)
  589. OK_TO_SKIP_PRE_REBASE=yes
  590. ;;
  591. --verify)
  592. ;;
  593. --continue)
  594. is_standalone "$@" || usage
  595. get_saved_options
  596. comment_for_reflog continue
  597. test -d "$DOTEST" || die "No interactive rebase running"
  598. # Sanity check
  599. git rev-parse --verify HEAD >/dev/null ||
  600. die "Cannot read HEAD"
  601. git update-index --ignore-submodules --refresh &&
  602. git diff-files --quiet --ignore-submodules ||
  603. die "Working tree is dirty"
  604. # do we have anything to commit?
  605. if git diff-index --cached --quiet --ignore-submodules HEAD --
  606. then
  607. : Nothing to commit -- skip this
  608. else
  609. . "$AUTHOR_SCRIPT" ||
  610. die "Cannot find the author identity"
  611. amend=
  612. if test -f "$AMEND"
  613. then
  614. amend=$(git rev-parse --verify HEAD)
  615. test "$amend" = $(cat "$AMEND") ||
  616. die "\
  617. You have uncommitted changes in your working tree. Please, commit them
  618. first and then run 'git rebase --continue' again."
  619. git reset --soft HEAD^ ||
  620. die "Cannot rewind the HEAD"
  621. fi
  622. do_with_author git commit --no-verify -F "$MSG" -e || {
  623. test -n "$amend" && git reset --soft $amend
  624. die "Could not commit staged changes."
  625. }
  626. fi
  627. require_clean_work_tree
  628. do_rest
  629. ;;
  630. --abort)
  631. is_standalone "$@" || usage
  632. get_saved_options
  633. comment_for_reflog abort
  634. git rerere clear
  635. test -d "$DOTEST" || die "No interactive rebase running"
  636. HEADNAME=$(cat "$DOTEST"/head-name)
  637. HEAD=$(cat "$DOTEST"/head)
  638. case $HEADNAME in
  639. refs/*)
  640. git symbolic-ref HEAD $HEADNAME
  641. ;;
  642. esac &&
  643. output git reset --hard $HEAD &&
  644. rm -rf "$DOTEST"
  645. exit
  646. ;;
  647. --skip)
  648. is_standalone "$@" || usage
  649. get_saved_options
  650. comment_for_reflog skip
  651. git rerere clear
  652. test -d "$DOTEST" || die "No interactive rebase running"
  653. output git reset --hard && do_rest
  654. ;;
  655. -s)
  656. case "$#,$1" in
  657. *,*=*)
  658. STRATEGY="-s "$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
  659. 1,*)
  660. usage ;;
  661. *)
  662. STRATEGY="-s $2"
  663. shift ;;
  664. esac
  665. ;;
  666. -m)
  667. # we use merge anyway
  668. ;;
  669. -v)
  670. VERBOSE=t
  671. ;;
  672. -p)
  673. PRESERVE_MERGES=t
  674. ;;
  675. -i)
  676. # yeah, we know
  677. ;;
  678. --root)
  679. REBASE_ROOT=t
  680. ;;
  681. --autosquash)
  682. AUTOSQUASH=t
  683. ;;
  684. --onto)
  685. shift
  686. ONTO=$(parse_onto "$1") ||
  687. die "Does not point to a valid commit: $1"
  688. ;;
  689. --)
  690. shift
  691. test -z "$REBASE_ROOT" -a $# -ge 1 -a $# -le 2 ||
  692. test ! -z "$REBASE_ROOT" -a $# -le 1 || usage
  693. test -d "$DOTEST" &&
  694. die "Interactive rebase already started"
  695. git var GIT_COMMITTER_IDENT >/dev/null ||
  696. die "You need to set your committer info first"
  697. if test -z "$REBASE_ROOT"
  698. then
  699. UPSTREAM_ARG="$1"
  700. UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
  701. test -z "$ONTO" && ONTO=$UPSTREAM
  702. shift
  703. else
  704. UPSTREAM=
  705. UPSTREAM_ARG=--root
  706. test -z "$ONTO" &&
  707. die "You must specify --onto when using --root"
  708. fi
  709. run_pre_rebase_hook "$UPSTREAM_ARG" "$@"
  710. comment_for_reflog start
  711. require_clean_work_tree
  712. if test ! -z "$1"
  713. then
  714. output git show-ref --verify --quiet "refs/heads/$1" ||
  715. die "Invalid branchname: $1"
  716. output git checkout "$1" ||
  717. die "Could not checkout $1"
  718. fi
  719. HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
  720. mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
  721. : > "$DOTEST"/interactive || die "Could not mark as interactive"
  722. git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
  723. echo "detached HEAD" > "$DOTEST"/head-name
  724. echo $HEAD > "$DOTEST"/head
  725. case "$REBASE_ROOT" in
  726. '')
  727. rm -f "$DOTEST"/rebase-root ;;
  728. *)
  729. : >"$DOTEST"/rebase-root ;;
  730. esac
  731. echo $ONTO > "$DOTEST"/onto
  732. test -z "$STRATEGY" || echo "$STRATEGY" > "$DOTEST"/strategy
  733. test t = "$VERBOSE" && : > "$DOTEST"/verbose
  734. if test t = "$PRESERVE_MERGES"
  735. then
  736. if test -z "$REBASE_ROOT"
  737. then
  738. mkdir "$REWRITTEN" &&
  739. for c in $(git merge-base --all $HEAD $UPSTREAM)
  740. do
  741. echo $ONTO > "$REWRITTEN"/$c ||
  742. die "Could not init rewritten commits"
  743. done
  744. else
  745. mkdir "$REWRITTEN" &&
  746. echo $ONTO > "$REWRITTEN"/root ||
  747. die "Could not init rewritten commits"
  748. fi
  749. # No cherry-pick because our first pass is to determine
  750. # parents to rewrite and skipping dropped commits would
  751. # prematurely end our probe
  752. MERGES_OPTION=
  753. first_after_upstream="$(git rev-list --reverse --first-parent $UPSTREAM..$HEAD | head -n 1)"
  754. else
  755. MERGES_OPTION="--no-merges --cherry-pick"
  756. fi
  757. SHORTHEAD=$(git rev-parse --short $HEAD)
  758. SHORTONTO=$(git rev-parse --short $ONTO)
  759. if test -z "$REBASE_ROOT"
  760. # this is now equivalent to ! -z "$UPSTREAM"
  761. then
  762. SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
  763. REVISIONS=$UPSTREAM...$HEAD
  764. SHORTREVISIONS=$SHORTUPSTREAM..$SHORTHEAD
  765. else
  766. REVISIONS=$ONTO...$HEAD
  767. SHORTREVISIONS=$SHORTHEAD
  768. fi
  769. git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
  770. --abbrev=7 --reverse --left-right --topo-order \
  771. $REVISIONS | \
  772. sed -n "s/^>//p" | while read shortsha1 rest
  773. do
  774. if test t != "$PRESERVE_MERGES"
  775. then
  776. echo "pick $shortsha1 $rest" >> "$TODO"
  777. else
  778. sha1=$(git rev-parse $shortsha1)
  779. if test -z "$REBASE_ROOT"
  780. then
  781. preserve=t
  782. for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
  783. do
  784. if test -f "$REWRITTEN"/$p -a \( $p != $ONTO -o $sha1 = $first_after_upstream \)
  785. then
  786. preserve=f
  787. fi
  788. done
  789. else
  790. preserve=f
  791. fi
  792. if test f = "$preserve"
  793. then
  794. touch "$REWRITTEN"/$sha1
  795. echo "pick $shortsha1 $rest" >> "$TODO"
  796. fi
  797. fi
  798. done
  799. # Watch for commits that been dropped by --cherry-pick
  800. if test t = "$PRESERVE_MERGES"
  801. then
  802. mkdir "$DROPPED"
  803. # Save all non-cherry-picked changes
  804. git rev-list $REVISIONS --left-right --cherry-pick | \
  805. sed -n "s/^>//p" > "$DOTEST"/not-cherry-picks
  806. # Now all commits and note which ones are missing in
  807. # not-cherry-picks and hence being dropped
  808. git rev-list $REVISIONS |
  809. while read rev
  810. do
  811. if test -f "$REWRITTEN"/$rev -a "$(sane_grep "$rev" "$DOTEST"/not-cherry-picks)" = ""
  812. then
  813. # Use -f2 because if rev-list is telling us this commit is
  814. # not worthwhile, we don't want to track its multiple heads,
  815. # just the history of its first-parent for others that will
  816. # be rebasing on top of it
  817. git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$DROPPED"/$rev
  818. short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
  819. sane_grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
  820. rm "$REWRITTEN"/$rev
  821. fi
  822. done
  823. fi
  824. test -s "$TODO" || echo noop >> "$TODO"
  825. test -n "$AUTOSQUASH" && rearrange_squash "$TODO"
  826. cat >> "$TODO" << EOF
  827. # Rebase $SHORTREVISIONS onto $SHORTONTO
  828. #
  829. # Commands:
  830. # p, pick = use commit
  831. # r, reword = use commit, but edit the commit message
  832. # e, edit = use commit, but stop for amending
  833. # s, squash = use commit, but meld into previous commit
  834. # f, fixup = like "squash", but discard this commit's log message
  835. #
  836. # If you remove a line here THAT COMMIT WILL BE LOST.
  837. # However, if you remove everything, the rebase will be aborted.
  838. #
  839. EOF
  840. has_action "$TODO" ||
  841. die_abort "Nothing to do"
  842. cp "$TODO" "$TODO".backup
  843. git_editor "$TODO" ||
  844. die_abort "Could not execute editor"
  845. has_action "$TODO" ||
  846. die_abort "Nothing to do"
  847. test -d "$REWRITTEN" || skip_unnecessary_picks
  848. git update-ref ORIG_HEAD $HEAD
  849. output git checkout $ONTO && do_rest
  850. ;;
  851. esac
  852. shift
  853. done