+static int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1)
+{
+ struct commit *new, *old;
+ struct commit_list *list;
+
+ if (force_update)
+ return 1;
+ old = lookup_commit_reference(old_sha1);
+ if (!old)
+ return 0;
+ new = lookup_commit_reference(new_sha1);
+ if (!new)
+ return 0;
+ if (parse_commit(new) < 0)
+ return 0;
+ list = NULL;
+ commit_list_insert(new, &list);
+ while (list) {
+ new = pop_most_recent_commit(&list, 1);
+ if (new == old)
+ return 1;
+ }
+ return 0;
+}
+
+static int local_ref_nr_match;
+static char **local_ref_match;
+static struct ref *local_ref_list;
+static struct ref **local_last_ref;
+
+static int try_to_match(const char *refname, const unsigned char *sha1)
+{
+ struct ref *ref;
+ int len;
+
+ if (!path_match(refname, local_ref_nr_match, local_ref_match)) {
+ if (!send_all)
+ return 0;
+
+ /* If we have it listed already, skip it */
+ for (ref = local_ref_list ; ref ; ref = ref->next) {
+ if (!strcmp(ref->name, refname))
+ return 0;
+ }
+ }
+
+ len = strlen(refname)+1;
+ ref = xmalloc(sizeof(*ref) + len);
+ memset(ref->old_sha1, 0, 20);
+ memcpy(ref->new_sha1, sha1, 20);
+ memcpy(ref->name, refname, len);
+ ref->next = NULL;
+ *local_last_ref = ref;
+ local_last_ref = &ref->next;
+ return 0;
+}
+