Commit 3b66c6a3970c056dac5a84bc0ebfcf851f7d3dda

Edward Thomson 2015-06-25T15:36:53

Merge pull request #3256 from libgit2/cmn/fetch-spec-fetchhead remote: insert refspecs with no rhs in FETCH_HEAD

diff --git a/src/remote.c b/src/remote.c
index 7c2d999..8475b1c 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -1342,9 +1342,20 @@ static int update_tips_for_spec(
 			} else {
 				continue;
 			}
-		} else if (git_refspec_src_matches(spec, head->name) && spec->dst) {
-			if (git_refspec_transform(&refname, spec, head->name) < 0)
-				goto on_error;
+		} else if (git_refspec_src_matches(spec, head->name)) {
+			if (spec->dst) {
+				if (git_refspec_transform(&refname, spec, head->name) < 0)
+					goto on_error;
+			} else {
+				/*
+				 * no rhs mans store it in FETCH_HEAD, even if we don't
+				 update anything else.
+				 */
+				if ((error = git_vector_insert(&update_heads, head)) < 0)
+					goto on_error;
+
+				continue;
+			}
 		} else {
 			continue;
 		}
diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c
index 24e87a6..b8f74d7 100644
--- a/tests/fetchhead/nonetwork.c
+++ b/tests/fetchhead/nonetwork.c
@@ -351,3 +351,47 @@ void test_fetchhead_nonetwork__quote_in_branch_name(void)
 	cl_git_rewritefile("./test1/.git/FETCH_HEAD", FETCH_HEAD_QUOTE_DATA);
 	cl_git_pass(git_repository_fetchhead_foreach(g_repo, read_noop, NULL));
 }
+
+static bool found_master;
+static bool find_master_called;
+
+int find_master(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload)
+{
+	GIT_UNUSED(remote_url);
+	GIT_UNUSED(oid);
+	GIT_UNUSED(payload);
+
+	find_master_called = true;
+
+	if (!strcmp("refs/heads/master", ref_name)) {
+		cl_assert(is_merge);
+		found_master = true;
+	}
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__create_when_refpecs_given(void)
+{
+	git_remote *remote;
+	git_buf path = GIT_BUF_INIT;
+	char *refspec = "refs/heads/master";
+	git_strarray specs = {
+		&refspec,
+		1,
+	};
+
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD"));
+	cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_fixture("testrepo.git")));
+
+	cl_assert(!git_path_exists(path.ptr));
+	cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL));
+	cl_assert(git_path_exists(path.ptr));
+
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, find_master, NULL));
+	cl_assert(find_master_called);
+	cl_assert(found_master);
+}