builtin/am: introduce write_state_*() helper functions
[gitweb.git] / builtin / update-ref.c
index 1993529521c0ef20860795168392d1dd7209c991..6763cf1837db99442a7140fe5bb87a0b3a1248fd 100644 (file)
@@ -6,9 +6,9 @@
 #include "argv-array.h"
 
 static const char * const git_update_ref_usage[] = {
-       N_("git update-ref [options] -d <refname> [<oldval>]"),
-       N_("git update-ref [options]    <refname> <newval> [<oldval>]"),
-       N_("git update-ref [options] --stdin [-z]"),
+       N_("git update-ref [<options>] -d <refname> [<old-val>]"),
+       N_("git update-ref [<options>]    <refname> <new-val> [<old-val>]"),
+       N_("git update-ref [<options>] --stdin [-z]"),
        NULL
 };
 
@@ -198,8 +198,9 @@ static const char *parse_cmd_update(struct ref_transaction *transaction,
        if (*next != line_termination)
                die("update %s: extra input: %s", refname, next);
 
-       if (ref_transaction_update(transaction, refname, new_sha1, old_sha1,
-                                  update_flags, have_old, msg, &err))
+       if (ref_transaction_update(transaction, refname,
+                                  new_sha1, have_old ? old_sha1 : NULL,
+                                  update_flags, msg, &err))
                die("%s", err.buf);
 
        update_flags = 0;
@@ -264,8 +265,9 @@ static const char *parse_cmd_delete(struct ref_transaction *transaction,
        if (*next != line_termination)
                die("delete %s: extra input: %s", refname, next);
 
-       if (ref_transaction_delete(transaction, refname, old_sha1,
-                                  update_flags, have_old, msg, &err))
+       if (ref_transaction_delete(transaction, refname,
+                                  have_old ? old_sha1 : NULL,
+                                  update_flags, msg, &err))
                die("%s", err.buf);
 
        update_flags = 0;
@@ -280,7 +282,6 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
 {
        struct strbuf err = STRBUF_INIT;
        char *refname;
-       unsigned char new_sha1[20];
        unsigned char old_sha1[20];
 
        refname = parse_refname(input, &next);
@@ -291,13 +292,11 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
                            PARSE_SHA1_OLD))
                hashclr(old_sha1);
 
-       hashcpy(new_sha1, old_sha1);
-
        if (*next != line_termination)
                die("verify %s: extra input: %s", refname, next);
 
-       if (ref_transaction_update(transaction, refname, new_sha1, old_sha1,
-                                  update_flags, 1, msg, &err))
+       if (ref_transaction_verify(transaction, refname, old_sha1,
+                                  update_flags, &err))
                die("%s", err.buf);
 
        update_flags = 0;
@@ -353,7 +352,8 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
 {
        const char *refname, *oldval;
        unsigned char sha1[20], oldsha1[20];
-       int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0, flags = 0;
+       int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0;
+       unsigned int flags = 0;
        struct option options[] = {
                OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")),
                OPT_BOOL('d', NULL, &delete, N_("delete the reference")),
@@ -408,14 +408,27 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
                        die("%s: not a valid SHA1", value);
        }
 
-       hashclr(oldsha1); /* all-zero hash in case oldval is the empty string */
-       if (oldval && *oldval && get_sha1(oldval, oldsha1))
-               die("%s: not a valid old SHA1", oldval);
+       if (oldval) {
+               if (!*oldval)
+                       /*
+                        * The empty string implies that the reference
+                        * must not already exist:
+                        */
+                       hashclr(oldsha1);
+               else if (get_sha1(oldval, oldsha1))
+                       die("%s: not a valid old SHA1", oldval);
+       }
 
        if (no_deref)
                flags = REF_NODEREF;
        if (delete)
-               return delete_ref(refname, oldval ? oldsha1 : NULL, flags);
+               /*
+                * For purposes of backwards compatibility, we treat
+                * NULL_SHA1 as "don't care" here:
+                */
+               return delete_ref(refname,
+                                 (oldval && !is_null_sha1(oldsha1)) ? oldsha1 : NULL,
+                                 flags);
        else
                return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
                                  flags, UPDATE_REFS_DIE_ON_ERR);