Skip to content

Commit 15a147e

Browse files
Martin von Zweigbergkgitster
authored andcommitted
rebase: use @{upstream} if no upstream specified
'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 <[email protected]> Helped-by: Jonathan Nieder <[email protected]> Signed-off-by: Martin von Zweigbergk <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c71f8f3 commit 15a147e

File tree

6 files changed

+85
-46
lines changed

6 files changed

+85
-46
lines changed

Documentation/config.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ branch.<name>.remote::
646646

647647
branch.<name>.merge::
648648
Defines, together with branch.<name>.remote, the upstream branch
649-
for the given branch. It tells 'git fetch'/'git pull' which
649+
for the given branch. It tells 'git fetch'/'git pull'/'git rebase' which
650650
branch to merge and can also affect 'git push' (see push.default).
651651
When in branch <name>, it tells 'git fetch' the default
652652
refspec to be marked for merging in FETCH_HEAD. The value is

Documentation/git-rebase.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ SYNOPSIS
99
--------
1010
[verse]
1111
'git rebase' [-i | --interactive] [options] [--onto <newbase>]
12-
<upstream> [<branch>]
12+
[<upstream>] [<branch>]
1313
'git rebase' [-i | --interactive] [options] --onto <newbase>
1414
--root [<branch>]
1515

@@ -21,6 +21,12 @@ If <branch> is specified, 'git rebase' will perform an automatic
2121
`git checkout <branch>` before doing anything else. Otherwise
2222
it remains on the current branch.
2323

24+
If <upstream> is not specified, the upstream configured in
25+
branch.<name>.remote and branch.<name>.merge options will be used; see
26+
linkgit:git-config[1] for details. If you are currently not on any
27+
branch or if the current branch does not have a configured upstream,
28+
the rebase will abort.
29+
2430
All changes made by commits in the current branch but that are not
2531
in <upstream> are saved to a temporary area. This is the same set
2632
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.
216222

217223
<upstream>::
218224
Upstream branch to compare against. May be any valid commit,
219-
not just an existing branch name.
225+
not just an existing branch name. Defaults to the configured
226+
upstream for the current branch.
220227

221228
<branch>::
222229
Working branch; defaults to HEAD.

