Merge branch 'master' into ph/strbuf
authorJunio C Hamano <gitster@pobox.com>
Mon, 10 Sep 2007 18:32:58 +0000 (11:32 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Sep 2007 18:32:58 +0000 (11:32 -0700)
* master:
archive - leakfix for format_subst()
Make --no-thin the default in git-push to save server resources
fix doc for --compression argument to pack-objects
git-tag -s must fail if gpg cannot sign the tag.
git-svn: understand grafts when doing dcommit
git-diff: don't squelch the new SHA1 in submodule diffs
Define NO_MEMMEM on Darwin as it lacks the function
git-svn: fix "Malformed network data" with svn:// servers
(cvs|svn)import: Ask git-tag to overwrite old tags.
git-rebase: fix -C option
git-rebase: support --whitespace=<option>
Documentation / grammer nit
archive: rename attribute specfile to export-subst
archive: specfile syntax change: "$Format:%PLCHLDR$" instead of just "%PLCHLDR" (take 2)
add memmem()
Remove unused function convert_sha1_file()
archive: specfile support (--pretty=format: in archive files)
Export format_commit_message()

1  2 
archive-tar.c
diff.c
diff --combined archive-tar.c
index c84d7c0652783bfd039fe66e4ce2ca59f6a7df8f,c0d95dab0d965ff0ae961d72d7eae4c021c5c05a..0612bb6051e1c60d5151b0c65d097fe51ba93f2e
@@@ -17,6 -17,7 +17,7 @@@ static unsigned long offset
  static time_t archive_time;
  static int tar_umask = 002;
  static int verbose;
+ static const struct commit *commit;
  
  /* writes out the whole block, but only if it is full */
  static void write_if_needed(void)
@@@ -78,6 -79,19 +79,6 @@@ static void write_trailer(void
        }
  }
  
 -static void strbuf_append_string(struct strbuf *sb, const char *s)
 -{
 -      int slen = strlen(s);
 -      int total = sb->len + slen;
 -      if (total + 1 > sb->alloc) {
 -              sb->buf = xrealloc(sb->buf, total + 1);
 -              sb->alloc = total + 1;
 -      }
 -      memcpy(sb->buf + sb->len, s, slen);
 -      sb->len = total;
 -      sb->buf[total] = '\0';
 -}
 -
  /*
   * pax extended header records have the format "%u %s=%s\n".  %u contains
   * the size of the whole string (including the %u), the first %s is the
  static void strbuf_append_ext_header(struct strbuf *sb, const char *keyword,
                                       const char *value, unsigned int valuelen)
  {
 -      char *p;
 -      int len, total, tmp;
 +      int len, tmp;
  
        /* "%u %s=%s\n" */
        len = 1 + 1 + strlen(keyword) + 1 + valuelen + 1;
        for (tmp = len; tmp > 9; tmp /= 10)
                len++;
  
 -      total = sb->len + len;
 -      if (total > sb->alloc) {
 -              sb->buf = xrealloc(sb->buf, total);
 -              sb->alloc = total;
 -      }
 -
 -      p = sb->buf;
 -      p += sprintf(p, "%u %s=", len, keyword);
 -      memcpy(p, value, valuelen);
 -      p += valuelen;
 -      *p = '\n';
 -      sb->len = total;
 +      strbuf_grow(sb, len);
 +      strbuf_addf(sb, "%u %s=", len, keyword);
 +      strbuf_add(sb, value, valuelen);
 +      strbuf_addch(sb, '\n');
  }
  
  static unsigned int ustar_header_chksum(const struct ustar_header *header)
