static void read_config(void)
{
static int loaded;
- unsigned char sha1[20];
+ struct object_id oid;
const char *head_ref;
int flag;
loaded = 1;
current_branch = NULL;
- head_ref = resolve_ref_unsafe("HEAD", 0, sha1, &flag);
+ head_ref = resolve_ref_unsafe("HEAD", 0, oid.hash, &flag);
if (head_ref && (flag & REF_ISSYMREF) &&
skip_prefix(head_ref, "refs/heads/", &head_ref)) {
current_branch = make_branch(head_ref, 0);
flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
if (fetch) {
- unsigned char unused[40];
+ struct object_id unused;
/* LHS */
if (!*rs[i].src)
; /* empty is ok; it means "HEAD" */
- else if (llen == 40 && !get_sha1_hex(rs[i].src, unused))
+ else if (llen == GIT_SHA1_HEXSZ && !get_oid_hex(rs[i].src, &unused))
rs[i].exact_sha1 = 1; /* ok */
else if (!check_refname_format(rs[i].src, flags))
; /* valid looking ref is ok */
const char *name)
{
size_t len = strlen(name);
- struct ref *ref = xcalloc(1, sizeof(struct ref) + prefixlen + len + 1);
+ struct ref *ref = xcalloc(1, st_add4(sizeof(*ref), prefixlen, len, 1));
memcpy(ref->name, prefix, prefixlen);
memcpy(ref->name + prefixlen, name, len);
return ref;
size_t len;
if (!ref)
return NULL;
- len = strlen(ref->name);
- cpy = xmalloc(sizeof(struct ref) + len + 1);
- memcpy(cpy, ref, sizeof(struct ref) + len + 1);
+ len = st_add3(sizeof(struct ref), strlen(ref->name), 1);
+ cpy = xmalloc(len);
+ memcpy(cpy, ref, len);
cpy->next = NULL;
cpy->symref = xstrdup_or_null(ref->symref);
cpy->remote_status = xstrdup_or_null(ref->remote_status);
static struct ref *alloc_delete_ref(void)
{
struct ref *ref = alloc_ref("(delete)");
- hashclr(ref->new_sha1);
+ oidclr(&ref->new_oid);
return ref;
}
static int try_explicit_object_name(const char *name,
struct ref **match)
{
- unsigned char sha1[20];
+ struct object_id oid;
if (!*name) {
if (match)
return 0;
}
- if (get_sha1(name, sha1))
+ if (get_sha1(name, oid.hash))
return -1;
if (match) {
*match = alloc_ref(name);
- hashcpy((*match)->new_sha1, sha1);
+ oidcpy(&(*match)->new_oid, &oid);
}
return 0;
}
static char *guess_ref(const char *name, struct ref *peer)
{
struct strbuf buf = STRBUF_INIT;
- unsigned char sha1[20];
+ struct object_id oid;
const char *r = resolve_ref_unsafe(peer->name, RESOLVE_REF_READING,
- sha1, NULL);
+ oid.hash, NULL);
if (!r)
return NULL;
return -1;
if (!dst_value) {
- unsigned char sha1[20];
+ struct object_id oid;
int flag;
dst_value = resolve_ref_unsafe(matched_src->name,
RESOLVE_REF_READING,
- sha1, &flag);
+ oid.hash, &flag);
if (!dst_value ||
((flag & REF_ISSYMREF) &&
!starts_with(dst_value, "refs/heads/")))
case 0:
if (starts_with(dst_value, "refs/"))
matched_dst = make_linked_ref(dst_value, dst_tail);
- else if (is_null_sha1(matched_src->new_sha1))
+ else if (is_null_oid(&matched_src->new_oid))
error("unable to delete '%s': remote ref does not exist",
dst_value);
else if ((dst_guess = guess_ref(dst_value, matched_src)))
int nr, alloc;
};
-static void add_to_tips(struct tips *tips, const unsigned char *sha1)
+static void add_to_tips(struct tips *tips, const struct object_id *oid)
{
struct commit *commit;
- if (is_null_sha1(sha1))
+ if (is_null_oid(oid))
return;
- commit = lookup_commit_reference_gently(sha1, 1);
+ commit = lookup_commit_reference_gently(oid->hash, 1);
if (!commit || (commit->object.flags & TMP_MARK))
return;
commit->object.flags |= TMP_MARK;
memset(&sent_tips, 0, sizeof(sent_tips));
for (ref = *dst; ref; ref = ref->next) {
if (ref->peer_ref &&
- !is_null_sha1(ref->peer_ref->new_sha1))
- add_to_tips(&sent_tips, ref->peer_ref->new_sha1);
+ !is_null_oid(&ref->peer_ref->new_oid))
+ add_to_tips(&sent_tips, &ref->peer_ref->new_oid);
else
- add_to_tips(&sent_tips, ref->old_sha1);
+ add_to_tips(&sent_tips, &ref->old_oid);
if (starts_with(ref->name, "refs/tags/"))
string_list_append(&dst_tag, ref->name);
}
continue; /* not a tag */
if (string_list_has_string(&dst_tag, ref->name))
continue; /* they already have it */
- if (sha1_object_info(ref->new_sha1, NULL) != OBJ_TAG)
+ if (sha1_object_info(ref->new_oid.hash, NULL) != OBJ_TAG)
continue; /* be conservative */
item = string_list_append(&src_tag, ref->name);
item->util = ref;
struct ref *dst_ref;
struct commit *commit;
- if (is_null_sha1(ref->new_sha1))
+ if (is_null_oid(&ref->new_oid))
continue;
- commit = lookup_commit_reference_gently(ref->new_sha1, 1);
+ commit = lookup_commit_reference_gently(ref->new_oid.hash, 1);
if (!commit)
/* not pushing a commit, which is not an error */
continue;
/* Add it in */
dst_ref = make_linked_ref(ref->name, dst_tail);
- hashcpy(dst_ref->new_sha1, ref->new_sha1);
+ oidcpy(&dst_ref->new_oid, &ref->new_oid);
dst_ref->peer_ref = copy_ref(ref);
}
}
/* Create a new one and link it */
dst_peer = make_linked_ref(dst_name, &dst_tail);
- hashcpy(dst_peer->new_sha1, ref->new_sha1);
+ oidcpy(&dst_peer->new_oid, &ref->new_oid);
string_list_insert(&dst_ref_index,
dst_peer->name)->util = dst_peer;
}
int reject_reason = 0;
if (ref->peer_ref)
- hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
+ oidcpy(&ref->new_oid, &ref->peer_ref->new_oid);
else if (!send_mirror)
continue;
- ref->deletion = is_null_sha1(ref->new_sha1);
+ ref->deletion = is_null_oid(&ref->new_oid);
if (!ref->deletion &&
- !hashcmp(ref->old_sha1, ref->new_sha1)) {
+ !oidcmp(&ref->old_oid, &ref->new_oid)) {
ref->status = REF_STATUS_UPTODATE;
continue;
}
/*
- * Bypass the usual "must fast-forward" check but
- * replace it with a weaker "the old value must be
- * this value we observed". If the remote ref has
- * moved and is now different from what we expect,
- * reject any push.
+ * If the remote ref has moved and is now different
+ * from what we expect, reject any push.
*
* It also is an error if the user told us to check
* with the remote-tracking branch to find the value
*/
if (ref->expect_old_sha1) {
if (ref->expect_old_no_trackback ||
- hashcmp(ref->old_sha1, ref->old_sha1_expect))
+ oidcmp(&ref->old_oid, &ref->old_oid_expect))
reject_reason = REF_STATUS_REJECT_STALE;
+ else
+ /* If the ref isn't stale then force the update. */
+ force_ref_update = 1;
}
/*
- * The usual "must fast-forward" rules.
+ * If the update isn't already rejected then check
+ * the usual "must fast-forward" rules.
*
* Decide whether an individual refspec A:B can be
* pushed. The push will succeed if any of the
* passing the --force argument
*/
- else if (!ref->deletion && !is_null_sha1(ref->old_sha1)) {
+ if (!reject_reason && !ref->deletion && !is_null_oid(&ref->old_oid)) {
if (starts_with(ref->name, "refs/tags/"))
reject_reason = REF_STATUS_REJECT_ALREADY_EXISTS;
- else if (!has_sha1_file(ref->old_sha1))
+ else if (!has_object_file(&ref->old_oid))
reject_reason = REF_STATUS_REJECT_FETCH_FIRST;
- else if (!lookup_commit_reference_gently(ref->old_sha1, 1) ||
- !lookup_commit_reference_gently(ref->new_sha1, 1))
+ else if (!lookup_commit_reference_gently(ref->old_oid.hash, 1) ||
+ !lookup_commit_reference_gently(ref->new_oid.hash, 1))
reject_reason = REF_STATUS_REJECT_NEEDS_FORCE;
- else if (!ref_newer(ref->new_sha1, ref->old_sha1))
+ else if (!ref_newer(&ref->new_oid, &ref->old_oid))
reject_reason = REF_STATUS_REJECT_NONFASTFORWARD;
}
{
struct remote *remote;
char *ref;
- unsigned char sha1[20];
+ struct object_id oid;
int i;
if (!ret)
strcmp(ret->remote_name, "."))
continue;
if (dwim_ref(ret->merge_name[i], strlen(ret->merge_name[i]),
- sha1, &ref) == 1)
+ oid.hash, &ref) == 1)
ret->merge[i]->dst = ref;
else
ret->merge[i]->dst = xstrdup(ret->merge_name[i]);
static int ignore_symref_update(const char *refname)
{
- unsigned char sha1[20];
+ struct object_id oid;
int flag;
- if (!resolve_ref_unsafe(refname, 0, sha1, &flag))
+ if (!resolve_ref_unsafe(refname, 0, oid.hash, &flag))
return 0; /* non-existing refs are OK */
return (flag & REF_ISSYMREF);
}
if (refspec->exact_sha1) {
ref_map = alloc_ref(name);
- get_sha1_hex(name, ref_map->old_sha1);
+ get_oid_hex(name, &ref_map->old_oid);
} else {
ref_map = get_remote_ref(remote_refs, name);
}
return 0;
for (; list; list = list->next)
if (!strcmp(ref->symref, list->name)) {
- hashcpy(ref->old_sha1, list->old_sha1);
+ oidcpy(&ref->old_oid, &list->old_oid);
return 0;
}
return 1;
}
}
-int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1)
+int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
{
struct object *o;
struct commit *old, *new;
* Both new and old must be commit-ish and new is descendant of
* old. Otherwise we require --force.
*/
- o = deref_tag(parse_object(old_sha1), NULL, 0);
+ o = deref_tag(parse_object(old_oid->hash), NULL, 0);
if (!o || o->type != OBJ_COMMIT)
return 0;
old = (struct commit *) o;
- o = deref_tag(parse_object(new_sha1), NULL, 0);
+ o = deref_tag(parse_object(new_oid->hash), NULL, 0);
if (!o || o->type != OBJ_COMMIT)
return 0;
new = (struct commit *) o;
int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
const char **upstream_name)
{
- unsigned char sha1[20];
+ struct object_id oid;
struct commit *ours, *theirs;
struct rev_info revs;
const char *base;
return -1;
/* Cannot stat if what we used to build on no longer exists */
- if (read_ref(base, sha1))
+ if (read_ref(base, oid.hash))
return -1;
- theirs = lookup_commit_reference(sha1);
+ theirs = lookup_commit_reference(oid.hash);
if (!theirs)
return -1;
- if (read_ref(branch->refname, sha1))
+ if (read_ref(branch->refname, oid.hash))
return -1;
- ours = lookup_commit_reference(sha1);
+ ours = lookup_commit_reference(oid.hash);
if (!ours)
return -1;
argv_array_push(&argv, ""); /* ignored */
argv_array_push(&argv, "--left-right");
argv_array_pushf(&argv, "%s...%s",
- sha1_to_hex(ours->object.sha1),
- sha1_to_hex(theirs->object.sha1));
+ oid_to_hex(&ours->object.oid),
+ oid_to_hex(&theirs->object.oid));
argv_array_push(&argv, "--");
init_revisions(&revs, NULL);
{
struct ref ***local_tail = cb_data;
struct ref *ref;
- int len;
/* we already know it starts with refs/ to get here */
if (check_refname_format(refname + 5, 0))
return 0;
- len = strlen(refname) + 1;
- ref = xcalloc(1, sizeof(*ref) + len);
- hashcpy(ref->new_sha1, oid->hash);
- memcpy(ref->name, refname, len);
+ ref = alloc_ref(refname);
+ oidcpy(&ref->new_oid, oid);
**local_tail = ref;
*local_tail = &ref->next;
return 0;
/* If refs/heads/master could be right, it is. */
if (!all) {
r = find_ref_by_name(refs, "refs/heads/master");
- if (r && !hashcmp(r->old_sha1, head->old_sha1))
+ if (r && !oidcmp(&r->old_oid, &head->old_oid))
return copy_ref(r);
}
for (r = refs; r; r = r->next) {
if (r != head &&
starts_with(r->name, "refs/heads/") &&
- !hashcmp(r->old_sha1, head->old_sha1)) {
+ !oidcmp(&r->old_oid, &head->old_oid)) {
*tail = copy_ref(r);
tail = &((*tail)->next);
if (!all)
if (stale) {
struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
- hashcpy(ref->new_sha1, oid->hash);
+ oidcpy(&ref->new_oid, oid);
}
clean_exit:
* If we cannot do so, return negative to signal an error.
*/
static int remote_tracking(struct remote *remote, const char *refname,
- unsigned char sha1[20])
+ struct object_id *oid)
{
char *dst;
dst = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
if (!dst)
return -1; /* no tracking ref for refname at remote */
- if (read_ref(dst, sha1))
+ if (read_ref(dst, oid->hash))
return -1; /* we know what the tracking ref is but we cannot read it */
return 0;
}
continue;
ref->expect_old_sha1 = 1;
if (!entry->use_tracking)
- hashcpy(ref->old_sha1_expect, cas->entry[i].expect);
- else if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
+ hashcpy(ref->old_oid_expect.hash, cas->entry[i].expect);
+ else if (remote_tracking(remote, ref->name, &ref->old_oid_expect))
ref->expect_old_no_trackback = 1;
return;
}
return;
ref->expect_old_sha1 = 1;
- if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
+ if (remote_tracking(remote, ref->name, &ref->old_oid_expect))
ref->expect_old_no_trackback = 1;
}