blob: 7cba61b269f041c195cbdd09061d178bab643707 [file] [log] [blame]
Benedikt Böhm00ccea62010-01-26 12:39:36 +01001#
Vincent Driessen6c2d30b2010-01-26 22:18:36 +01002# git-flow -- A collection of Git extensions to provide high-level
3# repository operations for Vincent Driessen's branching model.
Benedikt Böhm00ccea62010-01-26 12:39:36 +01004#
5# Original blog post presenting this model is found at:
6# http://nvie.com/archives/323
7#
8# Feel free to contribute to this project at:
9# http://github.com/nvie/gitflow
10#
Vincent Driessend72acba2010-04-04 16:10:17 +020011# Copyright 2010 Vincent Driessen. All rights reserved.
12#
13# Redistribution and use in source and binary forms, with or without
14# modification, are permitted provided that the following conditions are met:
15#
16# 1. Redistributions of source code must retain the above copyright notice,
17# this list of conditions and the following disclaimer.
18#
19# 2. Redistributions in binary form must reproduce the above copyright
20# notice, this list of conditions and the following disclaimer in the
21# documentation and/or other materials provided with the distribution.
22#
23# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR
24# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
26# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
30# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33#
34# The views and conclusions contained in the software and documentation are
35# those of the authors and should not be interpreted as representing official
36# policies, either expressed or implied, of Vincent Driessen.
Benedikt Böhm00ccea62010-01-26 12:39:36 +010037#
38
Vincent Driessen7832d6e2010-02-21 21:31:03 +010039require_git_repo
40require_gitflow_initialized
Vincent Driessend72e4ac2010-02-16 21:33:51 +010041gitflow_load_settings
Vincent Driessenc1598bf2010-02-20 16:52:48 +010042PREFIX=$(git config --get gitflow.prefix.feature)
Benedikt Böhm49dd62b2010-01-28 00:51:15 +010043
Benedikt Böhm00ccea62010-01-26 12:39:36 +010044usage() {
Vincent Driessenb03cf962010-02-01 22:00:39 +010045 echo "usage: git flow feature [list] [-v]"
Vincent Driessena2e41162010-02-24 01:37:07 +010046 echo " git flow feature start [-Ff] <name> [<base>]"
47 echo " git flow feature finish [-rF] <name|nameprefix>"
Vincent Driessen186d2b52010-01-27 23:48:39 +010048 echo " git flow feature publish <name>"
49 echo " git flow feature track <name>"
Vincent Driessena2e41162010-02-24 01:37:07 +010050 echo " git flow feature diff [<name|nameprefix>]"
51 echo " git flow feature rebase [-i] [<name|nameprefix>]"
Benedikt Böhm00ccea62010-01-26 12:39:36 +010052}
53
Vincent Driessen186d2b52010-01-27 23:48:39 +010054cmd_default() {
Vincent Driessenb866b012010-01-28 01:01:53 +010055 cmd_list "$@"
Benedikt Böhm00ccea62010-01-26 12:39:36 +010056}
57
Vincent Driessenb866b012010-01-28 01:01:53 +010058cmd_list() {
Vincent Driessen44174922010-02-02 23:53:21 +010059 DEFINE_boolean verbose false 'verbose (more) output' v
Vincent Driessen1b819232010-02-01 15:51:43 +010060 parse_args "$@"
61
Vincent Driessenf46e2902010-02-15 23:01:52 +010062 local feature_branches
63 local current_branch
64 local short_names
Vincent Driessen7832d6e2010-02-21 21:31:03 +010065 feature_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
Vincent Driessen27592dd2010-02-06 14:45:39 +010066 if [ -z "$feature_branches" ]; then
Vincent Driessen186d2b52010-01-27 23:48:39 +010067 warn "No feature branches exist."
68 exit 0
69 fi
Vincent Driessen27592dd2010-02-06 14:45:39 +010070 current_branch=$(git branch | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g')
71 short_names=$(echo "$feature_branches" | sed "s ^$PREFIX g")
Vincent Driessenf2536f42010-02-01 15:57:48 +010072
Vincent Driessenaa6d0162010-02-01 19:43:46 +010073 # determine column width first
Vincent Driessenf46e2902010-02-15 23:01:52 +010074 local width=0
75 local branch
Vincent Driessen27592dd2010-02-06 14:45:39 +010076 for branch in $short_names; do
Vincent Driessenf46e2902010-02-15 23:01:52 +010077 local len=${#branch}
Vincent Driessenaa6d0162010-02-01 19:43:46 +010078 width=$(max $width $len)
79 done
Vincent Driessenf46e2902010-02-15 23:01:52 +010080 width=$(($width+3))
Vincent Driessen1adbc3e2010-01-30 16:28:20 +010081
Vincent Driessenf46e2902010-02-15 23:01:52 +010082 local branch
Vincent Driessen27592dd2010-02-06 14:45:39 +010083 for branch in $short_names; do
Vincent Driessenf46e2902010-02-15 23:01:52 +010084 local fullname=$PREFIX$branch
85 local base=$(git merge-base "$fullname" "$DEVELOP_BRANCH")
86 local develop_sha=$(git rev-parse "$DEVELOP_BRANCH")
87 local branch_sha=$(git rev-parse "$fullname")
Vincent Driessen27592dd2010-02-06 14:45:39 +010088 if [ "$fullname" = "$current_branch" ]; then
Vincent Driessenaa6d0162010-02-01 19:43:46 +010089 printf "* "
90 else
91 printf " "
92 fi
Vincent Driessen44174922010-02-02 23:53:21 +010093 if flag verbose; then
Vincent Driessen1adbc3e2010-01-30 16:28:20 +010094 printf "%-${width}s" "$branch"
Vincent Driessenf2536f42010-02-01 15:57:48 +010095 if [ "$branch_sha" = "$develop_sha" ]; then
96 printf "(no commits yet)"
97 elif [ "$base" = "$branch_sha" ]; then
98 printf "(is behind develop, may ff)"
99 elif [ "$base" = "$develop_sha" ]; then
100 printf "(based on latest develop)"
101 else
102 printf "(may be rebased)"
103 fi
Vincent Driessenaa6d0162010-02-01 19:43:46 +0100104 else
105 printf "%s" "$branch"
106 fi
107 echo
108 done
Vincent Driessen186d2b52010-01-27 23:48:39 +0100109}
110
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100111cmd_help() {
112 usage
113 exit 0
114}
115
Vincent Driessend0991262010-02-06 21:19:07 +0100116require_name_arg() {
Vincent Driessen1b819232010-02-01 15:51:43 +0100117 if [ "$NAME" = "" ]; then
Vincent Driessen3c337fb2010-02-04 11:30:18 +0100118 warn "Missing argument <name>"
Vincent Driessen1b819232010-02-01 15:51:43 +0100119 usage
Vincent Driessen2e1856b2010-01-29 15:18:13 +0100120 exit 1
121 fi
122}
123
Vincent Driessend0991262010-02-06 21:19:07 +0100124expand_nameprefix_arg() {
125 require_name_arg
126
Vincent Driessenf46e2902010-02-15 23:01:52 +0100127 local expanded_name
128 local exitcode
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100129 expanded_name=$(gitflow_resolve_nameprefix "$NAME" "$PREFIX")
Vincent Driessend0991262010-02-06 21:19:07 +0100130 exitcode=$?
131 case $exitcode in
132 0) NAME=$expanded_name
133 BRANCH=$PREFIX$NAME
134 ;;
135 *) exit 1 ;;
136 esac
Vincent Driessen2e1856b2010-01-29 15:18:13 +0100137}
138
Vincent Driessend0991262010-02-06 21:19:07 +0100139expand_nameprefix_arg_or_current() {
Vincent Driessenc62633f2010-02-02 10:48:50 +0100140 if [ "$NAME" != "" ]; then
Vincent Driessend0991262010-02-06 21:19:07 +0100141 expand_nameprefix_arg
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100142 require_branch "$PREFIX$NAME"
Vincent Driessenc62633f2010-02-02 10:48:50 +0100143 else
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100144 local current_branch=$(git_current_branch)
Vincent Driessend0991262010-02-06 21:19:07 +0100145 if startswith "$current_branch" "$PREFIX"; then
146 BRANCH=$current_branch
147 NAME=${BRANCH#$PREFIX}
148 else
149 warn "The current HEAD is no feature branch."
150 warn "To diff a feature, specify a <name> argument."
151 usage
152 exit 1
153 fi
Vincent Driessenc62633f2010-02-02 10:48:50 +0100154 fi
155}
156
Vincent Driessenea608952010-01-29 16:56:29 +0100157parse_args() {
Vincent Driessen1b819232010-02-01 15:51:43 +0100158 # parse options
159 FLAGS "$@" || exit $?
160 eval set -- "${FLAGS_ARGV}"
161
162 # read arguments into global variables
Vincent Driessenc5fcc012010-02-10 00:18:08 +0100163 NAME=$1
Vincent Driessen11560922010-02-01 21:58:37 +0100164 BRANCH=$PREFIX$NAME
Vincent Driessenb866b012010-01-28 01:01:53 +0100165}
166
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100167cmd_start() {
Vincent Driessen44174922010-02-02 23:53:21 +0100168 DEFINE_boolean fetch false 'fetch from origin before performing local operation' F
Vincent Driessen5455a6f2010-02-03 00:14:05 +0100169 DEFINE_boolean force false 'force creation of feature branch (ignores dirty working tree)' f
Vincent Driessenea608952010-01-29 16:56:29 +0100170 parse_args "$@"
Vincent Driessenc5fcc012010-02-10 00:18:08 +0100171 BASE=${2:-$DEVELOP_BRANCH}
Vincent Driessend0991262010-02-06 21:19:07 +0100172 require_name_arg
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100173
174 # sanity checks
Vincent Driessen5455a6f2010-02-03 00:14:05 +0100175 if noflag force; then
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100176 require_clean_working_tree
Vincent Driessen5455a6f2010-02-03 00:14:05 +0100177 fi
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100178 require_branch_absent "$BRANCH"
Vincent Driessene034e4a2010-01-29 12:10:44 +0100179
180 # update the local repo with remote changes, if asked
Vincent Driessen44174922010-02-02 23:53:21 +0100181 if flag fetch; then
Vincent Driessena4dd2232010-02-10 00:34:59 +0100182 git fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100183 fi
184
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100185 require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
Vincent Driessene034e4a2010-01-29 12:10:44 +0100186
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100187 # create branch
Vincent Driessena4dd2232010-02-10 00:34:59 +0100188 if ! git checkout -b "$BRANCH" "$BASE"; then
Vincent Driessen5455a6f2010-02-03 00:14:05 +0100189 die "Could not create feature branch '$BRANCH'"
190 fi
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100191
192 echo
193 echo "Summary of actions:"
194 echo "- A new branch '$BRANCH' was created, based on '$BASE'"
195 echo "- You are now on branch '$BRANCH'"
196 echo ""
197 echo "Now, start committing on your feature. When done, use:"
198 echo ""
gmallard192ff522010-04-01 19:31:09 -0400199 echo " git flow feature finish $NAME"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100200 echo
201}
202
203cmd_finish() {
Vincent Driessenca73caf2010-02-07 19:46:38 +0100204 DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F
Vincent Driessen44174922010-02-02 23:53:21 +0100205 DEFINE_boolean rebase false 'rebase instead of merge' r
Vincent Driessen1b819232010-02-01 15:51:43 +0100206 parse_args "$@"
Vincent Driessend0991262010-02-06 21:19:07 +0100207 expand_nameprefix_arg
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100208
209 # sanity checks
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100210 require_branch "$BRANCH"
Vincent Driessene034e4a2010-01-29 12:10:44 +0100211
Vincent Driessen49c7d022010-01-28 12:40:33 +0100212 # detect if we're restoring from a merge conflict
Vincent Driessencf6e92a2010-02-19 19:44:48 +0100213 if [ -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" ]; then
Vincent Driessen49c7d022010-01-28 12:40:33 +0100214 #
215 # TODO: detect that we're working on the correct branch here!
216 # The user need not necessarily have given the same $NAME twice here
217 # (although he/she should).
218 #
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100219
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100220 # TODO: git_is_clean_working_tree() should provide an alternative
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100221 # exit code for "unmerged changes in working tree", which we should
222 # actually be testing for here
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100223 if git_is_clean_working_tree; then
Vincent Driessencf6e92a2010-02-19 19:44:48 +0100224 FINISH_BASE=$(cat "$DOT_GIT_DIR/.gitflow/MERGE_BASE")
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100225
226 # Since the working tree is now clean, either the user did a
227 # succesfull merge manually, or the merge was cancelled.
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100228 # We detect this using git_is_branch_merged_into()
229 if git_is_branch_merged_into "$BRANCH" "$FINISH_BASE"; then
Vincent Driessencf6e92a2010-02-19 19:44:48 +0100230 rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100231 helper_finish_cleanup
232 exit 0
233 else
234 # If the user cancelled the merge and decided to wait until later,
235 # that's fine. But we have to acknowledge this by removing the
236 # MERGE_BASE file and continuing normal execution of the finish
Vincent Driessencf6e92a2010-02-19 19:44:48 +0100237 rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100238 fi
Vincent Driessen49c7d022010-01-28 12:40:33 +0100239 else
240 echo
241 echo "Merge conflicts not resolved yet, use:"
242 echo " git mergetool"
243 echo " git commit"
244 echo
245 echo "You can then complete the finish by running it again:"
246 echo " git flow feature finish $NAME"
247 echo
248 exit 1
249 fi
250 fi
251
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100252 # sanity checks
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100253 require_clean_working_tree
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100254
Vincent Driessene034e4a2010-01-29 12:10:44 +0100255 # update local repo with remote changes first, if asked
Vincent Driessen44174922010-02-02 23:53:21 +0100256 if flag fetch; then
Vincent Driessena4dd2232010-02-10 00:34:59 +0100257 git fetch -q "$ORIGIN" "$BRANCH"
Vincent Driessene034e4a2010-01-29 12:10:44 +0100258 fi
259
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100260 if has "$ORIGIN/$BRANCH" "$(git_remote_branches)"; then
261 require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100262 fi
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100263 require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100264
Vincent Driessen95bf82c2010-02-02 11:58:37 +0100265 # if the user wants to rebase, do that first
Vincent Driessen44174922010-02-02 23:53:21 +0100266 if flag rebase; then
Vincent Driessen010252a2010-02-04 10:31:29 +0100267 if ! git flow feature rebase "$NAME" "$DEVELOP_BRANCH"; then
Vincent Driessen95bf82c2010-02-02 11:58:37 +0100268 warn "Finish was aborted due to conflicts during rebase."
269 warn "Please finish the rebase manually now."
270 warn "When finished, re-run:"
Vincent Driessen010252a2010-02-04 10:31:29 +0100271 warn " git flow feature finish '$NAME' '$DEVELOP_BRANCH'"
Vincent Driessen95bf82c2010-02-02 11:58:37 +0100272 exit 1
273 fi
274 fi
275
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100276 # merge into BASE
Vincent Driessena4dd2232010-02-10 00:34:59 +0100277 git checkout "$DEVELOP_BRANCH"
278 if [ "$(git rev-list -n2 "$DEVELOP_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; then
279 git merge --ff "$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100280 else
Vincent Driessena4dd2232010-02-10 00:34:59 +0100281 git merge --no-ff "$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100282 fi
283
Vincent Driessen49c7d022010-01-28 12:40:33 +0100284 if [ $? -ne 0 ]; then
285 # oops.. we have a merge conflict!
Vincent Driessen010252a2010-02-04 10:31:29 +0100286 # write the given $DEVELOP_BRANCH to a temporary file (we need it later)
Vincent Driessencf6e92a2010-02-19 19:44:48 +0100287 mkdir -p "$DOT_GIT_DIR/.gitflow"
288 echo "$DEVELOP_BRANCH" > "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
Vincent Driessen49c7d022010-01-28 12:40:33 +0100289 echo
290 echo "There were merge conflicts. To resolve the merge conflict manually, use:"
291 echo " git mergetool"
292 echo " git commit"
293 echo
294 echo "You can then complete the finish by running it again:"
295 echo " git flow feature finish $NAME"
296 echo
297 exit 1
298 fi
299
300 # when no merge conflict is detected, just clean up the feature branch
301 helper_finish_cleanup
302}
303
304helper_finish_cleanup() {
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100305 # sanity checks
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100306 require_branch "$BRANCH"
307 require_clean_working_tree
Vincent Driessenf6f152f2010-01-29 10:28:08 +0100308
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100309 # delete branch
Vincent Driessen44174922010-02-02 23:53:21 +0100310 if flag fetch; then
Vincent Driessena4dd2232010-02-10 00:34:59 +0100311 git push "$ORIGIN" ":refs/heads/$BRANCH"
Vincent Driesseneec73c62010-02-02 16:14:16 +0100312 fi
Vincent Driessena4dd2232010-02-10 00:34:59 +0100313 git branch -d "$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100314
315 echo
316 echo "Summary of actions:"
Vincent Driessen010252a2010-02-04 10:31:29 +0100317 echo "- The feature branch '$BRANCH' was merged into '$DEVELOP_BRANCH'"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100318 #echo "- Merge conflicts were resolved" # TODO: Add this line when it's supported
319 echo "- Feature branch '$BRANCH' has been removed"
Vincent Driessen010252a2010-02-04 10:31:29 +0100320 echo "- You are now on branch '$DEVELOP_BRANCH'"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100321 echo
322}
323
324cmd_publish() {
Vincent Driessenea608952010-01-29 16:56:29 +0100325 parse_args "$@"
Vincent Driessend0991262010-02-06 21:19:07 +0100326 expand_nameprefix_arg
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100327
328 # sanity checks
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100329 require_clean_working_tree
330 require_branch "$BRANCH"
Vincent Driessena4dd2232010-02-10 00:34:59 +0100331 git fetch -q "$ORIGIN"
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100332 require_branch_absent "$ORIGIN/$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100333
334 # create remote branch
Vincent Driessena4dd2232010-02-10 00:34:59 +0100335 git push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
336 git fetch -q "$ORIGIN"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100337
338 # configure remote tracking
Vincent Driessena4dd2232010-02-10 00:34:59 +0100339 git config "branch.$BRANCH.remote" "$ORIGIN"
340 git config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
341 git checkout "$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100342
343 echo
344 echo "Summary of actions:"
345 echo "- A new remote branch '$BRANCH' was created"
346 echo "- The local branch '$BRANCH' was configured to track the remote branch"
347 echo "- You are now on branch '$BRANCH'"
348 echo
349}
350
351cmd_track() {
Vincent Driessenea608952010-01-29 16:56:29 +0100352 parse_args "$@"
Vincent Driessend0991262010-02-06 21:19:07 +0100353 require_name_arg
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100354
355 # sanity checks
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100356 require_clean_working_tree
357 require_branch_absent "$BRANCH"
Vincent Driessena4dd2232010-02-10 00:34:59 +0100358 git fetch -q "$ORIGIN"
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100359 require_branch "$ORIGIN/$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100360
361 # create tracking branch
Vincent Driessena4dd2232010-02-10 00:34:59 +0100362 git checkout -b "$BRANCH" "$ORIGIN/$BRANCH"
Benedikt Böhm00ccea62010-01-26 12:39:36 +0100363
364 echo
365 echo "Summary of actions:"
366 echo "- A new remote tracking branch '$BRANCH' was created"
367 echo "- You are now on branch '$BRANCH'"
368 echo
369}
Vincent Driessenbd4f0952010-01-27 13:57:15 +0100370
Vincent Driessenbd4f0952010-01-27 13:57:15 +0100371cmd_diff() {
Vincent Driessen1b819232010-02-01 15:51:43 +0100372 parse_args "$@"
Vincent Driessen1b819232010-02-01 15:51:43 +0100373
Vincent Driessen5474e462010-02-04 15:50:06 +0100374 if [ "$NAME" != "" ]; then
Vincent Driessend0991262010-02-06 21:19:07 +0100375 expand_nameprefix_arg
Vincent Driessena4dd2232010-02-10 00:34:59 +0100376 BASE=$(git merge-base "$DEVELOP_BRANCH" "$BRANCH")
377 git diff "$BASE..$BRANCH"
Vincent Driessen5474e462010-02-04 15:50:06 +0100378 else
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100379 if ! git_current_branch | grep -q "^$PREFIX"; then
Vincent Driessen5474e462010-02-04 15:50:06 +0100380 die "Not on a feature branch. Name one explicitly."
381 fi
382
Vincent Driessena4dd2232010-02-10 00:34:59 +0100383 BASE=$(git merge-base "$DEVELOP_BRANCH" HEAD)
384 git diff "$BASE"
Vincent Driessen5474e462010-02-04 15:50:06 +0100385 fi
Vincent Driessenbd4f0952010-01-27 13:57:15 +0100386}
Vincent Driessenc62633f2010-02-02 10:48:50 +0100387
388cmd_rebase() {
Vincent Driessen44174922010-02-02 23:53:21 +0100389 DEFINE_boolean interactive false 'do an interactive rebase' i
Vincent Driessenc62633f2010-02-02 10:48:50 +0100390 parse_args "$@"
Vincent Driessend0991262010-02-06 21:19:07 +0100391 expand_nameprefix_arg_or_current
Vincent Driessenc62633f2010-02-02 10:48:50 +0100392 warn "Will try to rebase '$NAME'..."
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100393 require_clean_working_tree
394 require_branch "$BRANCH"
Vincent Driessenc62633f2010-02-02 10:48:50 +0100395
396 git checkout -q "$BRANCH"
Vincent Driessenf46e2902010-02-15 23:01:52 +0100397 local OPTS=
Vincent Driessen44174922010-02-02 23:53:21 +0100398 if flag interactive; then
Vincent Driessenc62633f2010-02-02 10:48:50 +0100399 OPTS="$OPTS -i"
400 fi
Vincent Driessen010252a2010-02-04 10:31:29 +0100401 git rebase $OPTS "$DEVELOP_BRANCH"
Vincent Driessenc62633f2010-02-02 10:48:50 +0100402}