@@@ -131,7 -154,8 +132,7 @@@ static void write_entry(const unsigned 
        struct strbuf ext_header;
  
        memset(&header, 0, sizeof(header));
 -      ext_header.buf = NULL;
 -      ext_header.len = ext_header.alloc = 0;
 +      strbuf_init(&ext_header);
  
        if (!sha1) {
                *header.typeflag = TYPEFLAG_GLOBAL_HEADER;
                sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
        } else {
                if (verbose)
 -                      fprintf(stderr, "%.*s\n", path->len, path->buf);
 +                      fprintf(stderr, "%.*s\n", (int)path->len, path->buf);
                if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
                        *header.typeflag = TYPEFLAG_DIR;
                        mode = (mode | 0777) & ~tar_umask;
  
        if (ext_header.len > 0) {
                write_entry(sha1, NULL, 0, ext_header.buf, ext_header.len);
 -              free(ext_header.buf);
        }
 +      strbuf_release(&ext_header);
        write_blocked(&header, sizeof(header));
        if (S_ISREG(mode) && buffer && size > 0)
                write_blocked(buffer, size);
  static void write_global_extended_header(const unsigned char *sha1)
  {
        struct strbuf ext_header;
 -      ext_header.buf = NULL;
 -      ext_header.len = ext_header.alloc = 0;
 +
 +      strbuf_init(&ext_header);
        strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40);
        write_entry(NULL, NULL, 0, ext_header.buf, ext_header.len);
 -      free(ext_header.buf);
 +      strbuf_release(&ext_header);
  }
  
  static int git_tar_config(const char *var, const char *value)
@@@ -237,22 -261,33 +238,23 @@@ static int write_tar_entry(const unsign
                             const char *base, int baselen,
                             const char *filename, unsigned mode, int stage)
  {
 -      static struct strbuf path;
 +      static struct strbuf path = STRBUF_INIT;
        int filenamelen = strlen(filename);
        void *buffer;
        enum object_type type;
        unsigned long size;
  
 -      if (!path.alloc) {
 -              path.buf = xmalloc(PATH_MAX);
 -              path.alloc = PATH_MAX;
 -              path.len = path.eof = 0;
 -      }
 -      if (path.alloc < baselen + filenamelen + 1) {
 -              free(path.buf);
 -              path.buf = xmalloc(baselen + filenamelen + 1);
 -              path.alloc = baselen + filenamelen + 1;
 -      }
 -      memcpy(path.buf, base, baselen);
 -      memcpy(path.buf + baselen, filename, filenamelen);
 -      path.len = baselen + filenamelen;
 -      path.buf[path.len] = '\0';
 +      strbuf_grow(&path, MAX(PATH_MAX, baselen + filenamelen + 1));
 +      strbuf_reset(&path);
 +      strbuf_add(&path, base, baselen);
 +      strbuf_add(&path, filename, filenamelen);
        if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
 -              strbuf_append_string(&path, "/");
 +              strbuf_addch(&path, '/');
                buffer = NULL;
                size = 0;
        } else {
-               buffer = convert_sha1_file(path.buf, sha1, mode, &type, &size);
+               buffer = sha1_file_to_archive(path.buf, sha1, mode, &type,
+                                             &size, commit);
                if (!buffer)
                        die("cannot read %s", sha1_to_hex(sha1));
        }
@@@ -271,6 -306,7 +273,7 @@@ int write_tar_archive(struct archiver_a
  
        archive_time = args->time;
        verbose = args->verbose;
+       commit = args->commit;
  
        if (args->commit_sha1)
                write_global_extended_header(args->commit_sha1);
diff --combined diff.c
index c054b234b877952501dcf05b2ea312ae77441042,1aca5df522d1c5249c9d1ce8d030849d59a5eb6a..26d7bb96bcaa52b4a104a2dfa17da388e3032c49
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -9,7 -9,6 +9,7 @@@
  #include "xdiff-interface.h"
  #include "color.h"
  #include "attr.h"
 +#include "strbuf.h"
  
  #ifdef NO_FAST_WORKING_DIRECTORY
  #define FAST_WORKING_DIRECTORY 0
@@@ -1546,16 -1545,26 +1546,16 @@@ static int reuse_worktree_file(const ch
  
  static int populate_from_stdin(struct diff_filespec *s)
  {
 -#define INCREMENT 1024
 -      char *buf;
 -      unsigned long size;
 -      ssize_t got;
 -
 -      size = 0;
 -      buf = NULL;
 -      while (1) {
 -              buf = xrealloc(buf, size + INCREMENT);
 -              got = xread(0, buf + size, INCREMENT);
 -              if (!got)
 -                      break; /* EOF */
 -              if (got < 0)
 -                      return error("error while reading from stdin %s",
 +      struct strbuf buf;
 +
 +      strbuf_init(&buf);
 +      if (strbuf_read(&buf, 0) < 0)
 +              return error("error while reading from stdin %s",
                                     strerror(errno));
 -              size += got;
 -      }
 +
        s->should_munmap = 0;
 -      s->data = buf;
 -      s->size = size;
 +      s->size = buf.len;
 +      s->data = strbuf_detach(&buf);
        s->should_free = 1;
        return 0;
  }
@@@ -3135,6 -3144,22 +3135,22 @@@ static void diffcore_apply_filter(cons
        *q = outq;
  }
  
+ /* Check whether two filespecs with the same mode and size are identical */
+ static int diff_filespec_is_identical(struct diff_filespec *one,
+                                     struct diff_filespec *two)
+ {
+       if (S_ISGITLINK(one->mode)) {
+               diff_fill_sha1_info(one);
+               diff_fill_sha1_info(two);
+               return !hashcmp(one->sha1, two->sha1);
+       }
+       if (diff_populate_filespec(one, 0))
+               return 0;
+       if (diff_populate_filespec(two, 0))
+               return 0;
+       return !memcmp(one->data, two->data, one->size);
+ }
  static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
  {
        int i;
                    diff_populate_filespec(p->one, 1) ||
                    diff_populate_filespec(p->two, 1) ||
                    (p->one->size != p->two->size) ||
-                   diff_populate_filespec(p->one, 0) || /* (2) */
-                   diff_populate_filespec(p->two, 0) ||
-                   memcmp(p->one->data, p->two->data, p->one->size))
+                   !diff_filespec_is_identical(p->one, p->two)) /* (2) */
                        diff_q(&outq, p);
                else {
                        /*