pack-refs: merge code from pack-refs.{c,h} into refs.{c,h}

pack-refs.c doesn't contain much code, and the code it does contain is closely related to reference handling. Moreover, there is some duplication between pack_refs() and repack_without_ref(). Therefore, merge pack-refs.c into refs.c and pack-refs.h into refs.h. The code duplication will be addressed in future commits. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Apr 22, 2013 at 21:52 UTC 32d462cea80cd52b2c3fa0d538aba7fcf079ba77
7 files changed +159 -170
Makefile
-2
@@ -644,7 +644,6 @@ LIB_H += notes-cache.h
644 LIB_H += notes-merge.h
645 LIB_H += notes.h
646 LIB_H += object.h
647 -LIB_H += pack-refs.h
647 LIB_H += pack-revindex.h
648 LIB_H += pack.h
649 LIB_H += parse-options.h
@@ -775,7 +774,6 @@ LIB_OBJS += notes-cache.o
774 LIB_OBJS += notes-merge.o
775 LIB_OBJS += object.o
776 LIB_OBJS += pack-check.o
778 -LIB_OBJS += pack-refs.o
777 LIB_OBJS += pack-revindex.o
778 LIB_OBJS += pack-write.o
779 LIB_OBJS += pager.o
builtin/clone.c
-1
@@ -18,7 +18,6 @@
18 #include "transport.h"
19 #include "strbuf.h"
20 #include "dir.h"
21 -#include "pack-refs.h"
21 #include "sigchain.h"
22 #include "branch.h"
23 #include "remote.h"
builtin/pack-refs.c
+1 -1
@@ -1,6 +1,6 @@
1 #include "builtin.h"
2 #include "parse-options.h"
3 -#include "pack-refs.h"
3 +#include "refs.h"
4
5 static char const * const pack_refs_usage[] = {
6 N_("git pack-refs [options]"),
pack-refs.c deleted
-148
@@ -1,148 +0,0 @@
1 -#include "cache.h"
2 -#include "refs.h"
3 -#include "tag.h"
4 -#include "pack-refs.h"
5 -
6 -struct ref_to_prune {
7 - struct ref_to_prune *next;
8 - unsigned char sha1[20];
9 - char name[FLEX_ARRAY];
10 -};
11 -
12 -struct pack_refs_cb_data {
13 - unsigned int flags;
14 - struct ref_to_prune *ref_to_prune;
15 - FILE *refs_file;
16 -};
17 -
18 -static int do_not_prune(int flags)
19 -{
20 - /* If it is already packed or if it is a symref,
21 - * do not prune it.
22 - */
23 - return (flags & (REF_ISSYMREF|REF_ISPACKED));
24 -}
25 -
26 -static int pack_one_ref(const char *path, const unsigned char *sha1,
27 - int flags, void *cb_data)
28 -{
29 - struct pack_refs_cb_data *cb = cb_data;
30 - struct object *o;
31 - int is_tag_ref;
32 -
33 - /* Do not pack the symbolic refs */
34 - if ((flags & REF_ISSYMREF))
35 - return 0;
36 - is_tag_ref = !prefixcmp(path, "refs/tags/");
37 -
38 - /* ALWAYS pack refs that were already packed or are tags */
39 - if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && !(flags & REF_ISPACKED))
40 - return 0;
41 -
42 - fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
43 -
44 - o = parse_object_or_die(sha1, path);
45 - if (o->type == OBJ_TAG) {
46 - o = deref_tag(o, path, 0);
47 - if (o)
48 - fprintf(cb->refs_file, "^%s\n",
49 - sha1_to_hex(o->sha1));
50 - }
51 -
52 - if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) {
53 - int namelen = strlen(path) + 1;
54 - struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen);
55 - hashcpy(n->sha1, sha1);
56 - strcpy(n->name, path);
57 - n->next = cb->ref_to_prune;
58 - cb->ref_to_prune = n;
59 - }
60 - return 0;
61 -}
62 -
63 -/*
64 - * Remove empty parents, but spare refs/ and immediate subdirs.
65 - * Note: munges *name.
66 - */
67 -static void try_remove_empty_parents(char *name)
68 -{
69 - char *p, *q;
70 - int i;
71 - p = name;
72 - for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */
73 - while (*p && *p != '/')
74 - p++;
75 - /* tolerate duplicate slashes; see check_refname_format() */
76 - while (*p == '/')
77 - p++;
78 - }
79 - for (q = p; *q; q++)
80 - ;
81 - while (1) {
82 - while (q > p && *q != '/')
83 - q--;
84 - while (q > p && *(q-1) == '/')
85 - q--;
86 - if (q == p)
87 - break;
88 - *q = '\0';
89 - if (rmdir(git_path("%s", name)))
90 - break;
91 - }
92 -}
93 -
94 -/* make sure nobody touched the ref, and unlink */
95 -static void prune_ref(struct ref_to_prune *r)
96 -{
97 - struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1);
98 -
99 - if (lock) {
100 - unlink_or_warn(git_path("%s", r->name));
101 - unlock_ref(lock);
102 - try_remove_empty_parents(r->name);
103 - }
104 -}
105 -
106 -static void prune_refs(struct ref_to_prune *r)
107 -{
108 - while (r) {
109 - prune_ref(r);
110 - r = r->next;
111 - }
112 -}
113 -
114 -static struct lock_file packed;
115 -
116 -int pack_refs(unsigned int flags)
117 -{
118 - int fd;
119 - struct pack_refs_cb_data cbdata;
120 -
121 - memset(&cbdata, 0, sizeof(cbdata));
122 - cbdata.flags = flags;
123 -
124 - fd = hold_lock_file_for_update(&packed, git_path("packed-refs"),
125 - LOCK_DIE_ON_ERROR);
126 - cbdata.refs_file = fdopen(fd, "w");
127 - if (!cbdata.refs_file)
128 - die_errno("unable to create ref-pack file structure");
129 -
130 - /* perhaps other traits later as well */
131 - fprintf(cbdata.refs_file, "# pack-refs with: peeled fully-peeled \n");
132 -
133 - for_each_ref(pack_one_ref, &cbdata);
134 - if (ferror(cbdata.refs_file))
135 - die("failed to write ref-pack file");
136 - if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
137 - die_errno("failed to write ref-pack file");
138 - /*
139 - * Since the lock file was fdopen()'ed and then fclose()'ed above,
140 - * assign -1 to the lock file descriptor so that commit_lock_file()
141 - * won't try to close() it.
142 - */
143 - packed.fd = -1;
144 - if (commit_lock_file(&packed) < 0)
145 - die_errno("unable to overwrite old ref-pack file");
146 - prune_refs(cbdata.ref_to_prune);
147 - return 0;
148 -}
pack-refs.h deleted
-18
@@ -1,18 +0,0 @@
1 -#ifndef PACK_REFS_H
2 -#define PACK_REFS_H
3 -
4 -/*
5 - * Flags for controlling behaviour of pack_refs()
6 - * PACK_REFS_PRUNE: Prune loose refs after packing
7 - * PACK_REFS_ALL: Pack _all_ refs, not just tags and already packed refs
8 - */
9 -#define PACK_REFS_PRUNE 0x0001
10 -#define PACK_REFS_ALL 0x0002
11 -
12 -/*
13 - * Write a packed-refs file for the current repository.
14 - * flags: Combination of the above PACK_REFS_* flags.
15 - */
16 -int pack_refs(unsigned int flags);
17 -
18 -#endif /* PACK_REFS_H */
refs.c
+144
@@ -1984,6 +1984,150 @@ static void write_packed_entry(int fd, char *refname, unsigned char *sha1,
1984 }
1985 }
1986
1987 +struct ref_to_prune {
1988 + struct ref_to_prune *next;
1989 + unsigned char sha1[20];
1990 + char name[FLEX_ARRAY];
1991 +};
1992 +
1993 +struct pack_refs_cb_data {
1994 + unsigned int flags;
1995 + struct ref_to_prune *ref_to_prune;
1996 + FILE *refs_file;
1997 +};
1998 +
1999 +static int do_not_prune(int flags)
2000 +{
2001 + /* If it is already packed or if it is a symref,
2002 + * do not prune it.
2003 + */
2004 + return (flags & (REF_ISSYMREF|REF_ISPACKED));
2005 +}
2006 +
2007 +static int pack_one_ref(const char *path, const unsigned char *sha1,
2008 + int flags, void *cb_data)
2009 +{
2010 + struct pack_refs_cb_data *cb = cb_data;
2011 + struct object *o;
2012 + int is_tag_ref;
2013 +
2014 + /* Do not pack the symbolic refs */
2015 + if ((flags & REF_ISSYMREF))
2016 + return 0;
2017 + is_tag_ref = !prefixcmp(path, "refs/tags/");
2018 +
2019 + /* ALWAYS pack refs that were already packed or are tags */
2020 + if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && !(flags & REF_ISPACKED))
2021 + return 0;
2022 +
2023 + fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
2024 +
2025 + o = parse_object_or_die(sha1, path);
2026 + if (o->type == OBJ_TAG) {
2027 + o = deref_tag(o, path, 0);
2028 + if (o)
2029 + fprintf(cb->refs_file, "^%s\n",
2030 + sha1_to_hex(o->sha1));
2031 + }
2032 +
2033 + if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) {
2034 + int namelen = strlen(path) + 1;
2035 + struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen);
2036 + hashcpy(n->sha1, sha1);
2037 + strcpy(n->name, path);
2038 + n->next = cb->ref_to_prune;
2039 + cb->ref_to_prune = n;
2040 + }
2041 + return 0;
2042 +}
2043 +
2044 +/*
2045 + * Remove empty parents, but spare refs/ and immediate subdirs.
2046 + * Note: munges *name.
2047 + */
2048 +static void try_remove_empty_parents(char *name)
2049 +{
2050 + char *p, *q;
2051 + int i;
2052 + p = name;
2053 + for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */
2054 + while (*p && *p != '/')
2055 + p++;
2056 + /* tolerate duplicate slashes; see check_refname_format() */
2057 + while (*p == '/')
2058 + p++;
2059 + }
2060 + for (q = p; *q; q++)
2061 + ;
2062 + while (1) {
2063 + while (q > p && *q != '/')
2064 + q--;
2065 + while (q > p && *(q-1) == '/')
2066 + q--;
2067 + if (q == p)
2068 + break;
2069 + *q = '\0';
2070 + if (rmdir(git_path("%s", name)))
2071 + break;
2072 + }
2073 +}
2074 +
2075 +/* make sure nobody touched the ref, and unlink */
2076 +static void prune_ref(struct ref_to_prune *r)
2077 +{
2078 + struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1);
2079 +
2080 + if (lock) {
2081 + unlink_or_warn(git_path("%s", r->name));
2082 + unlock_ref(lock);
2083 + try_remove_empty_parents(r->name);
2084 + }
2085 +}
2086 +
2087 +static void prune_refs(struct ref_to_prune *r)
2088 +{
2089 + while (r) {
2090 + prune_ref(r);
2091 + r = r->next;
2092 + }
2093 +}
2094 +
2095 +static struct lock_file packed;
2096 +
2097 +int pack_refs(unsigned int flags)
2098 +{
2099 + int fd;
2100 + struct pack_refs_cb_data cbdata;
2101 +
2102 + memset(&cbdata, 0, sizeof(cbdata));
2103 + cbdata.flags = flags;
2104 +
2105 + fd = hold_lock_file_for_update(&packed, git_path("packed-refs"),
2106 + LOCK_DIE_ON_ERROR);
2107 + cbdata.refs_file = fdopen(fd, "w");
2108 + if (!cbdata.refs_file)
2109 + die_errno("unable to create ref-pack file structure");
2110 +
2111 + /* perhaps other traits later as well */
2112 + fprintf(cbdata.refs_file, "# pack-refs with: peeled fully-peeled \n");
2113 +
2114 + for_each_ref(pack_one_ref, &cbdata);
2115 + if (ferror(cbdata.refs_file))
2116 + die("failed to write ref-pack file");
2117 + if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
2118 + die_errno("failed to write ref-pack file");
2119 + /*
2120 + * Since the lock file was fdopen()'ed and then fclose()'ed above,
2121 + * assign -1 to the lock file descriptor so that commit_lock_file()
2122 + * won't try to close() it.
2123 + */
2124 + packed.fd = -1;
2125 + if (commit_lock_file(&packed) < 0)
2126 + die_errno("unable to overwrite old ref-pack file");
2127 + prune_refs(cbdata.ref_to_prune);
2128 + return 0;
2129 +}
2130 +
2131 static int repack_ref_fn(struct ref_entry *entry, void *cb_data)
2132 {
2133 int *fd = cb_data;
refs.h
+14
@@ -72,6 +72,20 @@ extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refn
72 */
73 extern void add_packed_ref(const char *refname, const unsigned char *sha1);
74
75 +/*
76 + * Flags for controlling behaviour of pack_refs()
77 + * PACK_REFS_PRUNE: Prune loose refs after packing
78 + * PACK_REFS_ALL: Pack _all_ refs, not just tags and already packed refs
79 + */
80 +#define PACK_REFS_PRUNE 0x0001
81 +#define PACK_REFS_ALL 0x0002
82 +
83 +/*
84 + * Write a packed-refs file for the current repository.
85 + * flags: Combination of the above PACK_REFS_* flags.
86 + */
87 +int pack_refs(unsigned int flags);
88 +
89 extern int ref_exists(const char *);
90
91 /*