The attached patch moves the commands to a separate module and registers
them lazily, to save some import time.

Cheers,

Jelemr
-- 
Jelmer Vernooij <[email protected]> - http://samba.org/~jelmer/
Jabber: [email protected]
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [email protected]
# target_branch: lp:bzr-gtk
# testament_sha1: 2134f4b8617e4598274af4a15913ac7e2f7eec45
# timestamp: 2009-01-30 17:03:27 +0100
# source_branch: http://people.samba.org/bzr/jelmer/bzr-gtk/trunk
# base_revision_id: [email protected]
# 
# Begin patch
=== modified file '__init__.py'
--- __init__.py	2008-10-23 08:14:59 +0000
+++ __init__.py	2009-01-30 16:03:10 +0000
@@ -34,9 +34,11 @@
 visualise         Graphically visualise this branch. 
 """
 
-import sys
-
 import bzrlib
+from bzrlib import errors
+from bzrlib.commands import plugin_cmds
+
+import os.path
 
 version_info = (0, 96, 0, 'dev', 1)
 
@@ -54,12 +56,8 @@
     If version is < bzr-gtk version, assume incompatible.
     """
     bzrlib_version = bzrlib.version_info[:2]
-    try:
+    if bzrlib_version < desired:
         from bzrlib.trace import warning
-    except ImportError:
-        # get the message out any way we can
-        from warnings import warn as warning
-    if bzrlib_version < desired:
         from bzrlib.errors import BzrError
         warning('Installed Bazaar version %s is too old to be used with bzr-gtk'
                 ' %s.' % (bzrlib.__version__, __version__))
@@ -69,27 +67,10 @@
 if version_info[2] == "final":
     check_bzrlib_version(required_bzrlib)
 
-from bzrlib.trace import warning
 if __name__ != 'bzrlib.plugins.gtk':
+    from bzrlib.trace import warning
     warning("Not running as bzrlib.plugins.gtk, things may break.")
 
-from bzrlib.lazy_import import lazy_import
-lazy_import(globals(), """
-from bzrlib import (
-    branch,
-    builtins,
-    errors,
-    merge_directive,
-    workingtree,
-    )
-""")
-
-from bzrlib.commands import Command, register_command, display_command
-from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
-from bzrlib.option import Option
-
-import os.path
-
 def import_pygtk():
     try:
         import pygtk
@@ -135,498 +116,35 @@
     return gtk
  
 
