@@ -927,6 +927,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
927
927
struct ref * mapped_refs = NULL ;
928
928
const struct ref * ref ;
929
929
struct strbuf key = STRBUF_INIT ;
930
+ struct strbuf buf = STRBUF_INIT ;
930
931
struct strbuf branch_top = STRBUF_INIT , reflog_msg = STRBUF_INIT ;
931
932
struct transport * transport = NULL ;
932
933
const char * src_ref_prefix = "refs/heads/" ;
@@ -1126,6 +1127,50 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1126
1127
git_dir = real_git_dir ;
1127
1128
}
1128
1129
1130
+ /*
1131
+ * We have a chicken-and-egg situation between initializing the refdb
1132
+ * and spawning transport helpers:
1133
+ *
1134
+ * - Initializing the refdb requires us to know about the object
1135
+ * format. We thus have to spawn the transport helper to learn
1136
+ * about it.
1137
+ *
1138
+ * - The transport helper may want to access the Git repository. But
1139
+ * because the refdb has not been initialized, we don't have "HEAD"
1140
+ * or "refs/". Thus, the helper cannot find the Git repository.
1141
+ *
1142
+ * Ideally, we would have structured the helper protocol such that it's
1143
+ * mandatory for the helper to first announce its capabilities without
1144
+ * yet assuming a fully initialized repository. Like that, we could
1145
+ * have added a "lazy-refdb-init" capability that announces whether the
1146
+ * helper is ready to handle not-yet-initialized refdbs. If any helper
1147
+ * didn't support them, we would have fully initialized the refdb with
1148
+ * the SHA1 object format, but later on bailed out if we found out that
1149
+ * the remote repository used a different object format.
1150
+ *
1151
+ * But we didn't, and thus we use the following workaround to partially
1152
+ * initialize the repository's refdb such that it can be discovered by
1153
+ * Git commands. To do so, we:
1154
+ *
1155
+ * - Create an invalid HEAD ref pointing at "refs/heads/.invalid".
1156
+ *
1157
+ * - Create the "refs/" directory.
1158
+ *
1159
+ * - Set up the ref storage format and repository version as
1160
+ * required.
1161
+ *
1162
+ * This is sufficient for Git commands to discover the Git directory.
1163
+ */
1164
+ initialize_repository_version (GIT_HASH_UNKNOWN ,
1165
+ the_repository -> ref_storage_format , 1 );
1166
+
1167
+ strbuf_addf (& buf , "%s/HEAD" , git_dir );
1168
+ write_file (buf .buf , "ref: refs/heads/.invalid" );
1169
+
1170
+ strbuf_reset (& buf );
1171
+ strbuf_addf (& buf , "%s/refs" , git_dir );
1172
+ safe_create_dir (buf .buf , 1 );
1173
+
1129
1174
/*
1130
1175
* additional config can be injected with -c, make sure it's included
1131
1176
* after init_db, which clears the entire config environment.
@@ -1454,6 +1499,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1454
1499
free (remote_name );
1455
1500
strbuf_release (& reflog_msg );
1456
1501
strbuf_release (& branch_top );
1502
+ strbuf_release (& buf );
1457
1503
strbuf_release (& key );
1458
1504
free_refs (mapped_refs );
1459
1505
free_refs (remote_head_points_at );
0 commit comments