Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 1.9, 1.9.1, and 1.9.2

compress: introduce a history compression dialog

Changeset b6d0a08a8af3

Parent 2dcab361bb42

by Steve Borho

Changes to 2 files · Browse files at b6d0a08a8af3 Showing diff from parent 2dcab361bb42 Diff from another changeset...

Change 1 of 1 Show Entire File tortoisehg/​hgqt/​compress.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
@@ -0,0 +1,161 @@
+# compress.py - History compression dialog for TortoiseHg +# +# Copyright 2010 Steve Borho <steve@borho.org> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2, incorporated herein by reference. + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +import os + +from mercurial import merge as mergemod + +from tortoisehg.util import hglib +from tortoisehg.hgqt.i18n import _ +from tortoisehg.hgqt import qtlib, csinfo, cmdui, commit + +BB = QDialogButtonBox + +class CompressDialog(QDialog): + showMessage = pyqtSignal(QString) + + def __init__(self, repo, revs, parent): + super(CompressDialog, self).__init__(parent) + f = self.windowFlags() + self.setWindowFlags(f & ~Qt.WindowContextHelpButtonHint) + self.repo = repo + self.revs = revs + + box = QVBoxLayout() + box.setSpacing(8) + box.setContentsMargins(*(6,)*4) + self.setLayout(box) + + style = csinfo.panelstyle(selectable=True) + + srcb = QGroupBox( _('Compress changesets up to and including')) + srcb.setLayout(QVBoxLayout()) + srcb.layout().setContentsMargins(*(2,)*4) + source = csinfo.create(self.repo, revs[0], style, withupdate=True) + srcb.layout().addWidget(source) + self.layout().addWidget(srcb) + + destb = QGroupBox( _('Onto destination')) + destb.setLayout(QVBoxLayout()) + destb.layout().setContentsMargins(*(2,)*4) + dest = csinfo.create(self.repo, revs[1], style, withupdate=True) + destb.layout().addWidget(dest) + self.destcsinfo = dest + self.layout().addWidget(destb) + + self.cmd = cmdui.Widget() + self.cmd.commandFinished.connect(self.commandFinished) + self.cmd.show_output(True) + self.showMessage.connect(self.cmd.stbar.showMessage) + self.cmd.stbar.linkActivated.connect(self.linkActivated) + self.layout().addWidget(self.cmd, 2) + + bbox = QDialogButtonBox() + self.cancelbtn = bbox.addButton(QDialogButtonBox.Cancel) + self.cancelbtn.clicked.connect(self.reject) + self.compressbtn = bbox.addButton(_('Compress'), + QDialogButtonBox.ActionRole) + self.compressbtn.clicked.connect(self.compress) + self.layout().addWidget(bbox) + self.bbox = bbox + + self.showMessage.emit(_('Checking...')) + QTimer.singleShot(0, self.checkStatus) + + self.setMinimumWidth(480) + self.setMaximumHeight(800) + self.resize(0, 340) + self.setWindowTitle(_('Compress - %s') % repo.displayname) + + def checkStatus(self): + repo = self.repo + class CheckThread(QThread): + def __init__(self, parent): + QThread.__init__(self, parent) + self.dirty = False + + def run(self): + wctx = repo[None] + if len(wctx.parents()) > 1: + self.dirty = True + elif wctx.dirty(): + self.dirty = True + else: + ms = mergemod.mergestate(repo) + unresolved = False + for path in ms: + if ms[path] == 'u': + self.dirty = True + break + def completed(): + self.th.wait() + if self.th.dirty: + self.compressbtn.setEnabled(False) + txt = _('Before compress, you must <a href="commit">' + '<b>commit</b></a> or <a href="discard">' + '<b>discard</b></a> changes.') + else: + self.compressbtn.setEnabled(True) + txt = _('You may continue the compress') + self.showMessage.emit(txt) + self.th = CheckThread(self) + self.th.finished.connect(completed) + self.th.start() + + def compress(self): + self.cancelbtn.setShown(False) + uc = ['update', '--repository', self.repo.root, '--clean', '--rev', + str(self.revs[1])] + rc = ['revert', '--repository', self.repo.root, '--all', '--rev', + str(self.revs[0])] + self.repo.incrementBusyCount() + self.cmd.run(uc, rc) + + def commandFinished(self, ret): + self.repo.decrementBusyCount() + self.showMessage.emit(_('Changes have been moved, you must now commit')) + self.compressbtn.setText(_('Commit')) + self.compressbtn.clicked.disconnect(self.compress) + self.compressbtn.clicked.connect(self.commit) + + def commit(self): + # TODO: + # self.repo.opener('last-message.txt', 'w').write(msg) + dlg = commit.CommitDialog([], dict(root=self.repo.root), self) + dlg.finished.connect(dlg.deleteLater) + dlg.exec_() + self.showMessage.emit(_('Compress is complete, old history untouched')) + self.compressbtn.setText(_('Close')) + self.compressbtn.clicked.disconnect(self.commit) + self.compressbtn.clicked.connect(self.accept) + + def linkActivated(self, cmd): + if cmd == 'commit': + dlg = commit.CommitDialog([], dict(root=self.repo.root), self) + dlg.finished.connect(dlg.deleteLater) + dlg.exec_() + self.checkStatus() + elif cmd == 'discard': + labels = [(QMessageBox.Yes, _('&Discard')), + (QMessageBox.No, _('Cancel'))] + if not qtlib.QuestionMsgBox(_('Confirm Discard'), _('Discard' + ' outstanding changes in working directory?'), + labels=labels, parent=self): + return + def finished(ret): + self.repo.decrementBusyCount() + if ret == 0: + self.checkStatus() + cmdline = ['update', '--clean', '--repository', self.repo.root, + '--rev', '.'] + self.runner = cmdui.Runner(_('Discard - TortoiseHg'), True, self) + self.runner.commandFinished.connect(finished) + self.repo.incrementBusyCount() + self.runner.run(cmdline)
 
