Plugins/VcsPlugins/vcsMercurial/hg.py

branch
Py2 comp.
changeset 2847
1843ef6e2656
parent 2791
a9577f248f04
parent 2844
a61ee61b1c2c
child 3057
10516539f238
--- a/Plugins/VcsPlugins/vcsMercurial/hg.py	Mon Aug 12 19:41:53 2013 +0200
+++ b/Plugins/VcsPlugins/vcsMercurial/hg.py	Mon Aug 12 22:21:53 2013 +0200
@@ -97,7 +97,9 @@
         self.log = None
         self.logBrowser = None
         self.diff = None
+        self.sbsDiff = None
         self.status = None
+        self.summary = None
         self.tagbranchList = None
         self.annotate = None
         self.repoEditor = None
@@ -161,8 +163,12 @@
             self.logBrowser.close()
         if self.diff is not None:
             self.diff.close()
+        if self.sbsDiff is not None:
+            self.sbsDiff.close()
         if self.status is not None:
             self.status.close()
+        if self.summary is not None:
+            self.summary.close()
         if self.tagbranchList is not None:
             self.tagbranchList.close()
         if self.annotate is not None:
@@ -368,7 +374,7 @@
             os.remove(os.path.join(projectDir, '.hgignore'))
         return status
     
-    def vcsCommit(self, name, message, noDialog=False, closeBranch=False):
+    def vcsCommit(self, name, message, noDialog=False, closeBranch=False, mq=False):
         """
         Public method used to make the change of a file/directory permanent in the
         Mercurial repository.
@@ -377,14 +383,19 @@
         @param message message for this operation (string)
         @param noDialog flag indicating quiet operations
         @keyparam closeBranch flag indicating a close branch commit (boolean)
+        @keyparam mq flag indicating a queue commit (boolean)
         """
         msg = message
         
+        if mq:
+            # ensure dialog is shown for a queue commit
+            noDialog = False
+        
         if not noDialog and not msg:
             # call CommitDialog and get message from there
             if self.__commitDialog is None:
                 from .HgCommitDialog import HgCommitDialog
-                self.__commitDialog = HgCommitDialog(self, self.__ui)
+                self.__commitDialog = HgCommitDialog(self, mq, self.__ui)
                 self.__commitDialog.accepted.connect(self.__vcsCommit_Step2)
             self.__commitDialog.show()
             self.__commitDialog.raise_()
@@ -394,6 +405,7 @@
         self.__commitData["msg"] = msg
         self.__commitData["noDialog"] = noDialog
         self.__commitData["closeBranch"] = closeBranch
+        self.__commitData["mq"] = mq
         
         if noDialog:
             self.__vcsCommit_Step2()
@@ -406,6 +418,7 @@
         msg = self.__commitData["msg"]
         noDialog = self.__commitData["noDialog"]
         closeBranch = self.__commitData["closeBranch"]
+        mq = self.__commitData["mq"]
         
         if not noDialog:
             # check, if there are unsaved changes, that should be committed
@@ -442,7 +455,6 @@
             msg = self.__commitDialog.logMessage()
             amend = self.__commitDialog.amend()
             commitSubrepositories = self.__commitDialog.commitSubrepositories()
-##            self.__commitDialog.accepted.disconnect(self.__vcsCommit_Step2)
             self.__commitDialog.deleteLater()
             self.__commitDialog = None
         else:
@@ -457,12 +469,15 @@
         self.addArguments(args, self.options['global'])
         self.addArguments(args, self.options['commit'])
         args.append("-v")
-        if closeBranch:
-            args.append("--close-branch")
-        if amend:
-            args.append("--amend")
-        if commitSubrepositories:
-            args.append("--subrepos")
+        if mq:
+            args.append("--mq")
+        else:
+            if closeBranch:
+                args.append("--close-branch")
+            if amend:
+                args.append("--amend")
+            if commitSubrepositories:
+                args.append("--subrepos")
         if msg:
             args.append("--message")
             args.append(msg)
