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
/*