Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Sun, 9 Nov 2008 05:33:55 +0000 (21:33 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 9 Nov 2008 05:33:55 +0000 (21:33 -0800)
* maint:
GIT 1.6.0.4
Update RPM spec for the new location of git-cvsserver.
push: fix local refs update if already up-to-date
do not force write of packed refs

Conflicts:
builtin-revert.c

1  2 
builtin-send-pack.c
refs.c
diff --combined builtin-send-pack.c
index 298bd719240ba503a3128486883d33df011765b1,e428eace2b2213750d4dfa0fe4da9c07bd656892..a9fdbf9d45ddd84e6397ab3e559b06e105c52a19
@@@ -18,7 -18,7 +18,7 @@@ static struct send_pack_args args = 
  /*
   * Make a pack stream and spit it out into file descriptor fd
   */
 -static int pack_objects(int fd, struct ref *refs)
 +static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra)
  {
        /*
         * The child becomes pack-objects --revs; we feed
@@@ -34,8 -34,6 +34,8 @@@
                NULL,
        };
        struct child_process po;
 +      int i;
 +      char buf[42];
  
        if (args.use_thin_pack)
                argv[4] = "--thin";
         * We feed the pack-objects we just spawned with revision
         * parameters by writing to the pipe.
         */
 -      while (refs) {
 -              char buf[42];
 +      for (i = 0; i < extra->nr; i++) {
 +              memcpy(buf + 1, sha1_to_hex(&extra->array[i][0]), 40);
 +              buf[0] = '^';
 +              buf[41] = '\n';
 +              if (!write_or_whine(po.in, buf, 42, "send-pack: send refs"))
 +                      break;
 +      }
  
 +      while (refs) {
                if (!is_null_sha1(refs->old_sha1) &&
                    has_sha1_file(refs->old_sha1)) {
                        memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
@@@ -230,7 -222,7 +230,7 @@@ static void update_tracking_ref(struct 
  {
        struct refspec rs;
  
-       if (ref->status != REF_STATUS_OK)
+       if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
                return;
  
        rs.src = ref->name;
@@@ -395,17 -387,14 +395,17 @@@ static int do_send_pack(int in, int out
        int expect_status_report = 0;
        int flags = MATCH_REFS_NONE;
        int ret;
 +      struct extra_have_objects extra_have;
  
 +      memset(&extra_have, 0, sizeof(extra_have));
        if (args.send_all)
                flags |= MATCH_REFS_ALL;
        if (args.send_mirror)
                flags |= MATCH_REFS_MIRROR;
  
        /* No funny business with the matcher */
 -      remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
 +      remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL,
 +                                     &extra_have);
        get_local_heads();
  
        /* Does the other end support the reporting? */
         */
        new_refs = 0;
        for (ref = remote_refs; ref; ref = ref->next) {
-               const unsigned char *new_sha1;
-               if (!ref->peer_ref) {
-                       if (!args.send_mirror)
-                               continue;
-                       new_sha1 = null_sha1;
-               }
-               else
-                       new_sha1 = ref->peer_ref->new_sha1;
  
+               if (ref->peer_ref)
+                       hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
+               else if (!args.send_mirror)
+                       continue;
  
-               ref->deletion = is_null_sha1(new_sha1);
+               ref->deletion = is_null_sha1(ref->new_sha1);
                if (ref->deletion && !allow_deleting_refs) {
                        ref->status = REF_STATUS_REJECT_NODELETE;
                        continue;
                }
                if (!ref->deletion &&
-                   !hashcmp(ref->old_sha1, new_sha1)) {
+                   !hashcmp(ref->old_sha1, ref->new_sha1)) {
                        ref->status = REF_STATUS_UPTODATE;
                        continue;
                }
                    !ref->deletion &&
                    !is_null_sha1(ref->old_sha1) &&
                    (!has_sha1_file(ref->old_sha1)
-                     || !ref_newer(new_sha1, ref->old_sha1));
+                     || !ref_newer(ref->new_sha1, ref->old_sha1));
  
                if (ref->nonfastforward && !ref->force && !args.force_update) {
                        ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
                        continue;
                }
  
-               hashcpy(ref->new_sha1, new_sha1);
                if (!ref->deletion)
                        new_refs++;
  
  
        packet_flush(out);
        if (new_refs && !args.dry_run) {
 -              if (pack_objects(out, remote_refs) < 0)
 +              if (pack_objects(out, remote_refs, &extra_have) < 0)
                        return -1;
        }
        else
diff --combined refs.c
index 9ae447b10b79a4ba3c834dd74977db5bd321f055,293389e7641a8d4ec948f21407de3f69eacbdddd..42bde72ddbab4a7b338e9072f3c7ab17549cb361
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -390,18 -390,6 +390,18 @@@ int resolve_gitlink_ref(const char *pat
        return retval;
  }
  
 +/*
 + * If the "reading" argument is set, this function finds out what _object_
 + * the ref points at by "reading" the ref.  The ref, if it is not symbolic,
 + * has to exist, and if it is symbolic, it has to point at an existing ref,
 + * because the "read" goes through the symref to the ref it points at.
 + *
 + * The access that is not "reading" may often be "writing", but does not
 + * have to; it can be merely checking _where it leads to_. If it is a
 + * prelude to "writing" to the ref, a write to a symref that points at
 + * yet-to-be-born ref will create the real ref pointed by the symref.
 + * reading=0 allows the caller to check where such a symref leads to.
 + */
  const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag)
  {
        int depth = MAXDEPTH;
                        return NULL;
  
                git_snpath(path, sizeof(path), "%s", ref);
 -              /* Special case: non-existing file.
 -               * Not having the refs/heads/new-branch is OK
 -               * if we are writing into it, so is .git/HEAD
 -               * that points at refs/heads/master still to be
 -               * born.  It is NOT OK if we are resolving for
 -               * reading.
 -               */
 +              /* Special case: non-existing file. */
                if (lstat(path, &st) < 0) {
                        struct ref_list *list = get_packed_refs();
                        while (list) {
@@@ -795,10 -789,10 +795,10 @@@ static struct ref_lock *lock_ref_sha1_b
        char *ref_file;
        const char *orig_ref = ref;
        struct ref_lock *lock;
-       struct stat st;
        int last_errno = 0;
        int type, lflags;
        int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
+       int missing = 0;
  
        lock = xcalloc(1, sizeof(struct ref_lock));
        lock->lock_fd = -1;
                        orig_ref, strerror(errno));
                goto error_return;
        }
+       missing = is_null_sha1(lock->old_sha1);
        /* When the ref did not exist and we are creating it,
         * make sure there is no existing ref that is packed
         * whose name begins with our refname, nor a ref whose
         * name is a proper prefix of our refname.
         */
-       if (is_null_sha1(lock->old_sha1) &&
+       if (missing &&
              !is_refname_available(ref, NULL, get_packed_refs(), 0))
                goto error_return;
  
        lock->ref_name = xstrdup(ref);
        lock->orig_ref_name = xstrdup(orig_ref);
        ref_file = git_path("%s", ref);
-       if (lstat(ref_file, &st) && errno == ENOENT)
+       if (missing)
                lock->force_write = 1;
        if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
                lock->force_write = 1;