static int register_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { if (!strcmp(refname, "bad")) { current_bad_sha1 = sha1; } else if (!prefixcmp(refname, "good-")) { sha1_array_append(&good_revs, sha1); } else if (!prefixcmp(refname, "skip-")) { sha1_array_append(&skipped_revs, sha1); } return 0; }
static int register_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { if (!strcmp(refname, "bad")) { current_bad_oid = xmalloc(sizeof(*current_bad_oid)); hashcpy(current_bad_oid->hash, sha1); } else if (starts_with(refname, "good-")) { sha1_array_append(&good_revs, sha1); } else if (starts_with(refname, "skip-")) { sha1_array_append(&skipped_revs, sha1); } return 0; }
int main(int argc, char **argv) { struct sha1_array array = SHA1_ARRAY_INIT; struct strbuf line = STRBUF_INIT; while (strbuf_getline_lf(&line, stdin) != EOF) { const char *arg; unsigned char sha1[20]; if (skip_prefix(line.buf, "append ", &arg)) { if (get_sha1_hex(arg, sha1)) die("not a hexadecimal SHA1: %s", arg); sha1_array_append(&array, sha1); } else if (skip_prefix(line.buf, "lookup ", &arg)) { if (get_sha1_hex(arg, sha1)) die("not a hexadecimal SHA1: %s", arg); printf("%d\n", sha1_array_lookup(&array, sha1)); } else if (!strcmp(line.buf, "clear")) sha1_array_clear(&array); else if (!strcmp(line.buf, "for_each_unique")) sha1_array_for_each_unique(&array, print_sha1, NULL); else die("unknown command: %s", line.buf); } return 0; }
void check_for_new_submodule_commits(unsigned char new_sha1[20]) { if (!initialized_fetch_ref_tips) { for_each_ref(add_sha1_to_array, &ref_tips_before_fetch); initialized_fetch_ref_tips = 1; } sha1_array_append(&ref_tips_after_fetch, new_sha1); }
static int register_ref(const char *refname, const struct object_id *oid, int flags, void *cb_data) { struct strbuf good_prefix = STRBUF_INIT; strbuf_addstr(&good_prefix, term_good); strbuf_addstr(&good_prefix, "-"); if (!strcmp(refname, term_bad)) { current_bad_oid = xmalloc(sizeof(*current_bad_oid)); oidcpy(current_bad_oid, oid); } else if (starts_with(refname, good_prefix.buf)) { sha1_array_append(&good_revs, oid->hash); } else if (starts_with(refname, "skip-")) { sha1_array_append(&skipped_revs, oid->hash); } strbuf_release(&good_prefix); return 0; }
static struct command *read_head_info(struct sha1_array *shallow) { struct command *commands = NULL; struct command **p = &commands; for (;;) { char *line; unsigned char old_sha1[20], new_sha1[20]; struct command *cmd; char *refname; int len, reflen; line = packet_read_line(0, &len); if (!line) break; if (len == 48 && starts_with(line, "shallow ")) { if (get_sha1_hex(line + 8, old_sha1)) die("protocol error: expected shallow sha, got '%s'", line + 8); sha1_array_append(shallow, old_sha1); continue; } if (len < 83 || line[40] != ' ' || line[81] != ' ' || get_sha1_hex(line, old_sha1) || get_sha1_hex(line + 41, new_sha1)) die("protocol error: expected old/new/ref, got '%s'", line); refname = line + 82; reflen = strlen(refname); if (reflen + 82 < len) { const char *feature_list = refname + reflen + 1; if (parse_feature_request(feature_list, "report-status")) report_status = 1; if (parse_feature_request(feature_list, "side-band-64k")) use_sideband = LARGE_PACKET_MAX; if (parse_feature_request(feature_list, "quiet")) quiet = 1; } cmd = xcalloc(1, sizeof(struct command) + len - 80); hashcpy(cmd->old_sha1, old_sha1); hashcpy(cmd->new_sha1, new_sha1); memcpy(cmd->ref_name, line + 82, len - 81); *p = cmd; p = &cmd->next; } return commands; }
int parse_opt_object_name(const struct option *opt, const char *arg, int unset) { unsigned char sha1[20]; if (unset) { sha1_array_clear(opt->value); return 0; } if (!arg) return -1; if (get_sha1(arg, sha1)) return error(_("malformed object name '%s'"), arg); sha1_array_append(opt->value, sha1); return 0; }
/** * Appends merge candidates from FETCH_HEAD that are not marked not-for-merge * into merge_heads. */ static void get_merge_heads(struct sha1_array *merge_heads) { const char *filename = git_path("FETCH_HEAD"); FILE *fp; struct strbuf sb = STRBUF_INIT; unsigned char sha1[GIT_SHA1_RAWSZ]; if (!(fp = fopen(filename, "r"))) die_errno(_("could not open '%s' for reading"), filename); while (strbuf_getline_lf(&sb, fp) != EOF) { if (get_sha1_hex(sb.buf, sha1)) continue; /* invalid line: does not start with SHA1 */ if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t")) continue; /* ref is not-for-merge */ sha1_array_append(merge_heads, sha1); } fclose(fp); strbuf_release(&sb); }
static int builtin_diff_combined(struct rev_info *revs, int argc, const char **argv, struct object_array_entry *ent, int ents) { struct sha1_array parents = SHA1_ARRAY_INIT; int i; if (argc > 1) usage(builtin_diff_usage); if (!revs->dense_combined_merges && !revs->combine_merges) revs->dense_combined_merges = revs->combine_merges = 1; for (i = 1; i < ents; i++) sha1_array_append(&parents, ent[i].item->sha1); diff_tree_combined(ent[0].item->sha1, &parents, revs->dense_combined_merges, revs); sha1_array_clear(&parents); return 0; }
static void update_shallow_info(struct command *commands, struct shallow_info *si, struct sha1_array *ref) { struct command *cmd; int *ref_status; remove_nonexistent_theirs_shallow(si); if (!si->nr_ours && !si->nr_theirs) { shallow_update = 0; return; } for (cmd = commands; cmd; cmd = cmd->next) { if (is_null_sha1(cmd->new_sha1)) continue; sha1_array_append(ref, cmd->new_sha1); cmd->index = ref->nr - 1; } si->ref = ref; if (shallow_update) { prepare_shallow_update(commands, si); return; } ALLOC_ARRAY(ref_status, ref->nr); assign_shallow_commits_to_refs(si, NULL, ref_status); for (cmd = commands; cmd; cmd = cmd->next) { if (is_null_sha1(cmd->new_sha1)) continue; if (ref_status[cmd->index]) { cmd->error_string = "shallow update not allowed"; cmd->skip_update = 1; } } free(ref_status); }
static int update_shallow_ref(struct command *cmd, struct shallow_info *si) { static struct lock_file shallow_lock; struct sha1_array extra = SHA1_ARRAY_INIT; const char *alt_file; uint32_t mask = 1 << (cmd->index % 32); int i; trace_printf_key(&trace_shallow, "shallow: update_shallow_ref %s\n", cmd->ref_name); for (i = 0; i < si->shallow->nr; i++) if (si->used_shallow[i] && (si->used_shallow[i][cmd->index / 32] & mask) && !delayed_reachability_test(si, i)) sha1_array_append(&extra, si->shallow->sha1[i]); setup_alternate_shallow(&shallow_lock, &alt_file, &extra); if (check_shallow_connected(command_singleton_iterator, 0, cmd, alt_file)) { rollback_lock_file(&shallow_lock); sha1_array_clear(&extra); return -1; } commit_lock_file(&shallow_lock); /* * Make sure setup_alternate_shallow() for the next ref does * not lose these new roots.. */ for (i = 0; i < extra.nr; i++) register_shallow(extra.sha1[i]); si->shallow_ref[cmd->index] = 0; sha1_array_clear(&extra); return 0; }
static void init_skiplist(struct fsck_options *options, const char *path) { static struct sha1_array skiplist = SHA1_ARRAY_INIT; int sorted, fd; char buffer[41]; unsigned char sha1[20]; if (options->skiplist) sorted = options->skiplist->sorted; else { sorted = 1; options->skiplist = &skiplist; } fd = open(path, O_RDONLY); if (fd < 0) die("Could not open skip list: %s", path); for (;;) { int result = read_in_full(fd, buffer, sizeof(buffer)); if (result < 0) die_errno("Could not read '%s'", path); if (!result) break; if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') die("Invalid SHA-1: %s", buffer); sha1_array_append(&skiplist, sha1); if (sorted && skiplist.nr > 1 && hashcmp(skiplist.sha1[skiplist.nr - 2], sha1) > 0) sorted = 0; } close(fd); if (sorted) skiplist.sorted = 1; }
static int add_sha1_to_array(const char *ref, const unsigned char *sha1, int flags, void *data) { sha1_array_append(data, sha1); return 0; }
static int add_sha1_to_array(const char *ref, const struct object_id *oid, int flags, void *data) { sha1_array_append(data, oid->hash); return 0; }
int transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags, unsigned int *reject_reasons) { *reject_reasons = 0; transport_verify_remote_names(refspec_nr, refspec); if (transport->push) { /* Maybe FIXME. But no important transport uses this case. */ if (flags & TRANSPORT_PUSH_SET_UPSTREAM) die("This transport does not support using --set-upstream"); return transport->push(transport, refspec_nr, refspec, flags); } else if (transport->push_refs) { struct ref *remote_refs; struct ref *local_refs = get_local_heads(); int match_flags = MATCH_REFS_NONE; int verbose = (transport->verbose > 0); int quiet = (transport->verbose < 0); int porcelain = flags & TRANSPORT_PUSH_PORCELAIN; int pretend = flags & TRANSPORT_PUSH_DRY_RUN; int push_ret, ret, err; if (check_push_refs(local_refs, refspec_nr, refspec) < 0) return -1; remote_refs = transport->get_refs_list(transport, 1); if (flags & TRANSPORT_PUSH_ALL) match_flags |= MATCH_REFS_ALL; if (flags & TRANSPORT_PUSH_MIRROR) match_flags |= MATCH_REFS_MIRROR; if (flags & TRANSPORT_PUSH_PRUNE) match_flags |= MATCH_REFS_PRUNE; if (flags & TRANSPORT_PUSH_FOLLOW_TAGS) match_flags |= MATCH_REFS_FOLLOW_TAGS; if (match_push_refs(local_refs, &remote_refs, refspec_nr, refspec, match_flags)) { return -1; } if (transport->smart_options && transport->smart_options->cas && !is_empty_cas(transport->smart_options->cas)) apply_push_cas(transport->smart_options->cas, transport->remote, remote_refs); set_ref_status_for_push(remote_refs, flags & TRANSPORT_PUSH_MIRROR, flags & TRANSPORT_PUSH_FORCE); if (!(flags & TRANSPORT_PUSH_NO_HOOK)) if (run_pre_push_hook(transport, remote_refs)) return -1; if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | TRANSPORT_RECURSE_SUBMODULES_ONLY)) && !is_bare_repository()) { struct ref *ref = remote_refs; struct sha1_array commits = SHA1_ARRAY_INIT; for (; ref; ref = ref->next) if (!is_null_oid(&ref->new_oid)) sha1_array_append(&commits, ref->new_oid.hash); if (!push_unpushed_submodules(&commits, transport->remote->name, pretend)) { sha1_array_clear(&commits); die("Failed to push all needed submodules!"); } sha1_array_clear(&commits); } if (((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) || ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | TRANSPORT_RECURSE_SUBMODULES_ONLY)) && !pretend)) && !is_bare_repository()) { struct ref *ref = remote_refs; struct string_list needs_pushing = STRING_LIST_INIT_DUP; struct sha1_array commits = SHA1_ARRAY_INIT; for (; ref; ref = ref->next) if (!is_null_oid(&ref->new_oid)) sha1_array_append(&commits, ref->new_oid.hash); if (find_unpushed_submodules(&commits, transport->remote->name, &needs_pushing)) { sha1_array_clear(&commits); die_with_unpushed_submodules(&needs_pushing); } string_list_clear(&needs_pushing, 0); sha1_array_clear(&commits); } if (!(flags & TRANSPORT_RECURSE_SUBMODULES_ONLY)) push_ret = transport->push_refs(transport, remote_refs, flags); else push_ret = 0; err = push_had_errors(remote_refs); ret = push_ret | err; if (!quiet || err) transport_print_push_status(transport->url, remote_refs, verbose | porcelain, porcelain, reject_reasons); if (flags & TRANSPORT_PUSH_SET_UPSTREAM) set_upstreams(transport, remote_refs, pretend); if (!(flags & (TRANSPORT_PUSH_DRY_RUN | TRANSPORT_RECURSE_SUBMODULES_ONLY))) { struct ref *ref; for (ref = remote_refs; ref; ref = ref->next) transport_update_tracking_ref(transport->remote, ref, verbose); } if (porcelain && !push_ret) puts("Done"); else if (!quiet && !ret && !transport_refs_pushed(remote_refs)) fprintf(stderr, "Everything up-to-date\n"); return ret; } return 1; }
static struct command *read_head_info(struct sha1_array *shallow) { struct command *commands = NULL; struct command **p = &commands; for (;;) { char *line; int len, linelen; line = packet_read_line(0, &len); if (!line) break; if (len == 48 && starts_with(line, "shallow ")) { unsigned char sha1[20]; if (get_sha1_hex(line + 8, sha1)) die("protocol error: expected shallow sha, got '%s'", line + 8); sha1_array_append(shallow, sha1); continue; } linelen = strlen(line); if (linelen < len) { const char *feature_list = line + linelen + 1; if (parse_feature_request(feature_list, "report-status")) report_status = 1; if (parse_feature_request(feature_list, "side-band-64k")) use_sideband = LARGE_PACKET_MAX; if (parse_feature_request(feature_list, "quiet")) quiet = 1; if (advertise_atomic_push && parse_feature_request(feature_list, "atomic")) use_atomic = 1; if (advertise_push_options && parse_feature_request(feature_list, "push-options")) use_push_options = 1; } if (!strcmp(line, "push-cert")) { int true_flush = 0; char certbuf[1024]; for (;;) { len = packet_read(0, NULL, NULL, certbuf, sizeof(certbuf), 0); if (!len) { true_flush = 1; break; } if (!strcmp(certbuf, "push-cert-end\n")) break; /* end of cert */ strbuf_addstr(&push_cert, certbuf); } if (true_flush) break; continue; } p = queue_command(p, line, linelen); } if (push_cert.len) queue_commands_from_cert(p, &push_cert); return commands; }
static void update_shallow(struct fetch_pack_args *args, struct ref **sought, int nr_sought, struct shallow_info *si) { struct sha1_array ref = SHA1_ARRAY_INIT; int *status; int i; if (args->depth > 0 && alternate_shallow_file) { if (*alternate_shallow_file == '\0') { /* --unshallow */ unlink_or_warn(git_path("shallow")); rollback_lock_file(&shallow_lock); } else commit_lock_file(&shallow_lock); return; } if (!si->shallow || !si->shallow->nr) return; if (args->cloning) { /* * remote is shallow, but this is a clone, there are * no objects in repo to worry about. Accept any * shallow points that exist in the pack (iow in repo * after get_pack() and reprepare_packed_git()) */ struct sha1_array extra = SHA1_ARRAY_INIT; unsigned char (*sha1)[20] = si->shallow->sha1; for (i = 0; i < si->shallow->nr; i++) if (has_sha1_file(sha1[i])) sha1_array_append(&extra, sha1[i]); if (extra.nr) { setup_alternate_shallow(&shallow_lock, &alternate_shallow_file, &extra); commit_lock_file(&shallow_lock); } sha1_array_clear(&extra); return; } if (!si->nr_ours && !si->nr_theirs) return; remove_nonexistent_theirs_shallow(si); if (!si->nr_ours && !si->nr_theirs) return; for (i = 0; i < nr_sought; i++) sha1_array_append(&ref, sought[i]->old_sha1); si->ref = &ref; if (args->update_shallow) { /* * remote is also shallow, .git/shallow may be updated * so all refs can be accepted. Make sure we only add * shallow roots that are actually reachable from new * refs. */ struct sha1_array extra = SHA1_ARRAY_INIT; unsigned char (*sha1)[20] = si->shallow->sha1; assign_shallow_commits_to_refs(si, NULL, NULL); if (!si->nr_ours && !si->nr_theirs) { sha1_array_clear(&ref); return; } for (i = 0; i < si->nr_ours; i++) sha1_array_append(&extra, sha1[si->ours[i]]); for (i = 0; i < si->nr_theirs; i++) sha1_array_append(&extra, sha1[si->theirs[i]]); setup_alternate_shallow(&shallow_lock, &alternate_shallow_file, &extra); commit_lock_file(&shallow_lock); sha1_array_clear(&extra); sha1_array_clear(&ref); return; } /* * remote is also shallow, check what ref is safe to update * without updating .git/shallow */ status = xcalloc(nr_sought, sizeof(*status)); assign_shallow_commits_to_refs(si, NULL, status); if (si->nr_ours || si->nr_theirs) { for (i = 0; i < nr_sought; i++) if (status[i]) sought[i]->status = REF_STATUS_REJECT_SHALLOW; } free(status); sha1_array_clear(&ref); }
static void collect_one_alternate_ref(const struct ref *ref, void *data) { struct sha1_array *sa = data; sha1_array_append(sa, ref->old_sha1); }