Avoid import and merge conflicts caused by expanded keywords
authorChristian Ebert <blacktrash@gmx.net>
Fri, 21 Dec 2007 00:40:25 +0100
changeset 315 c1ec4ffd1279
parent 314 d9f84b36de26
child 316 98656ffb1cec
Avoid import and merge conflicts caused by expanded keywords While monkeypatching patch.patchfile.__init__ is brute force and dirty, it seems the least intrusive method.
hgkw/keyword.py
--- a/hgkw/keyword.py	Thu Dec 20 22:15:43 2007 +0100
+++ b/hgkw/keyword.py	Fri Dec 21 00:40:25 2007 +0100
@@ -74,14 +74,10 @@
 Expansions spanning more than one line and incremental expansions,
 like CVS' $Log$, are not supported. A keyword template map
 "Log = {desc}" expands to the first line of the changeset description.
-
-Caveat: "hg import" fails if the patch context contains an active
-        keyword. In that case run "hg kwshrink", and then reimport.
-        Or, better, use bundle/unbundle to share changes.
 '''
 
-from mercurial import commands, cmdutil, context, fancyopts
-from mercurial import filelog, localrepo, revlog, templater, util
+from mercurial import commands, cmdutil, context, fancyopts, filelog
+from mercurial import patch, localrepo, revlog, templater, util
 from mercurial.node import *
 from mercurial.i18n import _
 import re, shutil, sys, tempfile, time
@@ -202,6 +198,46 @@
             return t2 != text
         return revlog.revlog.cmp(self, node, text)
 
+
+def _kwpatchfile_init(self, ui, fname, missing=False):
+    '''Monkeypatch patch.patchfile.__init__, to avoid
+    rejects or conflicts due to expanded keywords in working dir.'''
+    self.fname = fname
+    self.ui = ui
+    self.lines = []
+    self.exists = False
+    self.missing = missing
+    if not missing:
+        try:
+            fp = file(fname, 'rb')
+            
+            if _kwtemplater.matcher(self.fname):
+                # shrink keywords in working dir
+                kwshrunk = _kwtemplater.shrink(fp.read())
+                self.lines = kwshrunk.splitlines(True)
+
+            else:
+                self.lines = fp.readlines()
+            self.exists = True
+        except IOError:
+            pass
+    else:
+        self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
+
+    if not self.exists:
+        dirname = os.path.dirname(fname)
+        if dirname and not os.path.isdir(dirname):
+            os.makedirs(dirname)
+
+    self.hash = {}
+    self.dirty = 0
+    self.offset = 0
+    self.rej = []
+    self.fileprinted = False
+    self.printfile(False)
+    self.hunks = 0
+
+
 def _iskwfile(f, link):
     return not link(f) and _kwtemplater.matcher(f)
 
@@ -470,6 +506,7 @@
                 del wlock, lock
 
     repo.__class__ = kwrepo
+    patch.patchfile.__init__ = _kwpatchfile_init
 
 
 cmdtable = {