-class GTKCommand(Command):
-    """Abstract class providing GTK specific run commands."""
-
-    def run(self):
-        open_display()
-        dialog = self.get_gtk_dialog(os.path.abspath('.'))
-        dialog.run()
-
-
-class cmd_gbranch(GTKCommand):
-    """GTK+ branching.
-    
-    """
-
-    def get_gtk_dialog(self, path):
-        from bzrlib.plugins.gtk.branch import BranchDialog
-        return BranchDialog(path)
-
-
-class cmd_gcheckout(GTKCommand):
-    """ GTK+ checkout.
-    
-    """
-    
-    def get_gtk_dialog(self, path):
-        from bzrlib.plugins.gtk.checkout import CheckoutDialog
-        return CheckoutDialog(path)
-
-
-
-class cmd_gpush(GTKCommand):
-    """ GTK+ push.
-    
-    """
-    takes_args = [ "location?" ]
-
-    def run(self, location="."):
-        (br, path) = branch.Branch.open_containing(location)
-        open_display()
-        from bzrlib.plugins.gtk.push import PushDialog
-        dialog = PushDialog(br.repository, br.last_revision(), br)
-        dialog.run()
-
-
-class cmd_gloom(GTKCommand):
-    """ GTK+ loom.
-    
-    """
-    takes_args = [ "location?" ]
-
-    def run(self, location="."):
-        try:
-            (tree, path) = workingtree.WorkingTree.open_containing(location)
-            br = tree.branch
-        except NoWorkingTree, e:
-            (br, path) = branch.Branch.open_containing(location)
-            tree = None
-        open_display()
-        from bzrlib.plugins.gtk.loom import LoomDialog
-        dialog = LoomDialog(br, tree)
-        dialog.run()
-
-
-class cmd_gdiff(GTKCommand):
-    """Show differences in working tree in a GTK+ Window.
-    
-    Otherwise, all changes for the tree are listed.
-    """
-    takes_args = ['filename?']
-    takes_options = ['revision']
-
-    @display_command
-    def run(self, revision=None, filename=None):
-        set_ui_factory()
-        wt = workingtree.WorkingTree.open_containing(".")[0]
-        wt.lock_read()
-        try:
-            branch = wt.branch
-            if revision is not None:
-                if len(revision) == 1:
-                    tree1 = wt
-                    revision_id = revision[0].as_revision_id(tree1.branch)
-                    tree2 = branch.repository.revision_tree(revision_id)
-                elif len(revision) == 2:
-                    revision_id_0 = revision[0].as_revision_id(branch)
-                    tree2 = branch.repository.revision_tree(revision_id_0)
-                    revision_id_1 = revision[1].as_revision_id(branch)
-                    tree1 = branch.repository.revision_tree(revision_id_1)
-            else:
-                tree1 = wt
-                tree2 = tree1.basis_tree()
-
-            from diff import DiffWindow
-            import gtk
-            window = DiffWindow()
-            window.connect("destroy", gtk.main_quit)
-            window.set_diff("Working Tree", tree1, tree2)
-            if filename is not None:
-                tree_filename = wt.relpath(filename)
-                try:
-                    window.set_file(tree_filename)
-                except NoSuchFile:
-                    if (tree1.path2id(tree_filename) is None and 
-                        tree2.path2id(tree_filename) is None):
-                        raise NotVersionedError(filename)
-                    raise BzrCommandError('No changes found for file "%s"' % 
-                                          filename)
-            window.show()
-
-            gtk.main()
-        finally:
-            wt.unlock()
-
-
-def start_viz_window(branch, revisions, limit=None):
-    """Start viz on branch with revision revision.
-    
-    :return: The viz window object.
-    """
-    from bzrlib.plugins.gtk.viz import BranchWindow
-    return BranchWindow(branch, revisions, limit)
-
-
-class cmd_visualise(Command):
-    """Graphically visualise this branch.
-
-    Opens a graphical window to allow you to see the history of the branch
-    and relationships between revisions in a visual manner,
-
-    The default starting point is latest revision on the branch, you can
-    specify a starting point with -r revision.
-    """
-    takes_options = [
-        "revision",
-        Option('limit', "Maximum number of revisions to display.",
-               int, 'count')]
-    takes_args = [ "locations*" ]
-    aliases = [ "visualize", "vis", "viz" ]
-
-    def run(self, locations_list, revision=None, limit=None):
-        set_ui_factory()
-        if locations_list is None:
-            locations_list = ["."]
-        revids = []
-        for location in locations_list:
-            (br, path) = branch.Branch.open_containing(location)
-            if revision is None:
-                revids.append(br.last_revision())
-            else:
-                revids.append(revision[0].as_revision_id(br))
-        import gtk
-        pp = start_viz_window(br, revids, limit)
-        pp.connect("destroy", lambda w: gtk.main_quit())
-        pp.show()
-        gtk.main()
-
-
-class cmd_gannotate(GTKCommand):
-    """GTK+ annotate.
-    
-    Browse changes to FILENAME line by line in a GTK+ window.
-    """
-
-    takes_args = ["filename", "line?"]
-    takes_options = [
-        Option("all", help="Show annotations on all lines."),
-        Option("plain", help="Don't highlight annotation lines."),
-        Option("line", type=int, argname="lineno",
-               help="Jump to specified line number."),
-        "revision",
-    ]
-    aliases = ["gblame", "gpraise"]
-    
-    def run(self, filename, all=False, plain=False, line='1', revision=None):
-        gtk = open_display()
-
-        try:
-            line = int(line)
-        except ValueError:
-            raise BzrCommandError('Line argument ("%s") is not a number.' % 
-                                  line)
-
-        from annotate.gannotate import GAnnotateWindow
-        from annotate.config import GAnnotateConfig
-        from bzrlib.bzrdir import BzrDir
-
-        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
-        if wt is not None:
-            tree = wt
-        else:
-            tree = br.basis_tree()
-
-        file_id = tree.path2id(path)
-
-        if file_id is None:
-            raise NotVersionedError(filename)
-        if revision is not None:
-            if len(revision) != 1:
-                raise BzrCommandError("Only 1 revion may be specified.")
-            revision_id = revision[0].as_revision_id(br)
-            tree = br.repository.revision_tree(revision_id)
-        else:
-            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
-
-        window = GAnnotateWindow(all, plain, branch=br)
-        window.connect("destroy", lambda w: gtk.main_quit())
-        config = GAnnotateConfig(window)
-        window.show()
-        br.lock_read()
-        if wt is not None:
-            wt.lock_read()
-        try:
-            window.annotate(tree, br, file_id)
-            window.jump_to_line(line)
-            gtk.main()
-        finally:
-            br.unlock()
-            if wt is not None:
-                wt.unlock()
-
-
-
-class cmd_gcommit(GTKCommand):
-    """GTK+ commit dialog
-
-    Graphical user interface for committing revisions"""
-
-    aliases = [ "gci" ]
-    takes_args = []
-    takes_options = []
-
-    def run(self, filename=None):
-        import os
-        open_display()
-        from commit import CommitDialog
-        from bzrlib.errors import (BzrCommandError,
-                                   NotBranchError,
-                                   NoWorkingTree)
-
-        wt = None
-        br = None
-        try:
-            (wt, path) = workingtree.WorkingTree.open_containing(filename)
-            br = wt.branch
-        except NoWorkingTree, e:
-            from dialog import error_dialog
-            error_dialog(_i18n('Directory does not have a working tree'),
-                         _i18n('Operation aborted.'))
-            return 1 # should this be retval=3?
-
-        # It is a good habit to keep things locked for the duration, but it
-        # could cause difficulties if someone wants to do things in another
-        # window... We could lock_read() until we actually go to commit
-        # changes... Just a thought.
-        wt.lock_write()
-        try:
-            dlg = CommitDialog(wt)
-            return dlg.run()
-        finally:
-            wt.unlock()
-
-
-class cmd_gstatus(GTKCommand):
-    """GTK+ status dialog
-
-    Graphical user interface for showing status 
-    information."""
-
-    aliases = [ "gst" ]
-    takes_args = ['PATH?']
-    takes_options = ['revision']
-
-    def run(self, path='.', revision=None):
-        import os
-        gtk = open_display()
-        from bzrlib.plugins.gtk.status import StatusWindow
-        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
-
-        if revision is not None:
-            try:
-                revision_id = revision[0].as_revision_id(wt.branch)
-            except:
-                from bzrlib.errors import BzrError
-                raise BzrError('Revision %r doesn\'t exist'
-                               % revision[0].user_spec )
-        else:
-            revision_id = None
-
-        status = StatusWindow(wt, wt_path, revision_id)
-        status.connect("destroy", gtk.main_quit)
-        status.show()
-        gtk.main()
-
-
-class cmd_gsend(GTKCommand):
-    """GTK+ send merge directive.
-
-    """
-    def run(self):
-        (br, path) = branch.Branch.open_containing(".")
-        gtk = open_display()
-        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
-        from StringIO import StringIO
-        dialog = SendMergeDirectiveDialog(br)
-        if dialog.run() == gtk.RESPONSE_OK:
-            outf = StringIO()
-            outf.writelines(dialog.get_merge_directive().to_lines())
-            mail_client = br.get_config().get_mail_client()
-            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
-                outf.getvalue())
-
-            
-
-
-class cmd_gconflicts(GTKCommand):
-    """GTK+ conflicts.
-    
-    Select files from the list of conflicts and run an external utility to
-    resolve them.
-    """
-    def run(self):
-        (wt, path) = workingtree.WorkingTree.open_containing('.')
-        open_display()
-        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
-        dialog = ConflictsDialog(wt)
-        dialog.run()
-
-
-class cmd_gpreferences(GTKCommand):
-    """ GTK+ preferences dialog.
-
-    """
-    def run(self):
-        open_display()
-        from bzrlib.plugins.gtk.preferences import PreferencesWindow
-        dialog = PreferencesWindow()
-        dialog.run()
-
-
-class cmd_ginfo(Command):
-    """ GTK+ info dialog
-    
-    """
-    def run(self):
-        from bzrlib import workingtree
-        from bzrlib.plugins.gtk.olive.info import InfoDialog
-        wt = workingtree.WorkingTree.open_containing('.')[0]
-        info = InfoDialog(wt.branch)
-        info.display()
-        info.window.run()
-
-
-class cmd_gmerge(Command):
-    """ GTK+ merge dialog
-    
-    """
-    takes_args = ["merge_from_path?"]
-    def run(self, merge_from_path=None):
-        from bzrlib import workingtree
-        from bzrlib.plugins.gtk.dialog import error_dialog
-        from bzrlib.plugins.gtk.merge import MergeDialog
-        
-        (wt, path) = workingtree.WorkingTree.open_containing('.')
-        old_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
-        delta = wt.changes_from(old_tree)
-        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
-            error_dialog(_i18n('There are local changes in the branch'),
-                         _i18n('Please commit or revert the changes before merging.'))
-        else:
-            parent_branch_path = wt.branch.get_parent()
-            merge = MergeDialog(wt, path, parent_branch_path)
-            response = merge.run()
-            merge.destroy()
-
-
-class cmd_gmissing(Command):
-    """ GTK+ missing revisions dialog.
-
-    """
-    takes_args = ["other_branch?"]
-    def run(self, other_branch=None):
-        pygtk = import_pygtk()
-        try:
-            import gtk
-        except RuntimeError, e:
-            if str(e) == "could not open display":
-                raise NoDisplayError
-
-        from bzrlib.plugins.gtk.missing import MissingWindow
-        from bzrlib.branch import Branch
-
-        local_branch = Branch.open_containing(".")[0]
-        if other_branch is None:
-            other_branch = local_branch.get_parent()
-            
-            if other_branch is None:
-                raise errors.BzrCommandError("No peer location known or specified.")
-        remote_branch = Branch.open_containing(other_branch)[0]
-        set_ui_factory()
-        local_branch.lock_read()
-        try:
-            remote_branch.lock_read()
-            try:
-                dialog = MissingWindow(local_branch, remote_branch)
-                dialog.run()
-            finally:
-                remote_branch.unlock()
-        finally:
-            local_branch.unlock()
-
-
-class cmd_ginit(GTKCommand):
-    def run(self):
-        open_display()
-        from initialize import InitDialog
-        dialog = InitDialog(os.path.abspath(os.path.curdir))
-        dialog.run()
-
-
-class cmd_gtags(GTKCommand):
-    def run(self):
-        br = branch.Branch.open_containing('.')[0]
-        
-        gtk = open_display()
-        from tags import TagsWindow
-        window = TagsWindow(br)
-        window.show()
-        gtk.main()
-
-
-commands = [
-    cmd_gannotate, 
-    cmd_gbranch,
-    cmd_gcheckout, 
-    cmd_gcommit, 
-    cmd_gconflicts, 
-    cmd_gdiff,
-    cmd_ginit,
-    cmd_ginfo,
-    cmd_gmerge,
-    cmd_gmissing, 
-    cmd_gpreferences, 
-    cmd_gpush, 
-    cmd_gsend,
-    cmd_gstatus,
-    cmd_gtags,
-    cmd_visualise
-    ]
+commands = {
+    "gannotate": ["gblame", "gpraise"],
+    "gbranch": [],
+    "gcheckout": [], 
+    "gcommit": ["gci"], 
+    "gconflicts": [], 
+    "gdiff": [],
+    "ginit": [],
+    "ginfo": [],
+    "gmerge": [],
+    "gmissing": [], 
+    "gpreferences": [], 
+    "gpush": [], 
+    "gselftest": [],
+    "gsend": [],
+    "gstatus": ["gst"],
+    "gtags": [],
+    "visualise": ["visualize", "vis", "viz"],
+    }
 
 try:
     from bzrlib.plugins import loom
 except ImportError:
     pass # Loom plugin doesn't appear to be present
 else:
