Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 0.6, 0.7, and 0.7.1

hg-crew-tip merge with default

Changeset 12d443aa23b7

Parents bd649f9329c0

Parents 3bbe0ec7d904

by Peter Arrenbrecht

Changes to 45 files · Browse files at 12d443aa23b7 Showing diff from parent bd649f9329c0 3bbe0ec7d904 Diff from another changeset...

Change 1 of 1 Show Entire File .hgignore Stacked
 
1
2
3
4
5
6
7
8
9
10
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
@@ -1,11 +1,11 @@
-syntax: glob - -*.orig -*.rej -*.pyc -tortoise/__version__.py -build/ -dist/ -Output/ -.*.swp -Thumbs.db +syntax: glob + +*.orig +*.rej +*.pyc +tortoise/__version__.py +build/ +dist/ +Output/ +.*.swp +Thumbs.db
Change 1 of 1 Show Entire File .hgtags Stacked
 
7
8
9
 
 
 
 
 
7
8
9
10
11
12
13
@@ -7,3 +7,7 @@
 5a9d20cfcb2911b5a35234f38a7897c9c654c9d5 0.4rc1  dc4f96864ea7d0a48d831a05695b80001e226db5 0.4rc2  e677decc9814e94fe3b325ec13077a01e1ccbb87 0.4rc2 +e2211f1985b01b1edd3fc1abe0b7c97fb37fd9d1 0.4rc3 +864497951b6b801cfacbac16eec5b7edb4f1be3c 0.4rc4 +f627244263631682216716cde477d05bebc0d934 0.4 +491a94666fc3498827066b8aa65aab34d3a3e623 0.4.1
Change 1 of 5 Show Entire File COPYING.txt Stacked
 
55
56
57
58
59
60
61
 
110
111
112
113
114
115
116
 
168
169
170
171
172
173
174
 
225
226
227
228
229
230
231
 
278
279
280
281
282
283
284
 
55
56
57
 
58
59
60
 
110
111
112
 
113
114
115
 
168
169
170
 
171
172
173
 
225
226
227
 
228
229
230
 
278
279
280
 
281
282
283
@@ -55,7 +55,7 @@
    The precise terms and conditions for copying, distribution and  modification follow. - +     GNU GENERAL PUBLIC LICENSE   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @@ -110,7 +110,7 @@
  License. (Exception: if the Program itself is interactive but   does not normally print such an announcement, your work based on   the Program is not required to print an announcement.) - +    These requirements apply to the modified work as a whole. If  identifiable sections of that work are not derived from the Program, @@ -168,7 +168,7 @@
 access to copy the source code from the same place counts as  distribution of the source code, even though third parties are not  compelled to copy the source along with the object code. - +     4. You may not copy, modify, sublicense, or distribute the Program  except as expressly provided under this License. Any attempt @@ -225,7 +225,7 @@
   This section is intended to make thoroughly clear what is believed to  be a consequence of the rest of this License. - +     8. If the distribution and/or use of the Program is restricted in  certain countries either by patents or by copyrighted interfaces, the @@ -278,7 +278,7 @@
 POSSIBILITY OF SUCH DAMAGES.     END OF TERMS AND CONDITIONS - +     How to Apply These Terms to Your New Programs  
