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 b44427cd428e

Parents 895e1d1a817e

Parents 5d76519574c3

by Steve Borho

Changes to 20 files · Browse files at b44427cd428e Showing diff from parent 895e1d1a817e 5d76519574c3 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 2 Show Entire File hggtk/​commit.py Stacked
 
346
347
348
 
349
350
351
 
475
476
477
478
479
480
 
481
482
483
484
485
486
487
 
346
347
348
349
350
351
352
 
476
477
478
 
 
 
479
480
 
 
 
481
482
483
@@ -346,6 +346,7 @@
  self.get_toolbutton(_('_Add')).set_sensitive(not self.merging)   self.get_toolbutton(_('_Remove')).set_sensitive(not self.merging)   self.get_toolbutton(_('Move')).set_sensitive(not self.merging) + self.get_toolbutton(_('_Forget')).set_sensitive(not self.merging)     if self.merging:   # select all changes if repo is merged @@ -475,13 +476,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/​hgemail.py Stacked
 
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
 
245
246
247
 
354
355
356
357
 
358
359
360
361
362
 
363
364
365
 
224
225
226
 
 
 
 
 
 
 
 
 
 
 
 
227
228
229
230
231
 
232
233
234
235
 
342
343
344
 
345
346
347
348
349
 
350
351
352
353
@@ -224,24 +224,12 @@
  self._ccbox.child.set_text(hglib.fromutf(repo.ui.config('email', 'cc', '')))   self._frombox.child.set_text(hglib.fromutf(repo.ui.config('email', 'from', '')))   self._subjbox.child.set_text(hglib.fromutf(repo.ui.config('email', 'subject', ''))) - self._intro = False - self._in_reply_to = False - for arg in extensions.find('patchbomb').cmdtable['email'][1]: - if arg[1] == 'intro': - self._intro = True - elif arg[1] == 'in-reply-to': - self._in_reply_to = True - if self._intro: - addtip = '' - else: - addtip = ' ' + _('The description field is unused ' - 'when sending a single patch.')   self.tooltips.set_tip(self._eventbox,   _('Patch series description is sent in initial summary'   ' email with [PATCH 0 of N] subject. It should describe'   ' the effects of the entire patch series. When emailing'   ' a bundle, these fields make up the message subject and body.') - + addtip) + )   fill_history(history, self._tolist, 'email.to')   fill_history(history, self._cclist, 'email.cc')   fill_history(history, self._fromlist, 'email.from') @@ -354,12 +342,12 @@
  if self._inline.get_active(): cmdline += ['--inline']   if self._attach.get_active(): cmdline += ['--attach']   if self._diffstat.get_active(): cmdline += ['--diffstat'] - if inreplyto and self._in_reply_to: + if inreplyto:   cmdline += ['--in-reply-to', inreplyto]   start = self.descbuffer.get_start_iter()   end = self.descbuffer.get_end_iter()   desc = self.descbuffer.get_text(start, end) - if desc and self._intro: + if desc:   cmdline += ['--intro']   tmpfile = None   try:
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 13 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
210
 
211
212
213
 
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
 
672
673
674
 
675
676
677
 
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
 
215
216
217
218
 
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
 
405
 
406
407
408
409
 
443
444
445
 
446
447
448
449
 
575
576
577
 
578
579
580
581
 
587
588
589
 
 
590
591
592
593
594
 
619
620
621
622
623
624
625
626
627
628
629
 
654
655
656
 
657
658
659
660
 
663
664
665
666
667
668
669
 
690
691
692
693
694
695
696
@@ -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,10 +207,12 @@
  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: - lui = hasattr(_ui, 'copy') and _ui.copy() or _ui.ui(ui) + lui = ui.copy()   lui.readconfig(os.path.join(path, ".hg", "hgrc"))   except IOError:   pass @@ -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,114 @@
  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 forget(ui, *pats, **opts): + """file status viewer in forget mode""" + from hggtk.status import run + 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 +443,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 +575,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 +587,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 +619,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 +654,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')), @@ -672,6 +663,7 @@
  "^remove|rm": (revert, [], _('hgtk remove [FILE]...')),   "^rename|mv": (rename, [], _('hgtk rename SOURCE [DEST]')),   "^revert": (revert, [], _('hgtk revert [FILE]...')), + "^forget": (forget, [], _('hgtk forget [FILE]...')),   "^serve":   (serve,   [('', 'webdir-conf', '', _('name of the webdir config file'))], @@ -698,4 +690,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
 
754
755
756
 
 
 
 
 
 
 
 
 
757
758
759
 
21
22
23
 
24
25
26
27
 
401
402
403
404
405
406
407
 
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
@@ -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) @@ -754,6 +755,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]
 
73
74
75
76
 
