git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/4 v2] Move pack_refs() and friends into libgit

From
Johan Herland <johan@herland.net>
Date
Jun 15, 2008, 21:27 UTC
Message-ID
<200806152327.24586.johan@herland.net>
In-Reply-To
<20080615175159.GA6127@sigill.intra.peff.net>

This moves pack_refs() and underlying functionality into the library, to make pack-refs functionality easily available to all git programs.

Most of builtin-pack-refs.c has been moved verbatim into a new file pack-refs.c that is compiled into libgit.a. A corresponding header file, pack-refs.h, has also been added, declaring pack_refs() and the #defines associated with the flags parameter to pack_refs().

This patch introduces no other changes in functionality.
Signed-off-by: Johan Herland <johan@herland.net>
---
On Sunday 15 June 2008, Jeff King wrote:
> This patch would have been a lot easier to read, btw, if it had been
> generated with '-C' (then patch to pack-refs.c is based on
> builtin-pack-refs instead of /dev/null).
Sorry about that. Here you go.
...Johan	
 Makefile                           |    2 +
 builtin-pack-refs.c                |  121 +-----------------------------------
 builtin-pack-refs.c => pack-refs.c |   27 +--------
 pack-refs.h                        |   18 +++++
 4 files changed, 23 insertions(+), 145 deletions(-)
 copy builtin-pack-refs.c => pack-refs.c (80%)
 create mode 100644 pack-refs.h
diff --git a/Makefile b/Makefile
index 1937507..4a78388 100644
--- a/Makefile
+++ b/Makefile
@@ -354,6 +354,7 @@ LIB_H += log-tree.h
 LIB_H += mailmap.h
 LIB_H += object.h
 LIB_H += pack.h
+LIB_H += pack-refs.h
 LIB_H += pack-revindex.h
 LIB_H += parse-options.h
 LIB_H += patch-ids.h
@@ -429,6 +430,7 @@ LIB_OBJS += merge-file.o
 LIB_OBJS += name-hash.o
 LIB_OBJS += object.o
 LIB_OBJS += pack-check.o
+LIB_OBJS += pack-refs.o
 LIB_OBJS += pack-revindex.o
 LIB_OBJS += pack-write.o
 LIB_OBJS += pager.o
diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c
index 1aaa76d..ff90aef 100644
--- a/builtin-pack-refs.c
+++ b/builtin-pack-refs.c
@@ -1,125 +1,6 @@
-#include "builtin.h"
 #include "cache.h"
-#include "refs.h"
-#include "object.h"
-#include "tag.h"
 #include "parse-options.h"
