Skip to content

Commit 054b5e4

Browse files
ttaylorrgitster
authored andcommitted
builtin/repack.c: extract marking packs for deletion
At the end of a repack (when given `-d`), Git attempts to remove any packs which have been made "redundant" as a result of the repacking operation. For example, an all-into-one (`-A` or `-a`) repack makes every pre-existing pack which is not marked as kept redundant. Geometric repacks (with `--geometric=<n>`) make any packs which were rolled up redundant, and so on. But before deleting the set of packs we think are redundant, we first check to see whether or not we just wrote a pack which is identical to any one of the packs we were going to delete. When this is the case, Git must avoid deleting that pack, since it matches a pack we just wrote (so deleting it may cause the repository to become corrupt). Right now we only process the list of non-kept packs in a single pass. But a future change will split the existing non-kept packs further into two lists: one for cruft packs, and another for non-cruft packs. Factor out this routine to prepare for calling it twice on two separate lists in a future patch. Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e2b4383 commit 054b5e4

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

builtin/repack.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,36 @@ struct existing_packs {
105105
.non_kept_packs = STRING_LIST_INIT_DUP, \
106106
}
107107

108+
static void mark_packs_for_deletion_1(struct string_list *names,
109+
struct string_list *list)
110+
{
111+
struct string_list_item *item;
112+
const int hexsz = the_hash_algo->hexsz;
113+
114+
for_each_string_list_item(item, list) {
115+
char *sha1;
116+
size_t len = strlen(item->string);
117+
if (len < hexsz)
118+
continue;
119+
sha1 = item->string + len - hexsz;
120+
/*
121+
* Mark this pack for deletion, which ensures that this
122+
* pack won't be included in a MIDX (if `--write-midx`
123+
* was given) and that we will actually delete this pack
124+
* (if `-d` was given).
125+
*/
126+
if (!string_list_has_string(names, sha1))
127+
item->util = (void*)(uintptr_t)((size_t)item->util | DELETE_PACK);
128+
}
129+
}
130+
131+
static void mark_packs_for_deletion(struct existing_packs *existing,
132+
struct string_list *names)
133+
134+
{
135+
mark_packs_for_deletion_1(names, &existing->non_kept_packs);
136+
}
137+
108138
static void existing_packs_release(struct existing_packs *existing)
109139
{
110140
string_list_clear(&existing->kept_packs, 0);
@@ -1141,24 +1171,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
11411171
}
11421172
/* End of pack replacement. */
11431173

1144-
if (delete_redundant && pack_everything & ALL_INTO_ONE) {
1145-
const int hexsz = the_hash_algo->hexsz;
1146-
for_each_string_list_item(item, &existing.non_kept_packs) {
1147-
char *sha1;
1148-
size_t len = strlen(item->string);
1149-
if (len < hexsz)
1150-
continue;
1151-
sha1 = item->string + len - hexsz;
1152-
/*
1153-
* Mark this pack for deletion, which ensures that this
1154-
* pack won't be included in a MIDX (if `--write-midx`
1155-
* was given) and that we will actually delete this pack
1156-
* (if `-d` was given).
1157-
*/
1158-
if (!string_list_has_string(&names, sha1))
1159-
item->util = (void*)(uintptr_t)((size_t)item->util | DELETE_PACK);
1160-
}
1161-
}
1174+
if (delete_redundant && pack_everything & ALL_INTO_ONE)
1175+
mark_packs_for_deletion(&existing, &names);
11621176

11631177
if (write_midx) {
11641178
struct string_list include = STRING_LIST_INIT_NODUP;

0 commit comments

Comments
 (0)