static void find_non_local_tags(struct transport *transport, struct ref **head, struct ref ***tail) { struct string_list existing_refs = { NULL, 0, 0, 0 }; struct string_list new_refs = { NULL, 0, 0, 1 }; char *ref_name; int ref_name_len; const unsigned char *ref_sha1; const struct ref *tag_ref; struct ref *rm = NULL; const struct ref *ref; for_each_ref(add_existing, &existing_refs); for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) { if (prefixcmp(ref->name, "refs/tags")) continue; ref_name = xstrdup(ref->name); ref_name_len = strlen(ref_name); ref_sha1 = ref->old_sha1; if (!strcmp(ref_name + ref_name_len - 3, "^{}")) { ref_name[ref_name_len - 3] = 0; tag_ref = transport_get_remote_refs(transport); while (tag_ref) { if (!strcmp(tag_ref->name, ref_name)) { ref_sha1 = tag_ref->old_sha1; break; } tag_ref = tag_ref->next; } } if (!string_list_has_string(&existing_refs, ref_name) && !string_list_has_string(&new_refs, ref_name) && (has_sha1_file(ref->old_sha1) || will_fetch(head, ref->old_sha1))) { string_list_insert(ref_name, &new_refs); rm = alloc_ref(ref_name); rm->peer_ref = alloc_ref(ref_name); hashcpy(rm->old_sha1, ref_sha1); **tail = rm; *tail = &rm->next; } free(ref_name); } string_list_clear(&existing_refs, 0); string_list_clear(&new_refs, 0); }
static struct ref *parse_info_refs(struct discovery *heads) { char *data, *start, *mid; char *ref_name; int i = 0; struct ref *refs = NULL; struct ref *ref = NULL; struct ref *last_ref = NULL; data = heads->buf; start = NULL; mid = data; while (i < heads->len) { if (!start) { start = &data[i]; } if (data[i] == '\t') mid = &data[i]; if (data[i] == '\n') { if (mid - start != 40) die("%sinfo/refs not valid: is this a git repository?", url.buf); data[i] = 0; ref_name = mid + 1; ref = alloc_ref(ref_name); get_oid_hex(start, &ref->old_oid); if (!refs) refs = ref; if (last_ref) last_ref->next = ref; last_ref = ref; start = NULL; } i++; } ref = alloc_ref("HEAD"); if (!http_fetch_ref(url.buf, ref) && !resolve_remote_symref(ref, refs)) { ref->next = refs; refs = ref; } else { free(ref); } return refs; }
static void add_sought_entry(struct ref ***sought, int *nr, int *alloc, const char *name) { struct ref *ref; struct object_id oid; if (!get_oid_hex(name, &oid)) { if (name[GIT_SHA1_HEXSZ] == ' ') { /* <sha1> <ref>, find refname */ name += GIT_SHA1_HEXSZ + 1; } else if (name[GIT_SHA1_HEXSZ] == '\0') { ; /* <sha1>, leave sha1 as name */ } else { /* <ref>, clear cruft from oid */ oidclr(&oid); } } else { /* <ref>, clear cruft from get_oid_hex */ oidclr(&oid); } ref = alloc_ref(name); oidcpy(&ref->old_oid, &oid); (*nr)++; ALLOC_GROW(*sought, *nr, *alloc); (*sought)[*nr - 1] = ref; }
static void one_remote_ref(const char *refname) { struct ref *ref; struct object *obj; ref = alloc_ref(refname); if (http_fetch_ref(repo->url, ref) != 0) { fprintf(stderr, "Unable to fetch ref %s from %s\n", refname, repo->url); free(ref); return; } /* * Fetch a copy of the object if it doesn't exist locally - it * may be required for updating server info later. */ if (repo->can_update_info_refs && !has_object_file(&ref->old_oid)) { obj = lookup_unknown_object(ref->old_oid.hash); fprintf(stderr, " fetch %s for %s\n", oid_to_hex(&ref->old_oid), refname); add_fetch_request(obj); } ref->next = remote_refs; remote_refs = ref; }
static int process_ref(int len, struct ref ***list, unsigned int flags, struct oid_array *extra_have) { struct object_id old_oid; const char *name; if (parse_oid_hex(packet_buffer, &old_oid, &name)) return 0; if (*name != ' ') return 0; name++; if (extra_have && !strcmp(name, ".have")) { oid_array_append(extra_have, &old_oid); } else if (!strcmp(name, "capabilities^{}")) { die("protocol error: unexpected capabilities^{}"); } else if (check_ref(name, flags)) { struct ref *ref = alloc_ref(name); oidcpy(&ref->old_oid, &old_oid); **list = ref; *list = &ref->next; } check_no_capabilities(len); return 1; }
static struct ref *try_explicit_object_name(const char *name) { unsigned char sha1[20]; struct ref *ref; if (!*name) { ref = alloc_ref("(delete)"); hashclr(ref->new_sha1); return ref; } if (get_sha1(name, sha1)) return NULL; ref = alloc_ref(name); hashcpy(ref->new_sha1, sha1); return ref; }
static void add_sought_entry(struct ref ***sought, int *nr, int *alloc, const char *name) { struct ref *ref; struct object_id oid; const char *p; if (!parse_oid_hex(name, &oid, &p)) { if (*p == ' ') { /* <oid> <ref>, find refname */ name = p + 1; } else if (*p == '\0') { ; /* <oid>, leave oid as name */ } else { /* <ref>, clear cruft from oid */ oidclr(&oid); } } else { /* <ref>, clear cruft from get_oid_hex */ oidclr(&oid); } ref = alloc_ref(name); oidcpy(&ref->old_oid, &oid); (*nr)++; ALLOC_GROW(*sought, *nr, *alloc); (*sought)[*nr - 1] = ref; }
static int read_loose_refs(struct strbuf *path, int name_offset, struct ref **tail) { DIR *dir = opendir(path->buf); struct dirent *de; struct { char **entries; int nr, alloc; } list; int i, pathlen; if (!dir) return -1; memset (&list, 0, sizeof(list)); while ((de = readdir(dir))) { if (is_dot_or_dotdot(de->d_name)) continue; ALLOC_GROW(list.entries, list.nr + 1, list.alloc); list.entries[list.nr++] = xstrdup(de->d_name); } closedir(dir); /* sort the list */ qsort(list.entries, list.nr, sizeof(char *), str_cmp); pathlen = path->len; strbuf_addch(path, '/'); for (i = 0; i < list.nr; i++, strbuf_setlen(path, pathlen + 1)) { strbuf_addstr(path, list.entries[i]); if (read_loose_refs(path, name_offset, tail)) { int fd = open(path->buf, O_RDONLY); char buffer[40]; struct ref *next; if (fd < 0) continue; next = alloc_ref(path->buf + name_offset); if (read_in_full(fd, buffer, 40) != 40 || get_sha1_hex(buffer, next->old_sha1)) { close(fd); free(next); continue; } close(fd); (*tail)->next = next; *tail = next; } } strbuf_setlen(path, pathlen); for (i = 0; i < list.nr; i++) free(list.entries[i]); free(list.entries); return 0; }
static struct ref *get_refs_from_bundle(struct transport *transport, int for_push, const struct argv_array *ref_prefixes) { struct bundle_transport_data *data = transport->data; struct ref *result = NULL; int i; if (for_push) return NULL; if (data->fd > 0) close(data->fd); data->fd = read_bundle_header(transport->url, &data->header); if (data->fd < 0) die(_("could not read bundle '%s'"), transport->url); for (i = 0; i < data->header.references.nr; i++) { struct ref_list_entry *e = data->header.references.list + i; struct ref *ref = alloc_ref(e->name); oidcpy(&ref->old_oid, &e->oid); ref->next = result; result = ref; } return result; }
HL_PRIM wref *HL_NAME(ui_winlog_new)( const uchar *title, int width, int height ) { HWND wnd, text; RECT rc; RECT dtop; DWORD style = WS_SYSMENU | WS_OVERLAPPED | WS_CAPTION; DWORD exstyle = 0; wref *ref; // SIZE rc.left = 0; rc.right = width; rc.top = 0; rc.bottom = height; AdjustWindowRectEx(&rc, style, FALSE, exstyle); GetWindowRect(GetDesktopWindow(),&dtop); // WINDOW wnd = CreateWindowEx( exstyle, CLASS_NAME, title, style, (dtop.right - rc.right) / 2, (dtop.bottom - rc.bottom) / 2, rc.right - rc.left, rc.bottom - rc.top, GetActiveWindow(), NULL, GetModuleHandle(NULL), NULL ); // FONT if( font == NULL ) { LOGFONT f; f.lfHeight = -8; f.lfWidth = 0; f.lfEscapement = 0; f.lfOrientation = 0; f.lfWeight = FW_NORMAL; f.lfItalic = FALSE; f.lfUnderline = FALSE; f.lfStrikeOut = FALSE; f.lfCharSet = DEFAULT_CHARSET; f.lfOutPrecision = OUT_DEFAULT_PRECIS; f.lfClipPrecision = 0; f.lfQuality = DEFAULT_QUALITY; f.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; wcscpy(f.lfFaceName,USTR("MS Sans Serif")); font = CreateFontIndirect(&f); } // TEXT text = CreateWindowEx(WS_EX_CLIENTEDGE,USTR("RICHEDIT20A"),USTR(""),ES_MULTILINE | ES_DISABLENOSCROLL | ES_READONLY | WS_VSCROLL | WS_VISIBLE | WS_CHILD,5,5,width - 10,height - 50,wnd,NULL,NULL,NULL); SendMessage(text,WM_SETFONT,(WPARAM)font,TRUE); SetProp(wnd,PTEXT,text); SetTimer(wnd,0,1000,NULL); // prevent lock in ui_loop ShowWindow(wnd,SW_SHOW); ref = alloc_ref(wnd); ref->width = width; ref->height = height; return ref; }
HL_PRIM wref *HL_NAME(ui_button_new)( wref *w, const uchar *txt, vclosure *callb ) { HWND but = CreateWindowEx(0,USTR("BUTTON"),USTR(""),WS_VISIBLE | WS_CHILD,w->width - 80,w->height - 30,75,25,w->h,NULL,NULL,NULL); wref *ref = alloc_ref(but); w->width -= 80; ref->callb = callb; SendMessage(but,WM_SETFONT,(WPARAM)font,TRUE); SetWindowText(but,txt); return ref; }
static int add_to_tail(struct string_list_item *item, void *cb_data) { struct tag_data *data = (struct tag_data *)cb_data; struct ref *rm = NULL; /* We have already decided to ignore this item */ if (!item->util) return 0; rm = alloc_ref(item->string); rm->peer_ref = alloc_ref(item->string); hashcpy(rm->old_sha1, item->util); **data->tail = rm; *data->tail = &rm->next; return 0; }
static void parse_fetch(struct strbuf *buf) { struct ref **to_fetch = NULL; struct ref *list_head = NULL; struct ref **list = &list_head; int alloc_heads = 0, nr_heads = 0; do { const char *p; if (skip_prefix(buf->buf, "fetch ", &p)) { const char *name; struct ref *ref; struct object_id old_oid; if (get_oid_hex(p, &old_oid)) die("protocol error: expected sha/ref, got %s'", p); if (p[GIT_SHA1_HEXSZ] == ' ') name = p + GIT_SHA1_HEXSZ + 1; else if (!p[GIT_SHA1_HEXSZ]) name = ""; else die("protocol error: expected sha/ref, got %s'", p); ref = alloc_ref(name); oidcpy(&ref->old_oid, &old_oid); *list = ref; list = &ref->next; ALLOC_GROW(to_fetch, nr_heads + 1, alloc_heads); to_fetch[nr_heads++] = ref; } else die("http transport does not support %s", buf->buf); strbuf_reset(buf); if (strbuf_getline_lf(buf, stdin) == EOF) return; if (!*buf->buf) break; } while (1); if (fetch(nr_heads, to_fetch)) exit(128); /* error already reported */ free_refs(list_head); free(to_fetch); printf("\n"); fflush(stdout); strbuf_reset(buf); }
static void parse_fetch(struct strbuf *buf) { struct ref **to_fetch = NULL; struct ref *list_head = NULL; struct ref **list = &list_head; int alloc_heads = 0, nr_heads = 0; do { if (!prefixcmp(buf->buf, "fetch ")) { char *p = buf->buf + strlen("fetch "); char *name; struct ref *ref; unsigned char old_sha1[20]; if (strlen(p) < 40 || get_sha1_hex(p, old_sha1)) die("protocol error: expected sha/ref, got %s'", p); if (p[40] == ' ') name = p + 41; else if (!p[40]) name = ""; else die("protocol error: expected sha/ref, got %s'", p); ref = alloc_ref(name); hashcpy(ref->old_sha1, old_sha1); *list = ref; list = &ref->next; ALLOC_GROW(to_fetch, nr_heads + 1, alloc_heads); to_fetch[nr_heads++] = ref; } else die("http transport does not support %s", buf->buf); strbuf_reset(buf); if (strbuf_getline(buf, stdin, '\n') == EOF) return; if (!*buf->buf) break; } while (1); if (fetch(nr_heads, to_fetch)) exit(128); /* error already reported */ free_refs(list_head); free(to_fetch); printf("\n"); fflush(stdout); strbuf_reset(buf); }
static struct ref *get_local_ref(const char *name) { if (!name) return NULL; if (!prefixcmp(name, "refs/")) return alloc_ref(name); if (!prefixcmp(name, "heads/") || !prefixcmp(name, "tags/") || !prefixcmp(name, "remotes/")) return alloc_ref_with_prefix("refs/", 5, name); return alloc_ref_with_prefix("refs/heads/", 11, name); }
void fetch_objects(const char *remote_name, const struct object_id *oids, int oid_nr) { struct ref *ref = NULL; int i; for (i = 0; i < oid_nr; i++) { struct ref *new_ref = alloc_ref(oid_to_hex(&oids[i])); oidcpy(&new_ref->old_oid, &oids[i]); new_ref->exact_oid = 1; new_ref->next = ref; ref = new_ref; } fetch_refs(remote_name, ref); }
static int interpret_target(struct walker *walker, char *target, unsigned char *sha1) { if (!get_sha1_hex(target, sha1)) return 0; if (!check_ref_format(target)) { struct ref *ref = alloc_ref(target); if (!walker->fetch_ref(walker, ref)) { hashcpy(sha1, ref->old_sha1); free(ref); return 0; } free(ref); } return -1; }
static struct ref *parse_info_refs(struct discovery *heads) { char *data, *start, *mid; char *ref_name; int i = 0; struct ref *refs = NULL; struct ref *ref = NULL; struct ref *last_ref = NULL; data = heads->buf; start = NULL; mid = data; while (i < heads->len) { if (!start) { start = &data[i]; } if (data[i] == '\t') mid = &data[i]; if (data[i] == '\n') { data[i] = 0; ref_name = mid + 1; ref = xmalloc(sizeof(struct ref) + strlen(ref_name) + 1); memset(ref, 0, sizeof(struct ref)); strcpy(ref->name, ref_name); get_sha1_hex(start, ref->old_sha1); if (!refs) refs = ref; if (last_ref) last_ref->next = ref; last_ref = ref; start = NULL; } i++; } ref = alloc_ref("HEAD"); if (!http_fetch_ref(url, ref) && !resolve_remote_symref(ref, refs)) { ref->next = refs; refs = ref; } else { free(ref); } return refs; }
static struct ref *get_refs_list(struct transport *transport, int for_push) { struct helper_data *data = transport->data; struct child_process *helper; struct ref *ret = NULL; struct ref **tail = &ret; struct ref *posn; struct strbuf buf = STRBUF_INIT; helper = get_helper(transport); if (data->push && for_push) write_str_in_full(helper->in, "list for-push\n"); else write_str_in_full(helper->in, "list\n"); while (1) { char *eov, *eon; if (strbuf_getline(&buf, data->out, '\n') == EOF) exit(128); /* child died, message supplied already */ if (!*buf.buf) break; eov = strchr(buf.buf, ' '); if (!eov) die("Malformed response in ref list: %s", buf.buf); eon = strchr(eov + 1, ' '); *eov = '\0'; if (eon) *eon = '\0'; *tail = alloc_ref(eov + 1); if (buf.buf[0] == '@') (*tail)->symref = xstrdup(buf.buf + 1); else if (buf.buf[0] != '?') get_sha1_hex(buf.buf, (*tail)->old_sha1); tail = &((*tail)->next); } strbuf_release(&buf); for (posn = ret; posn; posn = posn->next) resolve_remote_symref(posn, ret); return ret; }
static void insert_packed_refs(const char *packed_refs, struct ref **list) { FILE *f = fopen(packed_refs, "r"); static char buffer[PATH_MAX]; if (!f) return; for (;;) { int cmp = 0; /* assigned before used */ int len; if (!fgets(buffer, sizeof(buffer), f)) { fclose(f); return; } if (hexval(buffer[0]) > 0xf) continue; len = strlen(buffer); if (len && buffer[len - 1] == '\n') buffer[--len] = '\0'; if (len < 41) continue; while ((*list)->next && (cmp = strcmp(buffer + 41, (*list)->next->name)) > 0) list = &(*list)->next; if (!(*list)->next || cmp < 0) { struct ref *next = alloc_ref(buffer + 41); buffer[40] = '\0'; if (get_sha1_hex(buffer, next->old_sha1)) { warning ("invalid SHA-1: %s", buffer); free(next); continue; } next->next = (*list)->next; (*list)->next = next; list = &(*list)->next; } } }
git_reference *git_reference__alloc_symbolic( const char *name, const char *target) { git_reference *ref; assert(name && target); ref = alloc_ref(name); if (!ref) return NULL; ref->type = GIT_REF_SYMBOLIC; if ((ref->target.symbolic = git__strdup(target)) == NULL) { git__free(ref); return NULL; } return ref; }
git_reference *git_reference__alloc( const char *name, const git_oid *oid, const git_oid *peel) { git_reference *ref; assert(name && oid); ref = alloc_ref(name); if (!ref) return NULL; ref->type = GIT_REF_OID; git_oid_cpy(&ref->target.oid, oid); if (peel != NULL) git_oid_cpy(&ref->peel, peel); return ref; }
static void add_remote_info_ref(struct remote_ls_ctx *ls) { struct strbuf *buf = (struct strbuf *)ls->userData; struct object *o; struct ref *ref; ref = alloc_ref(ls->dentry_name); if (http_fetch_ref(repo->url, ref) != 0) { fprintf(stderr, "Unable to fetch ref %s from %s\n", ls->dentry_name, repo->url); aborted = 1; free(ref); return; } o = parse_object(&ref->old_oid); if (!o) { fprintf(stderr, "Unable to parse object %s for remote ref %s\n", oid_to_hex(&ref->old_oid), ls->dentry_name); aborted = 1; free(ref); return; } strbuf_addf(buf, "%s\t%s\n", oid_to_hex(&ref->old_oid), ls->dentry_name); if (o->type == OBJ_TAG) { o = deref_tag(o, ls->dentry_name, 0); if (o) strbuf_addf(buf, "%s\t%s^{}\n", oid_to_hex(&o->oid), ls->dentry_name); } free(ref); }
static struct ref *get_refs_from_bundle(struct transport *transport, int for_push) { struct bundle_transport_data *data = transport->data; struct ref *result = NULL; int i; if (for_push) return NULL; if (data->fd > 0) close(data->fd); data->fd = read_bundle_header(transport->url, &data->header); if (data->fd < 0) die ("Could not read bundle '%s'.", transport->url); for (i = 0; i < data->header.references.nr; i++) { struct ref_list_entry *e = data->header.references.list + i; struct ref *ref = alloc_ref(e->name); hashcpy(ref->old_sha1, e->sha1); ref->next = result; result = ref; } return result; }
static struct ref *get_refs_via_curl(struct transport *transport, int for_push) { struct strbuf buffer = STRBUF_INIT; char *data, *start, *mid; char *ref_name; char *refs_url; int i = 0; int http_ret; struct ref *refs = NULL; struct ref *ref = NULL; struct ref *last_ref = NULL; struct walker *walker; if (for_push) return NULL; if (!transport->data) transport->data = get_http_walker(transport->url, transport->remote); walker = transport->data; refs_url = xmalloc(strlen(transport->url) + 11); sprintf(refs_url, "%s/info/refs", transport->url); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); switch (http_ret) { case HTTP_OK: break; case HTTP_MISSING_TARGET: die("%s not found: did you run git update-server-info on the" " server?", refs_url); default: http_error(refs_url, http_ret); die("HTTP request failed"); } data = buffer.buf; start = NULL; mid = data; while (i < buffer.len) { if (!start) start = &data[i]; if (data[i] == '\t') mid = &data[i]; if (data[i] == '\n') { data[i] = 0; ref_name = mid + 1; ref = xmalloc(sizeof(struct ref) + strlen(ref_name) + 1); memset(ref, 0, sizeof(struct ref)); strcpy(ref->name, ref_name); get_sha1_hex(start, ref->old_sha1); if (!refs) refs = ref; if (last_ref) last_ref->next = ref; last_ref = ref; start = NULL; } i++; } strbuf_release(&buffer); ref = alloc_ref("HEAD"); if (!walker->fetch_ref(walker, ref) && !resolve_remote_symref(ref, refs)) { ref->next = refs; refs = ref; } else { free(ref); } strbuf_release(&buffer); free(refs_url); return refs; }
/* Returns 1 when a valid ref has been added to `list`, 0 otherwise */ static int process_ref_v2(const char *line, struct ref ***list) { int ret = 1; int i = 0; struct object_id old_oid; struct ref *ref; struct string_list line_sections = STRING_LIST_INIT_DUP; const char *end; /* * Ref lines have a number of fields which are space deliminated. The * first field is the OID of the ref. The second field is the ref * name. Subsequent fields (symref-target and peeled) are optional and * don't have a particular order. */ if (string_list_split(&line_sections, line, ' ', -1) < 2) { ret = 0; goto out; } if (parse_oid_hex(line_sections.items[i++].string, &old_oid, &end) || *end) { ret = 0; goto out; } ref = alloc_ref(line_sections.items[i++].string); oidcpy(&ref->old_oid, &old_oid); **list = ref; *list = &ref->next; for (; i < line_sections.nr; i++) { const char *arg = line_sections.items[i].string; if (skip_prefix(arg, "symref-target:", &arg)) ref->symref = xstrdup(arg); if (skip_prefix(arg, "peeled:", &arg)) { struct object_id peeled_oid; char *peeled_name; struct ref *peeled; if (parse_oid_hex(arg, &peeled_oid, &end) || *end) { ret = 0; goto out; } peeled_name = xstrfmt("%s^{}", ref->name); peeled = alloc_ref(peeled_name); oidcpy(&peeled->old_oid, &peeled_oid); **list = peeled; *list = &peeled->next; free(peeled_name); } } out: string_list_clear(&line_sections, 0); return ret; }
static struct ref *make_linked_ref(const char *name, struct ref ***tail) { struct ref *ret = alloc_ref(name); tail_link_ref(ret, tail); return ret; }