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

commit: do record style commits

Lots of TODO:
* Removed files have bad performance, do not show delete diff
* Unselected files should have all chunks rejected
* Re-selected files should have all chunks accepted
* Refresh diff after commit

Changeset c102ef37af06

Parent 82c232d80df4

by Steve Borho

Changes to 2 files · Browse files at c102ef37af06 Showing diff from parent 82c232d80df4 Diff from another changeset...

Change 1 of 2 Show Entire File hggtk/​commit.py Stacked
 
8
9
10
 
11
12
 
 
13
 
14
15
16
 
236
237
238
239
 
 
 
240
241
242
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
245
246
 
8
9
10
11
12
13
14
15
16
17
18
19
20
 
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
@@ -8,9 +8,13 @@
 import os  import pygtk  pygtk.require('2.0') +import errno  import gtk  import pango +import tempfile +import cStringIO   +from mercurial.i18n import _  from mercurial import ui, hg  from shlib import shell_notify  from gdialog import * @@ -236,11 +240,98 @@
    commit_list = self._relevant_files(commitable)   if len(commit_list) > 0: - self._hg_commit(commit_list) + #self._hg_commit(commit_list) + self._commit_selected(commit_list) + return True   else:   Prompt('Nothing Commited', 'No committable files selected', self).run()   return True   + def _commit_selected(self, files): + import hgshelve + # 1a. get list of chunks not rejected + hlist = [x[4] for x in self.diff_model if not x[0]] + # 1b. ignore header chunks + nlist = [n for n in hlist if not self.diff_model[n][3]] + if not nlist: + Prompt('Commit', 'Please select diff chunks to commit', + self).run() + return + + repo, chunks, ui = self.repo, self._shelve_chunks, self.ui + + # 2. backup changed files, so we can restore them in the end + backups = {} + backupdir = repo.join('record-backups') + try: + os.mkdir(backupdir) + except OSError, err: + if err.errno != errno.EEXIST: + Prompt('Commit', 'Unable to create ' + backupdir, + self).run() + return + try: + # backup continues + for f in files: + if f not in self.modified: + continue + fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.', + dir=backupdir) + os.close(fd) + ui.debug(_('backup %r as %r\n') % (f, tmpname)) + util.copyfile(repo.wjoin(f), tmpname) + backups[f] = tmpname + + fp = cStringIO.StringIO() + for n, c in enumerate(chunks): + if c.filename() in backups and n in hlist: + c.write(fp) + dopatch = fp.tell() + fp.seek(0) + + # 3a. apply filtered patch to clean repo (clean) + if backups: + hg.revert(repo, repo.dirstate.parents()[0], backups.has_key) + + # 3b. (apply) + if dopatch: + try: + ui.debug(_('applying patch\n')) + ui.debug(fp.getvalue()) + patch.internalpatch(fp, ui, 1, repo.root) + except patch.PatchError, err: + s = str(err) + if s: + raise util.Abort(s) + else: + Prompt('Commit', 'Unable to apply patch', self).run() + raise util.Abort(_('patch failed to apply')) + del fp + + # 4. We prepared working directory according to filtered patch. + # Now is the time to delegate the job to commit/qrefresh or the like! + + # it is important to first chdir to repo root -- we'll call a + # highlevel command with list of pathnames relative to repo root + cwd = os.getcwd() + os.chdir(repo.root) + try: + self._hg_commit(files) + finally: + os.chdir(cwd) + + return 0 + finally: + # 5. finally restore backed-up files + try: + for realname, tmpname in backups.iteritems(): + ui.debug(_('restoring %r to %r\n') % (tmpname, realname)) + util.copyfile(tmpname, repo.wjoin(realname)) + os.unlink(tmpname) + os.rmdir(backupdir) + except OSError: + pass +     def _commit_file(self, stat, file):   if self._ready_message():
Change 1 of 2 Show Entire File hggtk/​status.py Stacked
 
428
429
430
431
432
 
433
434
435
436
437
 
 
 
438
439
440
 
648
649
650
 
 
651
652
653
 
428
429
430
 
 
431
432
433
434
435
436
437
438
439
440
441
442
 
650
651
652
653
654
655
656
657
@@ -428,13 +428,15 @@
    matcher = cmdutil.match(self.repo, self.pats, self.opts)   cwd = (self.pats and self.repo.getcwd()) or '' - modified, added, removed, deleted, unknown, ignored, clean = [ - n for n in self.repo.status(node1=self._node1, node2=self._node2, + status = [n for n in self.repo.status(node1=self._node1, node2=self._node2,   match=matcher,   ignored=self.test_opt('ignored'),   clean=self.test_opt('clean'),   unknown=self.test_opt('unknown'))]   + (modified, added, removed, deleted, unknown, ignored, clean) = status + self.modified = modified +   changetypes = (('modified', 'M', modified),   ('added', 'A', added),   ('removed', 'R', removed), @@ -648,6 +650,8 @@
  return False     def _diff_tree_row_act(self, tree, path, column): + # strikethrough-set property seems to be broken, so manually + # filter header chunks here using !isheader property of diffmodel.   if self.diff_model[path][2]:   self.diff_model[path][0] = not self.diff_model[path][0]