[PATCH 1 of 4] eol: make repo.commit use a custom commitctx wrapper (issue2254)

Dan Villiom Podlaski Christiansen danchr at gmail.com
Wed Jul 7 05:18:48 CDT 2010


# HG changeset patch
# User Dan Villiom Podlaski Christiansen <danchr at gmail.com>
# Date 1278497446 -7200
# Node ID a571e430eaff35810fe174bee31abd0b984a12fb
# Parent  a5c8326106957afea68a868d019f2fab9b4ddeae
eol: make repo.commit use a custom commitctx wrapper (issue2254)

Unconditionally wrapping commitctx() means that EOL-processing is
performed for *all* changeset creations; even if done as part of a
conversion or a pull using hgsubversion or hg-git.

In most cases, the bug would not be noticed, unless the converted
repository happened to contain a .hgeol file and the EOL extension was
enabled. Even if this case, EOL expansion should not occur during a
conversion; by design, conversions should be exact, unless the user
explicitely requests otherwise.

It should be noted, however, that the aforementioned issue was not how
this bug was discovered: hgsubversion will raise an IOError whenever
the commit callback for a deleted file is called. The EOL extension
did not anticipate this situation, causing pulls to fail if a revision
deleted any files and it was enabled.

The fix is similar to, and based on, a change by Christian Ebert to
the keyword extension in changeset 23e941d7f507.

diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -205,6 +205,7 @@ def reposetup(ui, repo):
             return match.match(self.root, '', [], include, exclude)
 
         def _hgcleardirstate(self):
+            self.__committing = False
             self._eolfile = self.readhgeol() or self.readhgeol('tip')
 
             if not self._eolfile:
@@ -239,18 +240,30 @@ def reposetup(ui, repo):
                         wlock.release()
 
         def commitctx(self, ctx, error=False):
-            for f in sorted(ctx.added() + ctx.modified()):
-                if not self._eolfile(f):
-                    continue
-                data = ctx[f].data()
-                if util.binary(data):
-                    # We should not abort here, since the user should
-                    # be able to say "** = native" to automatically
-                    # have all non-binary files taken care of.
-                    continue
-                if inconsistenteol(data):
-                    raise util.Abort(_("inconsistent newline style "
-                                       "in %s\n" % f))
+            # only expand during invocation of commit()
+            if self.__committing:
+                for f in sorted(ctx.added() + ctx.modified()):
+                    if not self._eolfile(f):
+                        continue
+                    data = ctx[f].data()
+                    if util.binary(data):
+                        # We should not abort here, since the user should
+                        # be able to say "** = native" to automatically
+                        # have all non-binary files taken care of.
+                        continue
+                    if inconsistenteol(data):
+                        raise util.Abort(_("inconsistent newline style "
+                                           "in %s\n" % f))
             return super(eolrepo, self).commitctx(ctx, error)
+
+        def commit(self, *args, **opts):
+            # enable commitctx() wrapping
+            orig = self.__committing
+            self.__committing = True
+            try:
+                return super(eolrepo, self).commit(*args, **opts)
+            finally:
+                self.__committing = orig
+
     repo.__class__ = eolrepo
     repo._hgcleardirstate()


More information about the Mercurial-devel mailing list