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 | 66 ++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c index d080e30d6..1952950c9 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,26 +87,51 @@ 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.flags = flags; + + fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1); + cbdata.refs_file = fdopen(fd, "w"); + if (!cbdata.refs_file) + die("unable to create ref-pack file structure (%s)", + strerror(errno)); + + /* perhaps other traits later as well */ + fprintf(cbdata.refs_file, "# pack-refs with: peeled \n"); + + for_each_ref(handle_one_ref, &cbdata); + 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.flags & PACK_REFS_PRUNE) + prune_refs(cbdata.ref_to_prune); + return 0; +} - cbdata.prune = 1; +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")) { - cbdata.prune = 1; /* now the default */ + flags |= PACK_REFS_PRUNE; /* now the default */ continue; } if (!strcmp(arg, "--no-prune")) { - cbdata.prune = 0; + flags &= ~PACK_REFS_PRUNE; continue; } if (!strcmp(arg, "--all")) { - cbdata.all = 1; + flags |= PACK_REFS_ALL; continue; } /* perhaps other parameters later... */ @@ -113,22 +140,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix) if (i != argc) usage(builtin_pack_refs_usage); - fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1); - cbdata.refs_file = fdopen(fd, "w"); - if (!cbdata.refs_file) - die("unable to create ref-pack file structure (%s)", - strerror(errno)); - - /* perhaps other traits later as well */ - 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 (commit_lock_file(&packed) < 0) - die("unable to overwrite old ref-pack file (%s)", strerror(errno)); - if (cbdata.prune) - prune_refs(cbdata.ref_to_prune); - return 0; + return pack_refs(flags); } -- 2.30.2