afh: Implement --preserve.
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 31 Jul 2018 11:21:06 +0000 (13:21 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Tue, 4 Sep 2018 10:36:17 +0000 (12:36 +0200)
This is easy because we already have the inode information of the
old file from the existing call to stat(2).

afh.c
m4/lls/afh.suite.m4

diff --git a/afh.c b/afh.c
index aa6570e1abc33bfe38e9ce87bf87316707263473..ffb4315b0d41e7087aa03ee7b353e7f690989126 100644 (file)
--- a/afh.c
+++ b/afh.c
@@ -113,6 +113,24 @@ static int rewrite_tags(const char *name, int input_fd, void *map,
                        goto out;
        }
        ret = xrename(tmp_name, name);
+       if (ret < 0)
+               goto out;
+       if (OPT_GIVEN(PRESERVE)) {
+               struct timespec times[2]; /* [0]: atime, [1]: mtime */
+               times[0].tv_nsec = UTIME_OMIT;
+               times[1] = sb.st_mtim;
+               /*
+                * We might well have written a file of identical size. If we
+                * keep the mtime as well, we might fool backup applications
+                * like rsync which skip files whose size and mtime haven't
+                * changed. So we change the mtime slightly.
+                */
+               times[1].tv_sec++;
+               if (futimens(output_fd, times) < 0) {
+                       ret = -ERRNO_TO_PARA_ERROR(errno);
+                       goto out;
+               }
+       }
 out:
        if (ret < 0 && output_fd >= 0)
                unlink(tmp_name); /* ignore errors */
index cf83b9724d824079e720c1d1a357962c9cd6872a..7ebf208c01552e7b17bfd7a5fff37b6f90051c58 100644 (file)
@@ -62,6 +62,12 @@ version-string = GIT_VERSION()
                        The backup suffix is '~'. That is, a single tilde character is appended
                        to the given file name.
                [/help]
+       [option preserve]
+               summary = preserve modification time
+               [help]
+                       If this option is given, the mtime of the modified file is set to
+                       the value prior to the modification.
+               [/help]
        [option year]
                short_opt = y
                summary = set the year tag