[PATCH] rebase: use @{upstream} if no upstream specified

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



'git rebase' without arguments is currently not supported. Make it
default to 'git rebase @{upstream}'. That is also what 'git pull
[--rebase]' defaults to, so it only makes sense that 'git rebase'
defaults to the same thing.

Defaulting to @{upstream} will make it possible to run e.g. 'git
rebase -i' without arguments, which is probably a quite common use
case. It also improves the scenario where you have multiple branches
that rebase against a remote-tracking branch, where you currently have
to choose between the extra network delay of 'git pull' or the
slightly awkward keys to enter 'git rebase @{u}'.

The error reporting when no upstream is configured for the current
branch or when no branch is checked out is reused from git-pull.sh. A
function is extracted into git-parse-remote.sh for this purpose.

Helped-by: Yann Dirson <ydirson@xxxxxxxxxx>
Helped-by: Jonathan Nieder <jrnieder@xxxxxxxxx>
Signed-off-by: Martin von Zweigbergk <martin.von.zweigbergk@xxxxxxxxx>
---

Changes since v1:

 * Extracted error reporting shared with git-pull.sh as suggested by
   Jonathan.

 * Now discards stderr from "git rev-parse -q @{upstream}", since it's
   not quite quiet when there is no upstream.


 Documentation/config.txt     |    2 +-
 Documentation/git-rebase.txt |   11 +++++++++--
 git-parse-remote.sh          |   38 ++++++++++++++++++++++++++++++++++++++
 git-pull.sh                  |   32 ++++----------------------------
 git-rebase.sh                |   21 +++++++++++++++------
 t/t3400-rebase.sh            |   27 ++++++++++++++++++---------
 6 files changed, 85 insertions(+), 46 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index c5e1835..b4e65b8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -646,7 +646,7 @@ branch.<name>.remote::
 
 branch.<name>.merge::
 	Defines, together with branch.<name>.remote, the upstream branch
-	for the given branch. It tells 'git fetch'/'git pull' which
+	for the given branch. It tells 'git fetch'/'git pull'/'git rebase' which
 	branch to merge and can also affect 'git push' (see push.default).
 	When in branch <name>, it tells 'git fetch' the default
 	refspec to be marked for merging in FETCH_HEAD. The value is
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 96680c8..d3e998d 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git rebase' [-i | --interactive] [options] [--onto <newbase>]
-	<upstream> [<branch>]
+	[<upstream>] [<branch>]
 'git rebase' [-i | --interactive] [options] --onto <newbase>
 	--root [<branch>]
 
@@ -21,6 +21,12 @@ If <branch> is specified, 'git rebase' will perform an automatic
 `git checkout <branch>` before doing anything else.  Otherwise
 it remains on the current branch.
 