-    commands.append(cmd_gloom)
-
-for cmd in commands:
-    register_command(cmd)
-
-
-class cmd_gselftest(GTKCommand):
-    """Version of selftest that displays a notification at the end"""
-
-    takes_args = builtins.cmd_selftest.takes_args
-    takes_options = builtins.cmd_selftest.takes_options
-    _see_also = ['selftest']
-
-    def run(self, *args, **kwargs):
-        import cgi
-        import sys
-        default_encoding = sys.getdefaultencoding()
-        # prevent gtk from blowing up later
-        gtk = import_pygtk()
-        # prevent gtk from messing with default encoding
-        import pynotify
-        if sys.getdefaultencoding() != default_encoding:
-            reload(sys)
-            sys.setdefaultencoding(default_encoding)
-        result = builtins.cmd_selftest().run(*args, **kwargs)
-        if result == 0:
-            summary = 'Success'
-            body = 'Selftest succeeded in "%s"' % os.getcwd()
-        if result == 1:
-            summary = 'Failure'
-            body = 'Selftest failed in "%s"' % os.getcwd()
-        pynotify.init("bzr gselftest")
-        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
-        note.set_timeout(pynotify.EXPIRES_NEVER)
-        note.show()
-
-
-register_command(cmd_gselftest)
+    commands["gloom"] = []
+
+for cmd, aliases in commands.iteritems():
+    plugin_cmds.register_lazy("cmd_%s" % cmd, aliases, "bzrlib.plugins.gtk.commands")
 
 
 import gettext
