15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from gi.repository import Gtk
19
from StringIO import StringIO
21
from gi.repository import (
20
26
from errors import show_bzr_error
22
29
import bzrlib.errors as errors
24
from bzrlib.plugins.gtk.dialog import (
30
from bzrlib.push import _show_push_branch
29
31
from bzrlib.plugins.gtk.history import UrlHistory
30
32
from bzrlib.plugins.gtk.i18n import _i18n
33
from bzrlib.plugins.gtk.ui import ProgressPanel
36
GObject.threads_init()
33
39
class PushDialog(Gtk.Dialog):
62
69
self._hbox_location.pack_start(
63
70
self._label_location, False, False, 0)
64
self._hbox_location.pack_start(self._combo, True, True, 0)
65
self.get_content_area().pack_start(self._hbox_location, True, True, 0)
71
self._hbox_location.pack_start(self._combo, False, False, 0)
72
self.get_content_area().pack_start(
73
self._hbox_location, False, False, 0)
66
74
self.get_action_area().pack_end(self._button_push, True, True, 0)
77
self.progress_widget = ProgressPanel()
78
ui.ui_factory.set_progress_bar_widget(self.progress_widget)
79
self.get_content_area().pack_start(
80
self.progress_widget, False, False, 0)
81
self.push_message = Gtk.Label()
82
alignment = Gtk.Alignment.new(0.0, 0.5, 0.0, 0.0)
83
alignment.add(self.push_message)
84
self.get_content_area().pack_start(alignment, False, False, 0)
69
87
self.get_content_area().show_all()
88
self.progress_widget.hide()
71
90
# Build location history
72
91
self._history = UrlHistory(self.branch.get_config(), 'push_history')
85
104
if location is not None:
86
105
self._combo.get_child().set_text(location)
107
def _on_close_clicked(self, widget):
108
"""Close dialog handler."""
109
ui.ui_factory.set_progress_bar_widget(None)
89
111
def _on_push_clicked(self, widget):
90
112
"""Push button clicked handler. """
113
self.push_message.hide()
114
self.progress_widget.show()
115
while Gtk.events_pending():
91
117
location = self._combo.get_child().get_text()
95
revs = do_push(self.branch, location=location, overwrite=False)
96
except errors.DivergedBranches:
97
response = question_dialog(
98
_i18n('Branches have been diverged'),
99
_i18n('You cannot push if branches have diverged.\n'
101
if response == Gtk.ResponseType.YES:
102
revs = do_push(self.branch, location=location, overwrite=True)
104
if self.branch is not None and self.branch.get_push_location() is None:
118
do_push(self.branch, location, False, self.on_push_complete)
120
def on_push_complete(self, location, message):
121
self._history.add_entry(location)
122
if (self.branch is not None
123
and self.branch.get_push_location() is None):
105
124
self.branch.set_push_location(location)
107
self._history.add_entry(location)
108
info_dialog(_i18n('Push successful'),
109
_i18n("%d revision(s) pushed.") % revs)
111
self.response(Gtk.ResponseType.OK)
114
def do_push(br_from, location, overwrite):
126
self.progress_widget.finished()
127
self.push_message.props.label = message
128
self.push_message.show()
132
class PushHandler(logging.Handler):
133
"""A logging handler to collect messages."""
136
logging.Handler.__init__(self, logging.INFO)
139
def handleError(self, record):
142
def emit(self, record):
143
self.messages.append(record.getMessage())
147
def do_push(br_from, location, overwrite, callback):
115
148
"""Update a mirror of a branch.
117
151
:param br_from: the source branch
118
152
:param location: the location of the branch that you'd like to update
119
153
:param overwrite: overwrite target location if it diverged
120
154
:return: number of revisions pushed
122
from bzrlib.bzrdir import BzrDir
123
from bzrlib.transport import get_transport
125
transport = get_transport(location)
126
location_url = transport.base
156
log = logging.getLogger('bzr')
157
old_propagate = log.propagate
158
message = 'Branch pushed'
159
handler = PushHandler()
131
dir_to = BzrDir.open(location_url)
132
br_to = dir_to.open_branch()
133
except errors.NotBranchError:
135
transport = transport.clone('..')
137
relurl = transport.relpath(location_url)
138
transport.mkdir(relurl)
139
except errors.NoSuchFile:
140
response = question_dialog(
141
_i18n('Non existing parent directory'),
142
_i18n("The parent directory (%s)\ndoesn't exist. Create?")
144
if response == Gtk.ResponseType.OK:
145
transport.create_prefix()
148
dir_to = br_from.bzrdir.clone(location_url,
149
revision_id=br_from.last_revision())
150
br_to = dir_to.open_branch()
151
count = len(br_to.revision_history())
153
old_rh = br_to.revision_history()
155
tree_to = dir_to.open_workingtree()
156
except errors.NotLocalUrl:
157
# FIXME - what to do here? how should we warn the user?
158
count = br_to.pull(br_from, overwrite)
159
except errors.NoWorkingTree:
160
count = br_to.pull(br_from, overwrite)
162
count = tree_to.pull(br_from, overwrite)
162
log.addHandler(handler)
163
log.propagate = False
164
# Revid is None to imply tip.
165
# The call assumes text ui (file) to write to.
167
br_from, None, location, StringIO(), overwrite=overwrite)
168
message = '\n'.join(handler.messages)
169
except errors.BzrCommandError, error:
170
message = _i18n('Error: ') + str(error)
172
log.removeHandler(handler)
173
log.propagate = old_propagate
174
callback(location, message)