Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 1.1, 1.1.1, and 1.1.2

thgpbranch: Add pfinish

The pfinish command was proposed by Jesse Glick, see
http://bitbucket.org/parren/hg-pbranch/issue/30/hg-pfinish

Changeset 7596b199b1ba

Parent c09ac59c52b0

by Peer Sommerlund

Changes to one file · Browse files at 7596b199b1ba Showing diff from parent c09ac59c52b0 Diff from another changeset...

 
6
7
8
 
9
10
11
12
 
 
13
14
15
 
466
467
468
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
470
471
 
480
481
482
483
484
485
486
487
488
489
 
 
 
 
 
 
 
 
490
491
492
 
500
501
502
503
 
 
 
 
504
505
506
 
528
529
530
531
 
532
533
534
 
548
549
550
551
 
552
553
554
 
561
562
563
 
564
565
566
 
743
744
745
746
 
747
748
749
 
769
770
771
 
 
 
 
6
7
8
9
10
11
12
13
14
15
16
17
18
 
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
 
569
570
571
 
 
 
 
 
 
 
572
573
574
575
576
577
578
579
580
581
582
 
590
591
592
 
593
594
595
596
597
598
599
 
621
622
623
 
624
625
626
627
 
641
642
643
 
644
645
646
647
 
654
655
656
657
658
659
660
 
837
838
839
 
840
841
842
843
 
863
864
865
866
867
868
@@ -6,10 +6,13 @@
 # GNU General Public License version 2, incorporated herein by reference.    import os +import tempfile  import gtk  import gobject    from mercurial import cmdutil, extensions +from mercurial import commands as hg +import mercurial.ui    from tortoisehg.util.i18n import _   @@ -466,6 +469,92 @@
  """   assert False   + def pfinish(self, patch_name): + """ + [pbranch] Execute 'pfinish' command. + + The workdir must be clean. + The patch branch dependencies must be merged. + + :param patch_name: A patch branch (not an internal branch) + """ + # Check preconditions for pfinish + + assert self.is_patch(patch_name) + + pmerge_status = self.pstatus(patch_name) + if pmerge_status != []: + dialog.error_dialog(self.parent_window, + _('Pending Pmerge'), + _('You cannot finish this patch branch unless you pmerge it first.\n' + 'pmerge will solve the following issues with %(patch)s:\n' + '* %(issuelist)s') % + {'patch': patch_name, + 'issuelist': '* '.join(pmerge_status)} + ) + return + + if not self.workdir_is_clean(): + dialog.error_dialog(self.parent_window, + _('Uncommitted Local Changes'), + _('pfinish uses your working directory for temporary work.\n' + 'Please commit your local changes before issuing pfinish.') + ) + return + + if hasattr(self.repo, 'mq') and len(self.repo.mq.applied) > 0: + dialog.error_dialog(self.parent_window, + _('Applied MQ patch'), + _('pfinish must be able to commit, but this is not allowed\n' + 'as long as you have MQ patches applied.') + ) + return + + # Set up environment for mercurial commands + class CmdWidgetUi(mercurial.ui.ui): + def __init__(self, cmdLogWidget): + src = None + super(CmdWidgetUi, self).__init__(src) + self.cmdLogWidget = cmdLogWidget + def write(self, *args): + for a in args: + self.cmdLogWidget.append(str(a)) + def write_err(self, *args): + for a in args: + self.cmdLogWidget.append(str(a), error=True) + def flush(self): + pass + def prompt(self, msg, choices=None, default="y"): + raise util.Abort("Internal Error: prompt not available") + def promptchoice(self, msg, choices, default=0): + raise util.Abort("Internal Error: promptchoice not available") + def getpass(self, prompt=None, default=None): + raise util.Abort("Internal Error: getpass not available") + repo = self.repo + ui = CmdWidgetUi(self.cmd.log) + old_ui = repo.ui + repo.ui = ui + + # Commit patch to dependency + fd, patch_file_name = tempfile.mkstemp(prefix='thg-patch-') + patch_file = os.fdopen(fd, 'w') + patch_file.writelines(self.pdiff(patch_name)) + patch_file.close() + upstream_branch = self.pgraph().deps(patch_name)[0] + hg.update(ui, repo, rev=upstream_branch) + hg.import_(ui, repo, patch_file_name, base='', strip=1) + os.unlink(patch_file_name) + + # Close patch branch + hg.update(ui, repo, rev=patch_name) + hg.merge(ui, repo, upstream_branch) + msg = _('Patch branch finished') + hg.commit(ui, repo, close_branch=True, message=msg) + + # Update GUI + repo.ui = old_ui + self.emit('repo-invalidated') +   def has_pbranch(self):   """ return True if pbranch extension can be used """   return self.pbranch is not None @@ -480,13 +569,14 @@
  dependencies. """   return self.has_pbranch() and self.pgraph().ispatch(branch_name)   - def cur_patch(self): - current_patch = self.repo.dirstate.branch() - if current_patch == 'default': - return None - if current_patch not in self.patch_list(): - return None - return current_patch + def cur_branch(self): + """ Return branch that workdir belongs to. """ + return self.repo.dirstate.branch() + + def workdir_is_clean(self): + """ return True if the working directory is clean """ + c = self.repo[None] + return not (c.modified() or c.added() or c.removed())     ### internal functions ###   @@ -500,7 +590,10 @@
    def get_path_by_patchname(self, name):   """ return path has specified patch name """ - return self.model.get_path(self.get_iter_by_patchname(name)) + iter = self.get_iter_by_patchname(name) + if iter: + return self.model.get_path(iter) + return None     def update_sensitives(self):   """ Update the sensitives of entire UI """ @@ -528,7 +621,7 @@
  """   if self.list.get_selection().count_selected_rows() > 0:   return - curpatch = self.cur_patch() + curpatch = self.cur_branch()   if not curpatch:   return   path = self.get_path_by_patchname(curpatch) @@ -548,7 +641,7 @@
  menu.append(item)     has_pbranch = self.has_pbranch() - is_current = self.has_patch() and self.cur_patch() == row[M_NAME] + is_current = self.has_patch() and self.cur_branch() == row[M_NAME]   is_patch = self.is_patch(row[M_NAME])   is_internal = self.pbranch.isinternal(row[M_NAME])   is_merge = len(self.repo.branchheads(row[M_NAME])) > 1 @@ -561,6 +654,7 @@
  append(_('_edit message'), self.edit_message_activated)   append(_('_rename'), self.rename_activated)   append(_('_delete'), self.delete_activated) + append(_('_finish'), self.finish_activated)     if len(menu.get_children()) > 0:   menu.show_all() @@ -743,7 +837,7 @@
    def pnew_activated(self, menuitem, row):   """Insert new patch after this row""" - if self.cur_patch() == row[M_NAME]: + if self.cur_branch() == row[M_NAME]:   self.pnew_ui()   return   # pnew from patch different than current @@ -769,3 +863,6 @@
    def rename_activated(self, menuitem, row):   assert False + + def finish_activated(self, menuitem, row): + self.pfinish(row[M_NAME])