1# $Id$
2# vim:et:ft=sh:sts=2:sw=2
3#
4# git-flow -- A collection of Git extensions to provide high-level
5# repository operations for Vincent Driessen's branching model.
6#
7# A blog post presenting this model is found at:
8#    http://blog.avirtualhome.com/development-workflow-using-git/
9#
10# Feel free to contribute to this project at:
11#    http://github.com/petervanderdoes/gitflow
12#
13# Authors:
14# Copyright 2012-2019 Peter van der Does. All rights reserved.
15#
16# Original Author:
17# Copyright 2010 Vincent Driessen. All rights reserved.
18#
19# Redistribution and use in source and binary forms, with or without
20# modification, are permitted provided that the following conditions are met:
21#
22# 1. Redistributions of source code must retain the above copyright notice, this
23#    list of conditions and the following disclaimer.
24# 2. Redistributions in binary form must reproduce the above copyright notice,
25#    this list of conditions and the following disclaimer in the documentation
26#    and/or other materials provided with the distribution.
27#
28# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
29# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
32# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38#
39
40initialize() {
41	require_git_repo
42	require_gitflow_initialized
43	git config --get gitflow.prefix.bugfix >/dev/null 2>&1 || die "Bugfix prefix not set. Please run 'git flow init'."
44	gitflow_load_settings
45	PREFIX=$(git config --get gitflow.prefix.bugfix)
46}
47
48usage() {
49	OPTIONS_SPEC="\
50git flow bugfix [list]
51git flow bugfix start
52git flow bugfix finish
53git flow bugfix publish
54git flow bugfix track
55git flow bugfix diff
56git flow bugfix rebase
57git flow bugfix checkout
58git flow bugfix pull
59git flow bugfix delete
60
61Manage your bugfix branches.
62
63For more specific help type the command followed by --help
64--
65"
66	flags_help
67}
68
69cmd_default() {
70	cmd_list "$@"
71}
72
73cmd_list() {
74	OPTIONS_SPEC="\
75git flow bugfix [list] [-h] [-v]
76
77Lists all the existing bugfix branches in the local repository.
78--
79h,help!     Show this help
80v,verbose   Verbose (more) output
81"
82	local bugfix_branches current_branch width branch len
83	local base develop_sha branch_sha
84
85	# Define flags
86	DEFINE_boolean 'verbose' false 'verbose (more) output' v
87
88	# Parse argun=ments
89	parse_args "$@"
90
91	bugfix_branches=$(git_local_branches_prefixed "$PREFIX")
92	if [ -z "$bugfix_branches" ]; then
93		warn "No bugfix branches exist."
94		warn ""
95		warn "You can start a new bugfix branch:"
96		warn ""
97		warn "    git flow bugfix start <name> [<base>]"
98		warn ""
99		exit 0
100	fi
101	current_branch=$(git_current_branch)
102
103	# Determine column width first
104	width=0
105	for branch in $bugfix_branches; do
106		len=${#branch}
107		width=$(max $width $len)
108	done
109	width=$(($width+3-${#PREFIX}))
110
111	for branch in $bugfix_branches; do
112		base=$(git merge-base "$branch" "$DEVELOP_BRANCH")
113		develop_sha=$(git rev-parse "$DEVELOP_BRANCH")
114		branch_sha=$(git rev-parse "$branch")
115		if [ "$branch" = "$current_branch" ]; then
116			printf "* "
117		else
118			printf "  "
119		fi
120		if flag verbose; then
121			printf "%-${width}s" "${branch#$PREFIX}"
122			if [ "$branch_sha" = "$develop_sha" ]; then
123				printf "(no commits yet)"
124			elif [ "$base" = "$branch_sha" ]; then
125				printf "(is behind develop, may ff)"
126			elif [ "$base" = "$develop_sha" ]; then
127				printf "(based on latest develop)"
128			else
129				printf "(may be rebased)"
130			fi
131		else
132			printf "%s" "${branch#$PREFIX}"
133		fi
134		echo
135	done
136}
137
138cmd_help() {
139	usage
140	exit 0
141}
142
143# Parse arguments and set common variables
144parse_args() {
145	FLAGS "$@" || exit $?
146	eval set -- "${FLAGS_ARGV}"
147
148	# read arguments into global variables
149	if [ -z $1 ]; then
150		NAME=''
151	else
152		NAME=$1
153	fi
154	BRANCH=$PREFIX$NAME
155}
156
157parse_remote_name() {
158	# Parse arguments
159	FLAGS "$@" || exit $?
160	eval set -- "${FLAGS_ARGV}"
161
162	# read arguments into global variables
163	if [ -z $1 ]; then
164		REMOTE=''
165	else
166		REMOTE=$1
167	fi
168
169	if [ -z $2 ]; then
170		NAME=''
171	else
172		NAME=$2
173	fi
174	BRANCH=$PREFIX$NAME
175}
176
177cmd_start() {
178	OPTIONS_SPEC="\
179git flow bugfix start [-h] [-F] <name> [<base>]
180
181Start new bugfix <name>, optionally basing it on <base> instead of <develop>
182--
183h,help!          Show this help
184showcommands!    Show git commands while executing them
185F,[no]fetch      Fetch from origin before performing local operation
186"
187	local base
188
189	# Define flags
190	DEFINE_boolean 'fetch' false 'fetch from origin before performing local operation' F
191
192	# Override defaults with values from config
193	gitflow_override_flag_boolean   "bugfix.start.fetch"   "fetch"
194
195	# Parse arguments
196	parse_args "$@"
197	eval set -- "${FLAGS_ARGV}"
198	base=${2:-$DEVELOP_BRANCH}
199
200	require_base_is_local_branch "$base"
201	gitflow_require_name_arg
202
203	# Update the local repo with remote changes, if asked
204	if flag fetch; then
205		git_fetch_branch "$ORIGIN" "$base"
206	fi
207
208	# Sanity checks
209	require_branch_absent "$BRANCH"
210
211	# If the origin branch counterpart exists, assert that the local branch
212	# isn't behind it (to avoid unnecessary rebasing)
213	if git_remote_branch_exists "$ORIGIN/$base"; then
214		require_branches_equal "$base" "$ORIGIN/$base"
215	fi
216
217	run_pre_hook "$NAME" "$ORIGIN" "$BRANCH" "$base"
218
219	gitflow_config_set_base_branch $base $BRANCH
220
221	# create branch
222	git_do checkout -b "$BRANCH" "$base" || die "Could not create bugfix branch '$BRANCH'."
223
224	run_post_hook "$NAME" "$ORIGIN" "$BRANCH" "$base"
225
226	echo
227	echo "Summary of actions:"
228	echo "- A new branch '$BRANCH' was created, based on '$base'"
229	echo "- You are now on branch '$(git_current_branch)'"
230	echo ""
231	echo "Now, start committing on your bugfix. When done, use:"
232	echo ""
233	echo "     git flow bugfix finish $NAME"
234	echo
235}
236
237cmd_finish() {
238	OPTIONS_SPEC="\
239git flow bugfix finish [-h] [-F] [-r] [-p] [-k] [-D] [-S] [--no-ff] <name|nameprefix>
240
241Finish bugfix <name>
242--
243h,help!                Show this help
244showcommands!          Show git commands while executing them
245F,[no]fetch            Fetch from origin before performing finish
246r,[no]rebase           Rebase before merging
247p,[no]preserve-merges  Preserve merges while rebasing
248[no]push               Push to origin after performing finish
249k,[no]keep             Keep branch after performing finish
250keepremote!        	   Keep the remote branch
251keeplocal!             Keep the local branch
252D,[no]force_delete     Force delete bugfix branch after finish
253S,[no]squash           Squash bugfix during merge
254no-ff!                 Never fast-forward during the merge
255"
256	local finish_base
257
258	# Define flags
259	DEFINE_boolean 'fetch' false "fetch from $ORIGIN before performing finish" F
260	DEFINE_boolean 'rebase' false "rebase before merging" r
261	DEFINE_boolean 'preserve-merges' false 'try to recreate merges while rebasing' p
262	DEFINE_boolean 'push' false "push to $ORIGIN after performing finish"
263	DEFINE_boolean 'keep' false "keep branch after performing finish" k
264	DEFINE_boolean 'keepremote' false "keep the remote branch"
265	DEFINE_boolean 'keeplocal' false "keep the local branch"
266	DEFINE_boolean 'force_delete' false "force delete bugfix branch after finish" D
267	DEFINE_boolean 'squash' false "squash bugfix during merge" S
268	DEFINE_boolean 'squash-info' false "add branch info during squash"
269	DEFINE_boolean 'no-ff!' false "Don't fast-forward ever during merge "
270
271	# Override defaults with values from config
272	gitflow_override_flag_boolean   "bugfix.finish.fetch"             "fetch"
273	gitflow_override_flag_boolean   "bugfix.finish.rebase"            "rebase"
274	gitflow_override_flag_boolean   "bugfix.finish.preserve-merges"   "preserve_merges"
275	gitflow_override_flag_boolean   "bugfix.finish.push"              "push"
276	gitflow_override_flag_boolean   "bugfix.finish.keep"              "keep"
277	gitflow_override_flag_boolean   "bugfix.finish.keepremote"        "keepremote"
278	gitflow_override_flag_boolean   "bugfix.finish.keeplocal"         "keeplocal"
279	gitflow_override_flag_boolean   "bugfix.finish.force-delete"      "force_delete"
280	gitflow_override_flag_boolean   "bugfix.finish.squash"            "squash"
281	gitflow_override_flag_boolean   "bugfix.finish.squash-info"       "squash_info"
282	gitflow_override_flag_boolean   "bugfix.finish.no-ff"             "no_ff"
283
284	# Parse arguments
285	parse_args "$@"
286
287	# Use current branch if no name is given
288	if [ "$NAME" = "" ]; then
289		gitflow_use_current_branch_name
290	fi
291
292	# Keeping both branches implies the --keep flag to be true.
293	if flag keepremote && flag keeplocal; then
294		FLAGS_keep=$FLAGS_TRUE
295	fi
296
297	# Sanity checks
298	require_branch "$BRANCH"
299
300	BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH)
301	BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH}
302	git_local_branch_exists "$BASE_BRANCH" || die "The base '$BASE_BRANCH' doesn't exists locally or is not a branch. Can't finish the bugfix branch '$BRANCH'."
303
304	# Detect if we're restoring from a merge conflict
305	if [ -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" ]; then
306		#
307		# TODO: detect that we're working on the correct branch here!
308		# The user need not necessarily have given the same $NAME twice here
309		# (although he/she should).
310		#
311
312		# TODO: git_is_clean_working_tree() should provide an alternative
313		# exit code for "unmerged changes in working tree", which we should
314		# actually be testing for here
315		if git_is_clean_working_tree; then
316			finish_base=$(cat "$DOT_GIT_DIR/.gitflow/MERGE_BASE")
317
318			# Since the working tree is now clean, either the user did a
319			# successful merge manually, or the merge was cancelled.
320			# We detect this using git_is_branch_merged_into()
321			if git_is_branch_merged_into "$BRANCH" "$finish_base"; then
322				rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
323				helper_finish_cleanup
324				exit 0
325			else
326				# If the user cancelled the merge and decided to wait until
327				# later,that's fine. But we have to acknowledge this by
328				# removing the MERGE_BASE file and continuing normal execution
329				# of the finish
330				rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
331			fi
332		else
333			echo
334			echo "Merge conflicts not resolved yet, use:"
335			echo "    git mergetool"
336			echo "    git commit"
337			echo
338			echo "You can then complete the finish by running it again:"
339			echo "    git flow bugfix finish $NAME"
340			echo
341			exit 1
342		fi
343	fi
344
345	# Sanity checks
346	require_clean_working_tree
347
348	# We always fetch the Branch from Origin
349	# This is done to avoid possible commits on the remote that are not
350	# merged into the local branch
351	if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
352		git_fetch_branch "$ORIGIN" "$BRANCH"
353	fi
354
355	# Update local branches with remote branches
356	if flag fetch; then
357		git_fetch_branch "$ORIGIN" "$BASE_BRANCH"
358	fi
359
360	# Check if the local branches have all the commits from the remote branches
361	if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
362			require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH"
363	fi
364	if git_remote_branch_exists "$ORIGIN/$BASE_BRANCH"; then
365		require_branches_equal "$BASE_BRANCH" "$ORIGIN/$BASE_BRANCH"
366	fi
367
368	run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
369
370	# If the user wants to rebase, do that first
371	if flag rebase; then
372		local _rebase_opts=""
373		if flag preserve_merges; then
374			_rebase_opts="$_rebase_opts -p"
375		fi
376		if flag showcommands; then
377			_rebase_opts="$_rebase_opts --showcommands"
378		fi
379		if ! git flow bugfix rebase $_rebase_opts "$NAME"; then
380			warn "Finish was aborted due to conflicts during rebase."
381			warn "Please finish the rebase manually now."
382			warn "When finished, re-run:"
383			warn "    git flow bugfix finish '$NAME' '$BASE_BRANCH'"
384			exit 1
385		fi
386	fi
387
388	# Merge into BASE
389	git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'."
390
391	if noflag squash; then
392		if flag no_ff; then
393			git_do merge --no-ff "$BRANCH"
394		else
395			if [ "$(git rev-list -n2 "$BASE_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; then
396				git_do merge --ff "$BRANCH"
397			else
398				git_do merge --no-ff "$BRANCH"
399			fi
400		fi
401	else
402		git_do merge --squash "$BRANCH"
403		flag squash_info && gitflow_create_squash_message "Merged bugfix branch '$BRANCH'" "$BASE_BRANCH" "$BRANCH" > "$DOT_GIT_DIR/SQUASH_MSG"
404		git_do commit
405	fi
406
407	if [ $? -ne 0 ]; then
408		# Oops.. we have a merge conflict!
409		# Write the given $BASE_BRANCH to a temporary file as we will
410		# be needing it later.
411		mkdir -p "$DOT_GIT_DIR/.gitflow"
412		echo "$BASE_BRANCH" > "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
413		echo
414		echo "There were merge conflicts. To resolve the merge conflict manually, use:"
415		echo "    git mergetool"
416		echo "    git commit"
417		echo
418		echo "You can then complete the finish by running it again:"
419		echo "    git flow bugfix finish $NAME"
420		echo
421		exit 1
422	fi
423
424	run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
425
426	# When no merge conflict is detected, just clean up the bugfix branch
427	gitflow_config_remove_base_branch "$BRANCH"
428	helper_finish_cleanup
429}
430
431helper_finish_cleanup() {
432	local keepmsg remotebranchdeleted localbranchdeleted
433
434	# Sanity checks
435	require_branch "$BRANCH"
436	require_clean_working_tree
437
438	remotebranchdeleted=$FLAGS_FALSE
439	localbranchdeleted=$FLAGS_FALSE
440
441	if flag push; then
442		git_do push "$ORIGIN" "$BASE_BRANCH" || die "Could not push branch '$BASE_BRANCH' to remote '$ORIGIN'."
443	fi
444
445	if noflag keep; then
446
447		# Always delete remote first
448		if noflag keepremote;then
449			if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
450				git_remote_branch_delete "$BRANCH" && remotebranchdeleted=$FLAGS_TRUE
451			fi
452		fi
453
454		# Delete local after remote to avoid warnings
455		if noflag keeplocal; then
456			if [ "$BRANCH" = "$(git_current_branch)" ]; then
457				git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'."
458			fi
459			if flag force_delete; then
460				git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE
461			else
462				if noflag squash; then
463					git_do branch -d "$BRANCH" && localbranchdeleted=$FLAGS_TRUE
464				else
465					git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE
466				fi
467			fi
468		fi
469
470		# no more branches: we can safely remove config section
471		if ! git_remote_branch_exists "$ORIGIN/$BRANCH" -a ! git_local_branch_exists "$BRANCH"; then
472			gitflow_config_remove_base_section "$BRANCH"
473		fi
474	fi
475
476	echo
477	echo "Summary of actions:"
478	echo "- The bugfix branch '$BRANCH' was merged into '$BASE_BRANCH'"
479	#echo "- Merge conflicts were resolved"		# TODO: Add this line when it's supported
480	if noflag keep; then
481		if [ $localbranchdeleted -eq $FLAGS_TRUE ]; then
482			keepmsg="has been locally deleted"
483		else
484			keepmsg="is still locally available"
485		fi
486		if [ $remotebranchdeleted -eq $FLAGS_TRUE ]; then
487			keepmsg=$keepmsg"; it has been remotely deleted from '$ORIGIN'"
488		elif git_remote_branch_exists "$ORIGIN/$BRANCH"; then
489			keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'"
490		fi
491	else
492		keepmsg="is still locally available"
493		if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
494			keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'"
495		fi
496	fi
497	echo "- bugfix branch '$BRANCH' "$keepmsg
498	echo "- You are now on branch '$(git_current_branch)'"
499	echo
500}
501
502cmd_publish() {
503	OPTIONS_SPEC="\
504git flow bugfix publish [-h] [<name>]
505
506Publish bugfix branch <name> on $ORIGIN.
507When <name> is omitted the current branch is used, but only if it's a bugfix branch.
508--
509h,help!          Show this help
510showcommands!    Show git commands while executing them
511"
512	# Parse arguments
513	parse_args "$@"
514
515	# Use current branch if no name is given
516	if [ "$NAME" = "" ]; then
517		gitflow_use_current_branch_name
518	fi
519
520
521	# Sanity checks
522	require_clean_working_tree
523	require_branch "$BRANCH"
524	git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'."
525	require_branch_absent "$ORIGIN/$BRANCH"
526
527	run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
528
529	# Create remote branch with remote tracking
530	git_do push -u "$ORIGIN" "$BRANCH:$BRANCH"
531	git_do fetch -q "$ORIGIN" "$BRANCH" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'."
532	git_do checkout "$BRANCH" || die "Could not check out branch '$BRANCH'."
533
534	run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
535
536	echo
537	echo "Summary of actions:"
538	echo "- The remote branch '$BRANCH' was created or updated"
539	echo "- The local branch '$BRANCH' was configured to track the remote branch"
540	echo "- You are now on branch '$(git_current_branch)'"
541	echo
542}
543
544cmd_track() {
545	OPTIONS_SPEC="\
546git flow bugfix track [-h] <name>
547
548Start tracking bugfix <name> that is shared on $ORIGIN
549--
550h,help!          Show this help
551showcommands!    Show git commands while executing them
552"
553	# Parse arguments
554	parse_args "$@"
555
556	gitflow_require_name_arg
557
558	# Sanity checks
559	require_clean_working_tree
560	require_local_branch_absent "$BRANCH"
561
562	run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
563
564	git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'."
565	git_remote_branch_exists "$ORIGIN/$BRANCH"
566
567	# Create tracking branch
568	git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" || die "Could not create '$BRANCH'."
569
570	run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
571
572	echo
573	echo "Summary of actions:"
574	echo "- A new remote tracking branch '$BRANCH' was created"
575	echo "- You are now on branch '$(git_current_branch)'"
576	echo
577}
578
579cmd_diff() {
580	OPTIONS_SPEC="\
581git flow bugfix diff [-h] [<name|nameprefix>]
582
583Show all changes in <name> that are not in the base
584--
585h,help!          Show this help
586showcommands!    Show git commands while executing them
587"
588	local base
589
590	# Parse arguments
591	parse_args "$@"
592
593	# Use current branch if no name is given
594	if [ "$NAME" = "" ]; then
595		gitflow_use_current_branch_name
596	fi
597
598	base=$(gitflow_config_get_base_branch $BRANCH)
599	base=${base:-$DEVELOP_BRANCH}
600
601	git_do diff "$base...$BRANCH"
602}
603
604cmd_checkout() {
605	OPTIONS_SPEC="\
606git flow bugfix checkout [-h] [<name|nameprefix>]
607
608Switch to bugfix branch <name>
609--
610h,help!          Show this help
611showcommands!    Show git commands while executing them
612"
613	# Parse arguments
614	parse_args "$@"
615
616	NAME=$(gitflow_resolve_nameprefix "$NAME" "$PREFIX")
617	if [ $? -eq 0 ]; then
618		BRANCH=$PREFIX$NAME
619		git_do checkout "$BRANCH"  || die "Could not check out branch '$BRANCH'."
620	fi
621}
622
623cmd_co() {
624	# Alias for checkout
625	cmd_checkout "$@"
626}
627
628cmd_rebase() {
629	OPTIONS_SPEC="\
630git flow bugfix rebase [-h] [-i] [-p] [<name|nameprefix>]
631
632Rebase <name> on <base_branch>
633--
634h,help!                Show this help
635showcommands!          Show git commands while executing them
636i,[no]interactive      Do an interactive rebase
637p,[no]preserve-merges  Preserve merges
638"
639	local opts
640
641	# Define flags
642	DEFINE_boolean 'interactive' false 'do an interactive rebase' i
643	DEFINE_boolean 'preserve-merges' false 'try to recreate merges' p
644
645	# Override defaults with values from config
646	gitflow_override_flag_boolean   "bugfix.rebase.interactive"       "interactive"
647	gitflow_override_flag_boolean   "bugfix.rebase.preserve-merges"   "preserve_merges"
648
649	# Parse arguments
650	parse_args "$@"
651
652	# Use current branch if no name is given
653	if [ "$NAME" = "" ]; then
654		gitflow_use_current_branch_name
655	fi
656
657
658	BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH)
659	BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH}
660
661	warn "Will try to rebase '$NAME' which is based on '$BASE_BRANCH'..."
662	if ! git_config_bool_exists "rebase.autostash"; then
663		require_clean_working_tree
664	fi
665	require_branch "$BRANCH"
666
667	git_local_branch_exists "$BASE_BRANCH" || die "The base '$BASE_BRANCH' doesn't exists locally or is not a branch. Can't rebase the bugfix branch '$BRANCH'."
668
669	git_do checkout -q "$BRANCH"  || die "Could not check out branch '$BRANCH'."
670	if flag interactive; then
671		opts="$opts -i"
672	fi
673	if flag preserve_merges; then
674		opts="$opts -p"
675	fi
676	git_do rebase $opts "$BASE_BRANCH"
677}
678
679avoid_accidental_cross_branch_action() {
680	local current_branch
681
682	current_branch=$(git_current_branch)
683	if [ "$BRANCH" != "$current_branch" ]; then
684		warn "Trying to pull from '$BRANCH' while currently on branch '$current_branch'."
685		warn "To avoid unintended merges, git-flow aborted."
686		return 1
687	fi
688	return 0
689}
690
691cmd_pull() {
692	OPTIONS_SPEC="\
693git flow bugfix pull [-h] <remote> [<name>]
694
695Pull bugfix <name> from <remote>
696--
697h,help!          Show this help
698showcommands!    Show git commands while executing them
699"
700	local current_branch
701
702	# Define flags
703	DEFINE_boolean 'rebase' false "pull with rebase" r
704
705	warn "The command 'git flow bugfix pull' will be deprecated per version 2.0.0. Use 'git flow bugfix track' instead."
706
707	# Parse arguments
708	parse_remote_name "$@"
709
710	if [ -z "$REMOTE" ]; then
711		die "Name a remote explicitly."
712	fi
713
714	# Use current branch if no name is given
715	if [ "$NAME" = "" ]; then
716		gitflow_use_current_branch_name
717	fi
718
719	# To avoid accidentally merging different bugfix branches into each other,
720	# die if the current bugfix branch differs from the requested $NAME
721	# argument.
722	current_branch=$(git_current_branch)
723	if startswith "$current_branch" "$PREFIX"; then
724		# We are on a local bugfix branch already, so $BRANCH must be equal to
725		# the current branch
726		avoid_accidental_cross_branch_action || die
727	fi
728
729	require_clean_working_tree
730
731	run_pre_hook "$NAME" "$REMOTE" "$BRANCH"
732
733	if git_local_branch_exists "$BRANCH"; then
734		# Again, avoid accidental merges
735		avoid_accidental_cross_branch_action || die
736
737		# We already have a local branch called like this, so simply pull the
738		# remote changes in
739		if flag rebase; then
740			if ! git_do pull --rebase -q "$REMOTE" "$BRANCH"; then
741				warn "Pull was aborted. There might be conflicts during rebase or '$REMOTE' might be inaccessible."
742				exit 1
743			fi
744		else
745			git_do pull -q "$REMOTE" "$BRANCH" || die "Failed to pull from remote '$REMOTE'."
746		fi
747
748		echo "Pulled $REMOTE's changes into $BRANCH."
749	else
750		# Setup the local branch clone for the first time
751		git_do fetch -q "$REMOTE" "$BRANCH" ||  die "Could not fetch branch '$BRANCH' from remote '$REMOTE'."     # Stores in FETCH_HEAD
752		git_do branch --no-track "$BRANCH" FETCH_HEAD || die "Branch failed."
753		git_do checkout -q "$BRANCH" || die "Could not check out branch '$BRANCH'."
754		echo "Created local branch $BRANCH based on $REMOTE's $BRANCH."
755	fi
756
757	run_post_hook "$NAME" "$REMOTE" "$BRANCH"
758}
759
760cmd_delete() {
761	OPTIONS_SPEC="\
762git flow bugfix delete [-h] [-f] [-r] <name>
763
764Delete a given bugfix branch
765--
766h,help!          Show this help
767showcommands!    Show git commands while executing them
768f,[no]force      Force deletion
769r,[no]remote     Delete remote branch
770"
771	local current_branch
772
773	# Define flags
774	DEFINE_boolean 'force' false "force deletion" f
775	DEFINE_boolean 'remote' false "delete remote branch" r
776
777	# Override defaults with values from config
778	gitflow_override_flag_boolean   "bugfix.delete.force"    "force"
779	gitflow_override_flag_boolean   "bugfix.delete.remote"   "remote"
780
781	# Parse arguments
782	parse_args "$@"
783
784	gitflow_require_name_arg
785
786	# Sanity checks
787	require_branch "$BRANCH"
788
789	BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH)
790	BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH}
791
792	run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
793
794	current_branch=$(git_current_branch)
795	# We can't delete a branch we are on, switch to the develop branch.
796	if [ "$BRANCH" = "$current_branch" ]; then
797		require_clean_working_tree
798		if git_local_branch_exists "$BASE_BRANCH"; then
799			git_do checkout "$BASE_BRANCH"
800		else
801			git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'."
802		fi
803	fi
804
805	if git_is_branch_merged_into "$BRANCH" "$BASE_BRANCH"; then
806		git_do branch -d "$BRANCH" || die "Could not delete the $BRANCH."
807		if flag remote; then
808			git_remote_branch_delete "$BRANCH"
809		fi
810	else
811		if flag force; then
812			git_do branch -D "$BRANCH" || die "Could not delete the $BRANCH."
813			if flag remote; then
814				git_remote_branch_delete "$BRANCH"
815			fi
816		else
817			die "bugfix branch '$BRANCH' has been not been merged yet. Use -f to force the deletion."
818		fi
819	fi
820
821	gitflow_config_remove_base_section "$BRANCH"
822	run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
823
824	echo
825	echo "Summary of actions:"
826	echo "- bugfix branch '$BRANCH' has been deleted."
827	flag remote && echo "- bugfix branch '$BRANCH' in '$ORIGIN' has been deleted."
828	echo "- You are now on branch '$(git_current_branch)'"
829	echo
830}
831
832cmd_rename() {
833	OPTIONS_SPEC="\
834git flow bugfix rename <new_name> [<new_name>]
835
836Rename a given bugfix branch
837--
838h,help!          Show this help
839showcommands!    Show git commands while executing them
840"
841	gitflow_rename_branch "$@"
842}
843