Skip to content

Commit 196d9e8

Browse files
committed
refs: allow loose files without packed-refs
The extensions.refFormat extension is a multi-valued config that specifies which ref formats are available to the current repository. By default, Git assumes the list of "files" and "packed", unless there is at least one of these extensions specified. With the current values, it is possible for a user to specify only "files" or only "packed". The only-"packed" option was already ruled as invalid since Git's current code has too many places that require a loose reference. This could change in the future. However, we can now allow the user to specify extensions.refFormat=files alone, making it impossible to create a packed-refs file (or to read one that might exist). Signed-off-by: Derrick Stolee <derrickstolee@github.com>
1 parent 8e3cad1 commit 196d9e8

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

refs/files-backend.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,12 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
12071207
struct strbuf err = STRBUF_INIT;
12081208
struct ref_transaction *transaction;
12091209

1210+
if (!packed_refs_enabled(refs->store_flags)) {
1211+
warning(_("refusing to create '%s' file because '%s' is not set"),
1212+
"packed-refs", "extensions.refFormat=packed");
1213+
return -1;
1214+
}
1215+
12101216
transaction = ref_store_transaction_begin(refs->packed_ref_store, &err);
12111217
if (!transaction)
12121218
return -1;

refs/packed-backend.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,9 @@ static int load_contents(struct snapshot *snapshot)
478478
size_t size;
479479
ssize_t bytes_read;
480480

481+
if (!packed_refs_enabled(snapshot->refs->store_flags))
482+
return 0;
483+
481484
fd = open(snapshot->refs->path, O_RDONLY);
482485
if (fd < 0) {
483486
if (errno == ENOENT) {

refs/refs-internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,11 @@ struct ref_store;
524524
#define REF_STORE_FORMAT_FILES (1 << 8) /* can use loose ref files */
525525
#define REF_STORE_FORMAT_PACKED (1 << 9) /* can use packed-refs file */
526526

527+
static inline int packed_refs_enabled(int flags)
528+
{
529+
return flags & REF_STORE_FORMAT_PACKED;
530+
}
531+
527532
/*
528533
* Initialize the ref_store for the specified gitdir. These functions
529534
* should call base_ref_store_init() to initialize the shared part of

t/t3212-ref-formats.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,24 @@ test_expect_success 'extensions.refFormat=packed only' '
3636
)
3737
'
3838

39+
test_expect_success 'extensions.refFormat=files only' '
40+
test_commit T &&
41+
git pack-refs --all &&
42+
git init only-loose &&
43+
(
44+
cd only-loose &&
45+
git config core.repositoryFormatVersion 1 &&
46+
git config extensions.refFormat files &&
47+
test_commit A &&
48+
test_commit B &&
49+
test_must_fail git pack-refs 2>err &&
50+
grep "refusing to create" err &&
51+
test_path_is_missing .git/packed-refs &&
52+
53+
# Refuse to parse a packed-refs file.
54+
cp ../.git/packed-refs .git/packed-refs &&
55+
test_must_fail git rev-parse refs/tags/T
56+
)
57+
'
58+
3959
test_done

0 commit comments

Comments
 (0)