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 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_oid.hash, 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/")))
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;
for (ref = *dst; ref; ref = ref->next) {
if (ref->peer_ref &&
!is_null_oid(&ref->peer_ref->new_oid))
- add_to_tips(&sent_tips, ref->peer_ref->new_oid.hash);
+ add_to_tips(&sent_tips, &ref->peer_ref->new_oid);
else
- add_to_tips(&sent_tips, ref->old_oid.hash);
+ add_to_tips(&sent_tips, &ref->old_oid);
if (starts_with(ref->name, "refs/tags/"))
string_list_append(&dst_tag, ref->name);
}
}
/*
- * 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_no_trackback ||
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_oid(&ref->old_oid)) {
+ 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_object_file(&ref->old_oid))
{
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);
}
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;
{
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);
+ ref = alloc_ref(refname);
oidcpy(&ref->new_oid, oid);
- memcpy(ref->name, refname, len);
**local_tail = ref;
*local_tail = &ref->next;
return 0;
* 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;
}
ref->expect_old_sha1 = 1;
if (!entry->use_tracking)
hashcpy(ref->old_oid_expect.hash, cas->entry[i].expect);
- else if (remote_tracking(remote, ref->name, ref->old_oid_expect.hash))
+ 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_oid_expect.hash))
+ if (remote_tracking(remote, ref->name, &ref->old_oid_expect))
ref->expect_old_no_trackback = 1;
}