+If <upstream> is not specified, the upstream configured in
+branch.<name>.remote and branch.<name>.merge options will be used; see
+linkgit:git-config[1] for details.  If you are currently not on any
+branch or if the current branch does not have a configured upstream,
+the rebase will abort.
+
 All changes made by commits in the current branch but that are not
 in <upstream> are saved to a temporary area.  This is the same set
 of commits that would be shown by `git log <upstream>..HEAD` (or
@@ -216,7 +222,8 @@ leave out at most one of A and B, in which case it defaults to HEAD.
 
 <upstream>::
 	Upstream branch to compare against.  May be any valid commit,
-	not just an existing branch name.
+	not just an existing branch name. Defaults to the configured
+	upstream for the current branch.
 
 <branch>::
 	Working branch; defaults to HEAD.
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 1cc2ba6..be17ecb 100644
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -99,3 +99,41 @@ get_remote_merge_branch () {
 	    esac
 	esac
 }
+
+error_on_missing_default_upstream () {
+	cmd="$1"
+	op_type="$2"
+	op_prep="$3"
+	example="$4"
+	branch_name=$(git symbolic-ref -q HEAD)
+	if test -z "$branch_name"
+	then
+		echo "You are not currently on a branch, so I cannot use any
+'branch.<branchname>.merge' in your configuration file.
+Please specify which branch you want to $op_type $op_prep on the command
+line and try again (e.g. '$example').
+See git-${cmd}(1) for details."
+	else
+		echo "You asked me to $cmd without telling me which branch you
+want to $op_type $op_prep, and 'branch.${branch_name#refs/heads/}.merge' in
+your configuration file does not tell me, either. Please
+specify which branch you want to use on the command line and
+try again (e.g. '$example').
+See git-${cmd}(1) for details.
+
+If you often $op_type $op_prep the same branch, you may want to
+use something like the following in your configuration file:
+    [branch \"${branch_name#refs/heads/}\"]
+    remote = <nickname>
+    merge = <remote-ref>"
+		test rebase = "$op_type" &&
+		echo "    rebase = true"
+		echo "
+    [remote \"<nickname>\"]
+    url = <url>
+    fetch = <refspec>
+
+See git-config(1) for details."
+	fi
+	exit 1
+}
diff --git a/git-pull.sh b/git-pull.sh
index eb87f49..2cdea26 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -163,34 +163,10 @@ error_on_no_merge_candidates () {
 		echo "You asked to pull from the remote '$1', but did not specify"
 		echo "a branch. Because this is not the default configured remote"
 		echo "for your current branch, you must specify a branch on the command line."
-	elif [ -z "$curr_branch" ]; then
-		echo "You are not currently on a branch, so I cannot use any"
-		echo "'branch.<branchname>.merge' in your configuration file."
-		echo "Please specify which remote branch you want to use on the command"
-		echo "line and try again (e.g. 'git pull <repository> <refspec>')."
-		echo "See git-pull(1) for details."
-	elif [ -z "$upstream" ]; then
-		echo "You asked me to pull without telling me which branch you"
-		echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
-		echo "your configuration file does not tell me, either. Please"
-		echo "specify which branch you want to use on the command line and"
-		echo "try again (e.g. 'git pull <repository> <refspec>')."
-		echo "See git-pull(1) for details."
-		echo
-		echo "If you often $op_type $op_prep the same branch, you may want to"
-		echo "use something like the following in your configuration file:"
-		echo
-		echo "    [branch \"${curr_branch}\"]"
-		echo "    remote = <nickname>"
-		echo "    merge = <remote-ref>"
-		test rebase = "$op_type" &&
-			echo "    rebase = true"
-		echo
-		echo "    [remote \"<nickname>\"]"
-		echo "    url = <url>"
-		echo "    fetch = <refspec>"
-		echo
-		echo "See git-config(1) for details."
+	elif [ -z "$curr_branch" -o -z "$upstream" ]; then
+		. git-parse-remote
+		error_on_missing_default_upstream "pull" $op_type $op_prep \
+			"git pull <repository> <refspec>"
 	else
 		echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
 		echo "from the remote, but no such ref was fetched."
diff --git a/git-rebase.sh b/git-rebase.sh
index be9ec2a..a040ab5 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] (<upstream>|--root) [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -345,8 +345,6 @@ and run me again.  I am stopping in case you still have something
 valuable there.'
 fi
 
-test $# -eq 0 && test -z "$rebase_root" && usage
-
 if test -n "$interactive_rebase"
 then
 	type=interactive
@@ -362,9 +360,20 @@ fi
 
 if test -z "$rebase_root"
 then
-	# The upstream head must be given.  Make sure it is valid.
-	upstream_name="$1"
-	shift
+	case "$#" in
+	0)
+		if ! upstream_name=$(git rev-parse --symbolic-full-name \
+			--verify -q @{upstream} 2>/dev/null)
+		then
+			. git-parse-remote
+			error_on_missing_default_upstream "rebase" "rebase" \
+				"against" "git rebase <upstream branch>"
+		fi
+		;;
+	*)	upstream_name="$1"
+		shift
+		;;
+	esac
 	upstream=`git rev-parse --verify "${upstream_name}^0"` ||
 	die "invalid upstream $upstream_name"
 	upstream_arg="$upstream_name"
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 349eebd..6eaecec 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -158,15 +158,24 @@ test_expect_success 'Show verbose error when HEAD could not be detached' '
 '
 rm -f B
 
-test_expect_success 'dump usage when upstream arg is missing' '
-	git checkout -b usage topic &&
-	test_must_fail git rebase 2>error1 &&
-	grep "[Uu]sage" error1 &&
-	test_must_fail git rebase --abort 2>error2 &&
-	grep "No rebase in progress" error2 &&
-	test_must_fail git rebase --onto master 2>error3 &&
-	grep "[Uu]sage" error3 &&
-	! grep "can.t shift" error3
+test_expect_success 'fail when upstream arg is missing and not on branch' '
+	git checkout topic &&
+	test_must_fail git rebase >output.out &&
+	grep "You are not currently on a branch" output.out
+'
+
+test_expect_success 'fail when upstream arg is missing and not configured' '
+	git checkout -b no-config topic &&
+	test_must_fail git rebase >output.out &&
+	grep "branch.no-config.merge" output.out
+'
+
+test_expect_success 'default to @{upstream} when upstream arg is missing' '
+	git checkout -b default topic &&
+	git config branch.default.remote .
+	git config branch.default.merge refs/heads/master
+	git rebase &&
+	test "$(git rev-parse default~1)" = "$(git rev-parse master)"
 '
 
 test_expect_success 'rebase -q is quiet' '
-- 
1.7.4.rc2.33.g8a14f

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]