@@ -753,6 +768,7 @@
         @param name file/directory name to show the log of (string)
         """
         dname, fname = self.splitPath(name)
+        isFile = os.path.isfile(name)
         
         # find the root of the repo
         repodir = dname
@@ -778,7 +794,7 @@
         if dlg.exec_() == QDialog.Accepted:
             revs, noEntries = dlg.getRevisions()
             from .HgLogDialog import HgLogDialog
-            self.log = HgLogDialog(self)
+            self.log = HgLogDialog(self, isFile=isFile)
             self.log.show()
             self.log.start(name, noEntries=noEntries, revisions=revs)
     
@@ -825,6 +841,18 @@
         self.status.show()
         self.status.start(name)
     
+    def hgSummary(self, mq=False):
+        """
+        Public method used to show some summary information of the
+        working directory state.
+        
+        @param mq flag indicating to show the queue status as well (boolean)
+        """
+        from .HgSummaryDialog import HgSummaryDialog
+        self.summary = HgSummaryDialog(self)
+        self.summary.show()
+        self.summary.start(self.__projectHelper.getProject().getProjectPath(), mq=mq)
+    
     def vcsTag(self, name):
         """
         Public method used to set the tag in the Mercurial repository.
@@ -1254,8 +1282,6 @@
         @param ppath local path to get the repository infos (string)
         @return string with ready formated info for display (string)
         """
-        info = []
-        
         args = []
         args.append('parents')
         args.append('--template')
@@ -1276,13 +1302,14 @@
         else:
             output, error = self.__client.runcommand(args)
         
+        infoBlock = []
         if output:
             index = 0
             for line in output.splitlines():
                 index += 1
                 changeset, tags, author, date, branches, bookmarks = line.split("@@@")
                 cdate, ctime = date.split()[:2]
-                info.append("""<p><table>""")
+                info = []
                 info.append(QApplication.translate("mercurial",
                     """<tr><td><b>Parent #{0}</b></td><td></td></tr>\n"""
                     """<tr><td><b>Changeset</b></td><td>{1}</td></tr>""")\
@@ -1304,7 +1331,11 @@
                     """<tr><td><b>Committed date</b></td><td>{1}</td></tr>\n"""
                     """<tr><td><b>Committed time</b></td><td>{2}</td></tr>""")\
                     .format(author, cdate, ctime))
-                info.append("""</table></p>""")
+                infoBlock.append("\n".join(info))
+        if infoBlock:
+            infoStr = """<tr></tr>{0}""".format("<tr></tr>".join(infoBlock))
+        else:
+            infoStr = ""
         
         url = ""
         args = []
@@ -1335,9 +1366,9 @@
             """<tr><td><b>Mercurial V.</b></td><td>{0}</td></tr>\n"""
             """<tr></tr>\n"""
             """<tr><td><b>URL</b></td><td>{1}</td></tr>\n"""
+            """{2}"""
             """</table></p>\n"""
-            """{2}"""
-            ).format(self.versionStr, url, "\n".join(info))
+            ).format(self.versionStr, url, infoStr)
 
     ############################################################################
     ## Private Mercurial specific methods are below.
@@ -1605,15 +1636,137 @@
             self.diff.show()
             self.diff.start(name, revisions)
     
