Does this look like a sensible thing to add?

https://github.com/nigoroll/tar/pull/1

Also I am not sure what else a change like this would need?

Thanks, Nils
>From e3e474b60b80cc4508a9a3ae02a5391b0398c620 Mon Sep 17 00:00:00 2001
From: Nils Goroll <[email protected]>
Date: Wed, 8 Jun 2016 16:10:17 +0200
Subject: [PATCH] Add --ignore-ctime-change option

The use case is to ignore ctime changes due to changes of the link count,
for instance when hardlinks are used as a snapshotting technique with
immutable files.

Ref: http://mail-archives.apache.org/mod_mbox/cassandra-user/201605.mbox/%[email protected]%3E
---
 doc/tar.texi | 5 +++++
 src/common.h | 2 ++
 src/create.c | 3 ++-
 src/tar.c    | 7 +++++++
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/doc/tar.texi b/doc/tar.texi
index 51ed159..aea259d 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -2852,6 +2852,11 @@ Ignore exit codes of subprocesses. @xref{Writing to an External Program}.
 Do not exit unsuccessfully merely because an unreadable file was encountered.
 @xref{Ignore Failed Read}.
 
+@opsummary{ignore-ctime-change}
+@item --ignore-ctime-change
+
+Do not exit unsuccessfully merely because the ctime of a file changed.
+
 @opsummary{ignore-zeros}
 @item --ignore-zeros
 @itemx -i
diff --git a/src/common.h b/src/common.h
index 50c34cc..d5cdc2b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -166,6 +166,8 @@ GLOBAL gid_t group_option;
 
 GLOBAL bool ignore_failed_read_option;
 
+GLOBAL bool ignore_ctime_change_option;
+
 GLOBAL bool ignore_zeros_option;
 
 GLOBAL bool incremental_option;
diff --git a/src/create.c b/src/create.c
index 3a0f2dc..86fbe61 100644
--- a/src/create.c
+++ b/src/create.c
@@ -1829,7 +1829,8 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
 
       if (ok)
 	{
-	  if ((timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0
+	  if ((! ignore_ctime_change_option &&
+	       timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0
 	       /* Original ctime will change if the file is a directory and
 		  --remove-files is given */
 	       && !(remove_files_option && is_dir))
diff --git a/src/tar.c b/src/tar.c
index ba24c43..0b93372 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -286,6 +286,7 @@ enum
   GROUP_MAP_OPTION,
   IGNORE_COMMAND_ERROR_OPTION,
   IGNORE_FAILED_READ_OPTION,
+  IGNORE_CTIME_CHANGE_OPTION,
   INDEX_FILE_OPTION,
   KEEP_DIRECTORY_SYMLINK_OPTION,
   KEEP_NEWER_FILES_OPTION,
@@ -433,6 +434,8 @@ static struct argp_option options[] = {
    N_("dump level for created listed-incremental archive"), GRID+1 },
   {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0,
    N_("do not exit with nonzero on unreadable files"), GRID+1 },
+  {"ignore-ctime-change", IGNORE_CTIME_CHANGE_OPTION, 0, 0,
+   N_("do not exit with nonzero when the ctime changes"), GRID+1 },
   {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
    N_("process only the NUMBERth occurrence of each file in the archive;"
       " this option is valid only in conjunction with one of the subcommands"
@@ -1734,6 +1737,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
       ignore_failed_read_option = true;
       break;
 
+    case IGNORE_CTIME_CHANGE_OPTION:
+      ignore_ctime_change_option = true;
+      break;
+
     case KEEP_DIRECTORY_SYMLINK_OPTION:
       keep_directory_symlink_option = true;
       break;
-- 
2.1.4

Reply via email to