Merge branch 'sg/rerere-gc-old-still-used'
authorJunio C Hamano <gitster@pobox.com>
Tue, 31 Aug 2010 23:14:27 +0000 (16:14 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 31 Aug 2010 23:14:27 +0000 (16:14 -0700)
* sg/rerere-gc-old-still-used:
rerere: fix overeager gc
mingw_utime(): handle NULL times parameter

1  2 
builtin/rerere.c
compat/mingw.c
rerere.c
diff --combined builtin/rerere.c
index 9b1e3a7cf50674ffdd834d08edba184f5c7c285d,6d1b5802add040b7189630077c1bc10b82f76756..67793fa2c795777b02c340551a5c4cee152ff68b
@@@ -19,6 -19,12 +19,12 @@@ static time_t rerere_created_at(const c
        return stat(rerere_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
  }
  
+ static time_t rerere_last_used_at(const char *name)
+ {
+       struct stat st;
+       return stat(rerere_path(name, "postimage"), &st) ? (time_t) 0 : st.st_mtime;
+ }
  static void unlink_rr_item(const char *name)
  {
        unlink(rerere_path(name, "thisimage"));
@@@ -40,7 -46,7 +46,7 @@@ static int git_rerere_gc_config(const c
  
  static void garbage_collect(struct string_list *rr)
  {
 -      struct string_list to_remove = { NULL, 0, 0, 1 };
 +      struct string_list to_remove = STRING_LIST_INIT_DUP;
        DIR *dir;
        struct dirent *e;
        int i, cutoff;
        while ((e = readdir(dir))) {
                if (is_dot_or_dotdot(e->d_name))
                        continue;
-               then = rerere_created_at(e->d_name);
-               if (!then)
-                       continue;
-               cutoff = (has_rerere_resolution(e->d_name)
-                         ? cutoff_resolve : cutoff_noresolve);
+               then = rerere_last_used_at(e->d_name);
+               if (then) {
+                       cutoff = cutoff_resolve;
+               } else {
+                       then = rerere_created_at(e->d_name);
+                       if (!then)
+                               continue;
+                       cutoff = cutoff_noresolve;
+               }
                if (then < now - cutoff * 86400)
 -                      string_list_append(e->d_name, &to_remove);
 +                      string_list_append(&to_remove, e->d_name);
        }
        for (i = 0; i < to_remove.nr; i++)
                unlink_rr_item(to_remove.items[i].string);
@@@ -102,7 -113,7 +113,7 @@@ static int diff_two(const char *file1, 
  
  int cmd_rerere(int argc, const char **argv, const char *prefix)
  {
 -      struct string_list merge_rr = { NULL, 0, 0, 1 };
 +      struct string_list merge_rr = STRING_LIST_INIT_DUP;
        int i, fd, flags = 0;
  
        if (2 < argc) {
                        if (!has_rerere_resolution(name))
                                unlink_rr_item(name);
                }
 -              unlink_or_warn(git_path("rr-cache/MERGE_RR"));
 +              unlink_or_warn(git_path("MERGE_RR"));
        } else if (!strcmp(argv[1], "gc"))
                garbage_collect(&merge_rr);
        else if (!strcmp(argv[1], "status"))
diff --combined compat/mingw.c
index 96be8a02cf2e48d9ff816638aec57987cc41c3af,24333cb167f785cbcf29775eec1237259221e89c..f2d9e1fd974b7271366da09370e10fafd2c50f08
@@@ -304,8 -304,13 +304,13 @@@ int mingw_utime (const char *file_name
                goto revert_attrs;
        }
  
-       time_t_to_filetime(times->modtime, &mft);
-       time_t_to_filetime(times->actime, &aft);
+       if (times) {
+               time_t_to_filetime(times->modtime, &mft);
+               time_t_to_filetime(times->actime, &aft);
+       } else {
+               GetSystemTimeAsFileTime(&mft);
+               aft = mft;
+       }
        if (!SetFileTime((HANDLE)_get_osfhandle(fh), NULL, &aft, &mft)) {
                errno = EINVAL;
                rc = -1;
@@@ -641,7 -646,7 +646,7 @@@ static char *lookup_prog(const char *di
  }
  
  /*
 - * Determines the absolute path of cmd using the the split path in path.
 + * Determines the absolute path of cmd using the split path in path.
   * If cmd contains a slash or backslash, no lookup is performed.
   */
  static char *path_lookup(const char *cmd, char **path, int exe_only)
diff --combined rerere.c
index 78bbcf140346f14bbb961ed5e39e5752568b8d95,a6f6681e112af2fc209fe2b5297ec319ebfd24b5..f42649c4991000786629ee3773ab7b8055403cce
+++ b/rerere.c
@@@ -46,7 -46,7 +46,7 @@@ static void read_rr(struct string_list 
                        ; /* do nothing */
                if (i == sizeof(buf))
                        die("filename too long");
 -              string_list_insert(buf, rr)->util = name;
 +              string_list_insert(rr, buf)->util = name;
        }
        fclose(in);
  }
@@@ -153,7 -153,7 +153,7 @@@ static int handle_path(unsigned char *s
        git_SHA_CTX ctx;
        int hunk_no = 0;
        enum {
 -              RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL,
 +              RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL
        } hunk = RR_CONTEXT;
        struct strbuf one = STRBUF_INIT, two = STRBUF_INIT;
        struct strbuf buf = STRBUF_INIT;
@@@ -354,7 -354,7 +354,7 @@@ static int find_conflict(struct string_
                    ce_same_name(e2, e3) &&
                    S_ISREG(e2->ce_mode) &&
                    S_ISREG(e3->ce_mode)) {
 -                      string_list_insert((const char *)e2->name, conflict);
 +                      string_list_insert(conflict, (const char *)e2->name);
                        i++; /* skip over both #2 and #3 */
                }
        }
@@@ -378,7 -378,13 +378,13 @@@ static int merge(const char *name, cons
        }
        ret = ll_merge(&result, path, &base, NULL, &cur, "", &other, "", 0);
        if (!ret) {
-               FILE *f = fopen(path, "w");
+               FILE *f;
+               if (utime(rerere_path(name, "postimage"), NULL) < 0)
+                       warning("failed utime() on %s: %s",
+                                       rerere_path(name, "postimage"),
+                                       strerror(errno));
+               f = fopen(path, "w");
                if (!f)
                        return error("Could not open %s: %s", path,
                                     strerror(errno));
@@@ -426,8 -432,8 +432,8 @@@ static int update_paths(struct string_l
  
  static int do_plain_rerere(struct string_list *rr, int fd)
  {
 -      struct string_list conflict = { NULL, 0, 0, 1 };
 -      struct string_list update = { NULL, 0, 0, 1 };
 +      struct string_list conflict = STRING_LIST_INIT_DUP;
 +      struct string_list update = STRING_LIST_INIT_DUP;
        int i;
  
        find_conflict(&conflict);
                        if (ret < 1)
                                continue;
                        hex = xstrdup(sha1_to_hex(sha1));
 -                      string_list_insert(path, rr)->util = hex;
 +                      string_list_insert(rr, path)->util = hex;
                        if (mkdir(git_path("rr-cache/%s", hex), 0755))
                                continue;
                        handle_file(path, NULL, rerere_path(hex, "preimage"));
                if (has_rerere_resolution(name)) {
                        if (!merge(name, path)) {
                                if (rerere_autoupdate)
 -                                      string_list_insert(path, &update);
 +                                      string_list_insert(&update, path);
                                fprintf(stderr,
                                        "%s '%s' using previous resolution.\n",
                                        rerere_autoupdate
@@@ -547,7 -553,7 +553,7 @@@ int setup_rerere(struct string_list *me
  
  int rerere(int flags)
  {
 -      struct string_list merge_rr = { NULL, 0, 0, 1 };
 +      struct string_list merge_rr = STRING_LIST_INIT_DUP;
        int fd;
  
        fd = setup_rerere(&merge_rr, flags);
@@@ -577,7 -583,7 +583,7 @@@ static int rerere_forget_one_path(cons
        fprintf(stderr, "Updated preimage for '%s'\n", path);
  
  
 -      string_list_insert(path, rr)->util = hex;
 +      string_list_insert(rr, path)->util = hex;
        fprintf(stderr, "Forgot resolution for %s\n", path);
        return 0;
  }
  int rerere_forget(const char **pathspec)
  {
        int i, fd;
 -      struct string_list conflict = { NULL, 0, 0, 1 };
 -      struct string_list merge_rr = { NULL, 0, 0, 1 };
 +      struct string_list conflict = STRING_LIST_INIT_DUP;
 +      struct string_list merge_rr = STRING_LIST_INIT_DUP;
  
        if (read_cache() < 0)
                return error("Could not read index");