19
20
21
22
 
23
24
25
 
812
813
814
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
815
816
817
 
822
823
824
825
 
 
826
827
828
 
19
20
21
 
22
23
24
25
 
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
 
837
838
839
 
840
841
842
843
844
@@ -19,7 +19,7 @@
 from tortoisehg.hgqt.repomodel import HgRepoListModel  from tortoisehg.hgqt import cmdui, update, tag, backout, merge, visdiff  from tortoisehg.hgqt import archive, thgimport, thgstrip, run, purge -from tortoisehg.hgqt import bisect, rebase, resolve, thgrepo +from tortoisehg.hgqt import bisect, rebase, resolve, thgrepo, compress    from tortoisehg.hgqt.repofilter import RepoFilterBar  from tortoisehg.hgqt.repoview import HgRepoView @@ -812,6 +812,21 @@
  dlg = bisect.BisectDialog(self.repo, opts, self)   dlg.finished.connect(dlg.deleteLater)   dlg.exec_() + def compressDlg(): + ctxa = self.repo[selection[0]] + ctxb = self.repo[selection[1]] + if ctxa.ancestor(ctxb) == ctxb: + pass + elif ctxa.ancestor(ctxb) == ctxa: + selection.reverse() + else: + InfoMsgBox(_('Unable to compress history'), + _('Selected changeset pair not related')) + return + dlg = compress.CompressDialog(self.repo, selection, self) + dlg.finished.connect(dlg.deleteLater) + dlg.exec_() +     if not self.paircmenu:   menu = QMenu(self) @@ -822,7 +837,8 @@
  (_('Export DAG Range'), exportDagRange),   (_('Email DAG Range...'), emailDagRange),   (_('Bisect - Good, Bad...'), bisectNormal), - (_('Bisect - Bad, Good...'), bisectReverse) + (_('Bisect - Bad, Good...'), bisectReverse), + (_('Compress History...'), compressDlg)   ):   a = QAction(name, self)   a.triggered.connect(cb)