Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 2.1, 2.1.1, and 2.1.2

Merge with stable

Changeset 1408d349ac7e

Parents 0865a2485b59

Parents 53ca55f9aa39

by Adrian Buehlmann

Changes to 6 files · Browse files at 1408d349ac7e Showing diff from parent 0865a2485b59 53ca55f9aa39 Diff from another changeset...

 
617
618
619
 
620
621
622
623
624
 
625
626
627
 
617
618
619
620
621
622
623
624
625
626
627
628
629
@@ -617,11 +617,13 @@
  self.commitButtonEnable.emit(False)   self.runner.run(*commandlines)   self.stopAction.setEnabled(True) + self.progress.emit(*cmdui.startProgress(_('Commit'), ''))     def stop(self):   self.runner.cancel()     def commandFinished(self, ret): + self.progress.emit(*cmdui.stopProgress(_('Commit')))   self.stopAction.setEnabled(False)   self.commitButtonEnable.emit(True)   self.repo.decrementBusyCount()
 
782
783
784
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
785
786
787
788
789
 
 
 
 
790
791
792
793
794
 
 
795
796
797
 
799
800
801
802
 
803
804
805
 
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
 
 
 
 
802
803
804
805
806
807
808
 
 
809
810
811
812
813
 
815
816
817
 
818
819
820
821
@@ -782,16 +782,32 @@
    # Capture drop events, try to import into current patch queue   + def detectPatches(self, paths): + filepaths = [] + for p in paths: + if not os.path.isfile(p): + continue + try: + pf = open(p, 'rb') + filename, message, user, date, branch, node, p1, p2 = \ + patch.extract(self.repo.ui, pf) + if filename: + filepaths.append(p) + os.unlink(filename) + except Exception, e: + pass + return filepaths +   def dragEnterEvent(self, event): - event.acceptProposedAction() - - def dragMoveEvent(self, event): - event.acceptProposedAction() + paths = [unicode(u.toLocalFile()) for u in event.mimeData().urls()] + if self.detectPatches(paths): + event.setDropAction(Qt.CopyAction) + event.accept()     def dropEvent(self, event):   paths = [unicode(u.toLocalFile()) for u in event.mimeData().urls()] - filepaths = [p for p in paths if os.path.isfile(p)] - if filepaths: + patches = self.detectPatches(paths) + if patches:   event.setDropAction(Qt.CopyAction)   event.accept()   else: @@ -799,7 +815,7 @@
  return   dlg = thgimport.ImportDialog(self.repo, self, mq=True)   dlg.finished.connect(dlg.deleteLater) - dlg.setfilepaths(filepaths) + dlg.setfilepaths(patches)   dlg.exec_()     # End drop events
 
9
10
11
12
 
13
14
15
 
435
436
437
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
439
440
 
441
442
443
444
445
446
447
448
449
450
 
 
 
 
 
 
451
452
453
 
9
10
11
 
12
13
14
15
 
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 
456
457
458
459
460
461
 
 
 
 
 
462
463
464
465
466
467
468
469
470
@@ -9,7 +9,7 @@
 import binascii  import os   -from mercurial import util, revset, error +from mercurial import util, revset, error, patch    from tortoisehg.util import shlib, hglib   @@ -435,19 +435,36 @@
  self.generateMultipleSelectionMenu()   self.generateBundleMenu()   + def detectPatches(self, paths): + filepaths = [] + for p in paths: + if not os.path.isfile(p): + continue + try: + pf = open(p, 'rb') + filename, message, user, date, branch, node, p1, p2 = \ + patch.extract(self.repo.ui, pf) + if filename: + filepaths.append(p) + os.unlink(filename) + except Exception, e: + pass + return filepaths +   def dragEnterEvent(self, event):   paths = [unicode(u.toLocalFile()) for u in event.mimeData().urls()] - if util.any(os.path.isfile(p) for p in paths): + if self.detectPatches(paths):   event.setDropAction(Qt.CopyAction)   event.accept()     def dropEvent(self, event):   paths = [unicode(u.toLocalFile()) for u in event.mimeData().urls()] - filepaths = [p for p in paths if os.path.isfile(p)] - if filepaths: - self.thgimport(filepaths) - event.setDropAction(Qt.CopyAction) - event.accept() + patches = self.detectPatches(paths) + if not patches: + return + event.setDropAction(Qt.CopyAction) + event.accept() + self.thgimport(patches)     ## Begin Workbench event forwards  
 
