Commits

Anonymous committed a522bf2

added cout.py: simple but working.

Comments (0)

Files changed (2)

+==================
+ HgCachedOutgoing
+==================
+
+What's this?
+============
+
+This mercurial extension provides cached version of ``hg outgoing``.
+Use this extension if you don't like to wait mercurial to finish
+asking remote server one single question every time when you execute
+``hg outgoing``.
+
+I wrote this extension because I like ``git status`` printing
+"Your branch is ahead of 'origin/master' by X commits"
+when I have some unpushed local changes.
+Mercurial should have this feature!
+
+
+Usage
+=====
+
+1. Download https://bitbucket.org/tkf/hgcachedoutgoing/src/tip/cout.py
+2. Add ``cout = /path/to/cout.py`` in ``[extensions]`` section
+   of your ``~/.hgrc``.
+3. Go to some mercurial repository and hit ``hg cout``.
+# -*- coding: utf-8 -*-
+
+# mercurial extension for cached version of ``hg outgoing``
+#
+# Copyright (C) 2011 by Takafumi Arakaki
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.
+
+
+"""Cached version of ``hg outgoing``"""
+
+import shelve
+import os
+from mercurial import hg
+from mercurial.node import short
+
+
+def _checkid(ui, repo, dest):
+    ui.debug("connecting to '{0}' to get the tip id.\n".format(dest))
+    destrepo = hg.peer(ui, {}, dest)
+    desttiprev = destrepo.lookup('tip')
+    # get "TypeError: 'sshrepository' object is unsubscriptable"
+    # if `destrepo['tip']` is used
+    return desttiprev
+
+
+def _get_cached_tip_id(ui, repo, dest, check):
+    dbpath = os.path.join(repo.root, '.hg', 'cout.db')
+    codb = shelve.open(dbpath)
+    ui.debug("opened DB in '{0}'\n".format(dbpath))
+    # get cached newest id on `dest` server (cdid)
+    dest = ui.expandpath(dest or 'default-push', dest or 'default')
+    if dest in codb and not check:
+        cdid = codb[dest]
+        ui.debug("dest '{0}' is in .hg/cout.db.\n".format(dest))
+    else:
+        # check tip id of dest
+        cdid = _checkid(ui, repo, dest)
+        codb[dest] = cdid
+    ui.debug("cdid='{0}' is successfully found.\n".format(short(cdid)))
+    codb.close()
+    ui.debug("closed DB in '{0}'\n".format(dbpath))
+    return cdid
+
+
+def cout(ui, repo, dest=None, check=False, **opts):
+    """Cached version of ``hg outgoing``"""
+
+    cdid = _get_cached_tip_id(ui, repo, dest, check)
+    # check if the newest id on server is the tip on local
+    if cdid in repo:
+        cdtip = repo[cdid]
+        ui.debug(
+            "got context object of tip on dest (rev='{0}', short='{1}').\n"
+            .format(cdtip.rev(), short(cdtip.node())))
+        ui.debug("short(codb['tip'].node()) = '{0}'\n"
+                 .format(short(repo['tip'].node())))
+        uncommitted = len(repo.status()[0])  # num. of uncommitted files
+        if cdtip == repo['tip'] and uncommitted == 0:
+            ui.write("there is nothing to push.\n")
+            return 1
+        else:
+            num_changes = repo['tip'].rev() - cdtip.rev()
+            ui.write("there is {0} changes to push.\n"
+                     .format(num_changes))
+            if uncommitted:
+                ui.write("and there are {0} uncommitted files in "
+                         "working directory.\n".format(uncommitted))
+    else:
+        ui.write("id='{0}' is not in current local repository.\n"
+                 "you might want to pull the changes.\n".format(cdid))
+
+
+cmdtable = {
+    # "command-name": (function-call, options-list, help-string)
+    "cout": (
+        cout,
+        [('c', 'check', False,
+          'forcefully check the tip of DEST (ignore cache)'),
+         ],
+        "[options] [DEST]")
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.