From 99b5a79e1329468bee26ae3bd9070c47418279d0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 26 May 2007 09:25:31 -0700 Subject: [PATCH] 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 Signed-off-by: Junio C Hamano --- builtin-pack-refs.c | 72 ++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c index d080e30d67..1952950c9a 100644 --- a/builtin-pack-refs.c +++ b/builtin-pack-refs.c @@ -12,9 +12,11 @@ struct ref_to_prune { char name[FLEX_ARRAY]; }; +#define PACK_REFS_PRUNE 0x0001 +#define PACK_REFS_ALL 0x0002 + struct pack_refs_cb_data { - int prune; - int all; + unsigned int flags; struct ref_to_prune *ref_to_prune; FILE *refs_file; }; @@ -39,7 +41,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, is_tag_ref = !prefixcmp(path, "refs/tags/"); /* ALWAYS pack refs that were already packed or are tags */ - if (!cb->all && !is_tag_ref && !(flags & REF_ISPACKED)) + if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && !(flags & REF_ISPACKED)) return 0; 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, } } - if (cb->prune && !do_not_prune(flags)) { + if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) { int namelen = strlen(path) + 1; struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen); hashcpy(n->sha1, sha1); @@ -85,33 +87,13 @@ static void prune_refs(struct ref_to_prune *r) static struct lock_file packed; -int cmd_pack_refs(int argc, const char **argv, const char *prefix) +static int pack_refs(unsigned int flags) { - int fd, i; + int fd; struct pack_refs_cb_data cbdata; memset(&cbdata, 0, sizeof(cbdata)); - - cbdata.prune = 1; - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; - if (!strcmp(arg, "--prune")) { - cbdata.prune = 1; /* now the default */ - continue; - } - if (!strcmp(arg, "--no-prune")) { - cbdata.prune = 0; - continue; - } - if (!strcmp(arg, "--all")) { - cbdata.all = 1; - continue; - } - /* perhaps other parameters later... */ - break; - } - if (i != argc) - usage(builtin_pack_refs_usage); + cbdata.flags = flags; fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1); cbdata.refs_file = fdopen(fd, "w"); @@ -123,12 +105,40 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix) fprintf(cbdata.refs_file, "# pack-refs with: peeled \n"); for_each_ref(handle_one_ref, &cbdata); - fflush(cbdata.refs_file); - fsync(fd); - fclose(cbdata.refs_file); + if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file)) + die("failed to write ref-pack file (%s)", strerror(errno)); if (commit_lock_file(&packed) < 0) die("unable to overwrite old ref-pack file (%s)", strerror(errno)); - if (cbdata.prune) + if (cbdata.flags & PACK_REFS_PRUNE) prune_refs(cbdata.ref_to_prune); return 0; } + +int cmd_pack_refs(int argc, const char **argv, const char *prefix) +{ + int i; + unsigned int flags; + + flags = PACK_REFS_PRUNE; + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, "--prune")) { + flags |= PACK_REFS_PRUNE; /* now the default */ + continue; + } + if (!strcmp(arg, "--no-prune")) { + flags &= ~PACK_REFS_PRUNE; + continue; + } + if (!strcmp(arg, "--all")) { + flags |= PACK_REFS_ALL; + continue; + } + /* perhaps other parameters later... */ + break; + } + if (i != argc) + usage(builtin_pack_refs_usage); + + return pack_refs(flags); +}