diff mercurial/context.py @ 33501:7008f6819002

context: name files relative to cwd in warning messages I was several directories deep in the kernel tree, ran `hg add`, and got the warning about the size of one of the files. I noticed that it suggested undoing the add with a specific revert command. The problem is, it would have failed since the path printed was relative to the repo root instead of cwd. While here, I just fixed the other messages too. As an added benefit, these messages now look the same as the verbose/inexact messages for the corresponding command. I don't think most of these messages are reachable (typically the corresponding cmdutil function does the check). I wasn't able to figure out why the keyword tests were failing when using pathto()- I couldn't cause an absolute path to be used by manipulating the --cwd flag on a regular add. (I did notice that keyword is adding the file without holding wlock.)
author Matt Harbison <matt_harbison@yahoo.com>
date Tue, 11 Jul 2017 00:40:29 -0400
parents 0407a51b9d8c
children 03039ff3082b
line wrap: on
line diff
--- a/mercurial/context.py	Sat Jul 15 00:52:36 2017 -0400
+++ b/mercurial/context.py	Tue Jul 11 00:40:29 2017 -0400
@@ -33,6 +33,7 @@
     mdiff,
     obsolete as obsmod,
     patch,
+    pathutil,
     phases,
     pycompat,
     repoview,
@@ -1518,17 +1519,20 @@
                 (missing and self.deleted()))
 
     def add(self, list, prefix=""):
-        join = lambda f: os.path.join(prefix, f)
         with self._repo.wlock():
             ui, ds = self._repo.ui, self._repo.dirstate
+            uipath = lambda f: ds.pathto(pathutil.join(prefix, f))
             rejected = []
             lstat = self._repo.wvfs.lstat
             for f in list:
-                scmutil.checkportable(ui, join(f))
+                # ds.pathto() returns an absolute file when this is invoked from
+                # the keyword extension.  That gets flagged as non-portable on
+                # Windows, since it contains the drive letter and colon.
+                scmutil.checkportable(ui, os.path.join(prefix, f))
                 try:
                     st = lstat(f)
                 except OSError:
-                    ui.warn(_("%s does not exist!\n") % join(f))
+                    ui.warn(_("%s does not exist!\n") % uipath(f))
                     rejected.append(f)
                     continue
                 if st.st_size > 10000000:
@@ -1536,13 +1540,13 @@
                               "to manage this file\n"
                               "(use 'hg revert %s' to cancel the "
                               "pending addition)\n")
-                              % (f, 3 * st.st_size // 1000000, join(f)))
+                            % (f, 3 * st.st_size // 1000000, uipath(f)))
                 if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
                     ui.warn(_("%s not added: only files and symlinks "
-                              "supported currently\n") % join(f))
+                              "supported currently\n") % uipath(f))
                     rejected.append(f)
                 elif ds[f] in 'amn':
-                    ui.warn(_("%s already tracked!\n") % join(f))
+                    ui.warn(_("%s already tracked!\n") % uipath(f))
                 elif ds[f] == 'r':
                     ds.normallookup(f)
                 else:
@@ -1550,12 +1554,13 @@
             return rejected
 
     def forget(self, files, prefix=""):
-        join = lambda f: os.path.join(prefix, f)
         with self._repo.wlock():
+            ds = self._repo.dirstate
+            uipath = lambda f: ds.pathto(pathutil.join(prefix, f))
             rejected = []
             for f in files:
                 if f not in self._repo.dirstate:
-                    self._repo.ui.warn(_("%s not tracked!\n") % join(f))
+                    self._repo.ui.warn(_("%s not tracked!\n") % uipath(f))
                     rejected.append(f)
                 elif self._repo.dirstate[f] != 'a':
                     self._repo.dirstate.remove(f)
@@ -1566,9 +1571,10 @@
     def undelete(self, list):
         pctxs = self.parents()
         with self._repo.wlock():
+            ds = self._repo.dirstate
             for f in list:
                 if self._repo.dirstate[f] != 'r':
-                    self._repo.ui.warn(_("%s not removed!\n") % f)
+                    self._repo.ui.warn(_("%s not removed!\n") % ds.pathto(f))
                 else:
                     fctx = f in pctxs[0] and pctxs[0][f] or pctxs[1][f]
                     t = fctx.data()
@@ -1581,11 +1587,13 @@
         except OSError as err:
             if err.errno != errno.ENOENT:
                 raise
-            self._repo.ui.warn(_("%s does not exist!\n") % dest)
+            self._repo.ui.warn(_("%s does not exist!\n")
+                               % self._repo.dirstate.pathto(dest))
             return
         if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
             self._repo.ui.warn(_("copy failed: %s is not a file or a "
-                                 "symbolic link\n") % dest)
+                                 "symbolic link\n")
+                               % self._repo.dirstate.pathto(dest))
         else:
             with self._repo.wlock():
                 if self._repo.dirstate[dest] in '?':