git-parse-remote.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,41 @@ get_remote_merge_branch () {
9999
esac
100100
esac
101101
}
102+
103+
error_on_missing_default_upstream () {
104+
cmd="$1"
105+
op_type="$2"
106+
op_prep="$3"
107+
example="$4"
108+
branch_name=$(git symbolic-ref -q HEAD)
109+
if test -z "$branch_name"
110+
then
111+
echo "You are not currently on a branch, so I cannot use any
112+
'branch.<branchname>.merge' in your configuration file.
113+
Please specify which branch you want to $op_type $op_prep on the command
114+
line and try again (e.g. '$example').
115+
See git-${cmd}(1) for details."
116+
else
117+
echo "You asked me to $cmd without telling me which branch you
118+
want to $op_type $op_prep, and 'branch.${branch_name#refs/heads/}.merge' in
119+
your configuration file does not tell me, either. Please
120+
specify which branch you want to use on the command line and
121+
try again (e.g. '$example').
122+
See git-${cmd}(1) for details.
123+
124+
If you often $op_type $op_prep the same branch, you may want to
125+
use something like the following in your configuration file:
126+
[branch \"${branch_name#refs/heads/}\"]
127+
remote = <nickname>
128+
merge = <remote-ref>"
129+
test rebase = "$op_type" &&
130+
echo " rebase = true"
131+
echo "
132+
[remote \"<nickname>\"]
133+
url = <url>
134+
fetch = <refspec>
135+
136+
See git-config(1) for details."
137+
fi
138+
exit 1
139+
}

git-pull.sh

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,34 +163,10 @@ error_on_no_merge_candidates () {
163163
echo "You asked to pull from the remote '$1', but did not specify"
164164
echo "a branch. Because this is not the default configured remote"
165165
echo "for your current branch, you must specify a branch on the command line."
166-
elif [ -z "$curr_branch" ]; then
167-
echo "You are not currently on a branch, so I cannot use any"
168-
echo "'branch.<branchname>.merge' in your configuration file."
169-
echo "Please specify which remote branch you want to use on the command"
170-
echo "line and try again (e.g. 'git pull <repository> <refspec>')."
171-
echo "See git-pull(1) for details."
172-
elif [ -z "$upstream" ]; then
173-
echo "You asked me to pull without telling me which branch you"
174-
echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in"
175-
echo "your configuration file does not tell me, either. Please"
176-
echo "specify which branch you want to use on the command line and"
177-
echo "try again (e.g. 'git pull <repository> <refspec>')."
178-
echo "See git-pull(1) for details."
179-
echo
180-
echo "If you often $op_type $op_prep the same branch, you may want to"
181-
echo "use something like the following in your configuration file:"
182-
echo
183-
echo " [branch \"${curr_branch}\"]"
184-
echo " remote = <nickname>"
185-
echo " merge = <remote-ref>"
186-
test rebase = "$op_type" &&
187-
echo " rebase = true"
188-
echo
189-
echo " [remote \"<nickname>\"]"
190-
echo " url = <url>"
191-
echo " fetch = <refspec>"
192-
echo
193-
echo "See git-config(1) for details."
166+
elif [ -z "$curr_branch" -o -z "$upstream" ]; then
167+
. git-parse-remote
168+
error_on_missing_default_upstream "pull" $op_type $op_prep \
169+
"git pull <repository> <refspec>"
194170
else
195171
echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
196172
echo "from the remote, but no such ref was fetched."

git-rebase.sh

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Copyright (c) 2005 Junio C Hamano.
44
#
55

6-
USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] (<upstream>|--root) [<branch>] [--quiet | -q]'
6+
USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
77
LONG_USAGE='git-rebase replaces <branch> with a new branch of the
88
same name. When the --onto option is provided the new branch starts
99
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
345345
valuable there.'
346346
fi
347347

348-
test $# -eq 0 && test -z "$rebase_root" && usage
349-
350348
if test -n "$interactive_rebase"
351349
then
352350
type=interactive
@@ -362,9 +360,20 @@ fi
362360

363361
if test -z "$rebase_root"
364362
then
365-
# The upstream head must be given. Make sure it is valid.
366-
upstream_name="$1"
367-
shift
363+
case "$#" in
364+
0)
365+
if ! upstream_name=$(git rev-parse --symbolic-full-name \
366+
--verify -q @{upstream} 2>/dev/null)
367+
then
368+
. git-parse-remote
369+
error_on_missing_default_upstream "rebase" "rebase" \
370+
"against" "git rebase <upstream branch>"
371+
fi
372+
;;
373+
*) upstream_name="$1"
374+
shift
375+
;;
376+
esac
368377
upstream=`git rev-parse --verify "${upstream_name}^0"` ||
369378
die "invalid upstream $upstream_name"
370379
upstream_arg="$upstream_name"

t/t3400-rebase.sh

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,24 @@ test_expect_success 'Show verbose error when HEAD could not be detached' '
158158
'
159159
rm -f B
160160

161-
test_expect_success 'dump usage when upstream arg is missing' '
162-
git checkout -b usage topic &&
163-
test_must_fail git rebase 2>error1 &&
164-
grep "[Uu]sage" error1 &&
165-
test_must_fail git rebase --abort 2>error2 &&
166-
grep "No rebase in progress" error2 &&
167-
test_must_fail git rebase --onto master 2>error3 &&
168-
grep "[Uu]sage" error3 &&
169-
! grep "can.t shift" error3
161+
test_expect_success 'fail when upstream arg is missing and not on branch' '
162+
git checkout topic &&
163+
test_must_fail git rebase >output.out &&
164+
grep "You are not currently on a branch" output.out
165+
'
166+
167+
test_expect_success 'fail when upstream arg is missing and not configured' '
168+
git checkout -b no-config topic &&
169+
test_must_fail git rebase >output.out &&
170+
grep "branch.no-config.merge" output.out
171+
'
172+
173+
test_expect_success 'default to @{upstream} when upstream arg is missing' '
174+
git checkout -b default topic &&
175+
git config branch.default.remote .
176+
git config branch.default.merge refs/heads/master
177+
git rebase &&
178+
test "$(git rev-parse default~1)" = "$(git rev-parse master)"
170179
'
171180

172181
test_expect_success 'rebase -q is quiet' '

0 commit comments

Comments
 (0)