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

[PATCH v4 4/4] commit: rewrite read_graft_line

From
Patryk Obara <patryk.obara@gmail.com>
Date
Aug 18, 2017, 18:33 UTC
Message-ID
<9a4548f1d0832d036cad152771339d853b5885f3.1503079879.git.patryk.obara@gmail.com>
In-Reply-To
<cover.1503079879.git.patryk.obara@gmail.com>

Old implementation determined number of hashes by dividing length of line by length of hash, which works only if all hash representations have same length.

New graft line parser works in two phases:
  1. In first phase line is scanned to verify correctness and compute
     number of hashes, then graft struct is allocated.
  2. In second phase line is scanned again to fill up already allocated
     graft struct.

This way graft parsing code can support different sizes of hashes without any further code adaptations.

A number of alternative implementations were considered and discarded:
  - Modifying graft structure to store oid_array instead of FLEXI_ARRAY
    indicates undesirable usage of struct to readers.
  - Parsing into temporary string_list or oid_array complicates code
    by adding more return paths, as these structures needs to be
    cleared before returning from function.
  - Determining number of hashes by counting separators might cause
    maintenance issues, if this function needs to be modified in future
    again.
Signed-off-by: Patryk Obara <patryk.obara@gmail.com>
---
 commit.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/commit.c b/commit.c
