static int add_refs_from_alternate(struct alternate_object_database *e, void *unused) { char *other; size_t len; struct remote *remote; struct transport *transport; const struct ref *extra; e->name[-1] = '\0'; other = xstrdup(make_absolute_path(e->base)); e->name[-1] = '/'; len = strlen(other); while (other[len-1] == '/') other[--len] = '\0'; if (len < 8 || memcmp(other + len - 8, "/objects", 8)) return 0; /* Is this a git repository with refs? */ memcpy(other + len - 8, "/refs", 6); if (!is_directory(other)) return 0; other[len - 8] = '\0'; remote = remote_get(other); transport = transport_get(remote, other); for (extra = transport_get_remote_refs(transport); extra; extra = extra->next) { add_extra_ref(".have", extra->old_sha1, 0); } transport_disconnect(transport); free(other); return 0; }
static void setup_reference(const char *repo) { const char *ref_git; char *ref_git_copy; struct remote *remote; struct transport *transport; const struct ref *extra; ref_git = make_absolute_path(option_reference); if (is_directory(mkpath("%s/.git/objects", ref_git))) ref_git = mkpath("%s/.git", ref_git); else if (!is_directory(mkpath("%s/objects", ref_git))) die("reference repository '%s' is not a local directory.", option_reference); ref_git_copy = xstrdup(ref_git); add_to_alternates_file(ref_git_copy); remote = remote_get(ref_git_copy); transport = transport_get(remote, ref_git_copy); for (extra = transport_get_remote_refs(transport); extra; extra = extra->next) add_extra_ref(extra->name, extra->old_sha1, 0); transport_disconnect(transport); free(ref_git_copy); }
static int add_one_reference(struct string_list_item *item, void *cb_data) { char *ref_git; struct strbuf alternate = STRBUF_INIT; struct remote *remote; struct transport *transport; const struct ref *extra; /* Beware: real_path() and mkpath() return static buffer */ ref_git = xstrdup(real_path(item->string)); if (is_directory(mkpath("%s/.git/objects", ref_git))) { char *ref_git_git = xstrdup(mkpath("%s/.git", ref_git)); free(ref_git); ref_git = ref_git_git; } else if (!is_directory(mkpath("%s/objects", ref_git))) die(_("reference repository '%s' is not a local directory."), item->string); strbuf_addf(&alternate, "%s/objects", ref_git); add_to_alternates_file(alternate.buf); strbuf_release(&alternate); remote = remote_get(ref_git); transport = transport_get(remote, ref_git); for (extra = transport_get_remote_refs(transport); extra; extra = extra->next) add_extra_ref(extra->name, extra->old_sha1, 0); transport_disconnect(transport); free(ref_git); return 0; }
static void write_remote_refs(const struct ref *local_refs) { const struct ref *r; for (r = local_refs; r; r = r->next) add_extra_ref(r->peer_ref->name, r->old_sha1, 0); pack_refs(PACK_REFS_ALL); clear_extra_refs(); }
static struct ref *write_remote_refs(const struct ref *refs, struct refspec *refspec, const char *reflog) { struct ref *local_refs = NULL; struct ref **tail = &local_refs; struct ref *r; get_fetch_map(refs, refspec, &tail, 0); if (!option_mirror) get_fetch_map(refs, tag_refspec, &tail, 0); for (r = local_refs; r; r = r->next) add_extra_ref(r->peer_ref->name, r->old_sha1, 0); pack_refs(PACK_REFS_ALL); clear_extra_refs(); return local_refs; }
static void add_one_alternate_sha1(const unsigned char sha1[20], void *unused) { add_extra_ref(".have", sha1, 0); }