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

[PATCH 1/2] fast-import: filemodify after M 040000 <tree> "" crashes

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Oct 18, 2010, 01:03 UTC
Message-ID
<20101018010338.GB25524@burratino>
In-Reply-To
<20101018010005.GA25524@burratino>

Until M 040000 <tree> "" syntax was introduced in commit 2794ad5 (fast-import: Allow filemodify to set the root, 2010-10-10), it was impossible for the root entry to refer to an unloaded tree. Update various functions to take that possibility into account. Otherwise

	M 040000 <tree> ""
	M 100644 :1 "foo"

and similar commands (using D, C, or R after resetting the root tree) segfault.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 fast-import.c          |   20 ++++++++++++++++----
 t/t9300-fast-import.sh |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index 8f68a89..aaf47c5 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1444,7 +1444,7 @@ static int tree_content_set(
 	const uint16_t mode,
 	struct tree_content *subtree)
 {
-	struct tree_content *t = root->tree;
+	struct tree_content *t;
 	const char *slash1;
 	unsigned int i, n;
 	struct tree_entry *e;
@@ -1468,6 +1468,9 @@ static int tree_content_set(
 	if (!slash1 && !S_ISDIR(mode) && subtree)
 		die("Non-directories cannot have subtrees");
 
+	if (!root->tree)
+		load_tree(root);
+	t = root->tree;
 	for (i = 0; i < t->entry_count; i++) {
 		e = t->entries[i];
 		if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
@@ -1523,7 +1526,7 @@ static int tree_content_remove(
 	const char *p,
 	struct tree_entry *backup_leaf)
 {
-	struct tree_content *t = root->tree;
+	struct tree_content *t;
 	const char *slash1;
 	unsigned int i, n;
 	struct tree_entry *e;
@@ -1534,6 +1537,9 @@ static int tree_content_remove(
 	else
 		n = strlen(p);
 
+	if (!root->tree)
+		load_tree(root);
+	t = root->tree;
 	for (i = 0; i < t->entry_count; i++) {
 		e = t->entries[i];
 		if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
@@ -1581,7 +1587,7 @@ static int tree_content_get(
 	const char *p,
 	struct tree_entry *leaf)
 {
-	struct tree_content *t = root->tree;
+	struct tree_content *t;
 	const char *slash1;
 	unsigned int i, n;
 	struct tree_entry *e;
@@ -1592,6 +1598,9 @@ static int tree_content_get(
 	else
 		n = strlen(p);
 
+	if (!root->tree)
+		load_tree(root);
+	t = root->tree;
 	for (i = 0; i < t->entry_count; i++) {
 		e = t->entries[i];
 		if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
@@ -2056,13 +2065,16 @@ static uintmax_t do_change_note_fanout(
 		char *fullpath, unsigned int fullpath_len,
 		unsigned char fanout)
 {
-	struct tree_content *t = root->tree;
+	struct tree_content *t;
 	struct tree_entry *e, leaf;
 	unsigned int i, tmp_hex_sha1_len, tmp_fullpath_len;
 	uintmax_t num_notes = 0;
 	unsigned char sha1[20];
 	char realpath[60];
 
+	if (!root->tree);
+		load_tree(root);
+	t = root->tree;
 	for (i = 0; t && i < t->entry_count; i++) {
 		e = t->entries[i];
 		tmp_hex_sha1_len = hex_sha1_len + e->name->str_len;
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 3c0cf05..de95a6e 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -928,6 +928,43 @@ test_expect_success \
 	 git diff-tree -C --find-copies-harder -r N5^^ N5 >actual &&
 	 compare_diff_raw expect actual'
 
+test_expect_success \
+	'N: copy to root by id and modify' \
+	'echo "hello, world" >expect.foo &&
+	 echo hello >expect.bar &&
+	 git fast-import <<-SETUP_END &&
+	commit refs/heads/N7
+	committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+	data <<COMMIT
+	hello, tree
+	COMMIT
+
+	deleteall
+	M 644 inline foo/bar
+	data <<EOF
+	hello
+	EOF
+	SETUP_END
+
+	 tree=$(git rev-parse --verify N7:) &&
+	 git fast-import <<-INPUT_END &&
+	commit refs/heads/N8
+	committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+	data <<COMMIT
+	copy to root by id and modify
+	COMMIT
+
+	M 040000 $tree ""
+	M 644 inline foo/foo
+	data <<EOF
+	hello, world
+	EOF
+	INPUT_END
+	 git show N8:foo/foo >actual.foo &&
+	 git show N8:foo/bar >actual.bar &&
+	 test_cmp expect.foo actual.foo &&
+	 test_cmp expect.bar actual.bar'
+
 ###
 ### series O
 ###
-- 
1.7.2.3
Previous: Jonathan NiederNext: Sverre Rabbelier
Message 22 of 31 in “fast-import: Allow filemodify to set the root”
  1. fast-import: Allow filemodify to set the rootDavid Barr, Oct 7, 2010
  2. Sverre RabbelierOct 7, 2010
  3. Jonathan NiederOct 7, 2010
  4. Sverre RabbelierOct 7, 2010
  5. David BarrOct 7, 2010
  6. fast-import: Allow filemodify to set the rootDavid Barr, Oct 7, 2010
  7. Sverre RabbelierOct 7, 2010
  8. Johannes SixtOct 8, 2010
  9. Jonathan NiederOct 8, 2010
  10. Johannes SixtOct 8, 2010
  11. Jonathan NiederOct 8, 2010
  12. Ramkumar RamachandraOct 8, 2010
  13. Gabriel FilionOct 8, 2010
  14. David Michael BarrOct 8, 2010
  15. Sverre RabbelierOct 8, 2010
  16. Jonathan NiederOct 8, 2010
  17. David Michael BarrOct 9, 2010
  18. Sverre RabbelierOct 9, 2010
  19. fast-import: Allow filemodify to set the rootDavid Barr, Oct 10, 2010
  20. Jonathan NiederOct 11, 2010
  21. 0/2 Re: fast-import: Allow filemodify to set the rootJonathan Nieder, Oct 18, 2010
  22. 1/2 fast-import: filemodify after M 040000 <tree> "" crashesJonathan Nieder, Oct 18, 2010
  23. Sverre RabbelierOct 18, 2010
  24. Jonathan NiederOct 18, 2010
  25. fast-import: do not clear notes in do_change_note_fanout()Jonathan Nieder, Oct 20, 2010
  26. 2/2 fast-import: tighten M 040000 syntaxJonathan Nieder, Oct 18, 2010
  27. Documentation/fast-import: put explanation of M 040000 <dataref> "" in contextJonathan Nieder, Jan 16, 2011
  28. Junio C HamanoJan 18, 2011
  29. Jonathan NiederJan 18, 2011
  30. Junio C HamanoJan 18, 2011
  31. Jonathan NiederJan 18, 2011

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.