Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 0.9, 0.9.1, and 0.9.1.1

merge with stable

Changeset ae3e57241d37

Parents 4baaab6cd08d

Parents ed5d831928be

by Steve Borho

Changes to 17 files · Browse files at ae3e57241d37 Showing diff from parent 4baaab6cd08d ed5d831928be Diff from another changeset...

Change 1 of 2 Show Entire File hggtk/​about.py Stacked
 
55
56
57
58
 
59
60
61
 
62
63
64
 
74
75
76
77
 
78
79
80
 
55
56
57
 
58
59
60
 
61
62
63
64
 
74
75
76
 
77
78
79
80
@@ -55,10 +55,10 @@
    self.set_website("http://bitbucket.org/tortoisehg/stable/")   self.set_name("TortoiseHg") - self.set_version("(version %s)" % version.version()) + self.set_version(_("(version %s)") % version.version())   if hasattr(self, 'set_wrap_license'):   self.set_wrap_license(True) - self.set_copyright("Copyright 2009 TK Soh and others") + self.set_copyright(_("Copyright 2009 TK Soh and others"))     thg_logo = paths.get_tortoise_icon('thg_logo_92x50.png')   thg_icon = paths.get_tortoise_icon('thg_logo.ico') @@ -74,7 +74,7 @@
  license = hgtk.shortlicense.splitlines()[1:]   self.set_license('\n'.join(license))   - self.set_comments("with " + lib_versions + "\n\n" + comment) + self.set_comments(_("with %s") % lib_versions + "\n\n" + comment)   self.set_logo(gtk.gdk.pixbuf_new_from_file(thg_logo))   self.set_icon_from_file(thg_icon)   self.connect('response', self.response)
Change 1 of 1 Show Entire File hggtk/​archive.py Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
209
210
@@ -0,0 +1,210 @@
+# archive.py - TortoiseHg's dialog for archiving a repo revision +# +# Copyright 2009 Emmanuel Rosa <goaway1000@gmail.com> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2, incorporated herein by reference. + +import os +import gtk +import gobject +import pango + +from mercurial import hg, ui + +from thgutil.i18n import _ +from thgutil import hglib, paths + +from hggtk import hgcmd, gtklib + +_working_dir_parent_ = _('= Working Directory Parent =') + +class ArchiveDialog(gtk.Window): + """ Dialog to archive a Mercurial repo """ + def __init__(self, rev=None): + """ Initialize the Dialog """ + gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) + gtklib.set_tortoise_icon(self, 'menucheckout.ico') + gtklib.set_tortoise_keys(self) + + self.set_default_size(550, 120) + self.notify_func = None + + try: + repo = hg.repository(ui.ui(), path=paths.find_root()) + except hglib.RepoError: + gobject.idle_add(self.destroy) + return + + title = _('Archive - %s') % hglib.toutf(os.path.basename(repo.root)) + self.set_title(title) + + vbox = gtk.VBox() + self.add(vbox) + + hbox = gtk.HBox() + lbl = gtk.Label(_('Archive revision:')) + hbox.pack_start(lbl, False, False, 2) + + # revisions editable combo box + combo = gtk.combo_box_entry_new_text() + hbox.pack_start(combo, True, True, 2) + vbox.pack_start(hbox, False, False, 10) + if rev: + combo.append_text(str(rev)) + else: + combo.append_text(_working_dir_parent_) + combo.set_active(0) + for b in repo.branchtags(): + combo.append_text(b) + tags = list(repo.tags()) + tags.sort() + tags.reverse() + for t in tags: + combo.append_text(t) + + vbox.add(self.get_destination_container(self.get_default_path())) + vbox.add(self.get_type_container()) + + hbbox = gtk.HButtonBox() + hbbox.set_layout(gtk.BUTTONBOX_END) + vbox.pack_start(hbbox, False, False, 2) + close = gtk.Button(_('Close')) + close.connect('clicked', lambda x: self.destroy()) + + accelgroup = gtk.AccelGroup() + self.add_accel_group(accelgroup) + key, modifier = gtk.accelerator_parse('Escape') + close.add_accelerator('clicked', accelgroup, key, 0, + gtk.ACCEL_VISIBLE) + hbbox.add(close) + + archive = gtk.Button(_('Archive')) + archive.connect('clicked', self.archive, combo, repo) + mod = gtklib.get_thg_modifier() + key, modifier = gtk.accelerator_parse(mod+'Return') + archive.add_accelerator('clicked', accelgroup, key, modifier, + gtk.ACCEL_VISIBLE) + hbbox.add(archive) + archive.grab_focus() + + entry = combo.child + entry.connect('activate', self.entry_activated, archive, combo, repo) + + def get_type_container(self): + """Return a frame containing the supported archive types""" + frame = gtk.Frame(_('Archive type')) + vbox = gtk.VBox() + + self.filesradio = gtk.RadioButton(None, _('Directory of files')) + self.tarradio = gtk.RadioButton(self.filesradio, _('Uncompressed tar archive')) + self.tbz2radio = gtk.RadioButton(self.filesradio, _('Tar archive compressed using bzip2')) + self.tgzradio = gtk.RadioButton(self.filesradio, _('Tar archive compressed using gzip')) + self.uzipradio = gtk.RadioButton(self.filesradio, _('Uncompressed zip archive')) + self.zipradio = gtk.RadioButton(self.filesradio, _('Zip archive compressed using deflate')) + + vbox.pack_start(self.filesradio, True, True, 2) + vbox.pack_start(self.tarradio, True, True, 2) + vbox.pack_start(self.tbz2radio, True, True, 2) + vbox.pack_start(self.tgzradio, True, True, 2) + vbox.pack_start(self.uzipradio, True, True, 2) + vbox.pack_start(self.zipradio, True, True, 2) + frame.add(vbox) + frame.set_border_width(2) + return frame + + def get_destination_container(self, default_path): + """Return an hbox containing the widgets for the destination path""" + hbox = gtk.HBox() + lbl = gtk.Label(_('Destination Path:')) + + # create drop-down list for source paths + self.destlist = gtk.ListStore(str) + destcombo = gtk.ComboBoxEntry(self.destlist, 0) + self.destentry = destcombo.get_child() + self.destentry.set_text(default_path) + self.destentry.set_position(-1) + + # replace the drop-down widget so we can modify it's properties + destcombo.clear() + cell = gtk.CellRendererText() + cell.set_property('ellipsize', pango.ELLIPSIZE_MIDDLE) + destcombo.pack_start(cell) + destcombo.add_attribute(cell, 'text', 0) + + destbrowse = gtk.Button(_('Browse...')) + destbrowse.connect('clicked', self.browse_clicked) + hbox.pack_start(lbl, False, False) + hbox.pack_start(destcombo, True, True, 2) + hbox.pack_end(destbrowse, False, False, 5) + return hbox + + def get_default_path(self): + """Return the default destination path""" + return hglib.toutf(os.getcwd()) + + def get_save_file_dialog(self, filter): + """Return a configured save file dialog""" + return gtklib.NativeSaveFileDialogWrapper( + InitialDir=self.destentry.get_text(), + Title=_('Select Destination File'), + Filter=filter) + + def get_selected_archive_type(self): + """Return a dictionary describing the selected archive type""" + dict = {} + if self.tarradio.get_active(): + dict['type'] = 'tar' + dict['filter'] = ((_('Tar archives'), '*.tar'),) + elif self.tbz2radio.get_active(): + dict['type'] = 'tbz2' + dict['filter'] = ((_('Bzip2 tar archives'), '*.tbz2'),) + elif self.tgzradio.get_active(): + dict['type'] = 'tgz' + dict['filter'] = ((_('Gzip tar archives'), '*.tgz'),) + elif self.uzipradio.get_active(): + dict['type'] = 'uzip' + dict['filter'] = ((_('Uncompressed zip archives'), '*.uzip'),) + elif self.zipradio.get_active(): + dict['type'] = 'zip' + dict['filter'] = ((_('Compressed zip archives'), '*.zip'),) + else: + dict['type'] = 'files' + + return dict + + def entry_activated(self, entry, button, combo, repo): + self.update(button, combo, repo) + + def browse_clicked(self, button): + """Select the destination directory or file""" + archive_type = self.get_selected_archive_type() + if archive_type['type'] == 'files': + response = gtklib.NativeFolderSelectDialog( + initial=self.destentry.get_text(), + title=_('Select Destination Folder')).run() + else: + filter = archive_type['filter'] + response = self.get_save_file_dialog(filter).run() + + if response: + self.destentry.set_text(response) + + def archive(self, button, combo, repo): + rev = combo.get_active_text() + + cmdline = ['hg', 'archive', '--verbose'] + if rev != _working_dir_parent_: + cmdline.append('--rev') + cmdline.append(rev) + + cmdline.append('-t') + cmdline.append(self.get_selected_archive_type()['type']) + cmdline.append(hglib.fromutf(self.destentry.get_text())) + + dlg = hgcmd.CmdDialog(cmdline) + dlg.run() + dlg.hide() + +def run(ui, *pats, **opts): + return ArchiveDialog(opts.get('rev'))
 
