summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2016-03-11 13:38:23 +0200
committerLars Wirzenius <liw@liw.fi>2016-03-11 17:22:41 +0200
commitc2eea0c73763be273e8964f8d4d24d002227e6d3 (patch)
tree4f4c415a0a3dab83990dbfb33e6c32a496a0e690
parent72cc119fa757a224a3a750b61a79268c2b0ac0ba (diff)
downloadobnam-c2eea0c73763be273e8964f8d4d24d002227e6d3.tar.gz
Only clone a DIR obj when actually changing it
-rw-r--r--obnamlib/fmt_ga/client.py21
-rw-r--r--obnamlib/fmt_ga/dirobj.py22
-rw-r--r--obnamlib/fmt_ga/dirobj_tests.py3
3 files changed, 29 insertions, 17 deletions
diff --git a/obnamlib/fmt_ga/client.py b/obnamlib/fmt_ga/client.py
index 441b93ea..a795b5dc 100644
--- a/obnamlib/fmt_ga/client.py
+++ b/obnamlib/fmt_ga/client.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Lars Wirzenius
+# Copyright 2015-2016 Lars Wirzenius
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -605,13 +605,17 @@ class GAFileMetadata(object):
filename, obnamlib.REPO_FILE_MODE, file_metadata.st_mode)
self._flush_added_file(filename)
- dir_obj, basename = self._get_mutable_dir_obj(filename)
- if not dir_obj:
+ dir_obj, _, basename = self._get_dir_obj(filename)
+ if dir_obj is None:
return False
for key, field in obnamlib.metadata_file_key_mapping:
value = getattr(file_metadata, field)
- dir_obj.set_file_key(basename, key, value)
+ old_value = dir_obj.get_file_key(basename, key)
+ if value != old_value:
+ if not dir_obj.is_mutable():
+ dir_obj, basename = self._get_mutable_dir_obj(filename)
+ dir_obj.set_file_key(basename, key, value)
return True
@@ -622,10 +626,13 @@ class GAFileMetadata(object):
self._flush_added_file(filename)
return True
else:
- dir_obj, basename = self._get_mutable_dir_obj(filename)
- if not dir_obj:
+ immutable, _, basename = self._get_dir_obj(filename)
+ if not immutable:
return False
- dir_obj.set_file_key(basename, key, value)
+ old_value = immutable.get_file_key(basename, key)
+ if old_value != value:
+ mutable, basename2 = self._get_mutable_dir_obj(filename)
+ mutable.set_file_key(basename2, key, value)
return True
def _get_mutable_dir_obj(self, filename):
diff --git a/obnamlib/fmt_ga/dirobj.py b/obnamlib/fmt_ga/dirobj.py
index e98019bd..da67abb9 100644
--- a/obnamlib/fmt_ga/dirobj.py
+++ b/obnamlib/fmt_ga/dirobj.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Lars Wirzenius
+# Copyright 2015-2016 Lars Wirzenius
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -41,19 +41,21 @@ class GADirectory(object):
self._dict = a_dict
def add_file(self, basename):
- self._require_mutable()
- self._dict['metadata'][basename] = {
- 'chunk-ids': [],
- }
+ if basename not in self._dict['metadata']:
+ self._require_mutable()
+ self._dict['metadata'][basename] = {
+ 'chunk-ids': [],
+ }
def _require_mutable(self):
if not self._mutable:
raise GAImmutableError()
def remove_file(self, basename):
- self._require_mutable()
if basename in self._dict['metadata']:
- del self._dict['metadata'][basename]
+ self._require_mutable()
+ if basename in self._dict['metadata']:
+ del self._dict['metadata'][basename]
def get_file_basenames(self):
return self._dict['metadata'].keys()
@@ -63,9 +65,11 @@ class GADirectory(object):
return self._dict['metadata'][basename].get(key_name)
def set_file_key(self, basename, key, value):
- self._require_mutable()
key_name = obnamlib.repo_key_name(key)
- self._dict['metadata'][basename][key_name] = value
+ old_value = self._dict['metadata'][basename].get(key_name, None)
+ if value != old_value:
+ self._require_mutable()
+ self._dict['metadata'][basename][key_name] = value
def get_file_chunk_ids(self, basename):
return self._dict['metadata'][basename]['chunk-ids']
diff --git a/obnamlib/fmt_ga/dirobj_tests.py b/obnamlib/fmt_ga/dirobj_tests.py
index c4e8b187..b43324cc 100644
--- a/obnamlib/fmt_ga/dirobj_tests.py
+++ b/obnamlib/fmt_ga/dirobj_tests.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Lars Wirzenius
+# Copyright 2015-2016 Lars Wirzenius
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -66,6 +66,7 @@ class GADirectoryTests(unittest.TestCase):
def test_raises_error_if_immutable_and_file_is_removed(self):
dir_obj = obnamlib.GADirectory()
+ dir_obj.add_file('README')
dir_obj.set_immutable()
self.assertRaises(
obnamlib.GAImmutableError,