Skip to content

Commit 99b5a79

Browse files
torvaldsJunio C Hamano
authored andcommitted
Make the pack-refs interfaces usable from outside
This just basically creates a "pack_refs()" function that could be used by anybody. You pass it in the flags you want as a bitmask (PACK_REFS_ALL and PACK_REFS_PRUNE), and it will do all the heavy lifting. Of course, it's still static, and it's all in the builtin-pack-refs.c file, so it's not actually visible to the outside, but the next step would be to just move it all to a library file (probably refs.c) and expose it. Then we could easily make "git gc" do this too. While I did it, I also made it check the return value of the fflush and fsync stage, to make sure that we don't overwrite the old packed-refs file with something that got truncated due to write errors! Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent c56ed46 commit 99b5a79

File tree

1 file changed

+38
-28
lines changed

1 file changed

+38
-28
lines changed

builtin-pack-refs.c

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ struct ref_to_prune {
1212
char name[FLEX_ARRAY];
1313
};
1414

15+
#define PACK_REFS_PRUNE 0x0001
16+
#define PACK_REFS_ALL 0x0002
17+
1518
struct pack_refs_cb_data {
16-
int prune;
17-
int all;
19+
unsigned int flags;
1820
struct ref_to_prune *ref_to_prune;
1921
FILE *refs_file;
2022
};
@@ -39,7 +41,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
3941
is_tag_ref = !prefixcmp(path, "refs/tags/");
4042

4143
/* ALWAYS pack refs that were already packed or are tags */
42-
if (!cb->all && !is_tag_ref && !(flags & REF_ISPACKED))
44+
if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && !(flags & REF_ISPACKED))
4345
return 0;
4446

4547
fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
@@ -53,7 +55,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
5355
}
5456
}
5557

56-
if (cb->prune && !do_not_prune(flags)) {
58+
if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) {
5759
int namelen = strlen(path) + 1;
5860
struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen);
5961
hashcpy(n->sha1, sha1);
@@ -85,26 +87,51 @@ static void prune_refs(struct ref_to_prune *r)
8587

8688
static struct lock_file packed;
8789

88-
int cmd_pack_refs(int argc, const char **argv, const char *prefix)
90+
static int pack_refs(unsigned int flags)
8991
{
90-
int fd, i;
92+
int fd;
9193
struct pack_refs_cb_data cbdata;
9294

9395
memset(&cbdata, 0, sizeof(cbdata));
96+
cbdata.flags = flags;
97+
98+
fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1);
99+
cbdata.refs_file = fdopen(fd, "w");
100+
if (!cbdata.refs_file)
101+
die("unable to create ref-pack file structure (%s)",
102+
strerror(errno));
103+
104+
/* perhaps other traits later as well */
105+
fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
106+
107+
for_each_ref(handle_one_ref, &cbdata);
108+
if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
109+
die("failed to write ref-pack file (%s)", strerror(errno));
110+
if (commit_lock_file(&packed) < 0)
111+
die("unable to overwrite old ref-pack file (%s)", strerror(errno));
112+
if (cbdata.flags & PACK_REFS_PRUNE)
113+
prune_refs(cbdata.ref_to_prune);
114+
return 0;
115+
}
94116

95-
cbdata.prune = 1;
117+
int cmd_pack_refs(int argc, const char **argv, const char *prefix)
118+
{
119+
int i;
120+
unsigned int flags;
121+
122+
flags = PACK_REFS_PRUNE;
96123
for (i = 1; i < argc; i++) {
97124
const char *arg = argv[i];
98125
if (!strcmp(arg, "--prune")) {
99-
cbdata.prune = 1; /* now the default */
126+
flags |= PACK_REFS_PRUNE; /* now the default */
100127
continue;
101128
}
102129
if (!strcmp(arg, "--no-prune")) {
103-
cbdata.prune = 0;
130+
flags &= ~PACK_REFS_PRUNE;
104131
continue;
105132
}
106133
if (!strcmp(arg, "--all")) {
107-
cbdata.all = 1;
134+
flags |= PACK_REFS_ALL;
108135
continue;
109136
}
110137
/* perhaps other parameters later... */
@@ -113,22 +140,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
113140
if (i != argc)
114141
usage(builtin_pack_refs_usage);
115142

116-
fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1);
117-
cbdata.refs_file = fdopen(fd, "w");
118-
if (!cbdata.refs_file)
119-
die("unable to create ref-pack file structure (%s)",
120-
strerror(errno));
121-
122-
/* perhaps other traits later as well */
123-
fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
124-
125-
for_each_ref(handle_one_ref, &cbdata);
126-
fflush(cbdata.refs_file);
127-
fsync(fd);
128-
fclose(cbdata.refs_file);
129-
if (commit_lock_file(&packed) < 0)
130-
die("unable to overwrite old ref-pack file (%s)", strerror(errno));
131-
if (cbdata.prune)
132-
prune_refs(cbdata.ref_to_prune);
133-
return 0;
143+
return pack_refs(flags);
134144
}

0 commit comments

Comments
 (0)