1#!/bin/sh 2# 3# Copyright (c) 2005 Junio C Hamano. 4# 5 6USAGE='[--onto <newbase>] <upstream> [<branch>]' 7LONG_USAGE='git-rebase replaces <branch> with a new branch of the 8same name. When the --onto option is provided the new branch starts 9out with a HEAD equal to <newbase>, otherwise it is equal to <upstream> 10It then attempts to create a new commit for each commit from the original 11<branch> that does not exist in the <upstream> branch. 12 13It is possible that a merge failure will prevent this process from being 14completely automatic. You will have to resolve any such merge failure 15and run git-rebase --continue. If you can not resolve the merge failure, 16running git-rebase --abort will restore the original <branch> and remove 17the working files found in the .dotest directory. 18 19Note that if <branch> is not specified on the command line, the 20currently checked out branch is used. You must be in the top 21directory of your project to start (or continue) a rebase. 22 23Example: git-rebase master~1 topic 24 25 A---B---C topic A'\''--B'\''--C'\'' topic 26 / --> / 27 D---E---F---G master D---E---F---G master 28' 29. git-sh-setup 30 31unset newbase 32while case"$#"in0)break;;esac 33do 34case"$1"in 35--continue) 36diff=$(git-diff-files) 37case"$diff"in 38 ?*)echo"You must edit all merge conflicts and then" 39echo"mark them as resolved using git update-index" 40exit1 41;; 42esac 43 git am --resolved --3way 44exit 45;; 46--abort) 47[-d .dotest ] || die "No rebase in progress?" 48 git reset--hard ORIG_HEAD 49rm-r .dotest 50exit 51;; 52--onto) 53test2-le"$#"|| usage 54 newbase="$2" 55shift 56;; 57-*) 58 usage 59;; 60*) 61break 62;; 63esac 64shift 65done 66 67# Make sure we do not have .dotest 68ifmkdir .dotest 69then 70rmdir .dotest 71else 72echo>&2' 73It seems that I cannot create a .dotest directory, and I wonder if you 74are in the middle of patch application or another rebase. If that is not 75the case, please rm -fr .dotest and run me again. I am stopping in case 76you still have something valuable there.' 77exit1 78fi 79 80# The tree must be really really clean. 81git-update-index --refresh||exit 82diff=$(git-diff-index --cached --name-status -r HEAD) 83case"$diff"in 84?*)echo"$diff" 85exit1 86;; 87esac 88 89# The upstream head must be given. Make sure it is valid. 90upstream_name="$1" 91upstream=`git rev-parse --verify "${upstream_name}^0"`|| 92 die "invalid upstream$upstream_name" 93 94# If a hook exists, give it a chance to interrupt 95iftest -x"$GIT_DIR/hooks/pre-rebase" 96then 97"$GIT_DIR/hooks/pre-rebase"${1+"$@"}|| { 98echo>&2"The pre-rebase hook refused to rebase." 99exit1 100} 101fi 102 103# If the branch to rebase is given, first switch to it. 104case"$#"in 1052) 106 branch_name="$2" 107 git-checkout"$2"|| usage 108;; 109*) 110 branch_name=`git symbolic-ref HEAD`|| die "No current branch" 111 branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'` 112;; 113esac 114branch=$(git-rev-parse --verify "${branch_name}^0")||exit 115 116# Make sure the branch to rebase onto is valid. 117onto_name=${newbase-"$upstream_name"} 118onto=$(git-rev-parse --verify "${onto_name}^0")||exit 119 120# Now we are rebasing commits $upstream..$branch on top of $onto 121 122# Check if we are already based on $onto, but this should be 123# done only when upstream and onto are the same. 124iftest"$upstream"="$onto" 125then 126 mb=$(git-merge-base "$onto" "$branch") 127iftest"$mb"="$onto" 128then 129echo>&2"Current branch$branch_nameis up to date." 130exit0 131fi 132fi 133 134# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD. 135git-reset --hard"$onto" 136 137# If the $onto is a proper descendant of the tip of the branch, then 138# we just fast forwarded. 139iftest"$mb"="$onto" 140then 141echo>&2"Fast-forwarded$branchto$newbase." 142exit0 143fi 144 145git-format-patch -k --stdout --full-index"$upstream" ORIG_HEAD | 146git am --binary -3 -k