Skip to contentSkip to conversation

with git-next, git pull --rebase can print out "fatal: No such ref: ''" for branches without an upstream

PATCH New Siddharth Agarwal 4 participants 9 messages Jun 15, 2016

lore
Share & tools
lore
#0 lore raw

With git-next, where git pull --rebase can print out "fatal: No such ref: ''" if git pull --rebase is run on branches without an upstream.

With git at b139ac2589b15d55cd9fa5c6957da44b150d0737, the following commands demonstrate the problem:

git init repo1
cd repo1
touch a; git add a; git commit -m "a"
cd ..
git clone repo1 repo2
cd repo2
git config remote.origin.fetch refs/heads/master:refs/remotes/origin/master git checkout -b test
git pull --rebase

This results in the following output:

fatal: No such ref: ''
Current branch test is up to date.

So the pull --rebase looks like it works, but it prints out a spurious fatal error.

I've managed to bisect this down to https://github.com/gitster/git/commit/48059e405028ebf8a09c5a9aede89dfb460cce98. Looks like get_remote_merge_branch is called without arguments, and it returns an empty string. This string is passed as-is to git merge-base, which causes the error.

#1 lore raw
Quoted 2 lines · Siddharth Agarwal

With git-next, where git pull --rebase can print out "fatal: No such
ref: ''" if git pull --rebase is run on branches without an upstream.

This is already fixed in bb3f458 (rebase: fix fork-point with zero arguments, 2014-01-09), I think.

-Peff

#2 lore raw
Quoted 6 lines · Jeff King
Quoted 2 lines · Siddharth Agarwal

With git-next, where git pull --rebase can print out "fatal: No such
ref: ''" if git pull --rebase is run on branches without an upstream.

This is already fixed in bb3f458 (rebase: fix fork-point with zero arguments, 2014-01-09), I think.

If I'm reading the patch correctly, that only fixes it for git rebase, not for git pull --rebase. git-pull.sh contains a separate invocation of git merge-base --fork-point.

#3 lore raw
Quoted 11 lines · Siddharth Agarwal
Quoted 6 lines · Jeff King
Quoted 2 lines · Siddharth Agarwal

With git-next, where git pull --rebase can print out "fatal: No such
ref: ''" if git pull --rebase is run on branches without an upstream.

This is already fixed in bb3f458 (rebase: fix fork-point with zero arguments, 2014-01-09), I think.

If I'm reading the patch correctly, that only fixes it for git rebase, not for git pull --rebase. git-pull.sh contains a separate invocation of git merge-base --fork-point.

I'm pretty sure the invocation in git-pull.sh is OK. The error then comes out of git-rebase.sh when git-pull invokes it.

Are you running a version of git-next that includes bb3f458?

#4 lore raw
Quoted 6 lines · John Keeping
Quoted 5 lines · Siddharth Agarwal
Quoted 4 lines · Jeff King
Quoted 2 lines · Siddharth Agarwal

With git-next, where git pull --rebase can print out "fatal: No such
ref: ''" if git pull --rebase is run on branches without an upstream.

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

This is already fixed in bb3f458 (rebase: fix fork-point with zero arguments, 2014-01-09), I think.

If I'm reading the patch correctly, that only fixes it for git rebase, not for git pull --rebase. git-pull.sh contains a separate invocation of git merge-base --fork-point.

I'm pretty sure the invocation in git-pull.sh is OK. The error then comes out of git-rebase.sh when git-pull invokes it.

That doesn't square with 48059e4 being the culprit commit.

Quoted 1 line

Are you running a version of git-next that includes bb3f458?

Yes, I am.

#5 lore raw
In reply to Jeff King
Quoted 7 lines · Jeff King
Quoted 2 lines · Siddharth Agarwal

With git-next, where git pull --rebase can print out "fatal: No such
ref: ''" if git pull --rebase is run on branches without an upstream.

This is already fixed in bb3f458 (rebase: fix fork-point with zero arguments, 2014-01-09), I think.

Doesn't the call to get_remote_merge_branch in this part

        test -n "$curr_branch" &&
        . git-parse-remote &&
        remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
        oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch)

yield an empty string, feeding it to "merge-base --fork-point" as its first parameter?

Perhaps something like this is needed?

 git-pull.sh | 1 +
 1 file changed, 1 insertion(+)
git-pull.sh +1 -0
index 605e957..467c66c 100755
@@ -229,6 +229,7 @@ test true = "$rebase" && {
 	test -n "$curr_branch" &&
 	. git-parse-remote &&
 	remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
+	test -n "$remoteref" &&
 	oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch)
 }
 orig_head=$(git rev-parse -q --verify HEAD)
#6 lore raw
Quoted 12 lines · Junio C Hamano
Quoted 7 lines · Jeff King
Quoted 2 lines · Siddharth Agarwal

With git-next, where git pull --rebase can print out "fatal: No such
ref: ''" if git pull --rebase is run on branches without an upstream.

This is already fixed in bb3f458 (rebase: fix fork-point with zero arguments, 2014-01-09), I think.

Doesn't the call to get_remote_merge_branch in this part

Quoted 7 lines
        test -n "$curr_branch" &&
        . git-parse-remote &&
        remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
        oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch)

yield an empty string, feeding it to "merge-base --fork-point" as its first parameter?

For some reason I assumed that get_remote_merge_branch would either yield a non-empty string or return failure, meaning that the &&-chain makes everything OK.

Before the change to use "merge-base --fork-point", the code was:

	oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
	for reflog in $(git rev-list -g $remoteref 2>/dev/null)
	do
		if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
		then
			oldremoteref="$reflog"
			break
		fi
	done

which has a similar failure - rev-list requires a revision argument and prints its usage if not given one.

Quoted 10 lines

Perhaps something like this is needed?

 git-pull.sh | 1 +
 1 file changed, 1 insertion(+)
git-pull.sh +0 -0
index 605e957..467c66c 100755

git-pull.sh test true = "$rebase" && { · line 235

Quoted 7 lines
git-pull.sh +1 -0
@@ -229,6 +229,7 @@ test true = "$rebase" && {
 	test -n "$curr_branch" &&
 	. git-parse-remote &&
 	remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
+	test -n "$remoteref" &&
 	oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch)
 }
 orig_head=$(git rev-parse -q --verify HEAD)

Either that or "2>/dev/null" like in the original, yes.

#7 lore raw

PATCH 1/1 pull: suppress error when no remoteref is found

Commit 48059e4 (pull: use merge-base --fork-point when appropriate, 2013-12-08) incorrectly assumes that get_remote_merge_branch will either yield a non-empty string or return an error, but there are circumstances where it will yield an empty string.

The previous code then invoked git-rev-list with no arguments, which results in an error suppressed by redirecting stderr to /dev/null. Now we invoke git-merge-base with an empty branch name, which also results in an error. Suppress this in the same way.

---
 git-pull.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
git-pull.sh +1 -1
index f210d0a..0a5aa2c 100755
@@ -229,7 +229,7 @@ test true = "$rebase" && {
 	test -n "$curr_branch" &&
 	. git-parse-remote &&
 	remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
-	oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch)
+	oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
 }
 orig_head=$(git rev-parse -q --verify HEAD)
 git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
Signature · 1 line
1.8.5.226.g0d60d77
#8 lore raw
In reply to John Keeping
Quoted 3 lines · John Keeping
Quoted 2 lines

Perhaps something like this is needed?
...

Either that or "2>/dev/null" like in the original, yes.

Ah, that makes sense. I see you already followed-up with a patch, so I'll pick it up.

Thanks.