Git development
 help / color / mirror / Atom feed
From: "Marc Becker via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Aniket Gupta <aniketgupta3001@gmail.com>,
	Marc Becker <becm@gmx.de>, Marc Becker <becm@gmx.de>
Subject: [PATCH v2] fast-import: fix lookup for new commits and tags
Date: Mon, 12 Oct 2026 22:50:20 +0000	[thread overview]
Message-ID: <pull.2252.v2.git.1791845420568.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2252.git.1791653078449.gitgitgadget@gmail.com>

From: Marc Becker <becm@gmx.de>

Queries for commits created during the same 'git fast-import' session
result in a crash:
    < reset refs/heads/newbranch
    < from <new-commit-oid>
    > fatal: not a valid commit: <new-commit-oid>

Getting file content for commit has no issue (working implementation):
    < ls <new-commit-oid> file-in-new-commit.txt
    > {file content}

During import, new objects may not (yet) be reachable via the ODB layer.
Try to resolve requested tag/commit via object cache first
to avoid crash.
Add test to 't/t9300.sh' with references to a pending tag and commit.

Signed-off-by: Marc Becker <becm@gmx.de>
---
    fast-import: fix lookup for new commits
    
    Changes since v1:
    
     * address notes regarding commit message
     * stick to line length in new code
     * add test with (fixed) pending references (files for SHA1 and SHA256,
       no coproc in sh, avoid named pipes)

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2252%2Fbecm%2Ffix-fast-import-commit-from-existing-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2252/becm/fix-fast-import-commit-from-existing-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/2252

Range-diff vs v1:

 1:  4e50f63354 ! 1:  d834e2fc47 fast-import: fix lookup for new commits
     @@ Metadata
      Author: Marc Becker <becm@gmx.de>
      
       ## Commit message ##
     -    fast-import: fix lookup for new commits
     +    fast-import: fix lookup for new commits and tags
      
     -    Queries for commits created during the same 'git fast-import'  session
     +    Queries for commits created during the same 'git fast-import' session
          result in a crash:
              < reset refs/heads/newbranch
              < from <new-commit-oid>
     @@ Commit message
      
          During import, new objects may not (yet) be reachable via the ODB layer.
          Try to resolve requested tag/commit via object cache first
     -    to avoid crash and (eventually) improve lookup speed.
     +    to avoid crash.
     +    Add test to 't/t9300.sh' with references to a pending tag and commit.
      
          Signed-off-by: Marc Becker <becm@gmx.de>
      
     @@ builtin/fast-import.c: static void fast_import_state_init(struct fast_import_sta
       	state->option = option;
       }
       
     -+static struct object_entry *dereference(struct object_entry *oe, struct object_id *oid);
     ++static struct object_entry *dereference(struct object_entry *oe,
     ++					struct object_id *oid);
      +
       static void parse_argv(struct fast_import_state *state);
       static void parse_get_mark(struct fast_import_state *state, const char *p);
     @@ builtin/fast-import.c: static void parse_from_existing(struct branch *b)
       		parse_from_commit(b, buf, size);
       		free(buf);
       	}
     +
     + ## t/t9300-fast-import.sh ##
     +@@ t/t9300-fast-import.sh: test_expect_success 'Y: rewrite submodules' '
     + 	)
     + '
     + 
     ++cat >Y-reference-pending-sha256 <<\Y_INPUT_END
     ++commit refs/heads/main
     ++committer A U Thor <author@example.com> 1712563200 +0000
     ++data 14
     ++commit message
     ++M 644 inline test file
     ++data 14
     ++dummy content
     ++
     ++tag newtag
     ++from 17e650f097a4db6fe069c96935360d3ccc9b35c4018728c5f311a4217c2ced3d
     ++tagger A U Thor <author@example.com> 1712563300 +0000
     ++data 11
     ++tag message
     ++# no emty line after tag data!
     ++reset refs/heads/other
     ++from 85edc5eac315bc680677b2fc71622bd77476f057eb8dc8ed6a497803a24f1f46
     ++
     ++commit refs/heads/further
     ++committer A U Thor <author@example.com> 1712563400 +0000
     ++data 21
     ++what about 2nd commit
     ++from 17e650f097a4db6fe069c96935360d3ccc9b35c4018728c5f311a4217c2ced3d
     ++M 644 inline other test file
     ++data 19
     ++more dummy content
     ++
     ++done
     ++Y_INPUT_END
     ++
     ++cat >Y-reference-pending-sha1 <<\Y_INPUT_END
     ++commit refs/heads/main
     ++committer A U Thor <author@example.com> 1712563200 +0000
     ++data 14
     ++commit message
     ++M 644 inline test file
     ++data 14
     ++dummy content
     ++
     ++tag newtag
     ++from 85b46dd918355ff17b4109ec738723d42f235a04
     ++tagger A U Thor <author@example.com> 1712563300 +0000
     ++data 11
     ++tag message
     ++# no emty line after tag data!
     ++reset refs/heads/other
     ++from ec6c4db71feb5f66615214dad2324ce030e777a7
     ++
     ++commit refs/heads/further
     ++committer A U Thor <author@example.com> 1712563400 +0000
     ++data 21
     ++what about 2nd commit
     ++from 85b46dd918355ff17b4109ec738723d42f235a04
     ++M 644 inline other test file
     ++data 19
     ++more dummy content
     ++
     ++done
     ++Y_INPUT_END
     ++
     ++test_expect_success 'Y: reference pending tag or commit' '
     ++	git init reference-pending &&
     ++	(
     ++		cd reference-pending &&
     ++		git fast-import < "../Y-reference-pending-$(git rev-parse --show-object-format)"
     ++	)
     ++'
     ++
     + test_done


 builtin/fast-import.c  | 19 +++++++++---
 t/t9300-fast-import.sh | 68 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index fbd919982c..574a03c484 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -292,6 +292,9 @@ static void fast_import_state_init(struct fast_import_state *state,
 	state->option = option;
 }
 