index 436eb34..3eefd9d 100644
--- a/commit.c
+++ b/commit.c
@@ -137,32 +137,37 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 struct commit_graft *read_graft_line(struct strbuf *line)
 {
 	/* The format is just "Commit Parent1 Parent2 ...\n" */
-	int i;
+	int i, phase;
+	const char *tail = NULL;
 	struct commit_graft *graft = NULL;
-	const int entry_size = GIT_SHA1_HEXSZ + 1;
+	struct object_id dummy_oid, *oid;
 
 	strbuf_rtrim(line);
 	if (!line->len || line->buf[0] == '#')
 		return NULL;
-	if ((line->len + 1) % entry_size)
-		goto bad_graft_data;
-	i = (line->len + 1) / entry_size - 1;
-	graft = xmalloc(st_add(sizeof(*graft),
-	                       st_mult(sizeof(struct object_id), i)));
-	graft->nr_parent = i;
-	if (get_oid_hex(line->buf, &graft->oid))
-		goto bad_graft_data;
-	for (i = GIT_SHA1_HEXSZ; i < line->len; i += entry_size) {
-		if (line->buf[i] != ' ')
-			goto bad_graft_data;
-		if (get_sha1_hex(line->buf + i + 1, graft->parent[i/entry_size].hash))
+	/*
+	 * phase 0 verifies line, counts hashes in line and allocates graft
+	 * phase 1 fills graft
+	 */
+	for (phase = 0; phase < 2; phase++) {
+		oid = graft ? &graft->oid : &dummy_oid;
+		if (parse_oid_hex(line->buf, oid, &tail))
 			goto bad_graft_data;
+		for (i = 0; *tail != '\0'; i++) {
+			oid = graft ? &graft->parent[i] : &dummy_oid;
+			if (!isspace(*tail++) || parse_oid_hex(tail, oid, &tail))
+				goto bad_graft_data;
+		}
+		if (!graft) {
+			graft = xmalloc(st_add(sizeof(*graft),
+			                       st_mult(sizeof(struct object_id), i)));
+			graft->nr_parent = i;
+		}
 	}
 	return graft;
 
 bad_graft_data:
 	error("bad graft data: %s", line->buf);
-	free(graft);
 	return NULL;
 }
 
-- 
2.9.5
Previous: Patryk ObaraNext: Patryk Obara
Message 53 of 59 in “Modernize read_graft_line implementation”
  1. 0/5 Modernize read_graft_line implementationPatryk Obara, Aug 15, 2017
  2. 1/5 cache: extend object_id size to sha3-256Patryk Obara, Aug 15, 2017
  3. 2/5 sha1_file: fix hardcoded size in null_sha1Patryk Obara, Aug 15, 2017
  4. Junio C HamanoAug 15, 2017
  5. Stefan BellerAug 15, 2017
  6. Junio C HamanoAug 15, 2017
  7. Patryk ObaraAug 16, 2017
  8. Junio C HamanoAug 16, 2017
  9. 4/5 commit: implement free_commit_graftPatryk Obara, Aug 15, 2017
  10. Stefan BellerAug 15, 2017
  11. Junio C HamanoAug 15, 2017
  12. Patryk ObaraAug 16, 2017
  13. 3/5 commit: replace the raw buffer with strbuf in read_graft_linePatryk Obara, Aug 15, 2017
  14. Stefan BellerAug 15, 2017
  15. Patryk ObaraAug 16, 2017
  16. brian m. carlsonAug 16, 2017
  17. Jeff KingAug 17, 2017
  18. Junio C HamanoAug 17, 2017
  19. Patryk ObaraAug 17, 2017
  20. Junio C HamanoAug 15, 2017
  21. 5/5 commit: rewrite read_graft_linePatryk Obara, Aug 15, 2017
  22. Stefan BellerAug 15, 2017
  23. Junio C HamanoAug 15, 2017
  24. Patryk ObaraAug 16, 2017
  25. Junio C HamanoAug 16, 2017
  26. Stefan BellerAug 15, 2017
  27. 0/4 Modernize read_graft_line implementationPatryk Obara, Aug 16, 2017
  28. 1/4 sha1_file: fix hardcoded size in null_sha1Patryk Obara, Aug 16, 2017
  29. Junio C HamanoAug 16, 2017
  30. 3/4 commit: implement free_commit_graftPatryk Obara, Aug 16, 2017
  31. 2/4 commit: replace the raw buffer with strbuf in read_graft_linePatryk Obara, Aug 16, 2017
  32. 4/4 commit: rewrite read_graft_linePatryk Obara, Aug 16, 2017
  33. Junio C HamanoAug 17, 2017
  34. Patryk ObaraAug 17, 2017
  35. 0/4 Modernize read_graft_line implementationPatryk Obara, Aug 18, 2017
  36. 2/4 commit: replace the raw buffer with strbuf in read_graft_linePatryk Obara, Aug 18, 2017
  37. Jeff KingAug 18, 2017
  38. Patryk ObaraAug 18, 2017
  39. Jeff KingAug 18, 2017
  40. 1/4 sha1_file: fix definition of null_sha1Patryk Obara, Aug 18, 2017
  41. 4/4 commit: rewrite read_graft_linePatryk Obara, Aug 18, 2017
  42. Jeff KingAug 18, 2017
  43. Junio C HamanoAug 18, 2017
  44. Patryk ObaraAug 18, 2017
  45. Jeff KingAug 18, 2017
  46. Junio C HamanoAug 18, 2017
  47. Patryk ObaraAug 18, 2017
  48. Junio C HamanoAug 18, 2017
  49. 3/4 commit: allocate array using object_id sizePatryk Obara, Aug 18, 2017
  50. Junio C HamanoAug 18, 2017
  51. 0/4 Modernize read_graft_line implementationPatryk Obara, Aug 18, 2017
  52. 2/4 commit: replace the raw buffer with strbuf in read_graft_linePatryk Obara, Aug 18, 2017
  53. 4/4 commit: rewrite read_graft_linePatryk Obara, Aug 18, 2017
  54. Patryk ObaraAug 18, 2017
  55. Junio C HamanoAug 18, 2017
  56. Patryk ObaraAug 18, 2017
  57. Junio C HamanoAug 18, 2017
  58. 1/4 sha1_file: fix definition of null_sha1Patryk Obara, Aug 18, 2017
  59. 3/4 commit: allocate array using object_id sizePatryk Obara, Aug 18, 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.