hgext/git/__init__.py
author Matt Harbison <matt_harbison@yahoo.com>
Sun, 20 Aug 2023 02:17:38 -0400
changeset 50854 1144c69c7f58
parent 50779 39eb3aab3e63
child 51863 f4733654f144
permissions -rw-r--r--
version: migrate `opts` to native kwargs
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     1
"""grant Mercurial the ability to operate on Git repositories. (EXPERIMENTAL)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     2
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     3
This is currently super experimental. It probably will consume your
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     4
firstborn a la Rumpelstiltskin, etc.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     5
"""
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     6
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     7
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     8
import os
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     9
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    10
from mercurial.i18n import _
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    11
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    12
from mercurial import (
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    13
    commands,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    14
    error,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
    extensions,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    16
    localrepo,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    17
    pycompat,
44951
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    18
    registrar,
49077
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
    19
    requirements as requirementsmod,
44623
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
    20
    scmutil,
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    21
    store,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
    util,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    23
)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    24
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    25
from . import (
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    26
    dirstate,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    27
    gitlog,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    28
    gitutil,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    29
    index,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    30
)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    31
45949
a001e28ad5eb git: add the standard `testedwith` attribute
Matt Harbison <matt_harbison@yahoo.com>
parents: 45942
diff changeset
    32
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
a001e28ad5eb git: add the standard `testedwith` attribute
Matt Harbison <matt_harbison@yahoo.com>
parents: 45942
diff changeset
    33
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
a001e28ad5eb git: add the standard `testedwith` attribute
Matt Harbison <matt_harbison@yahoo.com>
parents: 45942
diff changeset
    34
# be specifying the version(s) of Mercurial they are tested with, or
a001e28ad5eb git: add the standard `testedwith` attribute
Matt Harbison <matt_harbison@yahoo.com>
parents: 45942
diff changeset
    35
# leave the attribute unspecified.
a001e28ad5eb git: add the standard `testedwith` attribute
Matt Harbison <matt_harbison@yahoo.com>
parents: 45942
diff changeset
    36
testedwith = b'ships-with-hg-core'
a001e28ad5eb git: add the standard `testedwith` attribute
Matt Harbison <matt_harbison@yahoo.com>
parents: 45942
diff changeset
    37
44951
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    38
configtable = {}
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    39
configitem = registrar.configitem(configtable)
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    40
# git.log-index-cache-miss: internal knob for testing
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    41
configitem(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45419
diff changeset
    42
    b"git",
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45419
diff changeset
    43
    b"log-index-cache-miss",
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45419
diff changeset
    44
    default=False,
44951
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    45
)
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    46
45950
c7c1efdfd4de git: show the version of `pygit2` with verbose version output
Matt Harbison <matt_harbison@yahoo.com>
parents: 45949
diff changeset
    47
getversion = gitutil.pygit2_version
c7c1efdfd4de git: show the version of `pygit2` with verbose version output
Matt Harbison <matt_harbison@yahoo.com>
parents: 45949
diff changeset
    48
c7c1efdfd4de git: show the version of `pygit2` with verbose version output
Matt Harbison <matt_harbison@yahoo.com>
parents: 45949
diff changeset
    49
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    50
# TODO: extract an interface for this in core
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
    51
class gitstore:  # store.basicstore):
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
    def __init__(self, path, vfstype):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    53
        self.vfs = vfstype(path)
48539
b9d5ad7146a3 git: add opener attribute to gitstore
Augie Fackler <augie@google.com>
parents: 47631
diff changeset
    54
        self.opener = self.vfs
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    55
        self.path = self.vfs.base
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    56
        self.createmode = store._calcmode(self.vfs)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    57
        # above lines should go away in favor of:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    58
        # super(gitstore, self).__init__(path, vfstype)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    59
44484
ec54b3d2af0b git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents: 44477
diff changeset
    60
        self.git = gitutil.get_pygit2().Repository(
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    61
            os.path.normpath(os.path.join(path, b'..', b'.git'))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    62
        )
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    63
        self._progress_factory = lambda *args, **kwargs: None
