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