git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/5] remote.c: don't pass copies of refspecs to add_{fetch,push}_refspec()

From
SZEDER Gábor <szeder.dev@gmail.com>
Date
Jun 16, 2017, 19:28 UTC
Message-ID
<20170616192837.11035-3-szeder.dev@gmail.com>
In-Reply-To
<20170616192837.11035-1-szeder.dev@gmail.com>

Currently neither add_fetch_refspec() nor add_push_refspec() duplicate the refspecs before appending them to an array of refspecs, therefore all their callers pass them copies of refspecs. Soon we won't store refspecs as strings, therefore passing duplicated strings to these functions will not be necessary.

Perform the copying inside these functions and modify their callers to either not pass duplicates or free() them to avoid leaks.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 builtin/clone.c |  3 +--
 remote.c        | 21 ++++++++++++++-------
 2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 869e093ff..5b72d853f 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1054,8 +1054,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	remote = remote_get(option_origin);
 	strbuf_addf(&default_refspec, "+%s*:%s*", src_ref_prefix,
 		    branch_top.buf);
-	add_and_parse_fetch_refspec(remote,
-				    strbuf_detach(&default_refspec, NULL));
+	add_and_parse_fetch_refspec(remote, default_refspec.buf);
 
 	transport = transport_get(remote, remote->url[0]);
 	transport_set_verbosity(transport, option_verbosity, option_progress);
diff --git a/remote.c b/remote.c
index a021decee..d23518afd 100644
--- a/remote.c
+++ b/remote.c
@@ -91,7 +91,7 @@ static void add_push_refspec(struct remote *remote, const char *ref)
 	ALLOC_GROW(remote->push_refspec,
 		   remote->push_refspec_nr + 1,
 		   remote->push_refspec_alloc);
-	remote->push_refspec[remote->push_refspec_nr++] = ref;
+	remote->push_refspec[remote->push_refspec_nr++] = strdup(ref);
 }
 
 static void add_fetch_refspec(struct remote *remote, const char *ref)
@@ -99,7 +99,7 @@ static void add_fetch_refspec(struct remote *remote, const char *ref)
 	ALLOC_GROW(remote->fetch_refspec,
 		   remote->fetch_refspec_nr + 1,
 		   remote->fetch_refspec_alloc);
-	remote->fetch_refspec[remote->fetch_refspec_nr++] = ref;
+	remote->fetch_refspec[remote->fetch_refspec_nr++] = strdup(ref);
 }
 
 static void add_url(struct remote *remote, const char *url)
@@ -265,9 +265,9 @@ static void read_remotes_file(struct remote *remote)
 		if (skip_prefix(buf.buf, "URL:", &v))
 			add_url_alias(remote, xstrdup(skip_spaces(v)));
 		else if (skip_prefix(buf.buf, "Push:", &v))
-			add_push_refspec(remote, xstrdup(skip_spaces(v)));
+			add_push_refspec(remote, skip_spaces(v));
 		else if (skip_prefix(buf.buf, "Pull:", &v))
-			add_fetch_refspec(remote, xstrdup(skip_spaces(v)));
+			add_fetch_refspec(remote, skip_spaces(v));
 	}
 	strbuf_release(&buf);
 	fclose(f);
@@ -306,15 +306,20 @@ static void read_branches_file(struct remote *remote)
 		frag = "master";
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
-	add_fetch_refspec(remote, xstrfmt("refs/heads/%s:refs/heads/%s",
-					  frag, remote->name));
+
+	strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s", frag, remote->name);
+	add_fetch_refspec(remote, buf.buf);
+	strbuf_reset(&buf);
 
 	/*
 	 * Cogito compatible push: push current HEAD to remote #branch
 	 * (master if missing)
 	 */
-	add_push_refspec(remote, xstrfmt("HEAD:refs/heads/%s", frag));
+	strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
+	add_push_refspec(remote, buf.buf);
 	remote->fetch_tags = 1; /* always auto-follow */
+
+	strbuf_release(&buf);
 }
 
 static int handle_config(const char *key, const char *value, void *cb)
@@ -398,11 +403,13 @@ static int handle_config(const char *key, const char *value, void *cb)
 		if (git_config_string(&v, key, value))
 			return -1;
 		add_push_refspec(remote, v);
+		free((char*)v);
 	} else if (!strcmp(subkey, "fetch")) {
 		const char *v;
 		if (git_config_string(&v, key, value))
 			return -1;
 		add_fetch_refspec(remote, v);
+		free((char*)v);
 	} else if (!strcmp(subkey, "receivepack")) {
 		const char *v;
 		if (git_config_string(&v, key, value))
-- 
2.13.1.505.g7cc9fcafb
Previous: SZEDER GáborNext: SZEDER Gábor
Message 2 of 12 in “remote: eliminate remote->{fetch,push}_refspec and lazy parsing of refspecs”
  1. 0/5 remote: eliminate remote->{fetch,push}_refspec and lazy parsing of refspecsSZEDER Gábor, Jun 16, 2017
  2. 2/5 remote.c: don't pass copies of refspecs to add_{fetch,push}_refspec()SZEDER Gábor, Jun 16, 2017
  3. 4/5 remote.c: eliminate remote->fetch_refspecSZEDER Gábor, Jun 16, 2017
  4. 1/5 remote: don't use remote->{fetch,push}_refspecSZEDER Gábor, Jun 16, 2017
  5. Junio C HamanoJun 16, 2017
  6. 3/5 remote.c: extract a helper function to parse a single refspecSZEDER Gábor, Jun 16, 2017
  7. 5/5 remote.c: eliminate remote->push_refspecSZEDER Gábor, Jun 16, 2017
  8. Junio C HamanoJun 16, 2017
  9. SZEDER GáborJun 17, 2017
  10. Jeff KingJun 17, 2017
  11. Jeff KingJun 17, 2017
  12. Junio C HamanoJun 19, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.