changeset 899:5fa519c0b0f9

fixed the case when a renamed file is detected by directory scanning before the external rename commands exits. We have to update the FileData structure immediately, othervise we would get duplicate entries.
author Vladimir Nadvornik <nadvornik@suse.cz>
date Sun, 20 Jul 2008 13:19:22 +0000
parents 08a38be08b12
children 4cd9ef1771c1
files src/filedata.c
diffstat 1 files changed, 67 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Sun Jul 20 12:20:12 2008 +0000
+++ b/src/filedata.c	Sun Jul 20 13:19:22 2008 +0000
@@ -23,8 +23,10 @@
 
 
 static GHashTable *file_data_pool = NULL;
+static GHashTable *file_data_planned_change_hash = NULL;
 
 static gint sidecar_file_priority(const gchar *path);
+static void file_data_apply_ci(FileData *fd);
 
 
 /*
@@ -304,13 +306,25 @@
 	if (!file_data_pool)
 		file_data_pool = g_hash_table_new(g_str_hash, g_str_equal);
 
-	fd = g_hash_table_lookup(file_data_pool, path_utf8);
+	if ((fd = g_hash_table_lookup(file_data_pool, path_utf8)))
+		{
+		file_data_ref(fd);
+		}
+		
+	if (!fd && file_data_planned_change_hash)
+		{
+		if ((fd = g_hash_table_lookup(file_data_planned_change_hash, path_utf8)))
+			{
+			DEBUG_1("planned change: using %s -> %s", path_utf8, fd->path);
+			file_data_ref(fd);
+			file_data_apply_ci(fd);
+			}
+		}
+		
 	if (fd)
 		{
 		gboolean changed;
 		
-		file_data_ref(fd);
-
 		if (fd->parent)
 			changed = file_data_check_changed_files(fd);
 		else
@@ -1381,20 +1395,58 @@
  * fails if fd->change does not exist or the change type does not match
  */
 
+static void file_data_update_planned_change_hash(FileData *fd, const gchar *old_path, gchar *new_path)
+{
+	FileDataChangeType type = fd->change->type;
+	
+	if (type == FILEDATA_CHANGE_MOVE || type == FILEDATA_CHANGE_RENAME)
+		{
+		FileData *ofd;
+		
+		if (!file_data_planned_change_hash)
+			file_data_planned_change_hash = g_hash_table_new(g_str_hash, g_str_equal);
+		
+		if (old_path && g_hash_table_lookup(file_data_planned_change_hash, old_path) == fd)
+			{
+			DEBUG_1("planned change: removing %s -> %s", old_path, fd->path);
+			g_hash_table_remove(file_data_planned_change_hash, old_path);
+			file_data_unref(fd);
+			}
+
+		if ((ofd = g_hash_table_lookup(file_data_planned_change_hash, new_path)) != fd)
+			{
+			if (ofd)
+				{
+				DEBUG_1("planned change: replacing %s -> %s", new_path, ofd->path);
+				g_hash_table_remove(file_data_planned_change_hash, new_path);
+				file_data_unref(ofd);
+				}
+			
+			DEBUG_1("planned change: inserting %s -> %s", new_path, fd->path);
+			file_data_ref(fd);
+			g_hash_table_insert(file_data_planned_change_hash, new_path, fd);
+			}
+		}
+}
+
 static void file_data_update_ci_dest(FileData *fd, const gchar *dest_path)
 {
-	g_free(fd->change->dest);
+	gchar *old_path = fd->change->dest;
 	fd->change->dest = g_strdup(dest_path);
+	file_data_update_planned_change_hash(fd, old_path, fd->change->dest);
+	g_free(old_path);
 }
 
 static void file_data_update_ci_dest_preserve_ext(FileData *fd, const gchar *dest_path)
 {
 	const char *extension = extension_from_path(fd->change->source);
 	gchar *base = remove_extension_from_path(dest_path);
+	gchar *old_path = fd->change->dest;
 	
-	g_free(fd->change->dest);
 	fd->change->dest = g_strdup_printf("%s%s", base, extension);
+	file_data_update_planned_change_hash(fd, old_path, fd->change->dest);
 	
+	g_free(old_path);
 	g_free(base);
 }
 
@@ -1612,6 +1664,16 @@
 	/* FIXME delete ?*/
 	if (type == FILEDATA_CHANGE_MOVE || type == FILEDATA_CHANGE_RENAME)
 		{
+		if (file_data_planned_change_hash)
+			{
+			if (g_hash_table_lookup(file_data_planned_change_hash, fd->change->dest) == fd)
+				{
+				DEBUG_1("planned change: applying %s -> %s", fd->change->dest, fd->path);
+				g_hash_table_remove(file_data_planned_change_hash, fd->change->dest);
+				file_data_unref(fd);
+				}
+			}
+
 		file_data_set_path(fd, fd->change->dest);
 		}
 	file_data_increment_version(fd);
@@ -1639,7 +1701,6 @@
 	return TRUE;
 }
 
-
 /*
  * notify other modules about the change described by FileFataChangeInfo
  */