@@ -636,7 +154,7 @@
 # uses of '_' as an anonymous variable (think pdb for one).
 _i18n = gettext.gettext
 
-class NoDisplayError(BzrCommandError):
+class NoDisplayError(errors.BzrCommandError):
     """gtk could not find a proper display"""
 
     def __str__(self):

=== added file 'commands.py'
--- commands.py	1970-01-01 00:00:00 +0000
+++ commands.py	2009-01-30 16:03:10 +0000
@@ -0,0 +1,495 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from bzrlib import (
+    branch,
+    builtins,
+    merge_directive,
+    workingtree,
+    )
+from bzrlib.commands import (
+    Command,
+    display_command,
+    )
+from bzrlib.errors import (
+    BzrCommandError,
+    NotVersionedError,
+    NoSuchFile,
+    )
+from bzrlib.option import Option
+
+from bzrlib.plugins.gtk import (
+    open_display,
+    import_pygtk,
+    set_ui_factory,
+    )
+
+class GTKCommand(Command):
+    """Abstract class providing GTK specific run commands."""
+
+    def run(self):
+        open_display()
+        dialog = self.get_gtk_dialog(os.path.abspath('.'))
+        dialog.run()
+
+
+class cmd_gbranch(GTKCommand):
+    """GTK+ branching.
+    
+    """
+
+    def get_gtk_dialog(self, path):
+        from bzrlib.plugins.gtk.branch import BranchDialog
+        return BranchDialog(path)
+
+
+class cmd_gcheckout(GTKCommand):
+    """ GTK+ checkout.
+    
+    """
+    
+    def get_gtk_dialog(self, path):
+        from bzrlib.plugins.gtk.checkout import CheckoutDialog
+        return CheckoutDialog(path)
+
+
+
+class cmd_gpush(GTKCommand):
+    """ GTK+ push.
+    
+    """
+    takes_args = [ "location?" ]
+
+    def run(self, location="."):
+        (br, path) = branch.Branch.open_containing(location)
+        open_display()
+        from bzrlib.plugins.gtk.push import PushDialog
+        dialog = PushDialog(br.repository, br.last_revision(), br)
+        dialog.run()
+
+
+class cmd_gloom(GTKCommand):
+    """ GTK+ loom.
+    
+    """
+    takes_args = [ "location?" ]
+
+    def run(self, location="."):
+        try:
+            (tree, path) = workingtree.WorkingTree.open_containing(location)
+            br = tree.branch
+        except NoWorkingTree, e:
+            (br, path) = branch.Branch.open_containing(location)
+            tree = None
+        open_display()
+        from bzrlib.plugins.gtk.loom import LoomDialog
+        dialog = LoomDialog(br, tree)
+        dialog.run()
+
+
+class cmd_gdiff(GTKCommand):
+    """Show differences in working tree in a GTK+ Window.
+    
+    Otherwise, all changes for the tree are listed.
+    """
+    takes_args = ['filename?']
+    takes_options = ['revision']
+
+    @display_command
+    def run(self, revision=None, filename=None):
+        set_ui_factory()
+        wt = workingtree.WorkingTree.open_containing(".")[0]
+        wt.lock_read()
+        try:
+            branch = wt.branch
+            if revision is not None:
+                if len(revision) == 1:
+                    tree1 = wt
+                    revision_id = revision[0].as_revision_id(tree1.branch)
+                    tree2 = branch.repository.revision_tree(revision_id)
+                elif len(revision) == 2:
+                    revision_id_0 = revision[0].as_revision_id(branch)
+                    tree2 = branch.repository.revision_tree(revision_id_0)
+                    revision_id_1 = revision[1].as_revision_id(branch)
+                    tree1 = branch.repository.revision_tree(revision_id_1)
+            else:
+                tree1 = wt
+                tree2 = tree1.basis_tree()
+
+            from diff import DiffWindow
+            import gtk
+            window = DiffWindow()
+            window.connect("destroy", gtk.main_quit)
+            window.set_diff("Working Tree", tree1, tree2)
+            if filename is not None:
+                tree_filename = wt.relpath(filename)
+                try:
+                    window.set_file(tree_filename)
+                except NoSuchFile:
+                    if (tree1.path2id(tree_filename) is None and 
+                        tree2.path2id(tree_filename) is None):
+                        raise NotVersionedError(filename)
+                    raise BzrCommandError('No changes found for file "%s"' % 
+                                          filename)
+            window.show()
+
+            gtk.main()
+        finally:
+            wt.unlock()
+
+
+def start_viz_window(branch, revisions, limit=None):
+    """Start viz on branch with revision revision.
+    
+    :return: The viz window object.
+    """
+    from bzrlib.plugins.gtk.viz import BranchWindow
+    return BranchWindow(branch, revisions, limit)
+
+
+class cmd_visualise(Command):
+    """Graphically visualise this branch.
+
+    Opens a graphical window to allow you to see the history of the branch
+    and relationships between revisions in a visual manner,
+
+    The default starting point is latest revision on the branch, you can
+    specify a starting point with -r revision.
+    """
+    takes_options = [
+        "revision",
+        Option('limit', "Maximum number of revisions to display.",
+               int, 'count')]
+    takes_args = [ "locations*" ]
+    aliases = [ "visualize", "vis", "viz" ]
+
+    def run(self, locations_list, revision=None, limit=None):
+        set_ui_factory()
+        if locations_list is None:
+            locations_list = ["."]
+        revids = []
+        for location in locations_list:
+            (br, path) = branch.Branch.open_containing(location)
+            if revision is None:
+                revids.append(br.last_revision())
+            else:
+                revids.append(revision[0].as_revision_id(br))
+        import gtk
+        pp = start_viz_window(br, revids, limit)
+        pp.connect("destroy", lambda w: gtk.main_quit())
+        pp.show()
+        gtk.main()
+
+
+class cmd_gannotate(GTKCommand):
+    """GTK+ annotate.
+    
+    Browse changes to FILENAME line by line in a GTK+ window.
+    """
+
+    takes_args = ["filename", "line?"]
+    takes_options = [
+        Option("all", help="Show annotations on all lines."),
+        Option("plain", help="Don't highlight annotation lines."),
+        Option("line", type=int, argname="lineno",
+               help="Jump to specified line number."),
+        "revision",
+    ]
+    aliases = ["gblame", "gpraise"]
+    
+    def run(self, filename, all=False, plain=False, line='1', revision=None):
+        gtk = open_display()
+
+        try:
+            line = int(line)
+        except ValueError:
+            raise BzrCommandError('Line argument ("%s") is not a number.' % 
+                                  line)
+
+        from annotate.gannotate import GAnnotateWindow
+        from annotate.config import GAnnotateConfig
+        from bzrlib.bzrdir import BzrDir
+
+        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
+        if wt is not None:
+            tree = wt
+        else:
+            tree = br.basis_tree()
+
+        file_id = tree.path2id(path)
+
+        if file_id is None:
+            raise NotVersionedError(filename)
+        if revision is not None:
+            if len(revision) != 1:
+                raise BzrCommandError("Only 1 revion may be specified.")
+            revision_id = revision[0].as_revision_id(br)
+            tree = br.repository.revision_tree(revision_id)
+        else:
+            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
+
+        window = GAnnotateWindow(all, plain, branch=br)
+        window.connect("destroy", lambda w: gtk.main_quit())
+        config = GAnnotateConfig(window)
+        window.show()
+        br.lock_read()
+        if wt is not None:
+            wt.lock_read()
+        try:
+            window.annotate(tree, br, file_id)
+            window.jump_to_line(line)
+            gtk.main()
+        finally:
+            br.unlock()
+            if wt is not None:
+                wt.unlock()
+
+
+
+class cmd_gcommit(GTKCommand):
+    """GTK+ commit dialog
+
+    Graphical user interface for committing revisions"""
+
+    aliases = [ "gci" ]
+    takes_args = []
+    takes_options = []
+
+    def run(self, filename=None):
+        import os
+        open_display()
+        from commit import CommitDialog
+        from bzrlib.errors import (BzrCommandError,
+                                   NotBranchError,
+                                   NoWorkingTree)
+
+        wt = None
+        br = None
+        try:
+            (wt, path) = workingtree.WorkingTree.open_containing(filename)
+            br = wt.branch
+        except NoWorkingTree, e:
+            from dialog import error_dialog
+            error_dialog(_i18n('Directory does not have a working tree'),
+                         _i18n('Operation aborted.'))
+            return 1 # should this be retval=3?
+
+        # It is a good habit to keep things locked for the duration, but it
+        # could cause difficulties if someone wants to do things in another
+        # window... We could lock_read() until we actually go to commit
+        # changes... Just a thought.
+        wt.lock_write()
+        try:
+            dlg = CommitDialog(wt)
+            return dlg.run()
+        finally:
+            wt.unlock()
+
+
+class cmd_gstatus(GTKCommand):
+    """GTK+ status dialog
+
+    Graphical user interface for showing status 
+    information."""
+
+    aliases = [ "gst" ]
+    takes_args = ['PATH?']
+    takes_options = ['revision']
+
+    def run(self, path='.', revision=None):
+        import os
+        gtk = open_display()
+        from bzrlib.plugins.gtk.status import StatusWindow
+        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
+
+        if revision is not None:
+            try:
+                revision_id = revision[0].as_revision_id(wt.branch)
+            except:
+                from bzrlib.errors import BzrError
+                raise BzrError('Revision %r doesn\'t exist'
+                               % revision[0].user_spec )
+        else:
+            revision_id = None
+
+        status = StatusWindow(wt, wt_path, revision_id)
+        status.connect("destroy", gtk.main_quit)
+        status.show()
+        gtk.main()
+
+
+class cmd_gsend(GTKCommand):
+    """GTK+ send merge directive.
+
+    """
+    def run(self):
+        (br, path) = branch.Branch.open_containing(".")
+        gtk = open_display()
+        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
+        from StringIO import StringIO
+        dialog = SendMergeDirectiveDialog(br)
+        if dialog.run() == gtk.RESPONSE_OK:
+            outf = StringIO()
+            outf.writelines(dialog.get_merge_directive().to_lines())
+            mail_client = br.get_config().get_mail_client()
+            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
+                outf.getvalue())
+
+            
+
+
+class cmd_gconflicts(GTKCommand):
+    """GTK+ conflicts.
+    
+    Select files from the list of conflicts and run an external utility to
+    resolve them.
+    """
+    def run(self):
+        (wt, path) = workingtree.WorkingTree.open_containing('.')
+        open_display()
+        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
+        dialog = ConflictsDialog(wt)
+        dialog.run()
+
+
+class cmd_gpreferences(GTKCommand):
+    """ GTK+ preferences dialog.
+
+    """
+    def run(self):
+        open_display()
+        from bzrlib.plugins.gtk.preferences import PreferencesWindow
+        dialog = PreferencesWindow()
+        dialog.run()
+
+
+class cmd_ginfo(Command):
+    """ GTK+ info dialog
+    
+    """
+    def run(self):
+        from bzrlib import workingtree
+        from bzrlib.plugins.gtk.olive.info import InfoDialog
+        wt = workingtree.WorkingTree.open_containing('.')[0]
+        info = InfoDialog(wt.branch)
+        info.display()
+        info.window.run()
+
+
+class cmd_gmerge(Command):
+    """ GTK+ merge dialog
+    
+    """
+    takes_args = ["merge_from_path?"]
+    def run(self, merge_from_path=None):
+        from bzrlib.plugins.gtk.dialog import error_dialog
+        from bzrlib.plugins.gtk.merge import MergeDialog
+        
+        (wt, path) = workingtree.WorkingTree.open_containing('.')
+        old_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
+        delta = wt.changes_from(old_tree)
+        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
+            error_dialog(_i18n('There are local changes in the branch'),
+                         _i18n('Please commit or revert the changes before merging.'))
+        else:
+            parent_branch_path = wt.branch.get_parent()
+            merge = MergeDialog(wt, path, parent_branch_path)
+            response = merge.run()
+            merge.destroy()
+
+
+class cmd_gmissing(Command):
+    """ GTK+ missing revisions dialog.
+
+    """
+    takes_args = ["other_branch?"]
+    def run(self, other_branch=None):
+        pygtk = import_pygtk()
+        try:
+            import gtk
+        except RuntimeError, e:
+            if str(e) == "could not open display":
+                raise NoDisplayError
+
+        from bzrlib.plugins.gtk.missing import MissingWindow
+        from bzrlib.branch import Branch
+
+        local_branch = Branch.open_containing(".")[0]
+        if other_branch is None:
+            other_branch = local_branch.get_parent()
+            
+            if other_branch is None:
+                raise errors.BzrCommandError("No peer location known or specified.")
+        remote_branch = Branch.open_containing(other_branch)[0]
+        set_ui_factory()
+        local_branch.lock_read()
+        try:
+            remote_branch.lock_read()
+            try:
+                dialog = MissingWindow(local_branch, remote_branch)
+                dialog.run()
+            finally:
+                remote_branch.unlock()
+        finally:
+            local_branch.unlock()
+
+
+class cmd_ginit(GTKCommand):
+    def run(self):
+        open_display()
+        from initialize import InitDialog
+        dialog = InitDialog(os.path.abspath(os.path.curdir))
+        dialog.run()
+
+
+class cmd_gtags(GTKCommand):
+    def run(self):
+        br = branch.Branch.open_containing('.')[0]
+        
+        gtk = open_display()
+        from tags import TagsWindow
+        window = TagsWindow(br)
+        window.show()
+        gtk.main()
+
+
+class cmd_gselftest(GTKCommand):
+    """Version of selftest that displays a notification at the end"""
+
+    takes_args = builtins.cmd_selftest.takes_args
+    takes_options = builtins.cmd_selftest.takes_options
+    _see_also = ['selftest']
+
+    def run(self, *args, **kwargs):
+        import cgi
+        import sys
+        default_encoding = sys.getdefaultencoding()
+        # prevent gtk from blowing up later
+        gtk = import_pygtk()
+        # prevent gtk from messing with default encoding
+        import pynotify
+        if sys.getdefaultencoding() != default_encoding:
+            reload(sys)
+            sys.setdefaultencoding(default_encoding)
+        result = builtins.cmd_selftest().run(*args, **kwargs)
+        if result == 0:
+            summary = 'Success'
+            body = 'Selftest succeeded in "%s"' % os.getcwd()
+        if result == 1:
+            summary = 'Failure'
+            body = 'Selftest failed in "%s"' % os.getcwd()
+        pynotify.init("bzr gselftest")
+        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
+        note.set_timeout(pynotify.EXPIRES_NEVER)
+        note.show()

# Begin bundle
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
-- 
bzr-gtk mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.canonical.com/mailman/listinfo/bzr-gtk

Reply via email to