Merge branch 'dt/refs-check-refname-component-sse-fix'
authorJunio C Hamano <gitster@pobox.com>
Thu, 10 Jul 2014 18:27:55 +0000 (11:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 10 Jul 2014 18:27:55 +0000 (11:27 -0700)
Fixes to a topic that is already in 'master'.

* dt/refs-check-refname-component-sse-fix:
refs: fix valgrind suppression file
refs.c: handle REFNAME_REFSPEC_PATTERN at end of page

1  2 
refs.c
diff --combined refs.c
index 20e2bf18c9da51904d53ec594022eb75e7cefcf0,39871977ed2ad1ad39d8c28b21bc9f354abc9946..82e4842a36ef803d6406f852f2415b3b77f477f7
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -153,6 -153,7 +153,7 @@@ int check_refname_format(const char *re
        const __m128i tilde_lb = _mm_set1_epi8('~' - 1);
  
        int component_count = 0;
+       int orig_flags = flags;
  
        if (refname[0] == 0 || refname[0] == '/') {
                /* entirely empty ref or initial ref component */
                         * End-of-page; fall back to slow method for
                         * this entire ref.
                         */
-                       return check_refname_format_bytewise(refname, flags);
+                       return check_refname_format_bytewise(refname, orig_flags);
  
                tmp = _mm_loadu_si128((__m128i *)cp);
                tmp1 = _mm_loadu_si128((__m128i *)(cp + 1));
@@@ -1820,7 -1821,6 +1821,7 @@@ int peel_ref(const char *refname, unsig
  struct warn_if_dangling_data {
        FILE *fp;
        const char *refname;
 +      const struct string_list *refnames;
        const char *msg_fmt;
  };
  
@@@ -1835,12 -1835,8 +1836,12 @@@ static int warn_if_dangling_symref(cons
                return 0;
  
        resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL);
 -      if (!resolves_to || strcmp(resolves_to, d->refname))
 +      if (!resolves_to
 +          || (d->refname
 +              ? strcmp(resolves_to, d->refname)
 +              : !string_list_has_string(d->refnames, resolves_to))) {
                return 0;
 +      }
  
        fprintf(d->fp, d->msg_fmt, refname);
        fputc('\n', d->fp);
@@@ -1853,18 -1849,6 +1854,18 @@@ void warn_dangling_symref(FILE *fp, con
  
        data.fp = fp;
        data.refname = refname;
 +      data.refnames = NULL;
 +      data.msg_fmt = msg_fmt;
 +      for_each_rawref(warn_if_dangling_symref, &data);
 +}
 +
 +void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)
 +{
 +      struct warn_if_dangling_data data;
 +
 +      data.fp = fp;
 +      data.refname = NULL;
 +      data.refnames = refnames;
        data.msg_fmt = msg_fmt;
        for_each_rawref(warn_if_dangling_symref, &data);
  }
@@@ -2225,6 -2209,7 +2226,6 @@@ int dwim_log(const char *str, int len, 
  
        *log = NULL;
        for (p = ref_rev_parse_rules; *p; p++) {
 -              struct stat st;
                unsigned char hash[20];
                char path[PATH_MAX];
                const char *ref, *it;
                ref = resolve_ref_unsafe(path, hash, 1, NULL);
                if (!ref)
                        continue;
 -              if (!stat(git_path("logs/%s", path), &st) &&
 -                  S_ISREG(st.st_mode))
 +              if (reflog_exists(path))
                        it = path;
 -              else if (strcmp(ref, path) &&
 -                       !stat(git_path("logs/%s", ref), &st) &&
 -                       S_ISREG(st.st_mode))
 +              else if (strcmp(ref, path) && reflog_exists(ref))
                        it = ref;
                else
                        continue;
@@@ -2653,7 -2641,7 +2654,7 @@@ static int curate_packed_ref_fn(struct 
        return 0;
  }
  
 -static int repack_without_refs(const char **refnames, int n)
 +int repack_without_refs(const char **refnames, int n)
  {
        struct ref_dir *packed;
        struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
@@@ -3152,133 -3140,122 +3153,133 @@@ int create_symref(const char *ref_targe
        return 0;
  }
  
 -static char *ref_msg(const char *line, const char *endp)
 -{
 -      const char *ep;
 -      line += 82;
 -      ep = memchr(line, '\n', endp - line);
 -      if (!ep)
 -              ep = endp;
 -      return xmemdupz(line, ep - line);
 +struct read_ref_at_cb {
 +      const char *refname;
 +      unsigned long at_time;
 +      int cnt;
 +      int reccnt;
 +      unsigned char *sha1;
 +      int found_it;
 +
 +      unsigned char osha1[20];
 +      unsigned char nsha1[20];
 +      int tz;
 +      unsigned long date;
 +      char **msg;
 +      unsigned long *cutoff_time;
 +      int *cutoff_tz;
 +      int *cutoff_cnt;
 +};
 +
 +static int read_ref_at_ent(unsigned char *osha1, unsigned char *nsha1,
 +              const char *email, unsigned long timestamp, int tz,
 +              const char *message, void *cb_data)
 +{
 +      struct read_ref_at_cb *cb = cb_data;
 +
 +      cb->reccnt++;
 +      cb->tz = tz;
 +      cb->date = timestamp;
 +
 +      if (timestamp <= cb->at_time || cb->cnt == 0) {
 +              if (cb->msg)
 +                      *cb->msg = xstrdup(message);
 +              if (cb->cutoff_time)
 +                      *cb->cutoff_time = timestamp;
 +              if (cb->cutoff_tz)
 +                      *cb->cutoff_tz = tz;
 +              if (cb->cutoff_cnt)
 +                      *cb->cutoff_cnt = cb->reccnt - 1;
 +              /*
 +               * we have not yet updated cb->[n|o]sha1 so they still
 +               * hold the values for the previous record.
 +               */
 +              if (!is_null_sha1(cb->osha1)) {
 +                      hashcpy(cb->sha1, nsha1);
 +                      if (hashcmp(cb->osha1, nsha1))
 +                              warning("Log for ref %s has gap after %s.",
 +                                      cb->refname, show_date(cb->date, cb->tz, DATE_RFC2822));
 +              }
 +              else if (cb->date == cb->at_time)
 +                      hashcpy(cb->sha1, nsha1);
 +              else if (hashcmp(nsha1, cb->sha1))
 +                      warning("Log for ref %s unexpectedly ended on %s.",
 +                              cb->refname, show_date(cb->date, cb->tz,
 +                                                 DATE_RFC2822));
 +              hashcpy(cb->osha1, osha1);
 +              hashcpy(cb->nsha1, nsha1);
 +              cb->found_it = 1;
 +              return 1;
 +      }
 +      hashcpy(cb->osha1, osha1);
 +      hashcpy(cb->nsha1, nsha1);
 +      if (cb->cnt > 0)
 +              cb->cnt--;
 +      return 0;
 +}
 +
 +static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1,
 +                                const char *email, unsigned long timestamp,
 +                                int tz, const char *message, void *cb_data)
 +{
 +      struct read_ref_at_cb *cb = cb_data;
 +
 +      if (cb->msg)
 +              *cb->msg = xstrdup(message);
 +      if (cb->cutoff_time)
 +              *cb->cutoff_time = timestamp;
 +      if (cb->cutoff_tz)
 +              *cb->cutoff_tz = tz;
 +      if (cb->cutoff_cnt)
 +              *cb->cutoff_cnt = cb->reccnt;
 +      hashcpy(cb->sha1, osha1);
 +      if (is_null_sha1(cb->sha1))
 +              hashcpy(cb->sha1, nsha1);
 +      /* We just want the first entry */
 +      return 1;
  }
  
  int read_ref_at(const char *refname, unsigned long at_time, int cnt,
                unsigned char *sha1, char **msg,
                unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
  {
 -      const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
 -      char *tz_c;
 -      int logfd, tz, reccnt = 0;
 -      struct stat st;
 -      unsigned long date;
 -      unsigned char logged_sha1[20];
 -      void *log_mapped;
 -      size_t mapsz;
 +      struct read_ref_at_cb cb;
  
 -      logfile = git_path("logs/%s", refname);
 -      logfd = open(logfile, O_RDONLY, 0);
 -      if (logfd < 0)
 -              die_errno("Unable to read log '%s'", logfile);
 -      fstat(logfd, &st);
 -      if (!st.st_size)
 -              die("Log %s is empty.", logfile);
 -      mapsz = xsize_t(st.st_size);
 -      log_mapped = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, logfd, 0);
 -      logdata = log_mapped;
 -      close(logfd);
 +      memset(&cb, 0, sizeof(cb));
 +      cb.refname = refname;
 +      cb.at_time = at_time;
 +      cb.cnt = cnt;
 +      cb.msg = msg;
 +      cb.cutoff_time = cutoff_time;
 +      cb.cutoff_tz = cutoff_tz;
 +      cb.cutoff_cnt = cutoff_cnt;
 +      cb.sha1 = sha1;
 +
 +      for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);
 +
 +      if (!cb.reccnt)
 +              die("Log for %s is empty.", refname);
 +      if (cb.found_it)
 +              return 0;
 +
 +      for_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb);
  
 -      lastrec = NULL;
 -      rec = logend = logdata + st.st_size;
 -      while (logdata < rec) {
 -              reccnt++;
 -              if (logdata < rec && *(rec-1) == '\n')
 -                      rec--;
 -              lastgt = NULL;
 -              while (logdata < rec && *(rec-1) != '\n') {
 -                      rec--;
 -                      if (*rec == '>')
 -                              lastgt = rec;
 -              }
 -              if (!lastgt)
 -                      die("Log %s is corrupt.", logfile);
 -              date = strtoul(lastgt + 1, &tz_c, 10);
 -              if (date <= at_time || cnt == 0) {
 -                      tz = strtoul(tz_c, NULL, 10);
 -                      if (msg)
 -                              *msg = ref_msg(rec, logend);
 -                      if (cutoff_time)
 -                              *cutoff_time = date;
 -                      if (cutoff_tz)
 -                              *cutoff_tz = tz;
 -                      if (cutoff_cnt)
 -                              *cutoff_cnt = reccnt - 1;
 -                      if (lastrec) {
 -                              if (get_sha1_hex(lastrec, logged_sha1))
 -                                      die("Log %s is corrupt.", logfile);
 -                              if (get_sha1_hex(rec + 41, sha1))
 -                                      die("Log %s is corrupt.", logfile);
 -                              if (hashcmp(logged_sha1, sha1)) {
 -                                      warning("Log %s has gap after %s.",
 -                                              logfile, show_date(date, tz, DATE_RFC2822));
 -                              }
 -                      }
 -                      else if (date == at_time) {
 -                              if (get_sha1_hex(rec + 41, sha1))
 -                                      die("Log %s is corrupt.", logfile);
 -                      }
 -                      else {
 -                              if (get_sha1_hex(rec + 41, logged_sha1))
 -                                      die("Log %s is corrupt.", logfile);
 -                              if (hashcmp(logged_sha1, sha1)) {
 -                                      warning("Log %s unexpectedly ended on %s.",
 -                                              logfile, show_date(date, tz, DATE_RFC2822));
 -                              }
 -                      }
 -                      munmap(log_mapped, mapsz);
 -                      return 0;
 -              }
 -              lastrec = rec;
 -              if (cnt > 0)
 -                      cnt--;
 -      }
 -
 -      rec = logdata;
 -      while (rec < logend && *rec != '>' && *rec != '\n')
 -              rec++;
 -      if (rec == logend || *rec == '\n')
 -              die("Log %s is corrupt.", logfile);
 -      date = strtoul(rec + 1, &tz_c, 10);
 -      tz = strtoul(tz_c, NULL, 10);
 -      if (get_sha1_hex(logdata, sha1))
 -              die("Log %s is corrupt.", logfile);
 -      if (is_null_sha1(sha1)) {
 -              if (get_sha1_hex(logdata + 41, sha1))
 -                      die("Log %s is corrupt.", logfile);
 -      }
 -      if (msg)
 -              *msg = ref_msg(logdata, logend);
 -      munmap(log_mapped, mapsz);
 -
 -      if (cutoff_time)
 -              *cutoff_time = date;
 -      if (cutoff_tz)
 -              *cutoff_tz = tz;
 -      if (cutoff_cnt)
 -              *cutoff_cnt = reccnt;
        return 1;
  }
  
 +int reflog_exists(const char *refname)
 +{
 +      struct stat st;
 +
 +      return !lstat(git_path("logs/%s", refname), &st) &&
 +              S_ISREG(st.st_mode);
 +}
 +
 +int delete_reflog(const char *refname)
 +{
 +      return remove_path(git_path("logs/%s", refname));
 +}
 +
  static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data)
  {
        unsigned char osha1[20], nsha1[20];