Change 1 of 1 Show Entire File ReleaseNotes.txt 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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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
@@ -1,192 +1,281 @@
- Release Notes for TortoiseHg - -This file contains last minute notes to users about the releases, which may not -be included in the documentation or README files included with the distribution -kits. It also contains change information, for users who are interested in -what bugs have been fixed, and what features have been added in the current -version. - - -New features in 0.4 - - * Added user config 'tortoisehg.overlayicons' [True|False|localdisks], - to enable/disable overlay icons in selected repos. The 'localdisks' - global option disables overlay icons for repos reside on network drives. - - * Changeset viewer shows 'MAR' file status and uses background threads - to load changeset diffs. File list has been moved to the left hand - side. - - * Added 'strip' and 'backout' functions to history browser. - - * Two convenience functions added to Synchronize dialog: 'View Pulled - Changes', and 'Update to Tip'. - - * Added support for Fetch extension to Synchronize dialog [ 1914855 ]. - - * Grep searches in Datamine dialog can now be interrupted. - - * Recall recently committed messages in native Commit dialog - - * Recall recently accessed source and destination paths in Synchronize - and Clone dialogs - - * Add column for user names on annotate pages of Datamine dialog. - - * Hgk ('Revision Graph') is officially replaced by TortoiseHg's - history browser. - - * Installer now requires admin priviledges in order to prevent an - upgrade from requiring two reboots. - - * New TortoiseHg logo in About dialog, contributed by Peer Sommerlund. - - * Updated Hg icon (on context menu and dialogs) to new droplet design - from Mercurial 1.0 - - * Several minor bugfixes and improvements. - -Bug fixes in 0.4: - - * TortoiseHg program groups now read 'hgproc' with hg.ico. - In earlier versions, it used 'Python' with python.ico - * Fixed random crashes on web server. - * Fixed addremove behavior in Commit dialog - * [ 1884919 ] Change Log hscroller - * [ 1925985 ] HTTP port field not effective - * [ 1914859 ] Global options should show up more often - * [ 1914550 ] Changelog: Problems with german umlaut characters - * [ 1902446 ] Commit claims file not under root while kdiff is open. - * [ 1895443 ] Overlay: ThreadingModel registry setting - * [ 1892791 ] Windows Explorer painfully slow for network drives - -Changes and bug fixes since 0.4RC1: - - * Added buttons to stop command execution in Synchronize, Recovery, - as well as any dialogs that use hgcmd dialog, including Update and - Clone dialogs. - * Show progress on status bar when updating changeset viewer. - * Support Mercurial's HGENCODING environment variable. - * [ Feature 1944469 ] Save and recall pull-update option in Synchronize - dialog across sessions. - * [ Bug 1939794 ] Unable to Merge changes with builtin commit UI. - * [ Bug 1941545 ] Clone log window doesn't scroll. - * [ Bug 1943382 ] hgproc.bat not executable without "installer" - * [ Bug 1941368 ] Configure Repository "Test" button results broken. - * [ Bug 1939911 ] Modal Dialogs aren't staying on top on application switch - * [ Bug 1941376 ] hgtk with no parameters gives no help. - * [ Bug 1937966 ] Changelog: utf8 messages handled incorrectly - * [ Bug 1942777 ] National characters are not handled correctly. - -Fixes in Mercurial since 0.3: - - * qimport fixed on Windows - * new built-in filemerge system replaces hgmerge patches - * many fixes for keyword extension - * new -U (context lines) argument for diff and qdiff commands - -New features in 0.3 - - * Major improvements to changelog browser. It is now good enough to - deprecate both hgk and hgview. Neither are bundled with the 0.3 - binary installer, but both can be added by the user if they wish. - Support for external revision log viewers will be dropped in 0.4. - - * The new changelog browser supports filtering by file pattern, - keywords, dates, and branches. It is capable of graphing both the - repository changelog and individual filelogs. Changeset coloring by - author is optional (tortoisehg.authorcolor). All changeset graphing - is done incrementally in batches (tortoisehg.graphlimit: 500) - - * New DataMine application for searching history (hg grep) and - inspecting file histories (hg annotate). This new application is - tabbed to facilitate debugging sessions where search results and - annotations can be grouped together for easy cross-reference. - - * New changeset browser, supports multiple parents intrinsically and - supports a number of file-revision features (view at revision, save - at revision, annotate at revision, revert to revision, etc). The - new changeset browser is also integrated into the changelog browser. - - * Standardized window layouts. Close buttons have been moved to the - toolbar. Dialogs that use progress bars now use a standard status - bar/progress bar widget. Tooltips have been added. - - * Hgtk wrapper application for launching TortoiseHg dialogs from the - command line - - * Support for an external visual editor: tortoisehg.editor. Takes - precedence over ui.editor when viewing files with TortoiseHg - - * Performance improvements in Mercurial itself (cset 0973501e5f4a) - - * New installer bitmap from Peer Sommerlund - - * Misc: The Synchronize dialog has been improved. The Web Serve - dialog no longer requires a subprocess to run the web server. The - configuration dialog has a number of bug fixes for the paths tab, - and now has separators in the drop-down boxes for the varying value - types (current, suggested, history). Http authentication has been - fixed. The hg integration library has seen major cleanups. - -Bug Fixes in 0.3: - - * [ 1863086 ] "Revision Graph" fail on UNC path - Fixed by removing hgk from base install. Integrated log viewer - is UNC path safe. - * [ 1851395 ] Total Commander problem - * [ 1882074 ] global name 'p' is not defined - * [ 1854443 ] View changelog fails - -New features in 0.2 - - * Gtools has been integrated into TortoiseHg proper. It is no longer - bundled as a Mercurial extension. The graphlog extension is now enabled - again by default (only usable from the CLI, however). - - * Context menu icons, application window icons. The context menu has been - simplified. - - * The changelog browser has a number of new features (filters and context - menu options). The tag browser and changelog tagging features have been - merged into this tool. - - * Hgview is now the default history viewer, hgk is being deprecated. - - * An email dialog for interfacing with the patchbomb extension. It can be - reached from the synchronize dialog and from the changelog browser. - - * A new configuration tool (replacing hg-config dialogs) that allows you - to configure TortoiseHg and Mercurial. - - * Most dialogs now use HgThread and GtkUI to run hg commands. These - classes run the command in a background thread and provide GUI prompts - for when user interaction is necessary (http web auth, etc). For some - commands, it also provides a progress bar. - - * A preview of the new Mercurial merge back end. The python hgmerge.py - script is being integrated into Mercurial, and this installer has a - preview of how that will work. You need to unset any ui.merge in your - Mercurial.ini file in order for it to work properly. If you don't - configure anything it will use simplemerge to automatically perform - merges. If conflicts are found it falls back to kdiff3 to resolve - them interactively. - - * Slight improvement on speed of overlay icons display. - - * A new 'about' dialog. - -Bugs fixed in 0.2 - - * [SF Bug #1851395] Overlay icons and context menus are no longer - restricted to MS-Explorer. So other file managers, such as Total - Commander, should be supported. - - * [SF Bug #1844722] Users can now create repositories inside repository - via the context menu. - -Changes since 0.2rc1 - - - N/A - - - + Release Notes for TortoiseHg + +This file contains last minute notes to users about the releases, which may not +be included in the documentation or README files included with the distribution +kits. It also contains change information, for users who are interested in +what bugs have been fixed, and what features have been added in the current +version. + +New features and improvement in 0.4.1 + + * Installer-only release to link with Mercurial 1.0.2 + +New features and improvement in 0.4 + + * Updated to work, and link, with Mercurial 1.0.1 + + * Explorer shell extensions: + - Added user config option 'tortoisehg.overlayicons' to enable/disable + display of overlay icons in selected repos. + + Available options: + True: + Show overlay icons + False: + Don't show overlay icons + localdisks: + [global (user) setting only] + Don't show overlay icons for repos reside on network drives. + + - Create .hgignore file automatically when initializing new repo + via 'Initialize new repo' context menu. + + * Hgk ('Revision Graph' on Explorer's context menu), better known as + 'hg view', is officially replaced by TortoiseHg's changelog viewer + ('View Changelog'). + + Note: Hgk may be reinstated by user, if necessary. Though it would + need some work to setup. + + * Changelog (History) Viewer: + - Added 'strip' and 'backout' functions to file context menu. + - Loading of changeset data (file list of diff chunks) is done in + background to improve response. + - Changeset window shows 'MAR' file status. + - File list has been moved to the left hand side. + + * Synchronize dialog: + - Added 'Stop' button to abort command executions. + - Added support for Fetch extension, as Pull's 'Do fetch' option [ 1914855 ]. + - Added buttons to 'View Pulled Changes' and 'Update to Tip'. + - Recall source and destination paths accessed in recent sessions. + - Recall Pull's 'Update to new tip' option setting from previous session + [ 1944469 ]. + + * Datamine dialog: + - Added 'Stop' button to abort grep searches. + - Added column for user names on annotate pages. + + * Commit dialog (internal, _not_ Qct): + - Recall commit messages of recent commits. + - Fixed handlng of merged repo per new Hg behavior (must commit all + files in a merged repo) + + * Clone dialog: + - Recall source and destination paths accessed in recent sessions. + - Cloning can now be aborted with the new 'Stop' button in HgCmd dialog. + + * Recovery dialog: + - Added 'Stop' button to abort command executions. + + * Added 'Stop' button to abort command executions in HgCmd dialog. + This applies to including Update, Clone and Commit dialogs, which + utilize HgCmd dialog to perform respective operations. + + * Unicode handling: + - Improved handling of UTF strings in Mercurial's metadata (commit + message, author, etc). + - Support Mercurial's HGENCODING environment variable. + + * Hgtk: + - Simplified installation on Unix/Linux systems. + - Confirm presence of critical Python modules, i.e. PyGTK and Mercurial. + + * Logos and icons: + - Updated Hg icon (on context menu and dialogs) to new droplet design + introduced in Mercurial 1.0 + - New TortoiseHg logo (in About dialog) by Peer Sommerlund. + - Several new menu icons by Peer Sommerlund, with better Windows + integration. The corresponding SVG source is also available in + TortoiseHg source tree. + + * Several other bugfixes and UI improvements. + +Bug fixes in 0.4: + + * Explorer shell extensions: + - Register context menu and overlay icon extensions onto the Explorer's + approved list. + - Fixed ThreadingModel registry setting per MS doc [ 1895443 ] + * TortoiseHg program groups now read 'hgproc' with hg.ico (in earlier + versions, it used 'Python' with python.ico) + * Make modal dialogs stay on top of their respective parent application + (issue triggered by a bug in PyGTK). + * Fixed random crashes in web server. + * Fixed addremove behavior in Commit dialog. + * Activated target revision option in Synchronize window that had been + dormant so far (as reported by Doug Philips). + * Terminate all backgrounded searches in Datamine window upon exit, so + the associated Python process may terminate immediately too. + * [ 1884919 ] Change Log hscroller + * [ 1925985 ] HTTP port field not effective + * [ 1914859 ] Global options should show up more often + * [ 1914550 ] Changelog: Problems with german umlaut characters + * [ 1902446 ] Commit claims file not under root while kdiff is open. + * [ 1892791 ] Windows Explorer painfully slow for network drives + +Changes and bug fixes since 0.4RC4: + + * Fixed traceback when revert file in changeset or log windows. + * Fixed traceback when testing paths in Configure window. + +Changes and bug fixes since 0.4RC3: + + * Activated target revision option in Synchronize window that had been + dormant so far (as reported by Doug Philips). + * Terminate all backgrounded searches in Datamine window upon exit, so + the associated Python process may terminate immediately too. + * New icons by Peer Sommerlund for configuration windows to represent + repo and user config respectively. + * Theme improvement in the Configuration windows (by Peter Ruibal). + * Detect PyGtk and Mercurial installation more accurately in Hgtk + * Removed 'square-boxes' in license window (of About window) caused by + extra form-feed characters. + +Changes and bug fixes since 0.4RC2: + + * Fixed traceback in tracelog, which was broken in 0.4RC2. + * Right-click to diff/visual-diff to selected changeset, which replaced + the earlier diff-to-marked function. + * Create .hgignore file automatically when initializing new repo. + * Fix traceback when users try to enable internal commit dialog with + an empty 'commit' in mercurial.ini's 'tortoisehg' section. + * Handle empty cmd.differ entries in hgrc like hg does + * Register context menu and overlay icon extension onto the Explorer's + Approved list. + * Fixed UTF-8 encoding errors in hgcmd and several error message dialogs. + * New transparent TortoiseHg logo in About dialog, again by Peer Sommerlund. + * New 32x32 icons for dialogs to provide nicer icons when navigating + through the applications with Alt-Tab on Windows. + * Minor improvement/fixes on hgtk to simplify installation on *nix systems. + +Changes and bug fixes since 0.4RC1: + + * Added buttons to stop command execution in Synchronize, Recovery, + as well as any dialogs that use hgcmd dialog, including Update and + Clone dialogs. + * Show progress on status bar when updating changeset viewer. + * Support Mercurial's HGENCODING environment variable. + * [ Feature 1944469 ] Save and recall pull-update option in Synchronize + dialog across sessions. + * [ Bug 1939794 ] Unable to Merge changes with builtin commit UI. + * [ Bug 1941545 ] Clone log window doesn't scroll. + * [ Bug 1943382 ] hgproc.bat not executable without "installer" + * [ Bug 1941368 ] Configure Repository "Test" button results broken. + * [ Bug 1939911 ] Modal Dialogs aren't staying on top on application switch + * [ Bug 1941376 ] hgtk with no parameters gives no help. + * [ Bug 1937966 ] Changelog: utf8 messages handled incorrectly + * [ Bug 1942777 ] National characters are not handled correctly. + +Fixes in Mercurial since 0.3: + + * qimport fixed on Windows + * new built-in filemerge system replaces hgmerge patches + * many fixes for keyword extension + * new -U (context lines) argument for diff and qdiff commands + +New features in 0.3 + + * Major improvements to changelog browser. It is now good enough to + deprecate both hgk and hgview. Neither are bundled with the 0.3 + binary installer, but both can be added by the user if they wish. + Support for external revision log viewers will be dropped in 0.4. + + * The new changelog browser supports filtering by file pattern, + keywords, dates, and branches. It is capable of graphing both the + repository changelog and individual filelogs. Changeset coloring by + author is optional (tortoisehg.authorcolor). All changeset graphing + is done incrementally in batches (tortoisehg.graphlimit: 500) + + * New DataMine application for searching history (hg grep) and + inspecting file histories (hg annotate). This new application is + tabbed to facilitate debugging sessions where search results and + annotations can be grouped together for easy cross-reference. + + * New changeset browser, supports multiple parents intrinsically and + supports a number of file-revision features (view at revision, save + at revision, annotate at revision, revert to revision, etc). The + new changeset browser is also integrated into the changelog browser. + + * Standardized window layouts. Close buttons have been moved to the + toolbar. Dialogs that use progress bars now use a standard status + bar/progress bar widget. Tooltips have been added. + + * Hgtk wrapper application for launching TortoiseHg dialogs from the + command line + + * Support for an external visual editor: tortoisehg.editor. Takes + precedence over ui.editor when viewing files with TortoiseHg + + * Performance improvements in Mercurial itself (cset 0973501e5f4a) + + * New installer bitmap from Peer Sommerlund + + * Misc: The Synchronize dialog has been improved. The Web Serve + dialog no longer requires a subprocess to run the web server. The + configuration dialog has a number of bug fixes for the paths tab, + and now has separators in the drop-down boxes for the varying value + types (current, suggested, history). Http authentication has been + fixed. The hg integration library has seen major cleanups. + +Bug Fixes in 0.3: + + * [ 1863086 ] "Revision Graph" fail on UNC path + Fixed by removing hgk from base install. Integrated log viewer + is UNC path safe. + * [ 1851395 ] Total Commander problem + * [ 1882074 ] global name 'p' is not defined + * [ 1854443 ] View changelog fails + +New features in 0.2 + + * Gtools has been integrated into TortoiseHg proper. It is no longer + bundled as a Mercurial extension. The graphlog extension is now enabled + again by default (only usable from the CLI, however). + + * Context menu icons, application window icons. The context menu has been + simplified. + + * The changelog browser has a number of new features (filters and context + menu options). The tag browser and changelog tagging features have been + merged into this tool. + + * Hgview is now the default history viewer, hgk is being deprecated. + + * An email dialog for interfacing with the patchbomb extension. It can be + reached from the synchronize dialog and from the changelog browser. + + * A new configuration tool (replacing hg-config dialogs) that allows you + to configure TortoiseHg and Mercurial. + + * Most dialogs now use HgThread and GtkUI to run hg commands. These + classes run the command in a background thread and provide GUI prompts + for when user interaction is necessary (http web auth, etc). For some + commands, it also provides a progress bar. + + * A preview of the new Mercurial merge back end. The python hgmerge.py + script is being integrated into Mercurial, and this installer has a + preview of how that will work. You need to unset any ui.merge in your + Mercurial.ini file in order for it to work properly. If you don't + configure anything it will use simplemerge to automatically perform + merges. If conflicts are found it falls back to kdiff3 to resolve + them interactively. + + * Slight improvement on speed of overlay icons display. + + * A new 'about' dialog. + +Bugs fixed in 0.2 + + * [SF Bug #1851395] Overlay icons and context menus are no longer + restricted to MS-Explorer. So other file managers, such as Total + Commander, should be supported. + + * [SF Bug #1844722] Users can now create repositories inside repository + via the context menu. + +Changes since 0.2rc1 + + - N/A - + +
Change 1 of 1 Show Entire File contrib/​hg Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@@ -1,14 +1,14 @@
-#!/usr/bin/env python -# -# mercurial - scalable distributed SCM -# -# Copyright 2005-2007 Matt Mackall <mpm@selenic.com> -# -# This software may be used and distributed according to the terms -# of the GNU General Public License, incorporated herein by reference. - -# enable importing on demand to reduce startup time -from mercurial import demandimport; demandimport.enable() - -import mercurial.dispatch -mercurial.dispatch.run() +#!/usr/bin/env python +# +# mercurial - scalable distributed SCM +# +# Copyright 2005-2007 Matt Mackall <mpm@selenic.com> +# +# This software may be used and distributed according to the terms +# of the GNU General Public License, incorporated herein by reference. + +# enable importing on demand to reduce startup time +from mercurial import demandimport; demandimport.enable() + +import mercurial.dispatch +mercurial.dispatch.run()
Change 1 of 2 Show Entire File contrib/​hgtk 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
 
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
 
 
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
 
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
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
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
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
 
 
 
 
 
464
@@ -1,40 +1,110 @@
 #!/usr/bin/env python  #  # front-end script for TortoiseHg dialogs +#  # Copyright (C) 2008 Steve Borho <steve@borho.org> -# -# Modify this line to the location of your tortoisehg repository -# or set TORTOISEHG_PATH in your environment +# Copyright (C) 2008 TK Soh <teekaysoh@gmail.com> + +# set TORTOISEHG_PATH in your environment to point the location +# of your tortoisehg repository, or modify 'tortoisehg_dir' below:  tortoisehg_dir = '~/tools/tortoisehg-dev'    import os  import sys +import traceback +import pygtk +pygtk.require('2.0') +import gtk +import shlex +from mercurial.i18n import _ +from mercurial import hg, util, fancyopts, commands, cmdutil +from mercurial.repo import RepoError +import mercurial.ui as _ui   -dialogs = '''log synch status clone merge update userconfig repoconfig -serve recovery commit datamine about''' +class ParseError(Exception): + """Exception raised on errors in parsing the command line."""   -nonrepo_commands = 'clone about' +nonrepo_commands = 'userconfig clone about help'   -def help(): - print 'TortoiseHg Dialog Wrapper\n' - print 'hgtk [DIALOG]' - print ' dialogs:', dialogs +def dispatch(args): + "run the command specified in args" + try: + u = _ui.ui(traceback='--traceback' in args) + except util.Abort, inst: + sys.stderr.write(_("abort: %s\n") % inst) + return -1 + return _runcatch(u, args)   -def main(command): - dlist = dialogs.split() - l = [] - for d in dlist: - if d.startswith(command): - l.append(d) - if not l: - print 'dialog', command, 'not recognized' - help() - sys.exit(1) - if len(l) > 1: - print 'dialog', command, 'is ambiguous' - print '\tcould be one of', ' '.join(l) - sys.exit(1) - command = l[0] +def _parse(ui, args): + options = {} + cmdoptions = {} + + try: + args = fancyopts.fancyopts(args, globalopts, options) + except fancyopts.getopt.GetoptError, inst: + raise ParseError(None, inst) + + if args: + cmd, args = args[0], args[1:] + aliases, i = cmdutil.findcmd(ui, cmd, table) + cmd = aliases[0] + c = list(i[1]) + else: + cmd = None + c = [] + + # combine global options into local + for o in globalopts: + c.append((o[0], o[1], options[o[1]], o[3])) + + try: + args = fancyopts.fancyopts(args, c, cmdoptions) + except fancyopts.getopt.GetoptError, inst: + raise ParseError(cmd, inst) + + # separate global options back out + for o in globalopts: + n = o[1] + options[n] = cmdoptions[n] + del cmdoptions[n] + + return (cmd, cmd and i[0] or None, args, options, cmdoptions) + +def _runcatch(ui, args): + try: + try: + return runcommand(ui, args) + finally: + ui.flush() + except ParseError, inst: + if inst.args[0]: + ui.warn(_("hgtk %s: %s\n") % (inst.args[0], inst.args[1])) + help_(ui, inst.args[0]) + else: + ui.warn(_("hgtk: %s\n") % inst.args[1]) + help_('shortlist') + except cmdutil.AmbiguousCommand, inst: + ui.warn(_("hgtk: command '%s' is ambiguous:\n %s\n") % + (inst.args[0], " ".join(inst.args[1]))) + except cmdutil.UnknownCommand, inst: + ui.warn(_("hgtk: unknown command '%s'\n") % inst.args[0]) + help_(ui, 'shortlist') + except RepoError, inst: + ui.warn(_("abort: %s!\n") % inst) + except util.Abort, inst: + ui.warn(_("abort: %s\n") % inst) + + return -1 + +def runcommand(ui, args): + fullargs = args + cmd, func, args, options, cmdoptions = _parse(ui, args) + ui.updateopts(options["verbose"]) + + if options['help']: + return help_(ui, cmd) + elif not cmd: + return help_(ui, 'shortlist')     if hasattr(sys, "frozen"):   # Py2exe environment @@ -50,63 +120,345 @@
  try:   # assuming TortoiseHg source layout, with hgtk in contrib   path = os.path.dirname(os.path.realpath(__file__)) - norm = os.path.normpath(os.path.join(path, '..')) - if norm not in sys.path: - sys.path.append(norm) - except NameError: # __file__ is not always available - pass + except NameError: + # __file__ not available in pdb mode + path = os.path.dirname(sys.argv[0]) + norm = os.path.normpath(os.path.join(path, '..')) + if norm not in sys.path: + sys.path.append(norm)     try:   from hggtk import hglib - except ImportError: - # fix "tortoisehg_dir" at the top of this script, or ... - print 'Please set TORTOISEHG_PATH to location of your ' \ - 'tortoisehg repository' - sys.exit(1) + except ImportError, inst: + m = str(inst).split()[-1] + if m in "hglib hggtk".split(): + # fix "tortoisehg_dir" at the top of this script, or ... + raise util.Abort(_('Please set TORTOISEHG_PATH to location ' + 'of your tortoisehg repository')) + else: + raise util.Abort(_('could not import module %s!\n' % m)) + except: + raise   - cwd = os.getcwd() - root = hglib.rootpath(cwd) - opts = { 'root' : root, 'cwd' : cwd } + path = hglib.rootpath(os.getcwd()) + if path: + try: + lui = _ui.ui(parentui=ui) + lui.readconfig(os.path.join(path, ".hg", "hgrc")) + except IOError: + pass + else: + lui = ui + if options['repository']: + path = lui.expandpath(options['repository'])   - if not root and command not in nonrepo_commands: - print 'No repository found, and', command, 'requires one.' - sys.exit(1) + if cmd not in nonrepo_commands.split(): + try: + repo = hg.repository(ui, path=path) + except RepoError, inst: + # try to guess the repo from first of file args + root = None + if args: + path = hglib.rootpath(args[0]) + if path: + repo = hg.repository(ui, path=path) + else: + raise RepoError(_("There is no Mercurial repository here" + " (.hg not found)")) + cmdoptions['root'] = os.path.abspath(path)   - # add aliases to taste (and to commands at top of file) - if command in ('log'): - from hggtk.history import run - opts['files'] = [root] - elif command in ('datamine'): - from hggtk.datamine import run - elif command in ('synch'): - from hggtk.synch import run - elif command in ('status'): - from hggtk.status import run - elif command in ('clone'): - from hggtk.clone import run - elif command in ('merge'): - from hggtk.merge import run - elif command in ('update'): - from hggtk.update import run - elif command in ('serve'): - from hggtk.serve import run - elif command in ('recovery'): - from hggtk.recovery import run - elif command in ('commit'): - from hggtk.commit import run - elif command in ('repoconfig'): - from hggtk.thgconfig import run - opts['files'] = [root] - elif command in ('userconfig'): - from hggtk.thgconfig import run - elif command in ('about'): - from hggtk.about import run + try: + return func(ui, *args, **cmdoptions) + except TypeError, inst: + # was this an argument error? + tb = traceback.extract_tb(sys.exc_info()[2]) + if len(tb) != 1: # no + raise + raise ParseError(cmd, _("invalid arguments")) + +def about(ui, **opts): + """about TortoiseHg""" + from hggtk.about import run   run(**opts)   +def clone(ui, source=None, dest=None, **opts): + """clone tool""" + from hggtk.clone import run + opts['files'] = [os.path.abspath(x) for x in (source, dest) if x] + run(**opts) + +def commit(ui, *pats, **opts): + """commit tool""" + from hggtk.commit import run + opts['files'] = [os.path.abspath(x) for x in pats] + run(**opts) + +def userconfig(ui, **opts): + """user configuration editor""" + from hggtk.thgconfig import run + run(**opts) + +def repoconfig(ui, *pats, **opts): + """repository configuration editor""" + from hggtk.thgconfig import run + opts['files'] = opts['root'] + run(**opts) + +def datamine(ui, *pats, **opts): + """repository search and annotate tool""" + from hggtk.datamine import run + run(**opts) + +def log(ui, *pats, **opts): + """changelog viewer""" + from hggtk.history import run + opts['files'] = [os.path.abspath(x) for x in pats] + run(**opts) + +def merge(ui, node=None, rev=None, **opts): + """merge tool """ + from hggtk.merge import run + run(**opts) + +def recovery(ui, *pats, **opts): + """recover, rollback & verify""" + from hggtk.recovery import run + run(**opts) + +def serve(ui, **opts): + """web server""" + from hggtk.serve import run + run(**opts) + +def status(ui, *pats, **opts): + """file status viewer + + Also do add, remove and revert. + """ + + from hggtk.status import run + opts['files'] = [os.path.abspath(x) for x in pats] + run(**opts) + +def synch(ui, **opts): + """repository synchronization tool""" + from hggtk.synch import run + run(**opts) + +def update(ui, **opts): + """update/checkout tool""" + from hggtk.update import run + run(**opts) + +### help management, adapted from mercurial.commands.help_() +def help_(ui, name=None, with_version=False): + """show help for a command, extension, or list of commands + + With no arguments, print a list of commands and short help. + + Given a command name, print help for that command. + + Given an extension name, print help for that extension, and the + commands it provides.""" + option_lists = [] + + def addglobalopts(aliases): + if ui.verbose: + option_lists.append((_("global options:"), globalopts)) + if name == 'shortlist': + option_lists.append((_('use "hgtk help" for the full list ' + 'of commands'), ())) + else: + if name == 'shortlist': + msg = _('use "hgtk help" for the full list of commands ' + 'or "hgtk -v" for details') + elif aliases: + msg = _('use "hgtk -v help%s" to show aliases and ' + 'global options') % (name and " " + name or "") + else: + msg = _('use "hgtk -v help %s" to show global options') % name + option_lists.append((msg, ())) + + def helpcmd(name): + if with_version: + version_(ui) + ui.write('\n') + aliases, i = cmdutil.findcmd(ui, name, table) + # synopsis + ui.write("%s\n" % i[2]) + + # aliases + if not ui.quiet and len(aliases) > 1: + ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:])) + + # description + doc = i[0].__doc__ + if not doc: + doc = _("(No help text available)") + if ui.quiet: + doc = doc.splitlines(0)[0] + ui.write("\n%s\n" % doc.rstrip()) + + if not ui.quiet: + # options + if i[1]: + option_lists.append((_("options:\n"), i[1])) + + addglobalopts(False) + + def helplist(header, select=None): + h = {} + cmds = {} + for c, e in table.items(): + f = c.split("|", 1)[0] + if select and not select(f): + continue + if name == "shortlist" and not f.startswith("^"): + continue + f = f.lstrip("^") + if not ui.debugflag and f.startswith("debug"): + continue + doc = e[0].__doc__ + if not doc: + doc = _("(No help text available)") + h[f] = doc.splitlines(0)[0].rstrip() + cmds[f] = c.lstrip("^") + + if not h: + ui.status(_('no commands defined\n')) + return + + ui.status(header) + fns = h.keys() + fns.sort() + m = max(map(len, fns)) + for f in fns: + if ui.verbose: + commands = cmds[f].replace("|",", ") + ui.write(" %s:\n %s\n"%(commands, h[f])) + else: + ui.write(' %-*s %s\n' % (m, f, h[f])) + + if not ui.quiet: + addglobalopts(True) + + def helptopic(name): + v = None + for i in help.helptable: + l = i.split('|') + if name in l: + v = i + header = l[-1] + if not v: + raise cmdutil.UnknownCommand(name) + + # description + doc = help.helptable[v] + if not doc: + doc = _("(No help text available)") + if callable(doc): + doc = doc() + + ui.write("%s\n" % header) + ui.write("%s\n" % doc.rstrip()) + + def helpext(name): + try: + mod = extensions.find(name) + except KeyError: + raise cmdutil.UnknownCommand(name) + + doc = (mod.__doc__ or _('No help text available')).splitlines(0) + ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0])) + for d in doc[1:]: + ui.write(d, '\n') + + ui.status('\n') + + try: + ct = mod.cmdtable + except AttributeError: + ct = {} + + modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct]) + helplist(_('list of commands:\n\n'), modcmds.has_key) + + if name and name != 'shortlist': + i = None + for f in (helpcmd, helptopic, helpext): + try: + f(name) + i = None + break + except cmdutil.UnknownCommand, inst: + i = inst + if i: + raise i + + else: + # program name + if ui.verbose or with_version: + version_(ui) + else: + ui.status(_("Hgtk - TortoiseHg's GUI tools for Mercurial SCM (Hg)\n")) + ui.status('\n') + + # list of commands + if name == "shortlist": + header = _('basic commands:\n\n') + else: + header = _('list of commands:\n\n') + + helplist(header) + + # list all option lists + opt_output = [] + for title, options in option_lists: + opt_output.append(("\n%s" % title, None)) + for shortopt, longopt, default, desc in options: + if "DEPRECATED" in desc and not ui.verbose: continue + opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt, + longopt and " --%s" % longopt), + "%s%s" % (desc, + default + and _(" (default: %s)") % default + or ""))) + + if opt_output: + opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0]) + for first, second in opt_output: + if second: + ui.write(" %-*s %s\n" % (opts_len, first, second)) + else: + ui.write("%s\n" % first) + +def version_(ui): + """output version and copyright information""" + pass + +globalopts = [ + ('R', 'repository', '', + _('repository root directory or symbolic path name')), + ('v', 'verbose', None, _('enable additional output')), + ('h', 'help', None, _('display help and exit')), +] + +table = { + "^about": (about, [], _('hgtk about')), + "^clone": (clone, [], _('hgtk clone SOURCE [DEST]')), + "^commit|ci": (commit, [], _('hgtk commit [FILE]...')), + "^datamine": (datamine, [], _('hgtk datamine')), + "^log|history": (log, [], _('hgtk log [FILE]')), + "^merge": (merge, [], _('hgtk merge')), + "^recovery": (recovery, [], _('hgtk recovery')), + "^synch": (synch, [], _('hgtk synch')), + "^status": (status, [], _('hgtk status [FILE]...')), + "^userconfig": (userconfig, [], _('hgtk userconfig')), + "^repoconfig": (repoconfig, [], _('hgtk repoconfig')), + "^serve": (serve, [], _('hgtk serve')), + "^update|checkout|co": (update, [], _('hgtk update')), + "help": (help_, [], _('hgtk help [COMMAND]')), +}    if __name__=='__main__': - if len(sys.argv) != 2: - help() - else: - main(sys.argv[1]) - sys.exit(0) + sys.exit(dispatch(sys.argv[1:]))
 
168
169
170
 
 
 
 
 
171
172
 
173
174
175
 
168
169
170
171
172
173
174
175
176
 
177
178
179
180
@@ -168,8 +168,13 @@
  repo = self.get_repo_for_path(path)   cwd = os.path.isdir(path) and path or os.path.dirname(path)   + if repo is not None: + root = repo.root + else: + root = cwd +   cmdopts = [sys.executable, self.hgproc] - cmdopts += ['--root', repo.root] + cmdopts += ['--root', root]   cmdopts += ['--cwd', cwd]   cmdopts += ['--command', hgcmd]  
Change 1 of 1 Show Entire File hggtk/​about.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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
@@ -1,86 +1,87 @@
-# -# TortoiseHg About dialog -# -# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> -# - -import os -import sys - -import pygtk -pygtk.require('2.0') -import gtk -import gobject -import pango -import shlib - -import tortoise.version -import mercurial.version - -def browse_url(url): - import threading - def start_browser(): - if os.name == 'nt': - import win32api, win32con - win32api.ShellExecute(0, "open", url, None, "", - win32con.SW_SHOW) - else: - import gconf - client = gconf.client_get_default() - browser = client.get_string( - '/desktop/gnome/url-handlers/http/command') + '&' - os.system(browser % url) - threading.Thread(target=start_browser).start() - -def url_handler(dialog, link, user_data): - browse_url(link) - -gtk.about_dialog_set_url_hook(url_handler, None) - -def make_version(tuple): - vers = ".".join([str(x) for x in tuple]) - return vers - -class AboutDialog(gtk.AboutDialog): - def __init__(self): - super(AboutDialog, self).__init__() - - lib_versions = ', '.join([ - "Mercurial-%s" % mercurial.version.get_version(), - "Python-%s" % make_version(sys.version_info[0:3]), - "PyGTK-%s" % make_version(gtk.pygtk_version), - "GTK-%s" % make_version(gtk.gtk_version), - ]) - - comment = "Several icons are courtesy of the TortoiseSVN project" - - self.set_website("http://tortoisehg.sourceforge.net/") - self.set_name("TortoiseHg") - self.set_version("(version %s)" % tortoise.version.get_version()) - if hasattr(self, 'set_wrap_license'): - self.set_wrap_license(True) - self.set_copyright("Copyright 2008 TK Soh and others") - - hg_icon = os.path.normpath(shlib.get_tortoise_icon('thg_logo_92x50.png')) - prog_root = os.path.dirname(os.path.dirname(os.path.dirname(hg_icon))) - license_file = os.path.join(prog_root, "COPYING.txt") - - self.set_license(file(license_file).read()) - self.set_comments("with " + lib_versions + "\n\n" + comment) - self.set_logo(gtk.gdk.pixbuf_new_from_file(hg_icon)) - self.set_icon_from_file(hg_icon) - - # somehow clicking on the Close button doesn't automatically - # close the About dialog... - self.connect('response', gtk.main_quit) - -def run(*args, **opts): - dialog = AboutDialog() - dialog.show_all() - gtk.gdk.threads_init() - gtk.gdk.threads_enter() - gtk.main() - gtk.gdk.threads_leave() - -if __name__ == "__main__": - run() +# +# TortoiseHg About dialog +# +# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> +# + +import os +import sys + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import pango +import shlib + +import tortoise.version +import mercurial.version + +def browse_url(url): + import threading + def start_browser(): + if os.name == 'nt': + import win32api, win32con + win32api.ShellExecute(0, "open", url, None, "", + win32con.SW_SHOW) + else: + import gconf + client = gconf.client_get_default() + browser = client.get_string( + '/desktop/gnome/url-handlers/http/command') + '&' + os.system(browser % url) + threading.Thread(target=start_browser).start() + +def url_handler(dialog, link, user_data): + browse_url(link) + +gtk.about_dialog_set_url_hook(url_handler, None) + +def make_version(tuple): + vers = ".".join([str(x) for x in tuple]) + return vers + +class AboutDialog(gtk.AboutDialog): + def __init__(self): + super(AboutDialog, self).__init__() + + lib_versions = ', '.join([ + "Mercurial-%s" % mercurial.version.get_version(), + "Python-%s" % make_version(sys.version_info[0:3]), + "PyGTK-%s" % make_version(gtk.pygtk_version), + "GTK-%s" % make_version(gtk.gtk_version), + ]) + + comment = "Several icons are courtesy of the TortoiseSVN project" + + self.set_website("http://tortoisehg.sourceforge.net/") + self.set_name("TortoiseHg") + self.set_version("(version %s)" % tortoise.version.get_version()) + if hasattr(self, 'set_wrap_license'): + self.set_wrap_license(True) + self.set_copyright("Copyright 2008 TK Soh and others") + + thg_logo = os.path.normpath(shlib.get_tortoise_icon('thg_logo_92x50.png')) + thg_icon = os.path.normpath(shlib.get_tortoise_icon('thg_logo.ico')) + prog_root = os.path.dirname(os.path.dirname(os.path.dirname(thg_icon))) + license_file = os.path.join(prog_root, "COPYING.txt") + + self.set_license(file(license_file).read()) + self.set_comments("with " + lib_versions + "\n\n" + comment) + self.set_logo(gtk.gdk.pixbuf_new_from_file(thg_logo)) + self.set_icon_from_file(thg_icon) + + # somehow clicking on the Close button doesn't automatically + # close the About dialog... + self.connect('response', gtk.main_quit) + +def run(*args, **opts): + dialog = AboutDialog() + dialog.show_all() + gtk.gdk.threads_init() + gtk.gdk.threads_enter() + gtk.main() + gtk.gdk.threads_leave() + +if __name__ == "__main__": + run()
Change 1 of 1 Show Entire File hggtk/​addremove.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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
@@ -1,50 +1,50 @@
-# -# Add/Remove dialog for TortoiseHg -# -# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> -# - -try: - import pygtk - pygtk.require("2.0") -except: - pass - -import gtk -import gobject -from mercurial import ui, util, hg -from mercurial.i18n import _ -from status import GStatus - -def run(hgcmd='add', root='', cwd='', files=[], **opts): - u = ui.ui() - u.updateopts(debug=False, traceback=False) - repo = hg.repository(u, path=root) - - cmdoptions = { - 'all':False, 'clean':False, 'ignored':False, 'modified':False, - 'added':True, 'removed':True, 'deleted':True, 'unknown':False, 'rev':[], - 'exclude':[], 'include':[], 'debug':True,'verbose':True - } - - if hgcmd == 'add': - cmdoptions['unknown'] = True - elif hgcmd == 'remove': - cmdoptions['clean'] = True - else: - raise "Invalid command '%s'" % hgcmd - - dialog = GStatus(u, repo, cwd, files, cmdoptions, True) - - gtk.gdk.threads_init() - gtk.gdk.threads_enter() - dialog.display() - gtk.main() - gtk.gdk.threads_leave() - -if __name__ == "__main__": - import sys - opts = {} - opts['hgcmd'] = 'adda' - opts['root'] = len(sys.argv) > 1 and sys.argv[1] or '' - run(**opts) +# +# Add/Remove dialog for TortoiseHg +# +# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> +# + +try: + import pygtk + pygtk.require("2.0") +except: + pass + +import gtk +import gobject +from mercurial import ui, util, hg +from mercurial.i18n import _ +from status import GStatus + +def run(hgcmd='add', root='', cwd='', files=[], **opts): + u = ui.ui() + u.updateopts(debug=False, traceback=False) + repo = hg.repository(u, path=root) + + cmdoptions = { + 'all':False, 'clean':False, 'ignored':False, 'modified':False, + 'added':True, 'removed':True, 'deleted':True, 'unknown':False, 'rev':[], + 'exclude':[], 'include':[], 'debug':True,'verbose':True + } + + if hgcmd == 'add': + cmdoptions['unknown'] = True + elif hgcmd == 'remove': + cmdoptions['clean'] = True + else: + raise "Invalid command '%s'" % hgcmd + + dialog = GStatus(u, repo, cwd, files, cmdoptions, True) + + gtk.gdk.threads_init() + gtk.gdk.threads_enter() + dialog.display() + gtk.main() + gtk.gdk.threads_leave() + +if __name__ == "__main__": + import sys + opts = {} + opts['hgcmd'] = 'adda' + opts['root'] = len(sys.argv) > 1 and sys.argv[1] or '' + run(**opts)
Change 1 of 1 Show Entire File hggtk/​backout.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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
@@ -1,129 +1,129 @@
-# -# backout.py - TortoiseHg's dialog for backing out changeset -# -# Copyright (C) 2008 Steve Borho <steve@borho.org> -# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> -# - -import os -import sys -import gtk -import pango -from dialog import * -from hgcmd import CmdDialog -import histselect - -class BackoutDialog(gtk.Window): - """ Backout effect of a changeset """ - def __init__(self, root='', rev=''): - """ Initialize the Dialog """ - gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) - - self.root = root - self.set_title('Backout changeset - ' + rev) - self.set_default_size(600, 400) - self.notify_func = None - - self.tbar = gtk.Toolbar() - self.tips = gtk.Tooltips() - - sep = gtk.SeparatorToolItem() - sep.set_expand(True) - sep.set_draw(False) - - tbuttons = [ - self._toolbutton(gtk.STOCK_GO_BACK, 'Backout', - self._backout_clicked, - 'Backout selected changeset'), - sep, - self._toolbutton(gtk.STOCK_CLOSE, 'Close', - self._close_clicked, - 'Close Window') - ] - for btn in tbuttons: - self.tbar.insert(btn, -1) - vbox = gtk.VBox() - self.add(vbox) - vbox.pack_start(self.tbar, False, False, 2) - - # From: combo box - self.reventry = gtk.Entry() - self.reventry.set_text(rev) - self.browse = gtk.Button("Browse...") - self.browse.connect('clicked', self._btn_rev_clicked) - - hbox = gtk.HBox() - hbox.pack_start(gtk.Label('Revision to backout:'), False, False, 4) - hbox.pack_start(self.reventry, True, True, 4) - hbox.pack_start(self.browse, False, False, 4) - vbox.pack_start(hbox, False, False, 4) - - self.logview = gtk.TextView(buffer=None) - self.logview.set_editable(True) - self.logview.modify_font(pango.FontDescription("Monospace")) - buffer = self.logview.get_buffer() - buffer.set_text('Backed out changeset: ' + rev) - scrolledwindow = gtk.ScrolledWindow() - scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN) - scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - scrolledwindow.add(self.logview) - scrolledwindow.set_border_width(4) - frame = gtk.Frame('Backout commit message') - frame.set_border_width(4) - frame.add(scrolledwindow) - self.tips.set_tip(frame, - 'Commit message text for new changeset that reverses the' - ' effect of the change being backed out.') - vbox.pack_start(frame, True, True, 4) - - def _close_clicked(self, toolbutton, data=None): - self.destroy() - - def set_notify_func(self, func, *args): - self.notify_func = func - self.notify_args = args - - def _btn_rev_clicked(self, button): - """ select revision from history dialog """ - rev = histselect.select(self.root) - if rev is not None: - self.reventry.set_text(rev) - buffer = self.logview.get_buffer() - buffer.set_text('Backed out changeset: ' + rev) - - def _toolbutton(self, stock, label, handler, tip): - tbutton = gtk.ToolButton(stock) - tbutton.set_label(label) - tbutton.set_tooltip(self.tips, tip) - tbutton.connect('clicked', handler) - return tbutton - - def _backout_clicked(self, button): - buffer = self.logview.get_buffer() - start, end = buffer.get_bounds() - cmdline = ['hg', 'backout', '--rev', self.reventry.get_text(), - '--message', buffer.get_text(start, end)] - dlg = CmdDialog(cmdline) - dlg.show_all() - dlg.run() - dlg.hide() - if self.notify_func: - self.notify_func(self.notify_args) - -def run(root='', **opts): - # This dialog is intended to be launched by the changelog browser - # It's not expected to be used from hgproc or the command line. I - # leave this path in place for testing purposes. - dialog = BackoutDialog(root, 'tip') - dialog.show_all() - dialog.connect('destroy', gtk.main_quit) - gtk.gdk.threads_init() - gtk.gdk.threads_enter() - gtk.main() - gtk.gdk.threads_leave() - -if __name__ == "__main__": - import sys - opts = {} - opts['root'] = len(sys.argv) > 1 and sys.argv[1] or os.getcwd() - run(**opts) +# +# backout.py - TortoiseHg's dialog for backing out changeset +# +# Copyright (C) 2008 Steve Borho <steve@borho.org> +# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> +# + +import os +import sys +import gtk +import pango +from dialog import * +from hgcmd import CmdDialog +import histselect + +class BackoutDialog(gtk.Window): + """ Backout effect of a changeset """ + def __init__(self, root='', rev=''): + """ Initialize the Dialog """ + gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) + + self.root = root + self.set_title('Backout changeset - ' + rev) + self.set_default_size(600, 400) + self.notify_func = None + + self.tbar = gtk.Toolbar() + self.tips = gtk.Tooltips() + + sep = gtk.SeparatorToolItem() + sep.set_expand(True) + sep.set_draw(False) + + tbuttons = [ + self._toolbutton(gtk.STOCK_GO_BACK, 'Backout', + self._backout_clicked, + 'Backout selected changeset'), + sep, + self._toolbutton(gtk.STOCK_CLOSE, 'Close', + self._close_clicked, + 'Close Window') + ] + for btn in tbuttons: + self.tbar.insert(btn, -1) + vbox = gtk.VBox() + self.add(vbox) + vbox.pack_start(self.tbar, False, False, 2) + + # From: combo box + self.reventry = gtk.Entry() + self.reventry.set_text(rev) + self.browse = gtk.Button("Browse...") + self.browse.connect('clicked', self._btn_rev_clicked) + + hbox = gtk.HBox() + hbox.pack_start(gtk.Label('Revision to backout:'), False, False, 4) + hbox.pack_start(self.reventry, True, True, 4) + hbox.pack_start(self.browse, False, False, 4) + vbox.pack_start(hbox, False, False, 4) + + self.logview = gtk.TextView(buffer=None) + self.logview.set_editable(True) + self.logview.modify_font(pango.FontDescription("Monospace")) + buffer = self.logview.get_buffer() + buffer.set_text('Backed out changeset: ' + rev) + scrolledwindow = gtk.ScrolledWindow() + scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN) + scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolledwindow.add(self.logview) + scrolledwindow.set_border_width(4) + frame = gtk.Frame('Backout commit message') + frame.set_border_width(4) + frame.add(scrolledwindow) + self.tips.set_tip(frame, + 'Commit message text for new changeset that reverses the' + ' effect of the change being backed out.') + vbox.pack_start(frame, True, True, 4) + + def _close_clicked(self, toolbutton, data=None): + self.destroy() + + def set_notify_func(self, func, *args): + self.notify_func = func + self.notify_args = args + + def _btn_rev_clicked(self, button): + """ select revision from history dialog """ + rev = histselect.select(self.root) + if rev is not None: + self.reventry.set_text(rev) + buffer = self.logview.get_buffer() + buffer.set_text('Backed out changeset: ' + rev) + + def _toolbutton(self, stock, label, handler, tip): + tbutton = gtk.ToolButton(stock) + tbutton.set_label(label) + tbutton.set_tooltip(self.tips, tip) + tbutton.connect('clicked', handler) + return tbutton + + def _backout_clicked(self, button): + buffer = self.logview.get_buffer() + start, end = buffer.get_bounds() + cmdline = ['hg', 'backout', '--rev', self.reventry.get_text(), + '--message', buffer.get_text(start, end)] + dlg = CmdDialog(cmdline) + dlg.show_all() + dlg.run() + dlg.hide() + if self.notify_func: + self.notify_func(self.notify_args) + +def run(root='', **opts): + # This dialog is intended to be launched by the changelog browser + # It's not expected to be used from hgproc or the command line. I + # leave this path in place for testing purposes. + dialog = BackoutDialog(root, 'tip') + dialog.show_all() + dialog.connect('destroy', gtk.main_quit) + gtk.gdk.threads_init() + gtk.gdk.threads_enter() + gtk.main() + gtk.gdk.threads_leave() + +if __name__ == "__main__": + import sys + opts = {} + opts['root'] = len(sys.argv) > 1 and sys.argv[1] or os.getcwd() + run(**opts)
 
725
726
727
728
729
730
731
 
725
726
727
 
728
729
730
@@ -725,7 +725,6 @@
  if dialog.run() == gtk.RESPONSE_NO:   return   cmdline = ['hg', 'revert', '--verbose', '--rev', str(rev), self.curfile] - self.restore_cwd()   dlg = CmdDialog(cmdline)   dlg.run()   dlg.hide()
Show Entire File hggtk/​clone.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Change 1 of 7 Show Entire File hggtk/​commit.py Stacked
 
39
40
41
 
 
 
 
42
43
44
 
69
70
71
 
72
73
74
 
87
88
89
 
 
 
 
90
91
92
 
186
187
188
 
189
190
191
192
193
 
 
 
 
 
 
194
195
196
 
208
209
210
 
211
212
213
 
242
243
244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
246
247
 
296
297
298
 
299
300
 
 
 
 
 
 
 
301
302
303
 
39
40
41
42
43
44
45
46
47
48
 
73
74
75
76
77
78
79
 
92
93
94
95
96
97
98
99
100
101
 
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
 
224
225
226
227
228
229
230
 
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
 
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
@@ -39,6 +39,10 @@
    ### Overrides of base class methods ###   + def init(self): + GStatus.init(self) + self._last_commit_id = None +   def parse_opts(self):   GStatus.parse_opts(self)   @@ -69,6 +73,7 @@
  for entry in self.model :   if entry[1] in 'MAR':   entry[0] = True + self._update_check_count()       def save_settings(self): @@ -87,6 +92,10 @@
    def get_tbbuttons(self):   tbbuttons = GStatus.get_tbbuttons(self) + tbbuttons.insert(2, gtk.SeparatorToolItem()) + self._undo_button = self.make_toolbutton(gtk.STOCK_UNDO, '_Undo', + self._undo_clicked, tip='undo recent commit') + tbbuttons.insert(2, self._undo_button)   tbbuttons.insert(2, self.make_toolbutton(gtk.STOCK_OK, '_Commit',   self._commit_clicked, tip='commit'))   return tbbuttons @@ -186,11 +195,18 @@
  def reload_status(self):   success = GStatus.reload_status(self)   self._check_merge() + self._check_undo()   return success       ### End of overridable methods ###   + def _check_undo(self): + can_undo = os.path.exists(self.repo.sjoin("undo")) and \ + self._last_commit_id is not None + self._undo_button.set_sensitive(can_undo) + +   def _check_merge(self):   # disable the checkboxes on the filelist if repo in merging state   merged = len(self.repo.changectx(None).parents()) > 1 @@ -208,6 +224,7 @@
  for entry in self.model:   if entry[1] in 'MARD':   entry[0] = True + self._update_check_count()     # pre-fill commit message   self.text.get_buffer().set_text('merge') @@ -242,6 +259,28 @@
  return True     + def _undo_clicked(self, toolbutton, data=None): + response = Confirm('Undo commit', [], self, 'Undo last commit').run() + if response != gtk.RESPONSE_YES: + return + + tip = self._get_tip_rev(True) + if not tip == self._last_commit_id: + Prompt('Undo commit', + 'Unable to undo!\n\n' + 'Tip revision differs from last commit.', + self).run() + return + + try: + self.repo.rollback() + self._last_commit_id = None + self.reload_status() + except: + Prompt('Undo commit', 'Errors during rollback!', + self).run() + +   def _should_addremove(self, files):   if self.test_opt('addremove'):   return True @@ -296,8 +335,16 @@
  self.text.set_buffer(gtk.TextBuffer())   self._update_recent_messages(self.opts['message'])   shell_notify([self.cwd] + files) + self._last_commit_id = self._get_tip_rev(True)   self.reload_status()   + def _get_tip_rev(self, refresh=False): + if refresh: + self.repo.invalidate() + cl = self.repo.changelog + tip = cl.node(nullrev + cl.count()) + return hex(tip) +  def launch(root='', files=[], cwd='', main=True):   u = ui.ui()   u.updateopts(debug=False, traceback=False)
Change 1 of 4 Show Entire File hggtk/​datamine.py Stacked
 
3
4
5
 
 
6
7
8
 
38
39
40
41
 
42
43
44
 
77
78
79
 
 
 
 
80
81
82
 
344
345
346
347
 
348
349
 
 
 
 
 
 
 
 
350
351
352
 
3
4
5
6
7
8
9
10
 
40
41
42
 
43
44
45
46
 
79
80
81
82
83
84
85
86
87
88
 
350
351
352
 
353
354
355
356
357
358
359
360
361
362
363
364
365
366
@@ -3,6 +3,8 @@
 #  # Copyright (C) 2008 Steve Borho <steve@borho.org>   +import pygtk +pygtk.require('2.0')  import gtk  import gobject  import os @@ -38,7 +40,7 @@
    def get_tbbuttons(self):   self.stop_button = self.make_toolbutton(gtk.STOCK_STOP, 'Stop', - self._stop_search, tip='Stop operation on current tab') + self._stop_current_search, tip='Stop operation on current tab')   return [   self.make_toolbutton(gtk.STOCK_FIND, 'New Search',   self._search_clicked, tip='Open new search tab'), @@ -77,6 +79,10 @@
  self.stop_button.set_sensitive(False)   return vbox   + def _destroying(self, gtkobj): + self._stop_all_searches() + GDialog._destroying(self, gtkobj) +   def ann_header_context_menu(self, treeview):   _menu = gtk.Menu()   _button = gtk.CheckMenuItem("Filename") @@ -344,9 +350,17 @@
  self.curpath = fromutf(model[iter][self.COL_PATH])   self.stbar.set_status_text(toutf(model[iter][self.COL_TOOLTIP]))   - def _stop_search(self, button, widget): + def _stop_current_search(self, button, widget):   num = self.notebook.get_current_page()   frame = self.notebook.get_nth_page(num) + self._stop_search(frame) + + def _stop_all_searches(self): + for num in xrange(self.notebook.get_n_pages()): + frame = self.notebook.get_nth_page(num) + self._stop_search(frame) + + def _stop_search(self, frame):   if hasattr(frame, '_mythread') and frame._mythread:   frame._mythread.terminate()   frame._mythread.join()
Change 1 of 2 Show Entire File hggtk/​gdialog.py Stacked
 
101
102
103
 
104
105
106
 
 
 
107
108
109
 
302
303
304
305
306
307
308
309
310
 
311
312
313
 
101
102
103
104
105
106
107
108
109
110
111
112
113
 
306
307
308
 
 
 
 
 
 
309
310
311
312
@@ -101,9 +101,13 @@
  self.tmproot = None   self.toolbuttons = {}   self.settings = Settings(self.__class__.__name__) + self.init()     ### Following methods are meant to be overridden by subclasses ###   + def init(self): + pass +   def parse_opts(self):   pass   @@ -302,12 +306,7 @@
  # Subclass provides extra stuff in bottom hbox   extras = self.get_extras()   if extras: - hbox = gtk.HBox(False, 0) - hbox.set_border_width(6) - hbox.pack_start(extras, False, False) - # Hack! this prevents mysterious silent crashes. - hbox.pack_start(gtk.Label(''), True, True) - vbox.pack_end(hbox, False, False, 0) + vbox.pack_end(extras, False, False, 0)     self.connect('destroy', self._destroying)   self.connect('delete_event', self.should_live)
Change 1 of 1 Show Entire File hggtk/​hgcmd.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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
@@ -1,169 +1,169 @@
-# -# A simple dialog to execute random command for TortoiseHg -# -# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> -# - -import pygtk -pygtk.require("2.0") - -import gtk -import gobject -import pango -import os -import threading -import Queue -from hglib import HgThread, hgcmd_toq, toutf -from shlib import set_tortoise_icon, get_system_times - -class CmdDialog(gtk.Dialog): - def __init__(self, cmdline, progressbar=True, width=520, height=400): - title = 'hg ' + ' '.join(cmdline[1:]) - gtk.Dialog.__init__(self, - title=title, - flags=gtk.DIALOG_MODAL, - #buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) - ) - - set_tortoise_icon(self, 'hg.ico') - self.cmdline = cmdline - self.returncode = None - - # construct dialog - self.set_default_size(width, height) - - self._button_stop = gtk.Button("Stop") - self._button_stop.connect('clicked', self._on_stop_clicked) - self.action_area.pack_start(self._button_stop) - - self._button_ok = gtk.Button("Close") - self._button_ok.connect('clicked', self._on_ok_clicked) - self.action_area.pack_start(self._button_ok) - - self.connect('delete-event', self._delete) - self.connect('response', self._response) - - self.pbar = None - if progressbar: - self.last_pbar_update = 0 - - hbox = gtk.HBox() - - self.status_text = gtk.Label() - self.status_text.set_text(toutf(" ".join(cmdline).replace("\n", " "))) - self.status_text.set_alignment(0, 0.5) - self.status_text.set_ellipsize(pango.ELLIPSIZE_END) - hbox.pack_start(self.status_text, True, True, 3) - - # Create a centering alignment object - align = gtk.Alignment(0.0, 0.0, 1, 0) - hbox.pack_end(align, False, False, 3) - align.show() - - # create the progress bar - self.pbar = gtk.ProgressBar() - align.add(self.pbar) - self.pbar.pulse() - self.pbar.show() - - self.vbox.pack_start(hbox, False, False, 3) - - scrolledwindow = gtk.ScrolledWindow() - scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN) - scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.textview = gtk.TextView(buffer=None) - self.textview.set_editable(False) - self.textview.modify_font(pango.FontDescription("Monospace")) - scrolledwindow.add(self.textview) - self.textbuffer = self.textview.get_buffer() - - self.vbox.pack_start(scrolledwindow, True, True) - self.connect('map_event', self._on_window_map_event) - - self.show_all() - - def _on_ok_clicked(self, button): - """ Ok button clicked handler. """ - self.response(gtk.RESPONSE_ACCEPT) - - def _on_stop_clicked(self, button): - self.hgthread.terminate() - - def _delete(self, widget, event): - return True - - def _response(self, widget, response_id): - if self.hgthread.isAlive(): - widget.emit_stop_by_name('response') - - def _on_window_map_event(self, event, param): - self.hgthread = HgThread(self.cmdline[1:]) - self.hgthread.start() - self._button_ok.set_sensitive(False) - self._button_stop.set_sensitive(True) - gobject.timeout_add(10, self.process_queue) - - def write(self, msg, append=True): - msg = toutf(msg) - if append: - enditer = self.textbuffer.get_end_iter() - self.textbuffer.insert(enditer, msg) - else: - self.textbuffer.set_text(msg) - - def process_queue(self): - """ - Handle all the messages currently in the queue (if any). - """ - self.hgthread.process_dialogs() - enditer = self.textbuffer.get_end_iter() - while self.hgthread.getqueue().qsize(): - try: - msg = self.hgthread.getqueue().get(0) - self.textbuffer.insert(enditer, toutf(msg)) - self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0) - except Queue.Empty: - pass - self.update_progress() - if not self.hgthread.isAlive(): - self._button_ok.set_sensitive(True) - self._button_stop.set_sensitive(False) - self.returncode = self.hgthread.return_code() - if self.returncode is None: - self.write("[command interrupted]") - return False # Stop polling this function - else: - return True - - def update_progress(self): - if not self.pbar: - return # progress bar not enabled - - if not self.hgthread.isAlive(): - self.pbar.unmap() - else: - # pulse the progress bar every ~100ms - tm = get_system_times()[4] - if tm - self.last_pbar_update < 0.100: - return - self.last_pbar_update = tm - self.pbar.pulse() - -def run(cmdline=[], gui=True, **opts): - if not gui: - q = Queue.Queue() - hgcmd_toq(None, q, *cmdline[1:]) - return - - dlg = CmdDialog(cmdline) - dlg.connect('response', gtk.main_quit) - dlg.show_all() - gtk.gdk.threads_init() - gtk.gdk.threads_enter() - gtk.main() - gtk.gdk.threads_leave() - -if __name__ == "__main__": - import sys - run(sys.argv) - +# +# A simple dialog to execute random command for TortoiseHg +# +# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> +# + +import pygtk +pygtk.require("2.0") + +import gtk +import gobject +import pango +import os +import threading +import Queue +from hglib import HgThread, hgcmd_toq, toutf +from shlib import set_tortoise_icon, get_system_times + +class CmdDialog(gtk.Dialog): + def __init__(self, cmdline, progressbar=True, width=520, height=400): + title = 'hg ' + ' '.join(cmdline[1:]) + gtk.Dialog.__init__(self, + title=title, + flags=gtk.DIALOG_MODAL, + #buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) + ) + + set_tortoise_icon(self, 'hg.ico') + self.cmdline = cmdline + self.returncode = None + + # construct dialog + self.set_default_size(width, height) + + self._button_stop = gtk.Button("Stop") + self._button_stop.connect('clicked', self._on_stop_clicked) + self.action_area.pack_start(self._button_stop) + + self._button_ok = gtk.Button("Close") + self._button_ok.connect('clicked', self._on_ok_clicked) + self.action_area.pack_start(self._button_ok) + + self.connect('delete-event', self._delete) + self.connect('response', self._response) + + self.pbar = None + if progressbar: + self.last_pbar_update = 0 + + hbox = gtk.HBox() + + self.status_text = gtk.Label() + self.status_text.set_text(toutf(" ".join(cmdline).replace("\n", " "))) + self.status_text.set_alignment(0, 0.5) + self.status_text.set_ellipsize(pango.ELLIPSIZE_END) + hbox.pack_start(self.status_text, True, True, 3) + + # Create a centering alignment object + align = gtk.Alignment(0.0, 0.0, 1, 0) + hbox.pack_end(align, False, False, 3) + align.show() + + # create the progress bar + self.pbar = gtk.ProgressBar() + align.add(self.pbar) + self.pbar.pulse() + self.pbar.show() + + self.vbox.pack_start(hbox, False, False, 3) + + scrolledwindow = gtk.ScrolledWindow() + scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN) + scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.textview = gtk.TextView(buffer=None) + self.textview.set_editable(False) + self.textview.modify_font(pango.FontDescription("Monospace")) + scrolledwindow.add(self.textview) + self.textbuffer = self.textview.get_buffer() + + self.vbox.pack_start(scrolledwindow, True, True) + self.connect('map_event', self._on_window_map_event) + + self.show_all() + + def _on_ok_clicked(self, button): + """ Ok button clicked handler. """ + self.response(gtk.RESPONSE_ACCEPT) + + def _on_stop_clicked(self, button): + self.hgthread.terminate() + + def _delete(self, widget, event): + return True + + def _response(self, widget, response_id): + if self.hgthread.isAlive(): + widget.emit_stop_by_name('response') + + def _on_window_map_event(self, event, param): + self.hgthread = HgThread(self.cmdline[1:]) + self.hgthread.start() + self._button_ok.set_sensitive(False) + self._button_stop.set_sensitive(True) + gobject.timeout_add(10, self.process_queue) + + def write(self, msg, append=True): + msg = toutf(msg) + if append: + enditer = self.textbuffer.get_end_iter() + self.textbuffer.insert(enditer, msg) + else: + self.textbuffer.set_text(msg) + + def process_queue(self): + """ + Handle all the messages currently in the queue (if any). + """ + self.hgthread.process_dialogs() + enditer = self.textbuffer.get_end_iter() + while self.hgthread.getqueue().qsize(): + try: + msg = self.hgthread.getqueue().get(0) + self.textbuffer.insert(enditer, toutf(msg)) + self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0) + except Queue.Empty: + pass + self.update_progress() + if not self.hgthread.isAlive(): + self._button_ok.set_sensitive(True) + self._button_stop.set_sensitive(False) + self.returncode = self.hgthread.return_code() + if self.returncode is None: + self.write("\n[command interrupted]") + return False # Stop polling this function + else: + return True + + def update_progress(self): + if not self.pbar: + return # progress bar not enabled + + if not self.hgthread.isAlive(): + self.pbar.unmap() + else: + # pulse the progress bar every ~100ms + tm = get_system_times()[4] + if tm - self.last_pbar_update < 0.100: + return + self.last_pbar_update = tm + self.pbar.pulse() + +def run(cmdline=[], gui=True, **opts): + if not gui: + q = Queue.Queue() + hgcmd_toq(None, q, *cmdline[1:]) + return + + dlg = CmdDialog(cmdline) + dlg.connect('response', gtk.main_quit) + dlg.show_all() + gtk.gdk.threads_init() + gtk.gdk.threads_enter() + gtk.main() + gtk.gdk.threads_leave() + +if __name__ == "__main__": + import sys + run(sys.argv) +
Show Entire File hggtk/​hgemail.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​hglib.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​history.py Stacked
(No changes)
Show Entire File hggtk/​histselect.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​logfilter.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​merge.py Stacked
(No changes)
Show Entire File hggtk/​recovery.py Stacked
(No changes)
Show Entire File hggtk/​revisions.py Stacked
(No changes)
Show Entire File hggtk/​revtree.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​serve.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​shlib.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Change 1 of 6 Show Entire File hggtk/​status.py Stacked
 
44
45
46
 
 
 
47
48
49
 
50
51
52
 
183
184
185
 
 
 
 
 
186
187
188
 
281
282
283
284
 
 
 
 
 
 
 
285
 
 
 
 
 
 
 
 
 
 
286
287
288
 
348
349
350
 
 
351
352
353
 
387
388
389
 
390
391
392
 
668
669
670
 
671
672
673
 
44
45
46
47
48
49
50
51
52
53
54
55
56
 
187
188
189
190
191
192
193
194
195
196
197
 
290
291
292
 
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
 
373
374
375
376
377
378
379
380
 
414
415
416
417
418
419
420
 
696
697
698
699
700
701
702
@@ -44,9 +44,13 @@
    ### Following methods are meant to be overridden by subclasses ###   + def init(self): + GDialog.init(self) +   def auto_check(self):   if self.test_opt('check'):   for entry in self.model : entry[0] = True + self._update_check_count()       def get_menu_info(self): @@ -183,6 +187,11 @@
  self._menus['I'] = ignored_menu   self._menus['!'] = deleted_menu   + # model stores the file list. + # model[0] = file checked (marked for commit) + # model[1] = changetype char + # model[2] = file path as UTF-8 + # model[3] = file path   self.model = gtk.ListStore(bool, str, str, str)   self.model.set_sort_func(1001, self._sort_by_stat)   self.model.set_default_sort_func(self._sort_by_stat) @@ -281,8 +290,24 @@
  self._show_checks[type] = check   col += row   row = not row - return table + + self.counter = gtk.Label('') + self.counter.set_alignment(1.0, 0.0) # right up + + hbox = gtk.HBox() + hbox.pack_start(table, expand=False) + hbox.pack_end(self.counter, expand=True, padding=2)   + return hbox + + def _update_check_count(self): + file_count = 0 + check_count = 0 + for row in self.model: + file_count = file_count + 1 + if row[0]: + check_count = check_count + 1 + self.counter.set_text(_('%d selected, %d total') % (check_count, file_count))     def prepare_display(self):   self._ready = True @@ -348,6 +373,8 @@
  file = util.localpath(file)   self.model.append([file in recheck, char, toutf(file), file])   + self._update_check_count() +   selection = self.tree.get_selection()   selected = False   for row in self.model: @@ -387,6 +414,7 @@
    def _select_toggle(self, cellrenderer, path):   self.model[path][0] = not self.model[path][0] + self._update_check_count()   return True     @@ -668,6 +696,7 @@
    def _sel_desel_clicked(self, toolbutton, state):   for entry in self.model : entry[0] = state + self._update_check_count()   return True    
Show Entire File hggtk/​synch.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​tagadd.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​tags.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​thgconfig.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File hggtk/​update.py Stacked
(No changes)
Change 1 of 1 Show Entire File hgproc.bat Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
@@ -1,20 +1,20 @@
-:: -:: Win32 batch file to handle TortoiseHg external proc calls -:: - -@echo off -setlocal - -:: Look in the registry for TortoiseHg location -for /f "skip=2 tokens=3*" %%A in ( - '"reg query "HKEY_LOCAL_MACHINE\SOFTWARE\TortoiseHg" /ve 2> nul"' ) do set TortoisePath=%%B -if "%TortoisePath%"=="" (goto :notfound) else (goto :hgproc) - -:hgproc -python "%TortoisePath%\hgproc.py" %* -goto end - -:notfound -echo hgproc: cannot find TortoiseHg location in the registry. - +:: +:: Win32 batch file to handle TortoiseHg external proc calls +:: + +@echo off +setlocal + +:: Look in the registry for TortoiseHg location +for /f "skip=2 tokens=3*" %%A in ( + '"reg query "HKEY_LOCAL_MACHINE\SOFTWARE\TortoiseHg" /ve 2> nul"' ) do set TortoisePath=%%B +if "%TortoisePath%"=="" (goto :notfound) else (goto :hgproc) + +:hgproc +python "%TortoisePath%\hgproc.py" %* +goto end + +:notfound +echo hgproc: cannot find TortoiseHg location in the registry. +  :end \ No newline at end of file
Show Entire File hgproc.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Added image
Added image
Added image
Removed image
Added image
Subtracted image Added image
Show Entire File installer/​tortoisehg.iss Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File setup.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File tortoise/​contextmenu.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File tortoise/​test/​testiconoverlay.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File tortoisehg.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes
Show Entire File tracelog.py Stacked
This file's diff was not loaded because this changeset is very large. Load changes