/* An empty entry never compares same, not even to another empty entry */ static int same_entry(struct name_entry *a, struct name_entry *b) { return !is_null_oid(&a->oid) && !is_null_oid(&b->oid) && oideq(&a->oid, &b->oid) && a->mode == b->mode; }
static void stuff_change(struct diff_options *opt, unsigned old_mode, unsigned new_mode, const struct object_id *old_oid, const struct object_id *new_oid, int old_oid_valid, int new_oid_valid, const char *old_path, const char *new_path) { struct diff_filespec *one, *two; if (!is_null_oid(old_oid) && !is_null_oid(new_oid) && !oidcmp(old_oid, new_oid) && (old_mode == new_mode)) return; if (opt->flags.reverse_diff) { SWAP(old_mode, new_mode); SWAP(old_oid, new_oid); SWAP(old_path, new_path); } if (opt->prefix && (strncmp(old_path, opt->prefix, opt->prefix_length) || strncmp(new_path, opt->prefix, opt->prefix_length))) return; one = alloc_filespec(old_path); two = alloc_filespec(new_path); fill_filespec(one, old_oid, old_oid_valid, old_mode); fill_filespec(two, new_oid, new_oid_valid, new_mode); diff_queue(&diff_queued_diff, one, two); }
/** * Given the current HEAD SHA1, the merge head returned from git-fetch and the * fork point calculated by get_rebase_fork_point(), runs git-rebase with the * appropriate arguments and returns its exit status. */ static int run_rebase(const struct object_id *curr_head, const struct object_id *merge_head, const struct object_id *fork_point) { int ret; struct object_id oct_merge_base; struct argv_array args = ARGV_ARRAY_INIT; if (!get_octopus_merge_base(&oct_merge_base, curr_head, merge_head, fork_point)) if (!is_null_oid(fork_point) && oideq(&oct_merge_base, fork_point)) fork_point = NULL; argv_array_push(&args, "rebase"); /* Shared options */ argv_push_verbosity(&args); /* Options passed to git-rebase */ if (opt_rebase == REBASE_MERGES) argv_array_push(&args, "--rebase-merges"); else if (opt_rebase == REBASE_PRESERVE) argv_array_push(&args, "--preserve-merges"); else if (opt_rebase == REBASE_INTERACTIVE) argv_array_push(&args, "--interactive"); if (opt_diffstat) argv_array_push(&args, opt_diffstat); argv_array_pushv(&args, opt_strategies.argv); argv_array_pushv(&args, opt_strategy_opts.argv); if (opt_gpg_sign) argv_array_push(&args, opt_gpg_sign); if (opt_autostash == 0) argv_array_push(&args, "--no-autostash"); else if (opt_autostash == 1) argv_array_push(&args, "--autostash"); if (opt_verify_signatures && !strcmp(opt_verify_signatures, "--verify-signatures")) warning(_("ignoring --verify-signatures for rebase")); argv_array_push(&args, "--onto"); argv_array_push(&args, oid_to_hex(merge_head)); if (fork_point && !is_null_oid(fork_point)) argv_array_push(&args, oid_to_hex(fork_point)); else argv_array_push(&args, oid_to_hex(merge_head)); ret = run_command_v_opt(args.argv, RUN_GIT_CMD); argv_array_clear(&args); return ret; }
static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit, struct object_id *oid) { /* * We may or may not have the commit yet - if not, look it * up using the supplied sha1. */ if (!commit) { if (is_null_oid(oid)) return 0; commit = lookup_commit_reference_gently(the_repository, oid, 1); /* Not a commit -- keep it */ if (!commit) return 0; } /* Reachable from the current ref? Don't prune. */ if (commit->object.flags & REACHABLE) return 0; if (cb->mark_list && cb->mark_limit) { cb->mark_limit = 0; /* dig down to the root */ mark_reachable(cb); } return !(commit->object.flags & REACHABLE); }
static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_width) { if (ref->deletion) print_ref_status('-', "[deleted]", ref, NULL, NULL, porcelain, summary_width); else if (is_null_oid(&ref->old_oid)) print_ref_status('*', (starts_with(ref->name, "refs/tags/") ? "[new tag]" : "[new branch]"), ref, ref->peer_ref, NULL, porcelain, summary_width); else { struct strbuf quickref = STRBUF_INIT; char type; const char *msg; strbuf_add_unique_abbrev(&quickref, &ref->old_oid, DEFAULT_ABBREV); if (ref->forced_update) { strbuf_addstr(&quickref, "..."); type = '+'; msg = "forced update"; } else { strbuf_addstr(&quickref, ".."); type = ' '; msg = NULL; } strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV); print_ref_status(type, quickref.buf, ref, ref->peer_ref, msg, porcelain, summary_width); strbuf_release(&quickref); } }
/** * Sets merge_base to the octopus merge base of curr_head, merge_head and * fork_point. Returns 0 if a merge base is found, 1 otherwise. */ static int get_octopus_merge_base(struct object_id *merge_base, const struct object_id *curr_head, const struct object_id *merge_head, const struct object_id *fork_point) { struct commit_list *revs = NULL, *result; commit_list_insert(lookup_commit_reference(the_repository, curr_head), &revs); commit_list_insert(lookup_commit_reference(the_repository, merge_head), &revs); if (!is_null_oid(fork_point)) commit_list_insert(lookup_commit_reference(the_repository, fork_point), &revs); result = get_octopus_merge_bases(revs); free_commit_list(revs); reduce_heads_replace(&result); if (!result) return 1; oidcpy(merge_base, &result->item->object.oid); free_commit_list(result); return 0; }
static void get_default_heads(void) { if (head_points_at && !is_null_oid(&head_oid)) fsck_handle_ref("HEAD", &head_oid, 0, NULL); for_each_rawref(fsck_handle_ref, NULL); if (include_reflogs) for_each_reflog(fsck_handle_reflog, NULL); /* * Not having any default heads isn't really fatal, but * it does mean that "--unreachable" no longer makes any * sense (since in this case everything will obviously * be unreachable by definition. * * Showing dangling objects is valid, though (as those * dangling objects are likely lost heads). * * So we just print a warning about it, and clear the * "show_unreachable" flag. */ if (!default_refs) { fprintf(stderr, "notice: No default references\n"); show_unreachable = 0; } }
static int fsck_head_link(void) { int null_is_error = 0; if (verbose) fprintf(stderr, "Checking HEAD link\n"); head_points_at = resolve_ref_unsafe("HEAD", 0, &head_oid, NULL); if (!head_points_at) { errors_found |= ERROR_REFS; return error("Invalid HEAD"); } if (!strcmp(head_points_at, "HEAD")) /* detached HEAD */ null_is_error = 1; else if (!starts_with(head_points_at, "refs/heads/")) { errors_found |= ERROR_REFS; return error("HEAD points to something strange (%s)", head_points_at); } if (is_null_oid(&head_oid)) { if (null_is_error) { errors_found |= ERROR_REFS; return error("HEAD: detached HEAD points at nothing"); } fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n", head_points_at + 11); } return 0; }
/* * Add the lines from the named object to list, with trailing * newlines removed. */ static int string_list_add_note_lines(struct string_list *list, const struct object_id *oid) { char *data; unsigned long len; enum object_type t; if (is_null_oid(oid)) return 0; /* read_sha1_file NUL-terminates */ data = read_object_file(oid, &t, &len); if (t != OBJ_BLOB || !data || !len) { free(data); return t != OBJ_BLOB || !data; } /* * If the last line of the file is EOL-terminated, this will * add an empty string to the list. But it will be removed * later, along with any empty strings that came from empty * lines within the file. */ string_list_split(list, data, '\n', -1); free(data); return 0; }
/* * Determine whether we can simply reuse the file in the worktree. */ static int use_wt_file(const char *workdir, const char *name, struct object_id *oid) { struct strbuf buf = STRBUF_INIT; struct stat st; int use = 0; strbuf_addstr(&buf, workdir); add_path(&buf, buf.len, name); if (!lstat(buf.buf, &st) && !S_ISLNK(st.st_mode)) { struct object_id wt_oid; int fd = open(buf.buf, O_RDONLY); if (fd >= 0 && !index_fd(wt_oid.hash, fd, &st, OBJ_BLOB, name, 0)) { if (is_null_oid(oid)) { oidcpy(oid, &wt_oid); use = 1; } else if (!oidcmp(oid, &wt_oid)) use = 1; } } strbuf_release(&buf); return use; }
static void update_index_from_diff(struct diff_queue_struct *q, struct diff_options *opt, void *data) { int i; int intent_to_add = *(int *)data; for (i = 0; i < q->nr; i++) { struct diff_filespec *one = q->queue[i]->one; int is_missing = !(one->mode && !is_null_oid(&one->oid)); struct cache_entry *ce; if (is_missing && !intent_to_add) { remove_file_from_cache(one->path); continue; } ce = make_cache_entry(one->mode, one->oid.hash, one->path, 0, 0); if (!ce) die(_("make_cache_entry failed for path '%s'"), one->path); if (is_missing) { ce->ce_flags |= CE_INTENT_TO_ADD; set_object_name_for_intent_to_add_entry(ce); } add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE); } }
int transport_fetch_refs(struct transport *transport, struct ref *refs) { int rc; int nr_heads = 0, nr_alloc = 0, nr_refs = 0; struct ref **heads = NULL; struct ref *rm; for (rm = refs; rm; rm = rm->next) { nr_refs++; if (rm->peer_ref && !is_null_oid(&rm->old_oid) && !oidcmp(&rm->peer_ref->old_oid, &rm->old_oid)) continue; ALLOC_GROW(heads, nr_heads + 1, nr_alloc); heads[nr_heads++] = rm; } if (!nr_heads) { /* * When deepening of a shallow repository is requested, * then local and remote refs are likely to still be equal. * Just feed them all to the fetch method in that case. * This condition shouldn't be met in a non-deepening fetch * (see builtin/fetch.c:quickfetch()). */ ALLOC_ARRAY(heads, nr_refs); for (rm = refs; rm; rm = rm->next) heads[nr_heads++] = rm; } rc = transport->fetch(transport, nr_heads, heads); free(heads); return rc; }
static int checkout_branch(struct checkout_opts *opts, struct branch_info *new_branch_info) { if (opts->pathspec.nr) die(_("paths cannot be used with switching branches")); if (opts->patch_mode) die(_("'%s' cannot be used with switching branches"), "--patch"); if (!opts->overlay_mode) die(_("'%s' cannot be used with switching branches"), "--no-overlay"); if (opts->writeout_stage) die(_("'%s' cannot be used with switching branches"), "--ours/--theirs"); if (opts->force && opts->merge) die(_("'%s' cannot be used with '%s'"), "-f", "-m"); if (opts->force_detach && opts->new_branch) die(_("'%s' cannot be used with '%s'"), "--detach", "-b/-B/--orphan"); if (opts->new_orphan_branch) { if (opts->track != BRANCH_TRACK_UNSPECIFIED) die(_("'%s' cannot be used with '%s'"), "--orphan", "-t"); } else if (opts->force_detach) { if (opts->track != BRANCH_TRACK_UNSPECIFIED) die(_("'%s' cannot be used with '%s'"), "--detach", "-t"); } else if (opts->track == BRANCH_TRACK_UNSPECIFIED) opts->track = git_branch_track; if (new_branch_info->name && !new_branch_info->commit) die(_("Cannot switch branch to a non-commit '%s'"), new_branch_info->name); if (new_branch_info->path && !opts->force_detach && !opts->new_branch && !opts->ignore_other_worktrees) { int flag; char *head_ref = resolve_refdup("HEAD", 0, NULL, &flag); if (head_ref && (!(flag & REF_ISSYMREF) || strcmp(head_ref, new_branch_info->path))) die_if_checked_out(new_branch_info->path, 1); free(head_ref); } if (!new_branch_info->commit && opts->new_branch) { struct object_id rev; int flag; if (!read_ref_full("HEAD", 0, &rev, &flag) && (flag & REF_ISSYMREF) && is_null_oid(&rev)) return switch_unborn_to_new_branch(opts); } return switch_branches(opts, new_branch_info); }
int combine_notes_concatenate(struct object_id *cur_oid, const struct object_id *new_oid) { char *cur_msg = NULL, *new_msg = NULL, *buf; unsigned long cur_len, new_len, buf_len; enum object_type cur_type, new_type; int ret; /* read in both note blob objects */ if (!is_null_oid(new_oid)) new_msg = read_object_file(new_oid, &new_type, &new_len); if (!new_msg || !new_len || new_type != OBJ_BLOB) { free(new_msg); return 0; } if (!is_null_oid(cur_oid)) cur_msg = read_object_file(cur_oid, &cur_type, &cur_len); if (!cur_msg || !cur_len || cur_type != OBJ_BLOB) { free(cur_msg); free(new_msg); oidcpy(cur_oid, new_oid); return 0; } /* we will separate the notes by two newlines anyway */ if (cur_msg[cur_len - 1] == '\n') cur_len--; /* concatenate cur_msg and new_msg into buf */ buf_len = cur_len + 2 + new_len; buf = (char *) xmalloc(buf_len); memcpy(buf, cur_msg, cur_len); buf[cur_len] = '\n'; buf[cur_len + 1] = '\n'; memcpy(buf + cur_len + 2, new_msg, new_len); free(cur_msg); free(new_msg); /* create a new blob object from buf */ ret = write_object_file(buf, buf_len, blob_type, cur_oid); free(buf); return ret; }
static int merge_one_change_manual(struct notes_merge_options *o, struct notes_merge_pair *p, struct notes_tree *t) { const char *lref = o->local_ref ? o->local_ref : "local version"; const char *rref = o->remote_ref ? o->remote_ref : "remote version"; trace_printf("\t\t\tmerge_one_change_manual(obj = %.7s, base = %.7s, " "local = %.7s, remote = %.7s)\n", oid_to_hex(&p->obj), oid_to_hex(&p->base), oid_to_hex(&p->local), oid_to_hex(&p->remote)); /* add "Conflicts:" section to commit message first time through */ if (!o->has_worktree) strbuf_addstr(&(o->commit_msg), "\n\nConflicts:\n"); strbuf_addf(&(o->commit_msg), "\t%s\n", oid_to_hex(&p->obj)); if (o->verbosity >= 2) printf("Auto-merging notes for %s\n", oid_to_hex(&p->obj)); check_notes_merge_worktree(o); if (is_null_oid(&p->local)) { /* D/F conflict, checkout p->remote */ assert(!is_null_oid(&p->remote)); if (o->verbosity >= 1) printf("CONFLICT (delete/modify): Notes for object %s " "deleted in %s and modified in %s. Version from %s " "left in tree.\n", oid_to_hex(&p->obj), lref, rref, rref); write_note_to_worktree(&p->obj, &p->remote); } else if (is_null_oid(&p->remote)) { /* D/F conflict, checkout p->local */ assert(!is_null_oid(&p->local)); if (o->verbosity >= 1) printf("CONFLICT (delete/modify): Notes for object %s " "deleted in %s and modified in %s. Version from %s " "left in tree.\n", oid_to_hex(&p->obj), rref, lref, lref); write_note_to_worktree(&p->obj, &p->local); } else { /* "regular" conflict, checkout result of ll_merge() */ const char *reason = "content"; if (is_null_oid(&p->base)) reason = "add/add"; assert(!is_null_oid(&p->local)); assert(!is_null_oid(&p->remote)); if (o->verbosity >= 1) printf("CONFLICT (%s): Merge conflict in notes for " "object %s\n", reason, oid_to_hex(&p->obj)); ll_merge_in_worktree(o, p); } trace_printf("\t\t\tremoving from partial merge result\n"); remove_note(t, p->obj.hash); return 1; }
static int verify_notes_filepair(struct diff_filepair *p, struct object_id *oid) { switch (p->status) { case DIFF_STATUS_MODIFIED: assert(p->one->mode == p->two->mode); assert(!is_null_oid(&p->one->oid)); assert(!is_null_oid(&p->two->oid)); break; case DIFF_STATUS_ADDED: assert(is_null_oid(&p->one->oid)); break; case DIFF_STATUS_DELETED: assert(is_null_oid(&p->two->oid)); break; default: return -1; } assert(!strcmp(p->one->path, p->two->path)); return path_to_oid(p->one->path, oid); }
/* * When we cannot load the full patch-id for both commits for whatever * reason, the function returns -1 (i.e. return error(...)). Despite * the "neq" in the name of this function, the caller only cares about * the return value being zero (a and b are equivalent) or non-zero (a * and b are different), and returning non-zero would keep both in the * result, even if they actually were equivalent, in order to err on * the side of safety. The actual value being negative does not have * any significance; only that it is non-zero matters. */ static int patch_id_neq(const void *cmpfn_data, const void *entry, const void *entry_or_key, const void *unused_keydata) { /* NEEDSWORK: const correctness? */ struct diff_options *opt = (void *)cmpfn_data; struct patch_id *a = (void *)entry; struct patch_id *b = (void *)entry_or_key; if (is_null_oid(&a->patch_id) && commit_patch_id(a->commit, opt, &a->patch_id, 0)) return error("Could not get patch ID for %s", oid_to_hex(&a->commit->object.oid)); if (is_null_oid(&b->patch_id) && commit_patch_id(b->commit, opt, &b->patch_id, 0)) return error("Could not get patch ID for %s", oid_to_hex(&b->commit->object.oid)); return !oideq(&a->patch_id, &b->patch_id); }
static int show_modified(struct rev_info *revs, const struct cache_entry *old_entry, const struct cache_entry *new_entry, int report_missing, int cached, int match_missing) { unsigned int mode, oldmode; const struct object_id *oid; unsigned dirty_submodule = 0; if (get_stat_data(new_entry, &oid, &mode, cached, match_missing, &dirty_submodule, &revs->diffopt) < 0) { if (report_missing) diff_index_show_file(revs, "-", old_entry, &old_entry->oid, 1, old_entry->ce_mode, 0); return -1; } if (revs->combine_merges && !cached && (!oideq(oid, &old_entry->oid) || !oideq(&old_entry->oid, &new_entry->oid))) { struct combine_diff_path *p; int pathlen = ce_namelen(new_entry); p = xmalloc(combine_diff_path_size(2, pathlen)); p->path = (char *) &p->parent[2]; p->next = NULL; memcpy(p->path, new_entry->name, pathlen); p->path[pathlen] = 0; p->mode = mode; oidclr(&p->oid); memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent)); p->parent[0].status = DIFF_STATUS_MODIFIED; p->parent[0].mode = new_entry->ce_mode; oidcpy(&p->parent[0].oid, &new_entry->oid); p->parent[1].status = DIFF_STATUS_MODIFIED; p->parent[1].mode = old_entry->ce_mode; oidcpy(&p->parent[1].oid, &old_entry->oid); show_combined_diff(p, 2, revs->dense_combined_merges, revs); free(p); return 0; } oldmode = old_entry->ce_mode; if (mode == oldmode && oideq(oid, &old_entry->oid) && !dirty_submodule && !revs->diffopt.flags.find_copies_harder) return 0; diff_change(&revs->diffopt, oldmode, mode, &old_entry->oid, oid, 1, !is_null_oid(oid), old_entry->name, 0, dirty_submodule); return 0; }
static int merge_commit(struct notes_merge_options *o) { struct strbuf msg = STRBUF_INIT; struct object_id oid, parent_oid; struct notes_tree *t; struct commit *partial; struct pretty_print_context pretty_ctx; void *local_ref_to_free; int ret; /* * Read partial merge result from .git/NOTES_MERGE_PARTIAL, * and target notes ref from .git/NOTES_MERGE_REF. */ if (get_oid("NOTES_MERGE_PARTIAL", &oid)) die(_("failed to read ref NOTES_MERGE_PARTIAL")); else if (!(partial = lookup_commit_reference(&oid))) die(_("could not find commit from NOTES_MERGE_PARTIAL.")); else if (parse_commit(partial)) die(_("could not parse commit from NOTES_MERGE_PARTIAL.")); if (partial->parents) oidcpy(&parent_oid, &partial->parents->item->object.oid); else oidclr(&parent_oid); t = xcalloc(1, sizeof(struct notes_tree)); init_notes(t, "NOTES_MERGE_PARTIAL", combine_notes_overwrite, 0); o->local_ref = local_ref_to_free = resolve_refdup("NOTES_MERGE_REF", 0, oid.hash, NULL); if (!o->local_ref) die(_("failed to resolve NOTES_MERGE_REF")); if (notes_merge_commit(o, t, partial, &oid)) die(_("failed to finalize notes merge")); /* Reuse existing commit message in reflog message */ memset(&pretty_ctx, 0, sizeof(pretty_ctx)); format_commit_message(partial, "%s", &msg, &pretty_ctx); strbuf_trim(&msg); strbuf_insert(&msg, 0, "notes: ", 7); update_ref(msg.buf, o->local_ref, oid.hash, is_null_oid(&parent_oid) ? NULL : parent_oid.hash, 0, UPDATE_REFS_DIE_ON_ERR); free_notes(t); strbuf_release(&msg); ret = merge_abort(o); free(local_ref_to_free); return ret; }
/* * Fill the blob_sha1 field of an origin if it hasn't, so that later * call to fill_origin_blob() can use it to locate the data. blob_sha1 * for an origin is also used to pass the blame for the entire file to * the parent to detect the case where a child's blob is identical to * that of its parent's. * * This also fills origin->mode for corresponding tree path. */ static int fill_blob_sha1_and_mode(struct blame_origin *origin) { if (!is_null_oid(&origin->blob_oid)) return 0; if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode)) goto error_out; if (oid_object_info(the_repository, &origin->blob_oid, NULL) != OBJ_BLOB) goto error_out; return 0; error_out: oidclr(&origin->blob_oid); origin->mode = S_IFINVALID; return -1; }
int remove_note(struct notes_tree *t, const unsigned char *object_sha1) { struct leaf_node l; if (!t) t = &default_notes_tree; assert(t->initialized); hashcpy(l.key_oid.hash, object_sha1); oidclr(&l.val_oid); note_tree_remove(t, t->root, 0, &l); if (is_null_oid(&l.val_oid)) /* no note was removed */ return 1; t->dirty = 1; return 0; }
static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator, struct object_id *peeled) { struct packed_ref_iterator *iter = (struct packed_ref_iterator *)ref_iterator; if ((iter->base.flags & REF_KNOWS_PEELED)) { oidcpy(peeled, &iter->peeled); return is_null_oid(&iter->peeled) ? -1 : 0; } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) { return -1; } else { return !!peel_object(&iter->oid, peeled); } }
static void export_blob(const struct object_id *oid) { unsigned long size; enum object_type type; char *buf; struct object *object; int eaten; if (no_data) return; if (is_null_oid(oid)) return; object = lookup_object(oid->hash); if (object && object->flags & SHOWN) return; if (anonymize) { buf = anonymize_blob(&size); object = (struct object *)lookup_blob(oid); eaten = 0; } else { buf = read_object_file(oid, &type, &size); if (!buf) die ("Could not read blob %s", oid_to_hex(oid)); if (check_object_signature(oid, buf, size, type_name(type)) < 0) die("sha1 mismatch in blob %s", oid_to_hex(oid)); object = parse_object_buffer(oid, type, size, buf, &eaten); } if (!object) die("Could not read blob %s", oid_to_hex(oid)); mark_next_object(object); printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size); if (size && fwrite(buf, size, 1, stdout) != 1) die_errno ("Could not write blob '%s'", oid_to_hex(oid)); printf("\n"); show_progress(); object->flags |= SHOWN; if (!eaten) free(buf); }
static void set_upstreams(struct transport *transport, struct ref *refs, int pretend) { struct ref *ref; for (ref = refs; ref; ref = ref->next) { const char *localname; const char *tmp; const char *remotename; unsigned char sha[20]; int flag = 0; /* * Check suitability for tracking. Must be successful / * already up-to-date ref create/modify (not delete). */ if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE) continue; if (!ref->peer_ref) continue; if (is_null_oid(&ref->new_oid)) continue; /* Follow symbolic refs (mainly for HEAD). */ localname = ref->peer_ref->name; remotename = ref->name; tmp = resolve_ref_unsafe(localname, RESOLVE_REF_READING, sha, &flag); if (tmp && flag & REF_ISSYMREF && starts_with(tmp, "refs/heads/")) localname = tmp; /* Both source and destination must be local branches. */ if (!localname || !starts_with(localname, "refs/heads/")) continue; if (!remotename || !starts_with(remotename, "refs/heads/")) continue; if (!pretend) install_branch_config(BRANCH_CONFIG_VERBOSE, localname + 11, transport->remote->name, remotename); else printf(_("Would set upstream of '%s' to '%s' of '%s'\n"), localname + 11, remotename + 11, transport->remote->name); } }
static int gitmodule_oid_from_commit(const struct object_id *treeish_name, struct object_id *gitmodules_oid, struct strbuf *rev) { int ret = 0; if (is_null_oid(treeish_name)) { oidclr(gitmodules_oid); return 1; } strbuf_addf(rev, "%s:.gitmodules", oid_to_hex(treeish_name)); if (get_oid(rev->buf, gitmodules_oid) >= 0) ret = 1; return ret; }
static void show_new_file(struct rev_info *revs, const struct cache_entry *new_file, int cached, int match_missing) { const struct object_id *oid; unsigned int mode; unsigned dirty_submodule = 0; /* * New file in the index: it might actually be different in * the working tree. */ if (get_stat_data(new_file, &oid, &mode, cached, match_missing, &dirty_submodule, &revs->diffopt) < 0) return; diff_index_show_file(revs, "+", new_file, oid, !is_null_oid(oid), mode, dirty_submodule); }
int transport_fetch_refs(struct transport *transport, struct ref *refs) { int rc; int nr_heads = 0, nr_alloc = 0, nr_refs = 0; struct ref **heads = NULL; struct ref *rm; if (!transport->vtable->fetch_without_list) /* * Some transports (e.g. the built-in bundle transport and the * transport helper interface) do not work when fetching is * done immediately after transport creation. List the remote * refs anyway (if not already listed) as a workaround. */ transport_get_remote_refs(transport, NULL); for (rm = refs; rm; rm = rm->next) { nr_refs++; if (rm->peer_ref && !is_null_oid(&rm->old_oid) && oideq(&rm->peer_ref->old_oid, &rm->old_oid)) continue; ALLOC_GROW(heads, nr_heads + 1, nr_alloc); heads[nr_heads++] = rm; } if (!nr_heads) { /* * When deepening of a shallow repository is requested, * then local and remote refs are likely to still be equal. * Just feed them all to the fetch method in that case. * This condition shouldn't be met in a non-deepening fetch * (see builtin/fetch.c:quickfetch()). */ ALLOC_ARRAY(heads, nr_refs); for (rm = refs; rm; rm = rm->next) heads[nr_heads++] = rm; } rc = transport->vtable->fetch(transport, nr_heads, heads); free(heads); return rc; }
static void print_bases(struct base_tree_info *bases) { int i; /* Only do this once, either for the cover or for the first one */ if (is_null_oid(&bases->base_commit)) return; /* Show the base commit */ printf("base-commit: %s\n", oid_to_hex(&bases->base_commit)); /* Show the prerequisite patches */ for (i = bases->nr_patch_id - 1; i >= 0; i--) printf("prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i])); free(bases->patch_id); bases->nr_patch_id = 0; bases->alloc_patch_id = 0; oidclr(&bases->base_commit); }
static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid, timestamp_t timestamp) { struct object *obj; if (!is_null_oid(oid)) { obj = lookup_object(oid->hash); if (obj && (obj->flags & HAS_OBJ)) { if (timestamp && name_objects) add_decoration(fsck_walk_options.object_names, obj, xstrfmt("%s@{%"PRItime"}", refname, timestamp)); obj->flags |= USED; mark_object_reachable(obj); } else if (!is_promisor_object(oid)) { error("%s: invalid reflog entry %s", refname, oid_to_hex(oid)); errors_found |= ERROR_REACHABLE; } } }
void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) { struct commit_info *commit_info = get_commit_info(commit, &info->reflogs, 0); struct commit_reflog *commit_reflog; struct object *logobj; struct reflog_info *reflog; info->last_commit_reflog = NULL; if (!commit_info) return; commit_reflog = commit_info->util; if (commit_reflog->recno < 0) { commit->parents = NULL; return; } info->last_commit_reflog = commit_reflog; do { reflog = &commit_reflog->reflogs->items[commit_reflog->recno]; commit_reflog->recno--; logobj = parse_object(&reflog->ooid); } while (commit_reflog->recno && (logobj && logobj->type != OBJ_COMMIT)); if (!logobj && commit_reflog->recno >= 0 && is_null_oid(&reflog->ooid)) { /* a root commit, but there are still more entries to show */ reflog = &commit_reflog->reflogs->items[commit_reflog->recno]; logobj = parse_object(&reflog->noid); } if (!logobj || logobj->type != OBJ_COMMIT) { commit_info->commit = NULL; commit->parents = NULL; return; } commit_info->commit = (struct commit *)logobj; commit->parents = xcalloc(1, sizeof(struct commit_list)); commit->parents->item = commit_info->commit; }