44951
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    64
        self._logfn = lambda x: None
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    66
    @util.propertycache
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    67
    def _db(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    68
        # We lazy-create the database because we want to thread a
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    69
        # progress callback down to the indexing process if it's
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    70
        # required, and we don't have a ui handle in makestore().
44951
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
    71
        return index.get_index(self.git, self._logfn, self._progress_factory)
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    72
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    73
    def join(self, f):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    74
        """Fake store.join method for git repositories.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    75
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    76
        For the most part, store.join is used for @storecache
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
        decorators to invalidate caches when various files
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    78
        change. We'll map the ones we care about, and ignore the rest.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    79
        """
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    80
        if f in (b'00changelog.i', b'00manifest.i'):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    81
            # This is close enough: in order for the changelog cache
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    82
            # to be invalidated, HEAD will have to change.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    83
            return os.path.join(self.path, b'HEAD')
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    84
        elif f == b'lock':
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    85
            # TODO: we probably want to map this to a git lock, I
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    86
            # suspect index.lock. We should figure out what the
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    87
            # most-alike file is in git-land. For now we're risking
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    88
            # bad concurrency errors if another git client is used.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    89
            return os.path.join(self.path, b'hgit-bogus-lock')
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    90
        elif f in (b'obsstore', b'phaseroots', b'narrowspec', b'bookmarks'):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    91
            return os.path.join(self.path, b'..', b'.hg', f)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    92
        raise NotImplementedError(b'Need to pick file for %s.' % f)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    93
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents: 45950
diff changeset
    94
    def changelog(self, trypending, concurrencychecker):
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    95
        # TODO we don't have a plan for trypending in hg's git support yet
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    96
        return gitlog.changelog(self.git, self._db)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    97
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    98
    def manifestlog(self, repo, storenarrowmatch):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    99
        # TODO handle storenarrowmatch and figure out if we need the repo arg
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   100
        return gitlog.manifestlog(self.git, self._db)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   101
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   102
    def invalidatecaches(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   103
        pass
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   104
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   105
    def write(self, tr=None):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   106
        # normally this handles things like fncache writes, which we don't have
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   107
        pass
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   108
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   109
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   110
def _makestore(orig, requirements, storebasepath, vfstype):
44493
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   111
    if b'git' in requirements:
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   112
        if not os.path.exists(os.path.join(storebasepath, b'..', b'.git')):
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   113
            raise error.Abort(
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   114
                _(
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   115
                    b'repository specified git format in '
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   116
                    b'.hg/requires but has no .git directory'
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   117
                )
44484
ec54b3d2af0b git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents: 44477
diff changeset
   118
            )
44493
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   119
        # Check for presence of pygit2 only here. The assumption is that we'll
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   120
        # run this code iff we'll later need pygit2.
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   121
        if gitutil.get_pygit2() is None:
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   122
            raise error.Abort(
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   123
                _(
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   124
                    b'the git extension requires the Python '
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   125
                    b'pygit2 library to be installed'
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   126
                )
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   127
            )
44484
ec54b3d2af0b git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents: 44477
diff changeset
   128
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   129
        return gitstore(storebasepath, vfstype)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
    return orig(requirements, storebasepath, vfstype)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   131
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   133
class gitfilestorage:
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   134
    def file(self, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   135
        if path[0:1] == b'/':
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   136
            path = path[1:]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   137
        return gitlog.filelog(self.store.git, self.store._db, path)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   138
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   139
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   140
def _makefilestorage(orig, requirements, features, **kwargs):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   141
    store = kwargs['store']
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   142
    if isinstance(store, gitstore):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   143
        return gitfilestorage
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   144
    return orig(requirements, features, **kwargs)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   145
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   146
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   147
def _setupdothg(ui, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   148
    dothg = os.path.join(path, b'.hg')
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   149
    if os.path.exists(dothg):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
        ui.warn(_(b'git repo already initialized for hg\n'))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   151
    else:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   152
        os.mkdir(os.path.join(path, b'.hg'))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   153
        # TODO is it ok to extend .git/info/exclude like this?
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   154
        with open(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   155
            os.path.join(path, b'.git', b'info', b'exclude'), 'ab'
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   156
        ) as exclude:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   157
            exclude.write(b'\n.hg\n')
44493
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   158
    with open(os.path.join(dothg, b'requires'), 'wb') as f:
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   159
        f.write(b'git\n')
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   160
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   161
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   162
_BMS_PREFIX = 'refs/heads/'
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   163
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   164
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   165
class gitbmstore:
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   166
    def __init__(self, gitrepo):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   167
        self.gitrepo = gitrepo
44624
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   168
        self._aclean = True
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   169
        self._active = gitrepo.references['HEAD']  # git head, not mark
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   170
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   171
    def __contains__(self, name):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   172
        return (
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   173
            _BMS_PREFIX + pycompat.fsdecode(name)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   174
        ) in self.gitrepo.references
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   175
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   176
    def __iter__(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   177
        for r in self.gitrepo.listall_references():
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   178
            if r.startswith(_BMS_PREFIX):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   179
                yield pycompat.fsencode(r[len(_BMS_PREFIX) :])
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   180
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   181
    def __getitem__(self, k):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   182
        return (
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   183
            self.gitrepo.references[_BMS_PREFIX + pycompat.fsdecode(k)]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   184
            .peel()
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   185
            .id.raw
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   186
        )
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   187
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   188
    def get(self, k, default=None):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   189
        try:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   190
            if k in self:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   191
                return self[k]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   192
            return default
44484
ec54b3d2af0b git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents: 44477
diff changeset
   193
        except gitutil.get_pygit2().InvalidSpecError:
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   194
            return default
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   195
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   196
    @property
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   197
    def active(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   198
        h = self.gitrepo.references['HEAD']
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   199
        if not isinstance(h.target, str) or not h.target.startswith(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   200
            _BMS_PREFIX
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   201
        ):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   202
            return None
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   203
        return pycompat.fsencode(h.target[len(_BMS_PREFIX) :])
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   204
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   205
    @active.setter
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   206
    def active(self, mark):
49384
3b8fce9a74df git: make sure to fsdecode bookmark names everywhere (issue6723)
Anton Shestakov <av6@dwimlabs.net>
parents: 49077
diff changeset
   207
        githead = None
3b8fce9a74df git: make sure to fsdecode bookmark names everywhere (issue6723)
Anton Shestakov <av6@dwimlabs.net>
parents: 49077
diff changeset
   208
        if mark is not None:
3b8fce9a74df git: make sure to fsdecode bookmark names everywhere (issue6723)
Anton Shestakov <av6@dwimlabs.net>
parents: 49077
diff changeset
   209
            githead = _BMS_PREFIX + pycompat.fsdecode(mark)
44624
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   210
        if githead is not None and githead not in self.gitrepo.references:
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   211
            raise AssertionError(b'bookmark %s does not exist!' % mark)
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   212
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   213
        self._active = githead
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   214
        self._aclean = False
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   215
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   216
    def _writeactive(self):
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   217
        if self._aclean:
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   218
            return
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   219
        self.gitrepo.references.create('HEAD', self._active, True)
7cab8dbd0497 git: implement basic bookmark activation
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44623
diff changeset
   220
        self._aclean = True
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   221
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   222
    def names(self, node):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   223
        r = []
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   224
        for ref in self.gitrepo.listall_references():
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   225
            if not ref.startswith(_BMS_PREFIX):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   226
                continue
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   227
            if self.gitrepo.references[ref].peel().id.raw != node:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   228
                continue
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   229
            r.append(pycompat.fsencode(ref[len(_BMS_PREFIX) :]))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   230
        return r
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   231
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   232
    # Cleanup opportunity: this is *identical* to core's bookmarks store.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   233
    def expandname(self, bname):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   234
        if bname == b'.':
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   235
            if self.active:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   236
                return self.active
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   237
            raise error.RepoLookupError(_(b"no active bookmark"))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   238
        return bname
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   239
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   240
    def applychanges(self, repo, tr, changes):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45419
diff changeset
   241
        """Apply a list of changes to bookmarks"""
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   242
        # TODO: this should respect transactions, but that's going to
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   243
        # require enlarging the gitbmstore to know how to do in-memory
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   244
        # temporary writes and read those back prior to transaction
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   245
        # finalization.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   246
        for name, node in changes:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   247
            if node is None:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   248
                self.gitrepo.references.delete(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   249
                    _BMS_PREFIX + pycompat.fsdecode(name)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   250
                )
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   251
            else:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   252
                self.gitrepo.references.create(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   253
                    _BMS_PREFIX + pycompat.fsdecode(name),
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   254
                    gitutil.togitnode(node),
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   255
                    force=True,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   256
                )
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   257
44623
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   258
    def checkconflict(self, mark, force=False, target=None):
49384
3b8fce9a74df git: make sure to fsdecode bookmark names everywhere (issue6723)
Anton Shestakov <av6@dwimlabs.net>
parents: 49077
diff changeset
   259
        githead = _BMS_PREFIX + pycompat.fsdecode(mark)
44623
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   260
        cur = self.gitrepo.references['HEAD']
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   261
        if githead in self.gitrepo.references and not force:
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   262
            if target:
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   263
                if self.gitrepo.references[githead] == target and target == cur:
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   264
                    # re-activating a bookmark
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   265
                    return []
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   266
                # moving a bookmark - forward?
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   267
                raise NotImplementedError
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   268
            raise error.Abort(
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   269
                _(b"bookmark '%s' already exists (use -f to force)") % mark
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   270
            )
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   271
        if len(mark) > 3 and not force:
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   272
            try:
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   273
                shadowhash = scmutil.isrevsymbol(self._repo, mark)
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   274
            except error.LookupError:  # ambiguous identifier
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   275
                shadowhash = False
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   276
            if shadowhash:
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   277
                self._repo.ui.warn(
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   278
                    _(
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   279
                        b"bookmark %s matches a changeset hash\n"
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   280
                        b"(did you leave a -r out of an 'hg bookmark' "
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   281
                        b"command?)\n"
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   282
                    )
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   283
                    % mark
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   284
                )
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   285
        return []
bb3e05ca21ca git: implement a basic checkconflict bookmark store method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44542
diff changeset
   286
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   287
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   288
def init(orig, ui, dest=b'.', **opts):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   289
    if opts.get('git', False):
47631
16bae8abcc03 windows: use abspath in the git extension
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46607
diff changeset
   290
        path = util.abspath(dest)
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   291
        # TODO: walk up looking for the git repo
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   292
        _setupdothg(ui, path)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   293
        return 0
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   294
    return orig(ui, dest=dest, **opts)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   295
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   296
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   297
def reposetup(ui, repo):
44542
a2b49606a837 hgit: make sure repository is local before checking for store type
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44493
diff changeset
   298
    if repo.local() and isinstance(repo.store, gitstore):
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   299
        orig = repo.__class__
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   300
        repo.store._progress_factory = repo.ui.makeprogress
44951
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
   301
        if ui.configbool(b'git', b'log-index-cache-miss'):
83e41b73d115 git: add debug logging when there's a mismatch in the cached heads list
Augie Fackler <augie@google.com>
parents: 44624
diff changeset
   302
            repo.store._logfn = repo.ui.warn
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   303
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   304
        class gitlocalrepo(orig):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   305
            def _makedirstate(self):
49077
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
   306
                v2_req = requirementsmod.DIRSTATE_V2_REQUIREMENT
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
   307
                use_dirstate_v2 = v2_req in self.requirements
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
   308
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   309
                # TODO narrow support here
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   310
                return dirstate.gitdirstate(
49077
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
   311
                    self.ui,
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
   312
                    self.vfs,
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
   313
                    self.store.git,
20d151e43429 git: adapt to some recent dirstate API changes
Matt Harbison <matt_harbison@yahoo.com>
parents: 48946
diff changeset
   314
                    use_dirstate_v2,
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   315
                )
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   316
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   317
            def commit(self, *args, **kwargs):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   318
                ret = orig.commit(self, *args, **kwargs)
45419
6739ef7c5fcf git: correctly handle "nothing changed" commits
Augie Fackler <raf@durin42.com>
parents: 44951
diff changeset
   319
                if ret is None:
6739ef7c5fcf git: correctly handle "nothing changed" commits
Augie Fackler <raf@durin42.com>
parents: 44951
diff changeset
   320
                    # there was nothing to commit, so we should skip
6739ef7c5fcf git: correctly handle "nothing changed" commits
Augie Fackler <raf@durin42.com>
parents: 44951
diff changeset
   321
                    # the index fixup logic we'd otherwise do.
6739ef7c5fcf git: correctly handle "nothing changed" commits
Augie Fackler <raf@durin42.com>
parents: 44951
diff changeset
   322
                    return None
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   323
                tid = self.store.git[gitutil.togitnode(ret)].tree.id
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   324
                # DANGER! This will flush any writes staged to the
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   325
                # index in Git, but we're sidestepping the index in a
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   326
                # way that confuses git when we commit. Alas.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   327
                self.store.git.index.read_tree(tid)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   328
                self.store.git.index.write()
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   329
                return ret
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   330
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   331
            @property
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   332
            def _bookmarks(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   333
                return gitbmstore(self.store.git)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   334
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   335
        repo.__class__ = gitlocalrepo
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   336
    return repo
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   337
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   338
44493
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   339
def _featuresetup(ui, supported):
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   340
    # don't die on seeing a repo with the git requirement
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   341
    supported |= {b'git'}
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   342
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   343
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   344
def extsetup(ui):
50779
39eb3aab3e63 wrapfunction: use sysstr instead of bytes as argument in the "git" extension
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49384
diff changeset
   345
    extensions.wrapfunction(localrepo, 'makestore', _makestore)
39eb3aab3e63 wrapfunction: use sysstr instead of bytes as argument in the "git" extension
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49384
diff changeset
   346
    extensions.wrapfunction(localrepo, 'makefilestorage', _makefilestorage)
44477
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   347
    # Inject --git flag for `hg init`
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   348
    entry = extensions.wrapcommand(commands.table, b'init', init)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   349
    entry[1].extend(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   350
        [(b'', b'git', None, b'setup up a git repository instead of hg')]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   351
    )
44493
02c47b74366c git: key off `git` in .hg/requires rather than separate file
Augie Fackler <raf@durin42.com>
parents: 44484
diff changeset
   352
    localrepo.featuresetupfuncs.add(_featuresetup)