[PATCH v2] CachedVC: Add ability to update file status when its modified
- From: Peter Tyser <ptyser gmail com>
- To: meld-list gnome org
- Subject: [PATCH v2] CachedVC: Add ability to update file status when its modified
- Date: Mon, 10 Jan 2011 22:56:33 -0600
Previously, a VcView diff of a cached version controlled directory could
easily become out of date. For example, if the file 'AUTHORS' was a
version controlled file in a git repository:
> echo "asdf" >> AUTHORS
> meld ./
# Double click on the AUTHORS file to view its diff.
# Remove the "asdf" at the bottom of a file and save it.
# Close the AUTHORS tab.
# The state of the AUTHORS file will still show up as modified, even
# though it is now unmodified.
This change implements the new update_file_state() for git. Similar
funcationality could be added to monotone, darcs, bzr, and arch.
Signed-off-by: Peter Tyser <ptyser gmail com>
---
Changes since v1:
- Used docstring comments
- s/get_path_state()/_update_tree_state_cache()/
- Updated comments
meld/vc/_vc.py | 9 +++++++++
meld/vc/git.py | 38 +++++++++++++++++++++++++++++---------
meld/vcview.py | 1 +
3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/meld/vc/_vc.py b/meld/vc/_vc.py
index 4cd5560..09d9c6d 100644
--- a/meld/vc/_vc.py
+++ b/meld/vc/_vc.py
@@ -136,6 +136,15 @@ class Vc(object):
def uncache_inventory(self):
pass
+ def update_file_state(self, path):
+ """ Update the state of a specific file. For example after a file
+ has been modified and saved, its state may be out of date and require
+ updating. This can be implemented for Vc plugins that cache file
+ states, eg 'git' an 'bzr' so that the top-level file status is always
+ accurate.
+ """
+ pass
+
def get_patch_files(self, patch):
regex = re.compile(self.PATCH_INDEX_RE, re.M)
return [f.strip() for f in regex.findall(patch)]
diff --git a/meld/vc/git.py b/meld/vc/git.py
index 82c6c23..9b8ec94 100644
--- a/meld/vc/git.py
+++ b/meld/vc/git.py
@@ -77,7 +77,8 @@ class Vc(_vc.CachedVc):
else:
return ''
- def _lookup_tree_cache(self, rootdir):
+ def _update_tree_state_cache(self, path, tree_state):
+ """ Update the state of the file(s) at tree_state['path'] """
while 1:
try:
# Update the index before getting status, otherwise we could
@@ -87,17 +88,17 @@ class Vc(_vc.CachedVc):
# Get the status of files that are different in the "index" vs
# the HEAD of the git repository
proc = _vc.popen([self.CMD, "diff-index", "--name-status", \
- "--cached", "HEAD", "./"], cwd=self.location)
+ "--cached", "HEAD", path], cwd=self.location)
entries = proc.read().split("\n")[:-1]
# Get the status of files that are different in the "index" vs
# the files on disk
proc = _vc.popen([self.CMD, "diff-files", "--name-status", \
- "-0", "./"], cwd=self.location)
+ "-0", path], cwd=self.location)
entries += (proc.read().split("\n")[:-1])
proc = _vc.popen([self.CMD, "ls-files", "--others", \
- "--ignored", "--exclude-standard"], cwd=self.location)
+ "--ignored", "--exclude-standard", path], cwd=self.location)
entries += ("I\t%s" % f for f in proc.read().split("\n")[:-1])
# An unmerged file or a file that has been modified, added to
@@ -110,15 +111,34 @@ class Vc(_vc.CachedVc):
except OSError, e:
if e.errno != errno.EAGAIN:
raise
+
+ if len(entries) == 0 and os.path.isfile(path):
+ # If we're just updating a single file there's a chance that it
+ # was it was previously modified, and now has been edited
+ # so that it is un-modified. This will result in an empty
+ # 'entries' list, and tree_state['path'] will still contain stale
+ # data. When this corner case occurs we force tree_state['path']
+ # to STATE_NORMAL.
+ tree_state[path] = _vc.STATE_NORMAL
+ else:
+ # There are 1 or more modified files, parse their state
+ for entry in entries:
+ statekey, name = entry.split("\t", 2)
+ path = os.path.join(self.root, name.strip())
+ state = self.state_map.get(statekey.strip(), _vc.STATE_NONE)
+ tree_state[path] = state
+
+ def _lookup_tree_cache(self, rootdir):
+ # Get a list of all files in rootdir, as well as their status
tree_state = {}
- for entry in entries:
- statekey, name = entry.split("\t", 2)
- path = os.path.join(self.root, name.strip())
- state = self.state_map.get(statekey.strip(), _vc.STATE_NONE)
- tree_state[path] = state
+ self._update_tree_state_cache("./", tree_state)
return tree_state
+ def update_file_state(self, path):
+ tree_state = self._get_tree_cache(os.path.dirname(path))
+ self._update_tree_state_cache(path, tree_state)
+
def _get_dirsandfiles(self, directory, dirs, files):
tree = self._get_tree_cache(directory)
diff --git a/meld/vcview.py b/meld/vcview.py
index fcb65d4..e2bafb5 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -594,6 +594,7 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
it = self.find_iter_by_name(filename)
if it:
path = self.model.value_path(it, 0)
+ self.vc.update_file_state(path)
files = self.vc.lookup_files([], [(os.path.basename(path), path)])[1]
for e in files:
if e.path == path:
--
1.7.1.13.gcfb88
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]