@@ -177,7 +177,8 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree)
177
177
}
178
178
179
179
static int create_default_files (const char * template_path ,
180
- const char * original_git_dir )
180
+ const char * original_git_dir ,
181
+ const struct repository_format * fmt )
181
182
{
182
183
struct stat st1 ;
183
184
struct strbuf buf = STRBUF_INIT ;
@@ -187,6 +188,7 @@ static int create_default_files(const char *template_path,
187
188
int reinit ;
188
189
int filemode ;
189
190
struct strbuf err = STRBUF_INIT ;
191
+ int repo_version = GIT_REPO_VERSION ;
190
192
191
193
/* Just look for `init.templatedir` */
192
194
init_db_template_dir = NULL ; /* re-set in case it was set before */
@@ -244,11 +246,23 @@ static int create_default_files(const char *template_path,
244
246
exit (1 );
245
247
}
246
248
249
+ #ifndef ENABLE_SHA256
250
+ if (fmt -> hash_algo != GIT_HASH_SHA1 )
251
+ die (_ ("The hash algorithm %s is not supported in this build." ), hash_algos [fmt -> hash_algo ].name );
252
+ #endif
253
+
254
+ if (fmt -> hash_algo != GIT_HASH_SHA1 )
255
+ repo_version = GIT_REPO_VERSION_READ ;
256
+
247
257
/* This forces creation of new config file */
248
258
xsnprintf (repo_version_string , sizeof (repo_version_string ),
249
- "%d" , GIT_REPO_VERSION );
259
+ "%d" , repo_version );
250
260
git_config_set ("core.repositoryformatversion" , repo_version_string );
251
261
262
+ if (fmt -> hash_algo != GIT_HASH_SHA1 )
263
+ git_config_set ("extensions.objectformat" ,
264
+ hash_algos [fmt -> hash_algo ].name );
265
+
252
266
/* Check filemode trustability */
253
267
path = git_path_buf (& buf , "config" );
254
268
filemode = TEST_FILEMODE ;
@@ -340,12 +354,26 @@ static void separate_git_dir(const char *git_dir, const char *git_link)
340
354
write_file (git_link , "gitdir: %s" , git_dir );
341
355
}
342
356
357
+ static void validate_hash_algorithm (struct repository_format * repo_fmt , int hash )
358
+ {
359
+ /*
360
+ * If we already have an initialized repo, don't allow the user to
361
+ * specify a different algorithm, as that could cause corruption.
362
+ * Otherwise, if the user has specified one on the command line, use it.
363
+ */
364
+ if (repo_fmt -> version >= 0 && hash != GIT_HASH_UNKNOWN && hash != repo_fmt -> hash_algo )
365
+ die (_ ("attempt to reinitialize repository with different hash" ));
366
+ else if (hash != GIT_HASH_UNKNOWN )
367
+ repo_fmt -> hash_algo = hash ;
368
+ }
369
+
343
370
int init_db (const char * git_dir , const char * real_git_dir ,
344
- const char * template_dir , unsigned int flags )
371
+ const char * template_dir , int hash , unsigned int flags )
345
372
{
346
373
int reinit ;
347
374
int exist_ok = flags & INIT_DB_EXIST_OK ;
348
375
char * original_git_dir = real_pathdup (git_dir , 1 );
376
+ struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT ;
349
377
350
378
if (real_git_dir ) {
351
379
struct stat st ;
@@ -378,9 +406,11 @@ int init_db(const char *git_dir, const char *real_git_dir,
378
406
* config file, so this will not fail. What we are catching
379
407
* is an attempt to reinitialize new repository with an old tool.
380
408
*/
381
- check_repository_format (NULL );
409
+ check_repository_format (& repo_fmt );
382
410
383
- reinit = create_default_files (template_dir , original_git_dir );
411
+ validate_hash_algorithm (& repo_fmt , hash );
412
+
413
+ reinit = create_default_files (template_dir , original_git_dir , & repo_fmt );
384
414
385
415
create_object_directory ();
386
416
@@ -482,6 +512,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
482
512
const char * work_tree ;
483
513
const char * template_dir = NULL ;
484
514
unsigned int flags = 0 ;
515
+ const char * object_format = NULL ;
516
+ int hash_algo = GIT_HASH_UNKNOWN ;
485
517
const struct option init_db_options [] = {
486
518
OPT_STRING (0 , "template" , & template_dir , N_ ("template-directory" ),
487
519
N_ ("directory from which templates will be used" )),
@@ -494,6 +526,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
494
526
OPT_BIT ('q' , "quiet" , & flags , N_ ("be quiet" ), INIT_DB_QUIET ),
495
527
OPT_STRING (0 , "separate-git-dir" , & real_git_dir , N_ ("gitdir" ),
496
528
N_ ("separate git dir from working tree" )),
529
+ OPT_STRING (0 , "object-format" , & object_format , N_ ("hash" ),
530
+ N_ ("specify the hash algorithm to use" )),
497
531
OPT_END ()
498
532
};
499
533
@@ -546,6 +580,12 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
546
580
free (cwd );
547
581
}
548
582
583
+ if (object_format ) {
584
+ hash_algo = hash_algo_by_name (object_format );
585
+ if (hash_algo == GIT_HASH_UNKNOWN )
586
+ die (_ ("unknown hash algorithm '%s'" ), object_format );
587
+ }
588
+
549
589
if (init_shared_repository != -1 )
550
590
set_shared_repository (init_shared_repository );
551
591
@@ -597,5 +637,5 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
597
637
UNLEAK (work_tree );
598
638
599
639
flags |= INIT_DB_EXIST_OK ;
600
- return init_db (git_dir , real_git_dir , template_dir , flags );
640
+ return init_db (git_dir , real_git_dir , template_dir , hash_algo , flags );
601
641
}
0 commit comments