Source

hgcachedoutgoing / cout.py

# -*- 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 are {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.