77
78
79
 
73
74
75
 
76
77
78
79
@@ -73,7 +73,7 @@
  ascent = pango.PIXELS(metrics.get_ascent())   descent = pango.PIXELS(metrics.get_descent())   - self._box_size = ascent + descent + 6 + self._box_size = ascent + descent   return self._box_size     def set_colour(self, ctx, colour, bg, fg):
 
219
220
221
222
 
 
223
224
225
 
219
220
221
 
222
223
224
225
226
@@ -219,7 +219,8 @@
  if width > 500:   width = 500   self.graph_column.set_fixed_width(width) - self.graph_column.set_max_width(width) + # Allow the user to set size as they like + #self.graph_column.set_max_width(500)   self.graph_column.set_visible(self.show_graph)     if stopped:
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 8 Show Entire File hggtk/​status.py Stacked
 
3
4
5
 
6
7
8
 
105
106
107
108
 
 
109
110
111
 
122
123
124
125
 
 
126
127
128
 
212
213
214
 
 
 
215
216
217
 
1095
1096
1097
 
 
 
1098
1099
1100
 
1120
1121
1122
1123
1124
 
 
1125
1126
 
1127
1128
1129
 
1140
1141
1142
 
 
 
 
 
1143
1144
1145
 
1205
1206
1207
 
 
 
 
 
 
 
 
1208
1209
1210
 
3
4
5
6
7
8
9
 
106
107
108
 
109
110
111
112
113
 
124
125
126
 
127
128
129
130
131
 
215
216
217
218
219
220
221
222
223
 
1101
1102
1103
1104
1105
1106
1107
1108
1109
 
1129
1130
1131
 
 
1132
1133
1134
 
1135
1136
1137
1138
 
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
 
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
@@ -3,6 +3,7 @@
 # Copyright 2007 Brad Schick, brad at gmail . com  # Copyright 2007 TK Soh <teekaysoh@gmail.com>  # Copyright 2008 Steve Borho <steve@borho.org> +# Copyright 2008 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. @@ -105,7 +106,8 @@
  (_('edit'), self._view_file),   (_('view other'), self.view_left_file),   (_('_revert'), self.revert_file), - (_('l_og'), self.log_file)), + (_('l_og'), self.log_file), + (_('_forget'), self.forget_file)),   # addrem   ((_('_difference'), self._diff_file),   (_('_view'), self._view_file), @@ -122,7 +124,8 @@
  (_('re_move'), self.remove_file),   (_('re_name'), self.rename_file),   (_('_copy'), self.copy_file), - (_('l_og'), self.log_file)), + (_('l_og'), self.log_file), + (_('_forget'), self.forget_file)),   # ignored   ((_('_view'), self._view_file),   (_('_delete'), self.delete_file)), @@ -212,6 +215,9 @@
  tip=_('move selected files to other directory')),   self.make_toolbutton(gtk.STOCK_DELETE, _('_Remove'),   self.remove_clicked, tip=_('remove')), + self.make_toolbutton(gtk.STOCK_CLEAR, _('_Forget'), + self.forget_clicked, + tip=_('forget file(s) on next commit')),   gtk.SeparatorToolItem()]   return tbuttons   @@ -1095,6 +1101,9 @@
  dlg.display()   return True   + def forget_file(self, stat, wfile): + self.hg_forget([wfile]) + return True     def hg_revert(self, files):   wfiles = [self.repo.wjoin(x) for x in files] @@ -1120,10 +1129,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 @@ -1140,6 +1149,11 @@
  shlib.shell_notify(wfiles)   self.reload_status()   + def hg_forget(self, files): + wfiles = [self.repo.wjoin(x) for x in files] + commands.forget(self.ui, self.repo, *wfiles) + self.reload_status() +   def add_clicked(self, toolbutton, data=None):   add_list = self.relevant_files('?I')   if len(add_list) > 0: @@ -1205,6 +1219,14 @@
  'Note: only clean files can be moved.'), self).run()   return True   + def forget_clicked(self, toolbutton, data=None): + forget_list = self.relevant_files('CM') + if len(forget_list) > 0: + self.hg_forget(forget_list) + else: + gdialog.Prompt(_('Nothing Forgotten'), + _('No clean files selected'), self).run() +   def delete_file(self, stat, wfile):   self.delete_files([wfile])  
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
 
 
152
153
154
 
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
117
118
119
120
121
 
148
149
150
 
 
 
 
 
 
 
 
151
152
153
154
155
156
157
158
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -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,34 +101,21 @@
  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' + # This is a horrible hack. Please remove this when HG acquires a + # decent case-folding solution.   canonpats = []   cwd = os.getcwd()   root = paths.find_root(cwd) @@ -181,174 +148,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