]>
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>]' |
69a60af5 CW |
7 | LONG_USAGE='git-rebase applies to <upstream> (or optionally to <newbase>) commits |
8 | from <branch> that do not appear in <upstream>. When <branch> is not | |
9 | specified it defaults to the current branch (HEAD). | |
10 | ||
11 | When git-rebase is complete, <branch> will be updated to point to the | |
12 | newly created line of commit objects, so the previous line will not be | |
13 | accessible unless there are other references to it already. | |
14 | ||
15 | Assuming the following history: | |
e646c9c8 JH |
16 | |
17 | A---B---C topic | |
18 | / | |
19 | D---E---F---G master | |
20 | ||
69a60af5 | 21 | The result of the following command: |
e646c9c8 | 22 | |
69a60af5 | 23 | git-rebase --onto master~1 master topic |
e646c9c8 | 24 | |
69a60af5 | 25 | would be: |
e646c9c8 | 26 | |
69a60af5 CW |
27 | A'\''--B'\''--C'\'' topic |
28 | / | |
e646c9c8 JH |
29 | D---E---F---G master |
30 | ' | |
31 | ||
ae2b0f15 | 32 | . git-sh-setup |
4282c4fb | 33 | |
e646c9c8 JH |
34 | unset newbase |
35 | while case "$#" in 0) break ;; esac | |
36 | do | |
37 | case "$1" in | |
38 | --onto) | |
39 | test 2 -le "$#" || usage | |
40 | newbase="$2" | |
41 | shift | |
42 | ;; | |
43 | -*) | |
44 | usage | |
45 | ;; | |
46 | *) | |
47 | break | |
48 | ;; | |
49 | esac | |
50 | shift | |
51 | done | |
2db8aaec | 52 | |
7f4bd5d8 JH |
53 | # Make sure we do not have .dotest |
54 | if mkdir .dotest | |
55 | then | |
56 | rmdir .dotest | |
57 | else | |
58 | echo >&2 ' | |
59 | It seems that I cannot create a .dotest directory, and I wonder if you | |
60 | are in the middle of patch application or another rebase. If that is not | |
61 | the case, please rm -fr .dotest and run me again. I am stopping in case | |
62 | you still have something valuable there.' | |
63 | exit 1 | |
64 | fi | |
65 | ||
7f59dbbb | 66 | # The tree must be really really clean. |
215a7ad1 | 67 | git-update-index --refresh || exit |
7f59dbbb | 68 | diff=$(git-diff-index --cached --name-status -r HEAD) |
32d99544 | 69 | case "$diff" in |
7f59dbbb JH |
70 | ?*) echo "$diff" |
71 | exit 1 | |
72 | ;; | |
73 | esac | |
99a92f92 | 74 | |
e646c9c8 JH |
75 | # The upstream head must be given. Make sure it is valid. |
76 | upstream_name="$1" | |
77 | upstream=`git rev-parse --verify "${upstream_name}^0"` || | |
d0080b3c | 78 | die "invalid upstream $upstream_name" |
32d99544 | 79 | |
9a111c91 JH |
80 | # If a hook exists, give it a chance to interrupt |
81 | if test -x "$GIT_DIR/hooks/pre-rebase" | |
82 | then | |
83 | "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || { | |
84 | echo >&2 "The pre-rebase hook refused to rebase." | |
85 | exit 1 | |
86 | } | |
87 | fi | |
88 | ||
7f59dbbb | 89 | # If the branch to rebase is given, first switch to it. |
59e6b23a | 90 | case "$#" in |
7f59dbbb | 91 | 2) |
e646c9c8 | 92 | branch_name="$2" |
3ae39ab2 | 93 | git-checkout "$2" || usage |
e646c9c8 JH |
94 | ;; |
95 | *) | |
96 | branch_name=`git symbolic-ref HEAD` || die "No current branch" | |
97 | branch_name=`expr "$branch_name" : 'refs/heads/\(.*\)'` | |
98 | ;; | |
59e6b23a | 99 | esac |
e646c9c8 | 100 | branch=$(git-rev-parse --verify "${branch_name}^0") || exit |
59e6b23a | 101 | |
e646c9c8 JH |
102 | # Make sure the branch to rebase onto is valid. |
103 | onto_name=${newbase-"$upstream_name"} | |
104 | onto=$(git-rev-parse --verify "${onto_name}^0") || exit | |
32d99544 | 105 | |
e646c9c8 JH |
106 | # Now we are rebasing commits $upstream..$branch on top of $onto |
107 | ||
108 | # Check if we are already based on $onto, but this should be | |
109 | # done only when upstream and onto are the same. | |
110 | if test "$upstream" = "onto" | |
7f4bd5d8 | 111 | then |
e646c9c8 JH |
112 | mb=$(git-merge-base "$onto" "$branch") |
113 | if test "$mb" = "$onto" | |
114 | then | |
115 | echo >&2 "Current branch $branch_name is up to date." | |
116 | exit 0 | |
117 | fi | |
7f4bd5d8 JH |
118 | fi |
119 | ||
e646c9c8 JH |
120 | # Rewind the head to "$onto"; this saves our current head in ORIG_HEAD. |
121 | git-reset --hard "$onto" | |
32d99544 | 122 | |
e646c9c8 | 123 | # If the $onto is a proper descendant of the tip of the branch, then |
32d99544 | 124 | # we just fast forwarded. |
e646c9c8 | 125 | if test "$mb" = "$onto" |
32d99544 | 126 | then |
e646c9c8 | 127 | echo >&2 "Fast-forwarded $branch to $newbase." |
32d99544 LS |
128 | exit 0 |
129 | fi | |
130 | ||
e646c9c8 | 131 | git-format-patch -k --stdout --full-index "$upstream" ORIG_HEAD | |
7f59dbbb | 132 | git am --binary -3 -k |