-
-struct ref_to_prune {
-	struct ref_to_prune *next;
-	unsigned char sha1[20];
-	char name[FLEX_ARRAY];
-};
-
-#define PACK_REFS_PRUNE	0x0001
-#define PACK_REFS_ALL	0x0002
-
-struct pack_refs_cb_data {
-	unsigned int flags;
-	struct ref_to_prune *ref_to_prune;
-	FILE *refs_file;
-};
-
-static int do_not_prune(int flags)
-{
-	/* If it is already packed or if it is a symref,
-	 * do not prune it.
-	 */
-	return (flags & (REF_ISSYMREF|REF_ISPACKED));
-}
-
-static int handle_one_ref(const char *path, const unsigned char *sha1,
-			  int flags, void *cb_data)
-{
-	struct pack_refs_cb_data *cb = cb_data;
-	int is_tag_ref;
-
-	/* Do not pack the symbolic refs */
-	if ((flags & REF_ISSYMREF))
-		return 0;
-	is_tag_ref = !prefixcmp(path, "refs/tags/");
-
-	/* ALWAYS pack refs that were already packed or are tags */
-	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);
-	if (is_tag_ref) {
-		struct object *o = parse_object(sha1);
-		if (o->type == OBJ_TAG) {
-			o = deref_tag(o, path, 0);
-			if (o)
-				fprintf(cb->refs_file, "^%s\n",
-					sha1_to_hex(o->sha1));
-		}
-	}
-
-	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);
-		strcpy(n->name, path);
-		n->next = cb->ref_to_prune;
-		cb->ref_to_prune = n;
-	}
-	return 0;
-}
-
-/* make sure nobody touched the ref, and unlink */
-static void prune_ref(struct ref_to_prune *r)
-{
-	struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1);
-
-	if (lock) {
-		unlink(git_path("%s", r->name));
-		unlock_ref(lock);
-	}
-}
-
-static void prune_refs(struct ref_to_prune *r)
-{
-	while (r) {
-		prune_ref(r);
-		r = r->next;
-	}
-}
-
-static struct lock_file packed;
-
-static int pack_refs(unsigned int flags)
-{
-	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 (ferror(cbdata.refs_file))
-		die("failed to write ref-pack file");
-	if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
-		die("failed to write ref-pack file (%s)", strerror(errno));
-	/*
-	 * Since the lock file was fdopen()'ed and then fclose()'ed above,
-	 * assign -1 to the lock file descriptor so that commit_lock_file()
-	 * won't try to close() it.
-	 */
-	packed.fd = -1;
-	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;
-}
+#include "pack-refs.h"
 
 static char const * const pack_refs_usage[] = {
 	"git-pack-refs [options]",
diff --git a/builtin-pack-refs.c b/pack-refs.c
similarity index 80%
copy from builtin-pack-refs.c
copy to pack-refs.c
index 1aaa76d..848d311 100644
--- a/builtin-pack-refs.c
+++ b/pack-refs.c
@@ -1,9 +1,7 @@
-#include "builtin.h"
 #include "cache.h"
 #include "refs.h"
-#include "object.h"
 #include "tag.h"
-#include "parse-options.h"
+#include "pack-refs.h"
 
 struct ref_to_prune {
 	struct ref_to_prune *next;
@@ -11,9 +9,6 @@ struct ref_to_prune {
 	char name[FLEX_ARRAY];
 };
 
-#define PACK_REFS_PRUNE	0x0001
-#define PACK_REFS_ALL	0x0002
-
 struct pack_refs_cb_data {
 	unsigned int flags;
 	struct ref_to_prune *ref_to_prune;
@@ -86,7 +81,7 @@ static void prune_refs(struct ref_to_prune *r)
 
 static struct lock_file packed;
 
-static int pack_refs(unsigned int flags)
+int pack_refs(unsigned int flags)
 {
 	int fd;
 	struct pack_refs_cb_data cbdata;
@@ -120,21 +115,3 @@ static int pack_refs(unsigned int flags)
 		prune_refs(cbdata.ref_to_prune);
 	return 0;
 }
-
-static char const * const pack_refs_usage[] = {
-	"git-pack-refs [options]",
-	NULL
-};
-
-int cmd_pack_refs(int argc, const char **argv, const char *prefix)
-{
-	unsigned int flags = PACK_REFS_PRUNE;
-	struct option opts[] = {
-		OPT_BIT(0, "all",   &flags, "pack everything", PACK_REFS_ALL),
-		OPT_BIT(0, "prune", &flags, "prune loose refs (default)", PACK_REFS_PRUNE),
-		OPT_END(),
-	};
-	if (parse_options(argc, argv, opts, pack_refs_usage, 0))
-		usage_with_options(pack_refs_usage, opts);
-	return pack_refs(flags);
-}
diff --git a/pack-refs.h b/pack-refs.h
new file mode 100644
index 0000000..518acfb
--- /dev/null
+++ b/pack-refs.h
@@ -0,0 +1,18 @@
+#ifndef PACK_REFS_H
+#define PACK_REFS_H
+
+/*
+ * Flags for controlling behaviour of pack_refs()
+ * PACK_REFS_PRUNE: Prune loose refs after packing
+ * PACK_REFS_ALL:   Pack _all_ refs, not just tags and already packed refs
+ */
+#define PACK_REFS_PRUNE 0x0001
+#define PACK_REFS_ALL   0x0002
+
+/*
+ * Write a packed-refs file for the current repository.
+ * flags: Combination of the above PACK_REFS_* flags.
+ */
+int pack_refs(unsigned int flags);
+
+#endif /* PACK_REFS_H */
-- 
1.5.6.rc2.128.gf64ae
Previous: Jeff KingNext: Johan Herland
Message 5 of 13 in “Teach "git clone" to pack refs”
  1. 0/4 Teach "git clone" to pack refsJohan Herland, Jun 15, 2008
  2. 1/4 Incorporate fetched packs in future object traversalJohan Herland, Jun 15, 2008
  3. 2/4 Move pack_refs() and friends into libgitJohan Herland, Jun 15, 2008
  4. Jeff KingJun 15, 2008
  5. 2/4 Move pack_refs() and friends into libgitJohan Herland, Jun 15, 2008
  6. 3/4 Prepare testsuite for a "git clone" that packs refsJohan Herland, Jun 15, 2008
  7. Jeff KingJun 15, 2008
  8. Jakub NarebskiJun 15, 2008
  9. 3/4 Prepare testsuite for a "git clone" that packs refsJohan Herland, Jun 15, 2008
  10. 4/4 Teach "git clone" to pack refsJohan Herland, Jun 15, 2008
  11. Jeff KingJun 15, 2008
  12. Johan HerlandJun 15, 2008
  13. Jeff KingJun 16, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.