153
154
155
 
 
 
 
 
 
156
157
158
 
162
163
164
165
166
167
 
 
 
 
 
 
 
 
 
 
168
169
170
 
423
424
425
 
 
 
426
427
428
 
435
436
437
 
 
 
438
 
439
 
440
441
442
 
153
154
155
156
157
158
159
160
161
162
163
164
 
168
169
170
 
 
 
171
172
173
174
175
176
177
178
179
180
181
182
183
 
436
437
438
439
440
441
442
443
444
 
451
452
453
454
455
456
457
458
459
460
461
462
463
@@ -153,6 +153,12 @@
  if ctx.branch() != 'default':   title_line(_('branch:'), ctx.branch(), 'greybg')   title_line(_('user/date:'), ctx.user() + '\t' + date, 'changeset') + + if len(ctx.parents()) == 2 and self.parent_toggle.get_active(): + parentindex = 1 + else: + parentindex = 0 +   for pctx in ctx.parents():   try:   summary = pctx.description().splitlines()[0] @@ -162,9 +168,16 @@
  change = str(pctx.rev()) + ' : ' + str(pctx)   title = _('parent:')   title += ' ' * (12 - len(title)) - buf.insert_with_tags_by_name(eob, title, 'parent') - buf.insert_with_tags_by_name(eob, change, 'link') - buf.insert_with_tags_by_name(eob, ' ' + summary, 'parent') + + if len(ctx.parents()) == 2 and pctx == ctx.parents()[parentindex]: + buf.insert_with_tags_by_name(eob, title, 'parenthl') + buf.insert_with_tags_by_name(eob, change, 'linkhl') + buf.insert_with_tags_by_name(eob, ' ' + summary, 'parenthl') + else: + buf.insert_with_tags_by_name(eob, title, 'parent') + buf.insert_with_tags_by_name(eob, change, 'link') + buf.insert_with_tags_by_name(eob, ' ' + summary, 'parent') +   buf.insert(eob, "\n")   for cctx in ctx.children():   try: @@ -423,6 +436,9 @@
  paragraph_background='#F0F0F0'))   tag_table.add(make_texttag('parent', foreground='#000090',   paragraph_background='#F0F0F0')) + tag_table.add(make_texttag('parenthl', foreground='#000090', + paragraph_background='#F0F0F0', + weight=pango.WEIGHT_BOLD ))     tag_table.add( make_texttag( 'mono', family='Monospace' ))   tag_table.add( make_texttag( 'blue', foreground='blue' )) @@ -435,8 +451,13 @@
  tag_table.add( make_texttag( 'yellowbg', background='yellow' ))   link_tag = make_texttag( 'link', foreground='blue',   underline=pango.UNDERLINE_SINGLE ) + linkhl_tag = make_texttag( 'linkhl', foreground='blue', + underline=pango.UNDERLINE_SINGLE, + weight=pango.WEIGHT_BOLD )   link_tag.connect('event', self.link_event ) + linkhl_tag.connect('event', self.link_event )   tag_table.add( link_tag ) + tag_table.add( linkhl_tag )     def file_button_release(self, widget, event):   if event.button == 3 and not (event.state & (gtk.gdk.SHIFT_MASK |
Change 1 of 1 Show Entire File hggtk/​commit.py Stacked
 
475
476
477
478
479
480
 
481
482
483
484
485
486
487
 
475
476
477
 
 
 
478
479
 
 
 
480
481
482
@@ -475,13 +475,8 @@
  if dopatch:   try:   pfiles = {} - if patch.patchfile.__bases__: - # Mercurial 1.3 - patch.internalpatch(fp, ui, 1, repo.root, files=pfiles, + patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,   eolmode=None) - else: - # Mercurial 1.2 - patch.internalpatch(fp, ui, 1, repo.root, files=pfiles)   patch.updatedir(ui, repo, pfiles)   except patch.PatchError, err:   s = str(err)
Change 1 of 2 Show Entire File hggtk/​datamine.py Stacked
 
223
224
225
226
 
227
228
229
 
449
450
451
452
 
453
 
 
 
454
455
456
 
223
224
225
 
226
227
228
229
 
449
450
451
 
452
453
454
455
456
457
458
459
@@ -223,7 +223,7 @@
  search_hbox.pack_start(includes, True, True, 4)   search_hbox.pack_start(gtk.Label(_('Excludes:')), False, False, 4)   search_hbox.pack_start(excludes, True, True, 4) - search_hbox.pack_start(search, False, False) + search_hbox.pack_start(search, False, False, 4)   self.tooltips.set_tip(search, _('Start this search'))   self.tooltips.set_tip(regexp, _('Regular expression search pattern'))   self.tooltips.set_tip(includes, _('Comma separated list of' @@ -449,8 +449,11 @@
  def close_page(self, button, widget):   '''Close page button has been pressed'''   num = self.notebook.page_num(widget) - if num != -1 and self.notebook.get_n_pages() > 1: + if num != -1:   self.notebook.remove_page(num) + if self.notebook.get_n_pages() <= 1: + self.newpagecount = 1 + self.add_search_page()     def add_header_context_menu(self, col, menu):   lb = gtk.Label(col.get_title())
Change 1 of 2 Show Entire File hggtk/​gdialog.py Stacked
 
47
48
49
50
 
51
52
53
 
 
54
55
56
 
58
59
60
61
 
62
63
 
64
65
66
67
 
68
69
70
 
47
48
49
 
50
51
 
 
52
53
54
55
56
 
58
59
60
 
61
62
 
63
64
65
66
 
67
68
69
70
@@ -47,10 +47,10 @@
 class CustomPrompt(gtk.MessageDialog):   ''' Custom prompt dialog. Provide a list of choices with ampersands   to delineate response given for each choice (and keyboard - accelerator). Default must be one of the choice responses. + accelerator). Default must be the index of one of the choice responses.   ''' - # ret = CustomPrompt('Title', 'Message', self, ('&Yes', 'N&o'), 'o').run() - # ret will be (gtk.RESPONSE_DELETE_EVENT, ord('y'), or ord('o')) + # ret = CustomPrompt('Title', 'Message', self, ('&Yes', 'N&o'), 1).run() + # ret will be (gtk.RESPONSE_DELETE_EVENT, 0 (for yes), or 1 (for no)   def __init__(self, title, message, parent, choices, default=None):   gtk.MessageDialog.__init__(self, parent, gtk.DIALOG_MODAL,   gtk.MESSAGE_QUESTION) @@ -58,13 +58,13 @@
  self.format_secondary_markup('<b>' + hglib.toutf(message) + '</b>')   accel_group = gtk.AccelGroup()   self.add_accel_group(accel_group) - for s in choices: + for i, s in enumerate(choices):   char = s[s.index('&')+1].lower() - button = self.add_button(s.replace('&', '_'), ord(char)) + button = self.add_button(s.replace('&', '_'), i)   button.add_accelerator('clicked', accel_group, ord(char), 0,   gtk.ACCEL_VISIBLE)   if default: - self.set_default_response(ord(default)) + self.set_default_response(default)     def run(self):   response = gtklib.MessageDialog.run(self)
Change 1 of 2 Show Entire File hggtk/​hgshelve.py Stacked
 
430
431
432
433
 
434
435
436
 
502
503
504
505
506
507
508
509
510
 
511
512
513
 
430
431
432
 
433
434
435
436
 
502
503
504
 
 
 
 
 
 
505
506
507
508
@@ -430,7 +430,7 @@
    ? - display help'''   - if not hglib.calliffunc(ui.interactive): + if not ui.interactive():   raise util.Abort(_('shelve can only be run interactively'))     forced = opts['force'] or opts['append'] @@ -502,12 +502,7 @@
  if dopatch:   ui.debug(_('applying patch\n'))   ui.debug(fp.getvalue()) - if patch.patchfile.__bases__: - # Mercurial 1.3 - patch.internalpatch(fp, ui, 1, repo.root, eolmode=None) - else: - # Mercurial 1.2 - patch.internalpatch(fp, ui, 1, repo.root) + patch.internalpatch(fp, ui, 1, repo.root, eolmode=None)   del fp     # 3c. apply filtered patch to clean repo (shelve)
Change 1 of 5 Show Entire File hggtk/​hgthread.py Stacked
 
24
25
26
27
28
29
30
31
32
33
34
 
 
35
36
37
 
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
 
143
144
145
146
 
147
148
149
 
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
 
186
187
188
189
 
190
191
192
 
24
25
26
 
 
 
 
 
 
 
 
27
28
29
30
31
 
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
 
143
144
145
 
146
147
148
149
 
155
156
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
159
160
161
162
163
 
169
170
171
 
172
173
 
 
@@ -24,14 +24,8 @@
  main thread to pickup.   '''   def __init__(self, src=None, outputq=None, errorq=None, dialogq=None, - responseq=None, parentui=None): - if parentui: - # Mercurial 1.2 - super(GtkUi, self).__init__(parentui=parentui) - src = parentui - else: - # Mercurial 1.3 - super(GtkUi, self).__init__(src) + responseq=None): + super(GtkUi, self).__init__(src)   if src:   self.outputq = src.outputq   self.errorq = src.errorq @@ -57,28 +51,34 @@
  pass     def prompt(self, msg, choices=None, default="y"): - import re - if not hglib.calliffunc(self.interactive): return default - if isinstance(choices, str): - pat = choices - choices = None - else: - pat = None - while True: - try: - # send request to main thread, await response - self.dialogq.put( (msg, True, choices, default) ) - r = self.responseq.get(True) - if r is None: - raise EOFError - if not r: - return default - if not pat or re.match(pat, r): - return r - else: - self.write(_('unrecognized response\n')) - except EOFError: - raise util.Abort(_('response expected')) + if not self.interactive(): return default + try: + # send request to main thread, await response + self.dialogq.put( (msg, True, choices, default) ) + r = self.responseq.get(True) + if r is None: + raise EOFError + if not r: + return default + if choices: + # return char for Mercurial 1.3 + choice = choices[r] + return choice[choice.index("&")+1].lower() + return r + except EOFError: + raise util.Abort(_('response expected')) + + def promptchoice(self, msg, choices, default=0): + if not self.interactive(): return default + try: + # send request to main thread, await response + self.dialogq.put( (msg, True, choices, default) ) + r = self.responseq.get(True) + if r is None: + raise EOFError + return r + except EOFError: + raise util.Abort(_('response expected'))     def getpass(self, prompt=None, default=None):   # send request to main thread, await response @@ -143,7 +143,7 @@
  if response_id == gtk.RESPONSE_DELETE_EVENT:   self.responseq.put(None)   else: - self.responseq.put(chr(response_id)) + self.responseq.put(response_id)     def dialog_response(self, dialog, response_id):   if response_id == gtk.RESPONSE_OK: @@ -155,26 +155,9 @@
    def run(self):   try: - ret = None - if hasattr(self.ui, 'copy'): - # Mercurial 1.3 - for k, v in self.ui.configitems('defaults'): - self.ui.setconfig('defaults', k, '') - ret = hglib.dispatch._dispatch(self.ui, self.args) - else: - # Mercurial 1.2 - # Some commands create repositories, and thus must create - # new ui() instances. For those, we monkey-patch ui.ui() - # as briefly as possible. - origui = None - if self.args[0] in ('clone', 'init'): - origui = ui.ui - ui.ui = GtkUi - try: - ret = hglib.thgdispatch(self.ui, None, self.args) - finally: - if origui: - ui.ui = origui + for k, v in self.ui.configitems('defaults'): + self.ui.setconfig('defaults', k, '') + ret = hglib.dispatch._dispatch(self.ui, self.args)   if ret:   self.ui.write(_('[command returned code %d]\n') % int(ret))   else: @@ -186,7 +169,5 @@
  self.ui.write_err(_('abort: ') + str(e) + '\n')   except (hglib.RepoError, urllib2.HTTPError), e:   self.ui.write_err(str(e) + '\n') - except Exception, e: + except (Exception, OSError, IOError), e:   self.ui.write_err(str(e) + '\n') - except hglib.WinIOError, e: - self.ui.write_err(str(e) + '\n')
Change 1 of 12 Show Entire File hggtk/​hgtk.py Stacked
 
57
58
59
 
60
61
62
63
64
65
 
66
67
68
 
 
69
70
 
 
 
71
72
73
 
204
205
206
 
 
207
208
209
 
243
244
245
246
 
 
 
247
248
249
 
262
263
264
265
 
266
267
268
 
277
278
279
280
281
282
 
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
 
299
300
301
302
 
303
304
305
306
307
308
 
309
310
311
312
313
314
315
316
 
317
318
319
320
321
322
323
 
324
325
326
327
 
 
 
 
 
328
329
330
331
 
332
333
334
335
336
337
 
338
339
340
341
342
343
 
344
345
346
347
348
349
 
350
351
352
353
354
355
 
356
357
358
359
360
361
 
362
363
364
365
366
367
 
368
369
370
371
372
373
 
374
375
376
377
378
379
 
380
381
382
383
384
385
 
386
387
388
389
390
391
 
392
393
394
395
 
396
397
 
398
399
400
401
402
403
404
405
406
407
408
 
409
410
411
412
413
414
 
415
416
417
418
419
420
 
421
422
423
 
457
458
459
460
 
461
462
463
 
589
590
591
592
 
593
594
595
 
601
602
603
604
605
 
 
606
607
608
 
633
634
635
 
 
 
 
 
636
637
638
 
663
664
665
666
 
667
668
669
 
698
699
700
 
 
 
701
 
57
58
59
60
61
62
63
64
65
 
66
67
 
 
68
69
70
 
71
72
73
74
75
76
 
207
208
209
210
211
212
213
214
 
248
249
250
 
251
252
253
254
255
256
 
269
270
271
 
272
273
274
275
 
284
285
286
 
287
 
288
289
290
291
 
 
 
 
 
 
 
 
 
292
293
294
 
296
297
298
 
299
300
301
302
 
303
 
304
305
306
307
 
308
 
309
 
310
311
312
313
 
314
315
 
316
317
318
319
 
320
321
322
323
324
325
 
 
 
326
327
328
329
 
330
 
331
332
333
334
 
335
 
336
337
338
339
 
340
 
341
342
343
344
 
345
 
346
347
348
349
 
350
 
351
352
353
354
 
355
 
356
357
358
359
 
360
 
361
362
363
364
 
365
 
366
367
368
369
 
370
 
371
372
373
374
 
375
 
376
377
378
 
 
379
380
 
381
382
383
384
 
385
386
387
388
389
390
 
391
392
393
394
 
395
 
396
397
398
399
 
400
 
401
402
403
404
 
438
439
440
 
441
442
443
444
 
570
571
572
 
573
574
575
576
 
582
583
584
 
 
585
586
587
588
589
 
614
615
616
617
618
619
620
621
622
623
624
 
649
650
651
 
652
653
654
655
 
684
685
686
687
688
689
690
@@ -57,17 +57,20 @@
  opts = {}   opts['cmd'] = ' '.join(sys.argv[1:])   opts['error'] = error + opts['nofork'] = True   if gtkmainalive:   dlg = run(u, **opts)   dlg.display()   dlg.show_all()   else: - gtkrun(run(u, **opts)) + gtkrun(run, u, **opts)   -def portable_fork(): - if 'THG_HGTK_SPAWN' in os.environ or '--nofork' in sys.argv: +def portable_fork(ui, opts): + if 'THG_HGTK_SPAWN' in os.environ:   return - if '--repository' in sys.argv or '-R' in sys.argv: + if opts.get('nofork') or opts.get('repository'): + return + if not ui.configbool('tortoisehg', 'hgtkfork', True):   return   # Spawn background process and exit   if hasattr(sys, "frozen"): @@ -204,6 +207,8 @@
  path = ui.expandpath(options['repository'])   cmdoptions['repository'] = path   os.chdir(path) + if options['nofork']: + cmdoptions['nofork'] = True   path = paths.find_root(os.getcwd())   if path:   try: @@ -243,7 +248,9 @@
  if mainwindow.should_live(): return   mainwindow.destroy()   -def gtkrun(win): +def gtkrun(dlgfunc, ui, *args, **opts): + portable_fork(ui, opts) + win = dlgfunc(ui, *args, **opts)   global mainwindow, gtkmainalive   mainwindow = win   if hasattr(win, 'display'): @@ -262,7 +269,7 @@
 def about(ui, *pats, **opts):   """about TortoiseHg"""   from hggtk.about import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def add(ui, *pats, **opts):   """add files""" @@ -277,21 +284,11 @@
   def clone(ui, *pats, **opts):   """clone tool""" - portable_fork()   from hggtk.clone import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def commit(ui, *pats, **opts):   """commit tool""" - ct = ui.config('tortoisehg', 'extcommit', None) - if ct == 'qct': - from mercurial import dispatch as _dispatch - try: - _dispatch.dispatch([ct], *pats) - except SystemExit: - pass - return - portable_fork()   # move cwd to repo root if repo is merged, so we can show   # all the changed files   repo = hg.repository(ui, path=paths.find_root()) @@ -299,125 +296,109 @@
  os.chdir(repo.root)   pats = []   from hggtk.commit import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def shelve(ui, *pats, **opts):   """shelve/unshelve tool""" - portable_fork()   from hggtk.thgshelve import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def userconfig(ui, *pats, **opts):   """user configuration editor""" - # Import thgconfig first, to check for iniparse   from hggtk.thgconfig import run - portable_fork()   opts['repomode'] = False - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def repoconfig(ui, *pats, **opts):   """repository configuration editor""" - portable_fork()   from hggtk.thgconfig import run   opts['repomode'] = True - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def rename(ui, *pats, **opts):   """rename a single file or directory""" - portable_fork() + if not pats or len(pats) > 2: + from hggtk import gdialog + gdialog.Prompt(_('Rename error'), + _('rename takes one or two path arguments'), None).run() + return   from hggtk.rename import run - if not pats or len(pats) > 2: - raise util.Abort(_('rename takes one or two path arguments')) - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def guess(ui, *pats, **opts):   """guess previous renames or copies""" - portable_fork()   from hggtk.guess import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def datamine(ui, *pats, **opts):   """repository search and annotate tool""" - portable_fork()   from hggtk.datamine import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def hgignore(ui, *pats, **opts):   """ignore filter editor""" - portable_fork()   from hggtk.hgignore import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def hginit(ui, *pats, **opts):   """repository initialization tool""" - portable_fork()   from hggtk.hginit import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def log(ui, *pats, **opts):   """changelog viewer""" - portable_fork()   from hggtk.history import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def merge(ui, *pats, **opts):   """merge tool""" - portable_fork()   from hggtk.merge import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def recovery(ui, *pats, **opts):   """recover, rollback & verify""" - portable_fork()   from hggtk.recovery import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def remove(ui, *pats, **opts):   """file status viewer in remove mode""" - portable_fork()   from hggtk.status import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def revert(ui, *pats, **opts):   """file status viewer in revert mode""" - portable_fork()   from hggtk.status import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def serve(ui, *pats, **opts):   """web server""" - portable_fork()   from hggtk.serve import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def status(ui, *pats, **opts): - """file status viewer""" - portable_fork() + """file status & diff viewer"""   from hggtk.status import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def synch(ui, *pats, **opts):   """repository synchronization tool""" - portable_fork()   from hggtk.synch import run   cmd = opts['alias']   if cmd in ('push', 'outgoing', 'email'):   opts['pushmode'] = True   else:   opts['pushmode'] = False - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def update(ui, *pats, **opts):   """update/checkout tool""" - portable_fork()   from hggtk.update import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    def vdiff(ui, *pats, **opts):   """launch configured visual diff tool""" - portable_fork()   from hggtk.visdiff import run - gtkrun(run(ui, *pats, **opts)) + gtkrun(run, ui, *pats, **opts)    ### help management, adapted from mercurial.commands.help_()  def help_(ui, name=None, with_version=False): @@ -457,7 +438,7 @@
  aliases, i = cmdutil.findcmd(name, table, False)   except hglib.AmbiguousCommand, inst:   select = lambda c: c.lstrip('^').startswith(inst.args[0]) - helplist('list of commands:\n\n', select) + helplist(_('list of commands:\n\n'), select)   return     # synopsis @@ -589,7 +570,7 @@
  # this is a series of hacks, but Mercurial's versioning scheme   # doesn't lend itself to a "correct" solution. This will at least   # catch people who have old Mercurial packages. - reqver = ['1', '2'] + reqver = ['1', '3']   if not v or v == 'unknown' or len(v) >= 12:   # can't make any intelligent decisions about unknown or hashes   return @@ -601,8 +582,8 @@
  if vers == nextver:   return   raise util.Abort(_('This version of TortoiseHg requires Mercurial ' - 'version %s.n to %s.n, but finds %s') % ('.'.join(reqver), - '.'.join(nextver), v)) + 'version %s.n to %s.n, but finds %s') % + ('.'.join(reqver), '.'.join(nextver), v))    def version(ui, **opts):   """output version and copyright information""" @@ -633,6 +614,11 @@
  cmdlist = [' '.join(c[0]) for c in cmdlist.values()]   ui.write("%s\n" % "\n".join(sorted(cmdlist)))   +def archive(ui, *pats, **opts): + """create an unversioned archive of a repository revision""" + from hggtk.archive import run + gtkrun(run, ui, *pats, **opts) +  globalopts = [   ('R', 'repository', '',   _('repository root directory or symbolic path name')), @@ -663,7 +649,7 @@
  "^recovery|rollback|verify": (recovery, [], _('hgtk recovery')),   "^shelve|unshelve": (shelve, [], _('hgtk shelve')),   "^synch|pull|push|incoming|outgoing|email": (synch, [], _('hgtk synch')), - "^status|st": (status, + "^status|st|diff": (status,   [('r', 'rev', [], _('revisions to compare'))],   _('hgtk status [FILE]...')),   "^userconfig": (userconfig, [], _('hgtk userconfig')), @@ -698,4 +684,7 @@
  [('o', 'options', None, _('show the command options'))],   _('[-o] CMD')),   "help": (help_, [], _('hgtk help [COMMAND]')), + "^archive": (archive, + [('r', 'rev', '', _('revision to update'))], + ('hgtk archive')),  }
Change 1 of 3 Show Entire File hggtk/​history.py Stacked
 
21
22
23
24
 
25
26
27
 
401
402
403
 
404
405
406
 
756
757
758
 
 
 
 
 
 
 
 
 
759
760
761
 
21
22
23
 
24
25
26
27
 
401
402
403
404
405
406
407
 
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
@@ -21,7 +21,7 @@
 from hggtk.logview.treeview import TreeView as LogTreeView    from hggtk import gdialog, gtklib, hgcmd, datamine, logfilter -from hggtk import backout, status, hgemail, tagadd, update, merge +from hggtk import backout, status, hgemail, tagadd, update, merge, archive  from hggtk import changeset    def create_menu(label, callback): @@ -401,6 +401,7 @@
  m.append(create_menu(_('add/remove _tag'), self.add_tag))   m.append(create_menu(_('backout revision'), self.backout_rev))   m.append(create_menu(_('_revert'), self.revert)) + m.append(create_menu(_('_archive'), self.archive))     # need mq extension for strip command   extensions.loadall(self.ui) @@ -756,6 +757,15 @@
  elif not oldparents == newparents:   self.refresh_model()   + def archive(self, menuitem): + rev = self.currow[treemodel.REVID] + parents = [x.node() for x in self.repo.parents()] + dialog = archive.ArchiveDialog(rev) + dialog.set_transient_for(self) + dialog.show_all() + dialog.present() + dialog.set_transient_for(None) +   def selection_changed(self, treeview):   self.currow = self.graphview.get_revision()   rev = self.currow[treemodel.REVID]
Change 1 of 1 Show Entire File hggtk/​serve.py Stacked
 
292
293
294
295
296
 
297
298
299
 
292
293
294
 
 
295
296
297
298
@@ -292,8 +292,7 @@
  self.stopped = True   util.set_signal_handler()   try: - baseui = (getattr(repo, 'baseui', None) or - getattr(ui, 'parentui', None) or ui) + baseui = repo and repo.baseui or ui   repoui = repo and repo.ui != baseui and repo.ui or None   optlist = ("name templates style address port prefix ipv6"   " accesslog errorlog webdir_conf certificate")
Change 1 of 1 Show Entire File hggtk/​status.py Stacked
 
1120
1121
1122
1123
1124
 
 
1125
1126
 
1127
1128
1129
 
1120
1121
1122
 
 
1123
1124
1125
 
1126
1127
1128
1129
@@ -1120,10 +1120,10 @@
  elif self.merging:   resp = gdialog.CustomPrompt(_('Which parent to revert to?'),   _('Revert file(s) to local or other parent?'), - self, (_('&local'), _('&other')), _('l')).run() - if resp == ord(_('l')): + self, (_('&local'), _('&other')), 0).run() + if resp == 0:   revertopts['rev'] = self.repo[None].p1().rev() - elif resp == ord(_('o')): + elif resp == 1:   revertopts['rev'] = self.repo[None].p2().rev()   else:   return
Change 1 of 1 Show Entire File hggtk/​synch.py Stacked
 
566
567
568
569
570
571
572
 
573
574
575
576
577
578
579
580
581
 
566
567
568
 
 
 
 
569
570
571
572
 
 
 
573
574
575
@@ -566,16 +566,10 @@
  return False     def add_src_to_recent(self, src): - if os.path.exists(src): - src = os.path.abspath(src) - - # save src path to recent list in history (read by clone tool) + # add src path to recent list in history (read by clone tool)   self._settings.mrul('src_paths').add(src)   self._settings.write()   - # update drop-down list - self.fill_path_combo() -   def flush(self, *args):   pass  
 
56
57
58
59
 
 
 
 
 
 
 
60
61
62
63
64
65
66
67
68
69
70
 
155
156
157
 
 
 
158
159
160
161
162
163
164
165
 
56
57
58
 
59
60
61
62
63
64
65
66
67
68
69
 
 
 
 
70
71
72
 
157
158
159
160
161
162
163
164
 
 
 
165
166
167
@@ -56,15 +56,17 @@
  (_('Bottom Diffs'), 'gtools.diffbottom', ['False', 'True'],   _('Show the diff panel below the file list in status, shelve, and'   ' commit dialogs.' - ' Default: False (show diffs to right of file list)'))) + ' Default: False (show diffs to right of file list)')), + (_('Capture Stderr'), 'tortoisehg.stderrcapt', ['True', 'False'], + _('Redirect stderr to a buffer which is parsed at the end of' + ' the process for runtime errors. Default: True')), + (_('Fork hgtk'), 'tortoisehg.hgtkfork', ['True', 'False'], + _('When running hgtk from the command line, fork a background' + ' process to run graphical dialogs. Default: True')))    _commit_info = (   (_('Username'), 'ui.username', [],   _('Name associated with commits')), - (_('External Commit Tool'), 'tortoisehg.extcommit', ['None', 'qct'], - _('Select commit tool launched by TortoiseHg. (Qct is no longer' - ' distributed as part of TortoiseHG.)' - ' Default: None (use the builtin tool)')),   (_('Summary Line Length'), 'tortoisehg.summarylen', ['0', '70'],   _('Maximum length of the commit message summary line.'   ' If set, TortoiseHG will issue a warning if the' @@ -155,11 +157,11 @@
  (_('Bypass List'), 'http_proxy.no', [],   _('Optional. Comma-separated list of host names that'   ' should bypass the proxy')), + (_('User'), 'http_proxy.user', [], + _('Optional. User name to authenticate with at the' + ' proxy server')),   (_('Password'), 'http_proxy.passwd', [],   _('Optional. Password to authenticate with at the' - ' proxy server')), - (_('User'), 'http_proxy.user', [], - _('Optional. User name to authenticate with at the'   ' proxy server')))    _email_info = (
Change 1 of 2 Show Entire File hggtk/​visdiff.py Stacked
 
210
211
212
213
214
 
 
215
216
217
 
247
248
249
250
 
251
252
253
 
210
211
212
 
 
213
214
215
216
217
 
247
248
249
 
250
251
252
253
@@ -210,8 +210,8 @@
  except (IOError, OSError), e:   resp = gdialog.CustomPrompt(_('Unable to delete temp files'),   _('Close diff tools and try again, or quit to leak files?'), - self, (_('Try &Again'), _('&Quit')), _('q')).run() - if resp == ord(_('a')): + self, (_('Try &Again'), _('&Quit')), 1).run() + if resp == 0:   continue   else:   return @@ -247,7 +247,7 @@
  stderr=subprocess.PIPE,   stdout=subprocess.PIPE,   stdin=subprocess.PIPE) - except Exception, e: + except (OSError, EnvironmentError), e:   gdialog.Prompt(_('Tool launch failure'),   _('%s : %s') % (self.diffpath, str(e)), None).run()  
Change 1 of 3 Show Entire File hgtk Stacked
 
26
27
28
29
 
30
31
 
32
33
34
 
39
40
41
42
 
 
 
 
43
44
45
46
47
48
 
51
52
53
54
55
56
 
57
58
59
60
 
 
61
62
 
26
27
28
 
29
30
31
32
33
34
35
 
40
41
42
 
43
44
45
46
47
48
 
49
50
51
 
54
55
56
 
 
 
57
58
59
60
 
61
62
63
64
@@ -26,9 +26,10 @@
 pygtk.require('2.0')  import gtk   -from mercurial import demandimport; +from mercurial import demandimport  demandimport.ignore.append('win32com.shell')  demandimport.enable() +from mercurial import ui  import cStringIO    try: @@ -39,10 +40,12 @@
  sys.stderr.write("(check your install and PYTHONPATH)\n")   sys.exit(-1)   -if 'THGDEBUG' in os.environ: +_ui = ui.ui() +capt = _ui.configbool('tortoisehg', 'stderrcapt', True) + +if not capt or 'THGDEBUG' in os.environ:   sys.exit(hggtk.hgtk.dispatch(sys.argv[1:]))  else: - import cStringIO   mystderr = cStringIO.StringIO()   sys.stderr = mystderr   ret = hggtk.hgtk.dispatch(sys.argv[1:]) @@ -51,12 +54,11 @@
  if l.startswith('Traceback') or l.startswith('TypeError'):   from hggtk.bugreport import run   from hggtk.hgtk import gtkrun - from mercurial import ui - mystderr.seek(0) - error = 'Recoverable runtime error (stderr):\n' + mystderr.read() + error = 'Recoverable runtime error (stderr):\n'+mystderr.getvalue()   opts = {}   opts['cmd'] = ' '.join(sys.argv[1:])   opts['error'] = error - gtkrun(run(ui.ui(), **opts)) + opts['nofork'] = True + gtkrun(run, _ui, **opts)   break   sys.exit(ret)
Change 1 of 4 Show Entire File thgutil/​hglib.py Stacked
 
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
 
45
46
47
48
49
50
51
52
53
54
55
56
 
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
 
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
 
15
16
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
19
20
21
22
23
24
25
26
 
31
32
33
 
 
 
 
 
 
34
35
36
 
101
102
103
 
 
 
 
104
105
106
107
108
 
 
 
 
109
110
111
 
 
 
 
 
 
 
 
 
 
112
113
114
115
116
 
146
147
148
 
 
 
 
 
 
 
 
149
150
151
152
153
154
155
156
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -15,26 +15,12 @@
 from i18n import _  import paths   -try: - from mercurial.error import RepoError, ParseError, LookupError - from mercurial.error import UnknownCommand, AmbiguousCommand -except ImportError: - from mercurial.cmdutil import UnknownCommand, AmbiguousCommand - from mercurial.repo import RepoError - from mercurial.dispatch import ParseError - from mercurial.revlog import LookupError - -from mercurial import dispatch - -try: - from mercurial import encoding - _encoding = encoding.encoding - _encodingmode = encoding.encodingmode - _fallbackencoding = encoding.fallbackencoding -except ImportError: - _encoding = util._encoding - _encodingmode = util._encodingmode - _fallbackencoding = util._fallbackencoding +from mercurial.error import RepoError, ParseError, LookupError +from mercurial.error import UnknownCommand, AmbiguousCommand +from mercurial import dispatch, encoding, util +_encoding = encoding.encoding +_encodingmode = encoding.encodingmode +_fallbackencoding = encoding.fallbackencoding    try:   # post 1.1.2 @@ -45,12 +31,6 @@
  from mercurial import version   hgversion = version.get_version()   -try: - from mercurial.util import WinIOError -except: - class WinIOError(Exception): - 'WinIOError stub' -  def toutf(s):   """   Convert a string to UTF-8 encoding @@ -121,31 +101,16 @@
  write args if there are buffers   returns True if the caller shall handle writing   ''' - buffers = getattr(u, '_buffers', None) - if buffers == None: - buffers = u.buffers - if buffers: + if u._buffers:   ui.ui.write(u, *args)   return False   return True   -def calliffunc(f): - return hasattr(f, '__call__') and f() or f - -  def invalidaterepo(repo):   repo.invalidate()   repo.dirstate.invalidate() - if 'mq' in repo.__dict__: #do not create if it did not exist - mq = repo.mq - if hasattr(mq, 'invalidate'): - #Mercurial 1.3 - mq.invalidate() - else: - #Mercurial 1.2 - mqclass = mq.__class__ - repo.mq = mqclass(mq.ui, mq.basepath, mq.path) - + if 'mq' in repo.__dict__: #do not create if it does not exist + repo.mq.invalidate()    def canonpaths(list):   'Get canonical paths (relative to root) for list of files' @@ -181,174 +146,12 @@
  for a in args:   q.put(str(a))   u = Qui() - if hasattr(ui.ui, 'copy'): - # Mercurial 1.3 - for k, v in u.configitems('defaults'): - u.setconfig('defaults', k, '') - return dispatch._dispatch(u, list(args)) - else: - return thgdispatch(u, path, list(args)) - + for k, v in u.configitems('defaults'): + u.setconfig('defaults', k, '') + return dispatch._dispatch(u, list(args))    def displaytime(date):   return util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2')    def utctime(date):   return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(date[0])) - -# the remaining functions are only needed for Mercurial versions < 1.3 -def _earlygetopt(aliases, args): - """Return list of values for an option (or aliases). - - The values are listed in the order they appear in args. - The options and values are removed from args. - """ - try: - argcount = args.index("--") - except ValueError: - argcount = len(args) - shortopts = [opt for opt in aliases if len(opt) == 2] - values = [] - pos = 0 - while pos < argcount: - if args[pos] in aliases: - if pos + 1 >= argcount: - # ignore and let getopt report an error if there is no value - break - del args[pos] - values.append(args.pop(pos)) - argcount -= 2 - elif args[pos][:2] in shortopts: - # short option can have no following space, e.g. hg log -Rfoo - values.append(args.pop(pos)[2:]) - argcount -= 1 - else: - pos += 1 - return values - -_loaded = {} -def thgdispatch(ui, path=None, args=[], nodefaults=True): - ''' - Replicate functionality of mercurial dispatch but force the use - of the passed in ui for all purposes - ''' - - # clear all user-defined command defaults - if nodefaults: - for k, v in ui.configitems('defaults'): - ui.setconfig('defaults', k, '') - - # read --config before doing anything else - # (e.g. to change trust settings for reading .hg/hgrc) - config = _earlygetopt(['--config'], args) - if config: - for section, name, value in dispatch._parseconfig(config): - ui.setconfig(section, name, value) - - # check for cwd - cwd = _earlygetopt(['--cwd'], args) - if cwd: - os.chdir(cwd[-1]) - - # read the local repository .hgrc into a local ui object - path = paths.find_root(path) or "" - if path: - try: - ui.readconfig(os.path.join(path, ".hg", "hgrc")) - except IOError: - pass - - # now we can expand paths, even ones in .hg/hgrc - rpath = _earlygetopt(["-R", "--repository", "--repo"], args) - if rpath: - path = ui.expandpath(rpath[-1]) - - extensions.loadall(ui) - if not hasattr(extensions, 'extensions'): - extensions.extensions = lambda: () # pre-0.9.5, loadall did below - for name, module in extensions.extensions(): - if name in _loaded: - continue - - # setup extensions - extsetup = getattr(module, 'extsetup', None) - if extsetup: - extsetup() - - cmdtable = getattr(module, 'cmdtable', {}) - overrides = [cmd for cmd in cmdtable if cmd in commands.table] - if overrides: - ui.warn(_("extension '%s' overrides commands: %s\n") % - (name, " ".join(overrides))) - commands.table.update(cmdtable) - _loaded[name] = 1 - - # check for fallback encoding - fallback = ui.config('ui', 'fallbackencoding') - if fallback: - _fallbackencoding = fallback - - fullargs = args - cmd, func, args, options, cmdoptions = dispatch._parse(ui, args) - - if options["encoding"]: - _encoding = options["encoding"] - if options["encodingmode"]: - _encodingmode = options["encodingmode"] - if options['verbose'] or options['debug'] or options['quiet']: - ui.setconfig('ui', 'verbose', str(bool(options['verbose']))) - ui.setconfig('ui', 'debug', str(bool(options['debug']))) - ui.setconfig('ui', 'quiet', str(bool(options['quiet']))) - if options['traceback']: - ui.setconfig('ui', 'traceback', 'on') - if options['noninteractive']: - ui.setconfig('ui', 'interactive', 'off') - - if options['help']: - return commands.help_(ui, cmd, options['version']) - elif options['version']: - return commands.version_(ui) - elif not cmd: - return commands.help_(ui, 'shortlist') - - repo = None - if cmd not in commands.norepo.split(): - try: - repo = hg.repository(ui, path=path) - repo.ui = ui - ui.setconfig("bundle", "mainreporoot", repo.root) - if not repo.local(): - raise util.Abort(_("repository '%s' is not local") % path) - except RepoError: - if cmd not in commands.optionalrepo.split(): - if not path: - raise RepoError(_('There is no Mercurial repository here' - ' (.hg not found)')) - raise - d = lambda: func(ui, repo, *args, **cmdoptions) - else: - d = lambda: func(ui, *args, **cmdoptions) - - # run pre-hook, and abort if it fails - ret = hook.hook(ui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs)) - if ret: - return ret - - # Run actual command - try: - ret = d() - except TypeError: - # was this an argument error? - tb = traceback.extract_tb(sys.exc_info()[2]) - if len(tb) != 2: # no - raise - raise ParseError(cmd, _('invalid arguments')) - - # run post-hook, passing command result - hook.hook(ui, repo, "post-%s" % cmd, False, args=" ".join(fullargs), - result = ret) - - if repo: - shlib.update_thgstatus(repo.ui, repo.root, wait=True) - - return ret