+static struct object_entry *dereference(struct object_entry *oe,
+					struct object_id *oid);
+
 static void parse_argv(struct fast_import_state *state);
 static void parse_get_mark(struct fast_import_state *state, const char *p);
 static void parse_cat_blob(struct fast_import_state *state, const char *p);
@@ -2658,12 +2661,20 @@ static void parse_from_existing(struct branch *b)
 		oidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);
 	} else {
 		unsigned long size;
-		size_t size_st = 0;
 		char *buf;
+		struct object_entry *e = find_object(&b->oid);
 
-		buf = odb_read_object_peeled(the_repository->objects, &b->oid,
-					     OBJ_COMMIT, &size_st, &b->oid);
-		size = cast_size_t_to_ulong(size_st);
+		while (e && e->type == OBJ_TAG)
+			e = dereference(e, &b->oid);
+
+		if (e && e->type == OBJ_COMMIT && e->pack_id != MAX_PACK_ID) {
+			buf = gfi_unpack_entry(e, &size);
+		} else {
+			size_t size_st = 0;
+			buf = odb_read_object_peeled(the_repository->objects, &b->oid,
+						     OBJ_COMMIT, &size_st, &b->oid);
+			size = cast_size_t_to_ulong(size_st);
+		}
 		parse_from_commit(b, buf, size);
 		free(buf);
 	}
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index d9de2ef0d8..1f52be2c2c 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -3938,4 +3938,72 @@ test_expect_success 'Y: rewrite submodules' '
 	)
 '
 
+cat >Y-reference-pending-sha256 <<\Y_INPUT_END
+commit refs/heads/main
+committer A U Thor <author@example.com> 1712563200 +0000
+data 14
+commit message
+M 644 inline test file
+data 14
+dummy content
+
+tag newtag
+from 17e650f097a4db6fe069c96935360d3ccc9b35c4018728c5f311a4217c2ced3d
+tagger A U Thor <author@example.com> 1712563300 +0000
+data 11
+tag message
+# no emty line after tag data!
+reset refs/heads/other
+from 85edc5eac315bc680677b2fc71622bd77476f057eb8dc8ed6a497803a24f1f46
+
+commit refs/heads/further
+committer A U Thor <author@example.com> 1712563400 +0000
+data 21
+what about 2nd commit
+from 17e650f097a4db6fe069c96935360d3ccc9b35c4018728c5f311a4217c2ced3d
+M 644 inline other test file
+data 19
+more dummy content
+
+done
+Y_INPUT_END
+
+cat >Y-reference-pending-sha1 <<\Y_INPUT_END
+commit refs/heads/main
+committer A U Thor <author@example.com> 1712563200 +0000
+data 14
+commit message
+M 644 inline test file
+data 14
+dummy content
+
+tag newtag
+from 85b46dd918355ff17b4109ec738723d42f235a04
+tagger A U Thor <author@example.com> 1712563300 +0000
+data 11
+tag message
+# no emty line after tag data!
+reset refs/heads/other
+from ec6c4db71feb5f66615214dad2324ce030e777a7
+
+commit refs/heads/further
+committer A U Thor <author@example.com> 1712563400 +0000
+data 21
+what about 2nd commit
+from 85b46dd918355ff17b4109ec738723d42f235a04
+M 644 inline other test file
+data 19
+more dummy content
+
+done
+Y_INPUT_END
+
+test_expect_success 'Y: reference pending tag or commit' '
+	git init reference-pending &&
+	(
+		cd reference-pending &&
+		git fast-import < "../Y-reference-pending-$(git rev-parse --show-object-format)"
+	)
+'
+
 test_done

base-commit: 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd
-- 
gitgitgadget

  parent reply	other threads:[~2026-10-12 22:50 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-10 17:24 [PATCH] fast-import: fix lookup for new commits Marc Becker via GitGitGadget
2026-10-11 19:38 ` Aniket Gupta
2026-10-12 22:50 ` Marc Becker via GitGitGadget [this message]
2026-10-13  0:08   ` [PATCH v2] fast-import: fix lookup for new commits and tags Junio C Hamano
2026-10-13  1:39   ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.2252.v2.git.1791845420568.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=aniketgupta3001@gmail.com \
    --cc=becm@gmx.de \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox