hgext/fetch.py
author Vadim Gelfer <vadim.gelfer@gmail.com>
Mon, 07 Aug 2006 17:33:14 -0700
changeset 2801 bd4dada96c2e
parent 2800 135823f37304
child 2802 df220d0974dd
permissions -rw-r--r--
fetch: do not fetch if working dir modified
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     1
# fetch.py - pull and merge remote changes
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     2
#
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     3
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     4
#
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     7
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     8
from mercurial.demandload import *
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     9
from mercurial.i18n import gettext as _
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    10
from mercurial.node import *
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    11
demandload(globals(), 'mercurial:commands,hg,node')
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    12
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    13
def fetch(ui, repo, source='default', **opts):
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    14
    '''Pull changes from a remote repository, merge new changes if needed.
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    15
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    16
    This finds all changes from the repository at the specified path
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    17
    or URL and adds them to the local repository.
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    18
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    19
    If the pulled changes add a new head, the head is automatically
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    20
    merged, and the result of the merge is committed.  Otherwise, the
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    21
    working directory is updated.'''
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    22
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    23
    def postincoming(other, modheads):
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    24
        if modheads == 0:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    25
            return 0
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    26
        if modheads == 1:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    27
            return commands.doupdate(ui, repo)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    28
        newheads = repo.heads(parent)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    29
        newchildren = [n for n in repo.heads(parent) if n != parent]
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    30
        newparent = parent
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    31
        if newchildren:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    32
            commands.doupdate(ui, repo, node=hex(newchildren[0]))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    33
            newparent = newchildren[0]
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    34
        newheads = [n for n in repo.heads() if n != newparent]
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    35
        err = False
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    36
        if newheads:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    37
            ui.status(_('merging with new head %d:%s\n') %
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    38
                      (repo.changelog.rev(newheads[0]), short(newheads[0])))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    39
            err = repo.update(newheads[0], allow=True, remind=False)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    40
        if not err and len(newheads) > 1:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    41
            ui.status(_('not merging with %d other new heads '
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    42
                        '(use "hg heads" and "hg merge" to merge them)') %
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    43
                      (len(newheads) - 1))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    44
        if not err:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    45
            mod, add, rem = repo.status()[:3]
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    46
            message = (commands.logmessage(opts) or
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    47
                       (_('Automated merge with %s') % other.url()))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    48
            n = repo.commit(mod + add + rem, message,
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    49
                            opts['user'], opts['date'],
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    50
                            force_editor=opts.get('force_editor'))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    51
            ui.status(_('new changeset %d:%s merges remote changes '
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    52
                        'with local\n') % (repo.changelog.rev(n),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    53
                                           short(n)))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    54
    def pull():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    55
        commands.setremoteconfig(ui, opts)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    56
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    57
        other = hg.repository(ui, ui.expandpath(source))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    58
        ui.status(_('pulling from %s\n') % source)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    59
        revs = None
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    60
        if opts['rev'] and not other.local():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    61
            raise util.Abort(_("fetch -r doesn't work for remote repositories yet"))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    62
        elif opts['rev']:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    63
            revs = [other.lookup(rev) for rev in opts['rev']]
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    64
        modheads = repo.pull(other, heads=revs)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    65
        return postincoming(other, modheads)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    66
        
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    67
    parent, p2 = repo.dirstate.parents()
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    68
    if parent != repo.changelog.tip():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    69
        raise util.Abort(_('working dir not at tip '
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    70
                           '(use "hg update" to check out tip)'))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    71
    if p2 != nullid:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    72
        raise util.Abort(_('outstanding uncommitted merge'))
2801
bd4dada96c2e fetch: do not fetch if working dir modified
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2800
diff changeset
    73
    mod, add, rem = repo.status()[:3]
bd4dada96c2e fetch: do not fetch if working dir modified
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2800
diff changeset
    74
    if mod or add or rem:
bd4dada96c2e fetch: do not fetch if working dir modified
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2800
diff changeset
    75
        raise util.Abort(_('outstanding uncommitted changes'))
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    76
    if len(repo.heads()) > 1:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    77
        raise util.Abort(_('multiple heads in this repository '
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    78
                           '(use "hg heads" and "hg merge" to merge them)'))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    79
    return pull()
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    80
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    81
cmdtable = {
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    82
    'fetch':
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    83
    (fetch,
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    84
     [('e', 'ssh', '', _('specify ssh command to use')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    85
      ('m', 'message', '', _('use <text> as commit message')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    86
      ('l', 'logfile', '', _('read the commit message from <file>')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    87
      ('d', 'date', '', _('record datecode as commit date')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    88
      ('u', 'user', '', _('record user as commiter')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    89
      ('r', 'rev', [], _('a specific revision you would like to pull')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    90
      ('f', 'force-editor', None, _('edit commit message')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    91
      ('', 'remotecmd', '', _('hg command to run on the remote side'))],
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    92
     'hg fetch [SOURCE]'),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    93
    }