-    def hgLogBrowser(self, path):
+    def __hgGetFileForRevision(self, name, rev=""):
+        """
+        Private method to get a file for a specific revision from the repository.
+        
+        @param name file name to get from the repository (string)
+        @keyparam rev revision to retrieve (string)
+        @return contents of the file (string) and an error message (string)
+        """
+        args = []
+        args.append("cat")
+        if rev:
+            args.append("--rev")
+            args.append(rev)
+        args.append(name)
+        
+        if self.__client is None:
+            output = ""
+            error = ""
+            
+            # find the root of the repo
+            repodir = self.splitPath(name)[0]
+            while not os.path.isdir(os.path.join(repodir, self.adminDir)):
+                repodir = os.path.dirname(repodir)
+                if os.path.splitdrive(repodir)[1] == os.sep:
+                    return
+            
+            process = QProcess()
+            process.setWorkingDirectory(repodir)
+            process.start('hg', args)
+            procStarted = process.waitForStarted(5000)
+            if procStarted:
+                finished = process.waitForFinished(30000)
+                if finished:
+                    if process.exitCode() == 0:
+                        output = str(process.readAllStandardOutput(),
+                            Preferences.getSystem("IOEncoding"), 'replace')
+                    else:
+                        error = str(process.readAllStandardError(),
+                            Preferences.getSystem("IOEncoding"), 'replace')
+                else:
+                    error = self.trUtf8("The hg process did not finish within 30s.")
+            else:
+                error = self.trUtf8('The process {0} could not be started. '
+                    'Ensure, that it is in the search path.').format('hg')
+        else:
+            output, error = self.__client.runcommand(args)
+        
+        return output, error
+    
+    def hgSbsDiff(self, name, extended=False, revisions=None):
+        """
+        Public method used to view the difference of a file to the Mercurial repository
+        side-by-side.
+        
+        @param name file name to be diffed (string)
+        @keyparam extended flag indicating the extended variant (boolean)
+        @keyparam revisions tuple of two revisions (tuple of strings)
+        """
+        if isinstance(name, list):
+            raise ValueError("Wrong parameter type")
+        
+        if extended:
+            # find the root of the repo
+            repodir = self.splitPath(name)[0]
+            while not os.path.isdir(os.path.join(repodir, self.adminDir)):
+                repodir = os.path.dirname(repodir)
+                if os.path.splitdrive(repodir)[1] == os.sep:
+                    return
+            
+            if self.isExtensionActive("bookmarks"):
+                bookmarksList = \
+                    self.getExtensionObject("bookmarks").hgGetBookmarksList(repodir)
+            else:
+                bookmarksList = None
+            
+            from .HgRevisionsSelectionDialog import HgRevisionsSelectionDialog
+            dlg = HgRevisionsSelectionDialog(self.hgGetTagsList(repodir),
+                                             self.hgGetBranchesList(repodir),
+                                             bookmarksList)
+            if dlg.exec_() == QDialog.Accepted:
+                rev1, rev2 = dlg.getRevisions()
+        elif revisions:
+            rev1, rev2 = revisions[0], revisions[1]
+        else:
+            rev1, rev2 = "", ""
+        
+        output1, error = self.__hgGetFileForRevision(name, rev=rev1)
+        if error:
+            E5MessageBox.critical(self.__ui,
+                self.trUtf8("Mercurial Side-by-Side Difference"),
+                error)
+            return
+        name1 = "{0} (rev. {1})".format(name, rev1 and rev1 or ".")
+        
+        if rev2:
+            output2, error = self.__hgGetFileForRevision(name, rev=rev2)
+            if error:
+                E5MessageBox.critical(self.__ui,
+                    self.trUtf8("Mercurial Side-by-Side Difference"),
+                    error)
+                return
+            name2 = "{0} (rev. {1})".format(name, rev2)
+        else:
+            try:
+                f1 = open(name, "r", encoding="utf-8")
+                output2 = f1.read()
+                f1.close()
+                name2 = name
+            except IOError:
+                E5MessageBox.critical(self.__ui,
+                    self.trUtf8("Mercurial Side-by-Side Difference"),
+                    self.trUtf8("""<p>The file <b>{0}</b> could not be read.</p>""")
+                        .format(name))
+                return
+        
+        if self.sbsDiff is None:
+            from UI.CompareDialog import CompareDialog
+            self.sbsDiff = CompareDialog()
+        self.sbsDiff.show()
+        self.sbsDiff.compare(output1, output2, name1, name2)
+    
+    def hgLogBrowser(self, path, isFile=False):
         """
         Public method used to browse the log of a file/directory from the
         Mercurial repository.
         
         @param path file/directory name to show the log of (string)
+        @keyparam isFile flag indicating log for a file is to be shown (boolean)
         """
         from .HgLogBrowserDialog import HgLogBrowserDialog
-        self.logBrowser = HgLogBrowserDialog(self)
+        self.logBrowser = HgLogBrowserDialog(self, isFile=isFile)
         self.logBrowser.show()
         self.logBrowser.start(path)
     
@@ -2716,6 +2869,39 @@
             self.checkVCSStatus()
         return res
     
+    def hgArchive(self):
+        """
+        Public method to create an unversioned archive from the repository.
+        """
+        # find the root of the repo
+        repodir = self.__projectHelper.getProject().getProjectPath()
+        while not os.path.isdir(os.path.join(repodir, self.adminDir)):
+            repodir = os.path.dirname(repodir)
+            if os.path.splitdrive(repodir)[1] == os.sep:
+                return
+        
+        from .HgArchiveDialog import HgArchiveDialog
+        dlg = HgArchiveDialog(self)
+        if dlg.exec_() == QDialog.Accepted:
+            archive, type_, prefix, subrepos = dlg.getData()
+            
+            args = []
+            args.append("archive")
+            if type_:
+                args.append("--type")
+                args.append(type_)
+            if prefix:
+                args.append("--prefix")
+                args.append(prefix)
+            if subrepos:
+                args.append("--subrepos")
+            args.append(archive)
+            
+            dia = HgDialog(self.trUtf8("Create Unversioned Archive"), self)
+            res = dia.startProcess(args, repodir)
+            if res:
+                dia.exec_()
+    
     ############################################################################
     ## Methods to deal with subrepositories are below.
     ############################################################################

eric ide

mercurial