@matheusbsbs / matheus-bagliano / commits / 0bad611b1e
Fork 0

Teach ref iteration module about submodules

We will use this in a later patch to extend setup_revisions() to load revisions directly from a submodule. Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Heiko Voigt committed Jul 7, 2010 at 15:39 UTC 0bad611b1ebacf170976a10690bd0169f8d372bf
3 files changed +127 -32
cache.h
+3
@@ -641,6 +641,9 @@ extern char *git_pathdup(const char *fmt, ...)
641 /* Return a statically allocated filename matching the sha1 signature */
642 extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
643 extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
644 +extern char *git_path_submodule(const char *path, const char *fmt, ...)
645 + __attribute__((format (printf, 2, 3)));
646 +
647 extern char *sha1_file_name(const unsigned char *sha1);
648 extern char *sha1_pack_name(const unsigned char *sha1);
649 extern char *sha1_pack_index_name(const unsigned char *sha1);
path.c
+38
@@ -122,6 +122,44 @@ char *git_path(const char *fmt, ...)
122 return cleanup_path(pathname);
123 }
124
125 +char *git_path_submodule(const char *path, const char *fmt, ...)
126 +{
127 + char *pathname = get_pathname();
128 + struct strbuf buf = STRBUF_INIT;
129 + const char *git_dir;
130 + va_list args;
131 + unsigned len;
132 +
133 + len = strlen(path);
134 + if (len > PATH_MAX-100)
135 + return bad_path;
136 +
137 + strbuf_addstr(&buf, path);
138 + if (len && path[len-1] != '/')
139 + strbuf_addch(&buf, '/');
140 + strbuf_addstr(&buf, ".git");
141 +
142 + git_dir = read_gitfile_gently(buf.buf);
143 + if (git_dir) {
144 + strbuf_reset(&buf);
145 + strbuf_addstr(&buf, git_dir);
146 + }
147 + strbuf_addch(&buf, '/');
148 +
149 + if (buf.len >= PATH_MAX)
150 + return bad_path;
151 + memcpy(pathname, buf.buf, buf.len + 1);
152 +
153 + strbuf_release(&buf);
154 + len = strlen(pathname);
155 +
156 + va_start(args, fmt);
157 + len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
158 + va_end(args);
159 + if (len >= PATH_MAX)
160 + return bad_path;
161 + return cleanup_path(pathname);
162 +}
163
164 /* git_mkstemp() - create tmp file honoring TMPDIR variable */
165 int git_mkstemp(char *path, size_t len, const char *template)
refs.c
+86 -32
@@ -157,7 +157,7 @@ static struct cached_refs {
157 char did_packed;
158 struct ref_list *loose;
159 struct ref_list *packed;
160 -} cached_refs;
160 +} cached_refs, submodule_refs;
161 static struct ref_list *current_ref;
162
163 static struct ref_list *extra_refs;
@@ -229,23 +229,45 @@ void clear_extra_refs(void)
229 extra_refs = NULL;
230 }
231
232 -static struct ref_list *get_packed_refs(void)
232 +static struct ref_list *get_packed_refs(const char *submodule)
233 {
234 - if (!cached_refs.did_packed) {
235 - FILE *f = fopen(git_path("packed-refs"), "r");
236 - cached_refs.packed = NULL;
234 + const char *packed_refs_file;
235 + struct cached_refs *refs;
236 +
237 + if (submodule) {
238 + packed_refs_file = git_path_submodule(submodule, "packed-refs");
239 + refs = &submodule_refs;
240 + free_ref_list(refs->packed);
241 + } else {
242 + packed_refs_file = git_path("packed-refs");
243 + refs = &cached_refs;
244 + }
245 +
246 + if (!refs->did_packed || submodule) {
247 + FILE *f = fopen(packed_refs_file, "r");
248 + refs->packed = NULL;
249 if (f) {
238 - read_packed_refs(f, &cached_refs);
250 + read_packed_refs(f, refs);
251 fclose(f);
252 }
241 - cached_refs.did_packed = 1;
253 + refs->did_packed = 1;
254 }
243 - return cached_refs.packed;
255 + return refs->packed;
256 }
257
246 -static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
258 +static struct ref_list *get_ref_dir(const char *submodule, const char *base,
259 + struct ref_list *list)
260 {
248 - DIR *dir = opendir(git_path("%s", base));
261 + DIR *dir;
262 + const char *path;
263 +
264 + if (submodule)
265 + path = git_path_submodule(submodule, "%s", base);
266 + else
267 + path = git_path("%s", base);
268 +
269 +
270 + dir = opendir(path);
271
272 if (dir) {
273 struct dirent *de;
@@ -261,6 +283,7 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
283 struct stat st;
284 int flag;
285 int namelen;
286 + const char *refdir;
287
288 if (de->d_name[0] == '.')
289 continue;
@@ -270,16 +293,27 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
293 if (has_extension(de->d_name, ".lock"))
294 continue;
295 memcpy(ref + baselen, de->d_name, namelen+1);
273 - if (stat(git_path("%s", ref), &st) < 0)
296 + refdir = submodule
297 + ? git_path_submodule(submodule, "%s", ref)
298 + : git_path("%s", ref);
299 + if (stat(refdir, &st) < 0)
300 continue;
301 if (S_ISDIR(st.st_mode)) {
276 - list = get_ref_dir(ref, list);
302 + list = get_ref_dir(submodule, ref, list);
303 continue;
304 }
279 - if (!resolve_ref(ref, sha1, 1, &flag)) {
305 + if (submodule) {
306 hashclr(sha1);
281 - flag |= REF_BROKEN;
282 - }
307 + flag = 0;
308 + if (resolve_gitlink_ref(submodule, ref, sha1) < 0) {
309 + hashclr(sha1);
310 + flag |= REF_BROKEN;
311 + }
312 + } else
313 + if (!resolve_ref(ref, sha1, 1, &flag)) {
314 + hashclr(sha1);
315 + flag |= REF_BROKEN;
316 + }
317 list = add_ref(ref, sha1, flag, list, NULL);
318 }
319 free(ref);
@@ -322,10 +356,16 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
356 for_each_rawref(warn_if_dangling_symref, &data);
357 }
358
325 -static struct ref_list *get_loose_refs(void)
359 +static struct ref_list *get_loose_refs(const char *submodule)
360 {
361 + if (submodule) {
362 + free_ref_list(submodule_refs.loose);
363 + submodule_refs.loose = get_ref_dir(submodule, "refs", NULL);
364 + return submodule_refs.loose;
365 + }
366 +
367 if (!cached_refs.did_loose) {
328 - cached_refs.loose = get_ref_dir("refs", NULL);
368 + cached_refs.loose = get_ref_dir(NULL, "refs", NULL);
369 cached_refs.did_loose = 1;
370 }
371 return cached_refs.loose;
@@ -459,7 +499,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
499 git_snpath(path, sizeof(path), "%s", ref);
500 /* Special case: non-existing file. */
501 if (lstat(path, &st) < 0) {
462 - struct ref_list *list = get_packed_refs();
502 + struct ref_list *list = get_packed_refs(NULL);
503 while (list) {
504 if (!strcmp(ref, list->name)) {
505 hashcpy(sha1, list->sha1);
@@ -588,7 +628,7 @@ int peel_ref(const char *ref, unsigned char *sha1)
628 return -1;
629
630 if ((flag & REF_ISPACKED)) {
591 - struct ref_list *list = get_packed_refs();
631 + struct ref_list *list = get_packed_refs(NULL);
632
633 while (list) {
634 if (!strcmp(list->name, ref)) {
@@ -615,12 +655,12 @@ fallback:
655 return -1;
656 }
657
618 -static int do_for_each_ref(const char *base, each_ref_fn fn, int trim,
619 - int flags, void *cb_data)
658 +static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
659 + int trim, int flags, void *cb_data)
660 {
661 int retval = 0;
622 - struct ref_list *packed = get_packed_refs();
623 - struct ref_list *loose = get_loose_refs();
662 + struct ref_list *packed = get_packed_refs(submodule);
663 + struct ref_list *loose = get_loose_refs(submodule);
664
665 struct ref_list *extra;
666
@@ -657,24 +697,38 @@ end_each:
697 return retval;
698 }
699
660 -int head_ref(each_ref_fn fn, void *cb_data)
700 +
701 +static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)
702 {
703 unsigned char sha1[20];
704 int flag;
705
706 + if (submodule) {
707 + if (resolve_gitlink_ref(submodule, "HEAD", sha1) == 0)
708 + return fn("HEAD", sha1, 0, cb_data);
709 +
710 + return 0;
711 + }
712 +
713 if (resolve_ref("HEAD", sha1, 1, &flag))
714 return fn("HEAD", sha1, flag, cb_data);
715 +
716 return 0;
717 }
718
719 +int head_ref(each_ref_fn fn, void *cb_data)
720 +{
721 + return do_head_ref(NULL, fn, cb_data);
722 +}
723 +
724 int for_each_ref(each_ref_fn fn, void *cb_data)
725 {
672 - return do_for_each_ref("refs/", fn, 0, 0, cb_data);
726 + return do_for_each_ref(NULL, "refs/", fn, 0, 0, cb_data);
727 }
728
729 int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
730 {
677 - return do_for_each_ref(prefix, fn, strlen(prefix), 0, cb_data);
731 + return do_for_each_ref(NULL, prefix, fn, strlen(prefix), 0, cb_data);
732 }
733
734 int for_each_tag_ref(each_ref_fn fn, void *cb_data)
@@ -694,7 +748,7 @@ int for_each_remote_ref(each_ref_fn fn, void *cb_data)
748
749 int for_each_replace_ref(each_ref_fn fn, void *cb_data)
750 {
697 - return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data);
751 + return do_for_each_ref(NULL, "refs/replace/", fn, 13, 0, cb_data);
752 }
753
754 int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
@@ -734,7 +788,7 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
788
789 int for_each_rawref(each_ref_fn fn, void *cb_data)
790 {
737 - return do_for_each_ref("refs/", fn, 0,
791 + return do_for_each_ref(NULL, "refs/", fn, 0,
792 DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
793 }
794
@@ -958,7 +1012,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
1012 * name is a proper prefix of our refname.
1013 */
1014 if (missing &&
961 - !is_refname_available(ref, NULL, get_packed_refs(), 0)) {
1015 + !is_refname_available(ref, NULL, get_packed_refs(NULL), 0)) {
1016 last_errno = ENOTDIR;
1017 goto error_return;
1018 }
@@ -1021,7 +1075,7 @@ static int repack_without_ref(const char *refname)
1075 int fd;
1076 int found = 0;
1077
1024 - packed_ref_list = get_packed_refs();
1078 + packed_ref_list = get_packed_refs(NULL);
1079 for (list = packed_ref_list; list; list = list->next) {
1080 if (!strcmp(refname, list->name)) {
1081 found = 1;
@@ -1110,10 +1164,10 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
1164 if (!symref)
1165 return error("refname %s not found", oldref);
1166
1113 - if (!is_refname_available(newref, oldref, get_packed_refs(), 0))
1167 + if (!is_refname_available(newref, oldref, get_packed_refs(NULL), 0))
1168 return 1;
1169
1116 - if (!is_refname_available(newref, oldref, get_loose_refs(), 0))
1170 + if (!is_refname_available(newref, oldref, get_loose_refs(NULL), 0))
1171 return 1;
1172
1173 lock = lock_ref_sha1_basic(renamed_ref, NULL, 0, NULL);