575
576
577
578
579
580
581
 
 
 
 
 
 
 
 
582
583
584
 
575
576
577
 
 
 
 
578
579
580
581
582
583
584
585
586
587
588
@@ -575,10 +575,14 @@
 _pctxcache = {}  def genPatchContext(repo, patchpath, rev=None):   global _pctxcache - if os.path.exists(patchpath) and patchpath in _pctxcache: - cachedctx = _pctxcache[patchpath] - if cachedctx._mtime == os.path.getmtime(patchpath): - return cachedctx + try: + if os.path.exists(patchpath) and patchpath in _pctxcache: + cachedctx = _pctxcache[patchpath] + if cachedctx._mtime == os.path.getmtime(patchpath) and \ + cachedctx._fsize == os.path.getsize(patchpath): + return cachedctx + except EnvironmentError: + pass   # create a new context object   ctx = patchctx(patchpath, repo, rev=rev)   _pctxcache[patchpath] = ctx
 
392
393
394
395
 
396
397
398
 
603
604
605
606
607
608
609
610
611
612
 
392
393
394
 
395
396
397
398
 
603
604
605
 
 
 
 
606
607
608
@@ -392,7 +392,7 @@
  for u in d.urls():   root = self.find_root(u)   if root: - self.openRepo(root) + self.showRepo(root)   accept = True   if accept:   event.setDropAction(Qt.LinkAction) @@ -603,10 +603,6 @@
  for rw in self._findrepowidget(root):   rw.goto(rev)   - def reloadRepository(self, root): - for rw in self._findrepowidget(root): - rw.reload() -   def _findrepowidget(self, root):   """Iterates RepoWidget for the specified root"""   tw = self.repoTabsWidget
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
44
45
46
 
 
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
 # patchctx.py - TortoiseHg patch context class  #  # Copyright 2011 Steve Borho <steve@borho.org>  #  # This software may be used and distributed according to the terms of the  # GNU General Public License version 2 or any later version.    import os  import sys  import shlex  import binascii  import cStringIO    from mercurial import patch, util  from mercurial import node  from mercurial.util import propertycache  from hgext import mq, record    from tortoisehg.util import hglib    class patchctx(object):   _parseErrorFileName = '*ParseError*'     def __init__(self, patchpath, repo, pf=None, rev=None):   """ Read patch context from file   :param pf: currently ignored   The provided handle is used to read the patch and   the patchpath contains the name of the patch.   The handle is NOT closed.   """   self._path = patchpath   self._patchname = os.path.basename(patchpath)   self._repo = repo   self._rev = rev or 'patch'   self._status = [[], [], []]   self._fileorder = []   self._user = ''   self._date = ''   self._desc = ''   self._branch = ''   self._node = node.nullid   self._identity = node.nullid   self._mtime = None + self._fsize = 0   self._parseerror = None     try: + self._mtime = os.path.getmtime(patchpath) + self._fsize = os.path.getsize(patchpath)   ph = mq.patchheader(self._path)   self._ph = ph - self._mtime = os.path.getmtime(patchpath)   hash = util.sha1(self._path)   hash.update(str(self._mtime))   self._identity = hash.digest()   except EnvironmentError:   return     try:   self._branch = ph.branch or ''   self._node = binascii.unhexlify(ph.nodeid)   except TypeError:   pass   except AttributeError:   # hacks to try to deal with older versions of mq.py   self._branch = ''   ph.diffstartline = len(ph.comments)   if ph.message:   ph.diffstartline += 1   self._user = ph.user or ''   self._date = ph.date and util.parsedate(ph.date) or util.makedate()   self._desc = ph.message and '\n'.join(ph.message).strip() or ''     def invalidate(self):   # ensure the patch contents are re-read   self._mtime = 0     def __contains__(self, key):   return key in self._files     def __str__(self): return node.short(self.node())   def node(self): return self._node   def files(self): return self._files.keys()   def rev(self): return self._rev   def hex(self): return node.hex(self.node())   def user(self): return self._user   def date(self): return self._date   def description(self): return self._desc   def branch(self): return self._branch   def parents(self): return ()   def tags(self): return ()   def bookmarks(self): return ()   def children(self): return ()   def extra(self): return {}   def p1(self): return None   def p2(self): return None     def flags(self, wfile):   if wfile == self._parseErrorFileName:   return ''   if wfile in self._files:   for gp in patch.readgitpatch(self._files[wfile][0].header):   if gp.mode:   islink, isexec = gp.mode   if islink:   return 'l'   elif wfile in self._status[1]:   # Do not report exec mode change if file is added   return ''   elif isexec:   return 'x'   else:   # techincally, this case could mean the file has had its   # exec bit cleared OR its symlink state removed   # TODO: change readgitpatch() to differentiate   return '-'   return ''     # TortoiseHg methods   def thgtags(self): return []   def thgwdparent(self): return False   def thgmqappliedpatch(self): return False   def thgmqpatchname(self): return self._patchname   def thgbranchhead(self): return False   def thgmqunappliedpatch(self): return True   def thgid(self): return self._identity     def longsummary(self):   summary = hglib.tounicode(self.description())   if self._repo.ui.configbool('tortoisehg', 'longsummary'):   limit = 80   lines = summary.splitlines()   if lines:   summary = lines.pop(0)   while len(summary) < limit and lines:   summary += u' ' + lines.pop(0)   summary = summary[0:limit]   else:   summary = ''   else:   lines = summary.splitlines()   summary = lines and lines[0] or ''     if summary and len(lines) > 1:   summary += u' \u2026' # ellipsis ...     return summary     def changesToParent(self, whichparent):   'called by filelistmodel to get list of files'   if whichparent == 0 and self._files:   return self._status   else:   return [], [], []     def thgmqpatchdata(self, wfile):   'called by fileview to get diff data'   if wfile == self._parseErrorFileName:   return '\n\n\nErrors while parsing patch:\n'+str(self._parseerror)   if wfile in self._files:   buf = cStringIO.StringIO()   for chunk in self._files[wfile]:   chunk.write(buf)   return buf.getvalue()   return ''     @propertycache   def _files(self):   if not hasattr(self, '_ph') or not self._ph.haspatch:   return {}     M, A, R = 0, 1, 2   def get_path(a, b):   type = (a == '/dev/null') and A or M   type = (b == '/dev/null') and R or type   rawpath = (b != '/dev/null') and b or a   if not (rawpath.startswith('a/') or rawpath.startswith('b/')):   return type, rawpath   return type, rawpath.split('/', 1)[-1]     files = {}   pf = open(self._path, 'rb')   try:   try:   # consume comments and headers   for i in range(self._ph.diffstartline):   pf.readline()   for chunk in record.parsepatch(pf):   if not isinstance(chunk, record.header):   continue   top = patch.parsefilename(chunk.header[-2])   bot = patch.parsefilename(chunk.header[-1])   type, path = get_path(top, bot)   if path not in chunk.files():   type, path = 0, chunk.files()[-1]   if path not in files:   self._status[type].append(path)   files[path] = [chunk]   self._fileorder.append(path)   files[path].extend(chunk.hunks)   except patch.PatchError, e:   self._status[2].append(self._parseErrorFileName)   files[self._parseErrorFileName] = []   self._parseerror = e   if 'THGDEBUG' in os.environ:   print e   finally:   pf.close()   return files