[SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Fri Jan 18 12:57:29 MST 2013


The branch, master has been updated
       via  e1ded58 Improve handling of existing files for alt-dest opts. Fixes bug #5644.
      from  0bacacc Perl version of lsh that can change user w/o sudo.

;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e1ded589839627986937817bd102bdab380593a9
Author: Wayne Davison <wayned at samba.org>
Date:   Fri Jan 18 11:54:01 2013 -0800

    Improve handling of existing files for alt-dest opts.
    Fixes bug #5644.

-----------------------------------------------------------------------

Summary of changes:
 generator.c |   35 +++++++++++++++++++++++++++--------
 rsync.yo    |   15 +++++++++++----
 2 files changed, 38 insertions(+), 12 deletions(-)


Changeset truncated at 500 lines:

diff --git a/generator.c b/generator.c
index 973e03b..f95e57f 100644
--- a/generator.c
+++ b/generator.c
@@ -844,10 +844,14 @@ static int copy_altdest_file(const char *src, const char *dest, struct file_stru
 
 /* This is only called for regular files.  We return -2 if we've finished
  * handling the file, -1 if no dest-linking occurred, or a non-negative
- * value if we found an alternate basis file. */
+ * value if we found an alternate basis file.  If we're called with the
+ * find_exact_for_existing flag, the destination file already exists, so
+ * we only try to find an exact alt-dest match.  In this case, the returns
+ * can be -2 & -1 (both as above) as well as -3, which means that we
+ * removed the dest file but failed to create a hard link for it. */
 static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
-			 char *cmpbuf, stat_x *sxp, int itemizing,
-			 enum logcode code)
+			 char *cmpbuf, stat_x *sxp, int find_exact_for_existing,
+			 int itemizing, enum logcode code)
 {
 	int best_match = -1;
 	int match_level = 0;
@@ -889,10 +893,17 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
 	}
 
 	if (match_level == 3 && !copy_dest) {
+		if (find_exact_for_existing) {
+			if (do_unlink(fname) < 0 && errno != ENOENT)
+				return -1;
+		}
 #ifdef SUPPORT_HARD_LINKS
 		if (link_dest) {
-			if (!hard_link_one(file, fname, cmpbuf, 1))
+			if (!hard_link_one(file, fname, cmpbuf, 1)) {
+				if (find_exact_for_existing)
+					return -3;
 				goto try_a_copy;
+			}
 			if (preserve_hard_links && F_IS_HLINKED(file))
 				finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
 			if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) {
@@ -902,13 +913,18 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
 			}
 		} else
 #endif
-		if (itemizing)
-			itemize(cmpbuf, file, ndx, 0, sxp, 0, 0, NULL);
+		{
+			if (itemizing)
+				itemize(cmpbuf, file, ndx, 0, sxp, 0, 0, NULL);
+		}
 		if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
 			rprintf(FCLIENT, "%s is uptodate\n", fname);
 		return -2;
 	}
 
+	if (find_exact_for_existing)
+		return -1;
+
 	if (match_level >= 2) {
 #ifdef SUPPORT_HARD_LINKS
 	  try_a_copy: /* Copy the file locally. */
@@ -1640,9 +1656,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 		stat_errno = ENOENT;
 	}
 
-	if (statret != 0 && basis_dir[0] != NULL) {
+	if (basis_dir[0] != NULL && (statret != 0 || !copy_dest)) {
 		int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx,
-				      itemizing, code);
+				      statret == 0, itemizing, code);
 		if (j == -2) {
 			if (remove_source_files == 1)
 				goto return_with_success;
@@ -1652,6 +1668,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 			fnamecmp = fnamecmpbuf;
 			fnamecmp_type = j;
 			statret = 0;
+		} else if (j == -3) {
+			statret = -1;
+			stat_errno = ENOENT;
 		}
 	}
 
diff --git a/rsync.yo b/rsync.yo
index a062089..655301f 100644
--- a/rsync.yo
+++ b/rsync.yo
@@ -1773,6 +1773,8 @@ directory).  If a file is found in em(DIR) that is identical to the
 sender's file, the file will NOT be transferred to the destination
 directory.  This is useful for creating a sparse backup of just files that
 have changed from an earlier backup.
+This option is typically used to copy into an empty (or newly created)
+directory.
 
 Beginning in version 2.6.4, multiple bf(--compare-dest) directories may be
 provided, which will cause rsync to search the list in the order specified
@@ -1785,6 +1787,10 @@ selected to try to speed up the transfer.
 If em(DIR) is a relative path, it is relative to the destination directory.
 See also bf(--copy-dest) and bf(--link-dest).
 
+NOTE: beginning with version 3.1.0, rsync will remove a file from a non-empty
+destination hierarchy if an exact match is found in one of the compare-dest
+hierarchies (making the end result more closely match a fresh copy).
+
 dit(bf(--copy-dest=DIR)) This option behaves like bf(--compare-dest), but
 rsync will also copy unchanged files found in em(DIR) to the destination
 directory using a local copy.
@@ -1822,10 +1828,11 @@ If a match is not found, a basis file from one of the em(DIR)s will be
 selected to try to speed up the transfer.
 
 This option works best when copying into an empty destination hierarchy, as
-rsync treats existing files as definitive (so it never looks in the link-dest
-dirs when a destination file already exists), and as malleable (so it might
-change the attributes of a destination file, which affects all the hard-linked
-versions).
+existing files may get their attributes tweaked, and that can affect alternate
+destination files via hard-links.  Also, itemizing of changes can get a bit
+muddled.  Note that prior to version 3.1.0, an alternate-directory exact match
+would never be found (nor linked into the destination) when a destination file
+already exists.
 
 Note that if you combine this option with bf(--ignore-times), rsync will not
 link any files together because it only links identical files together as a


-- 
The rsync repository.


More information about the rsync-cvs mailing list