/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/git/revspec.py

  • Committer: Jelmer Vernooij
  • Date: 2020-09-02 16:35:18 UTC
  • mto: (7490.40.109 work)
  • mto: This revision was merged to the branch mainline in revision 7526.
  • Revision ID: jelmer@jelmer.uk-20200902163518-sy9f4unbboljphgu
Handle duplicate directories entries for git.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
 
1
# Copyright (C) 2009-2018 Jelmer Vernooij <jelmer@jelmer.uk>
2
2
 
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 3 of the License, or
 
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
 
 
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
16
17
"""Custom revision specifier for Subversion."""
17
18
 
 
19
from __future__ import absolute_import
 
20
 
18
21
# Please note that imports are delayed as much as possible here since
19
22
# if DWIM revspecs are supported this module is imported by __init__.py.
20
23
 
21
 
from bzrlib.errors import (
 
24
from ..errors import (
22
25
    InvalidRevisionId,
23
 
    InvalidRevisionSpec,
24
26
    )
25
 
from bzrlib.revision import (
 
27
from ..revision import (
26
28
    NULL_REVISION,
27
29
)
28
 
from bzrlib.revisionspec import (
 
30
from ..revisionspec import (
 
31
    InvalidRevisionSpec,
29
32
    RevisionInfo,
30
33
    RevisionSpec,
31
34
    )
33
36
 
34
37
def valid_git_sha1(hex):
35
38
    """Check if `hex` is a validly formatted Git SHA1.
36
 
    
 
39
 
37
40
    :param hex: Hex string to validate
38
41
    :return: Boolean
39
42
    """
40
 
    import binascii
41
43
    try:
42
 
        binascii.unhexlify(hex)
43
 
    except TypeError:
 
44
        int(hex, 16)
 
45
    except ValueError:
44
46
        return False
45
47
    else:
46
48
        return True
47
49
 
48
50
 
49
51
class RevisionSpec_git(RevisionSpec):
50
 
    """Selects a revision using a Subversion revision number."""
51
 
 
52
 
    help_txt = """Selects a revision using a Git revision sha1.
 
52
    """Selects a revision using a Git commit SHA1."""
 
53
 
 
54
    help_txt = """Selects a revision using a Git commit SHA1.
 
55
 
 
56
    Selects a revision using a Git commit SHA1, short or long.
 
57
 
 
58
    This works for both native Git repositories and Git revisions
 
59
    imported into Bazaar repositories.
53
60
    """
54
61
 
55
62
    prefix = 'git:'
56
63
    wants_revision_history = False
57
64
 
58
65
    def _lookup_git_sha1(self, branch, sha1):
59
 
        from bzrlib.plugins.git.errors import (
 
66
        from .errors import (
60
67
            GitSmartRemoteNotSupported,
61
68
            )
62
 
        from bzrlib.plugins.git.mapping import (
 
69
        from .mapping import (
63
70
            default_mapping,
64
71
            )
65
72
 
66
73
        bzr_revid = getattr(branch.repository, "lookup_foreign_revision_id",
67
 
                              default_mapping.revision_id_foreign_to_bzr)(sha1)
 
74
                            default_mapping.revision_id_foreign_to_bzr)(sha1)
68
75
        try:
69
76
            if branch.repository.has_revision(bzr_revid):
70
 
                history = self._history(branch, bzr_revid)
71
 
                return RevisionInfo.from_revision_id(branch, bzr_revid, history)
 
77
                return bzr_revid
72
78
        except GitSmartRemoteNotSupported:
73
 
            return RevisionInfo(branch, None, bzr_revid)
 
79
            return bzr_revid
74
80
        raise InvalidRevisionSpec(self.user_spec, branch)
75
81
 
76
 
    def _history(self, branch, revid):
77
 
        branch.lock_read()
78
 
        try:
79
 
            history = list(branch.repository.iter_reverse_revision_history(
80
 
                revid))
81
 
        finally:
82
 
            branch.unlock()
83
 
        history.reverse()
84
 
        return history
85
 
 
86
82
    def __nonzero__(self):
87
83
        # The default implementation uses branch.repository.has_revision()
88
84
        if self.rev_id is None:
92
88
        return True
93
89
 
94
90
    def _find_short_git_sha1(self, branch, sha1):
95
 
        from bzrlib.plugins.git.mapping import (
 
91
        from .mapping import (
96
92
            ForeignGit,
97
93
            mapping_registry,
98
94
            )
99
95
        parse_revid = getattr(branch.repository, "lookup_bzr_revision_id",
100
96
                              mapping_registry.parse_revision_id)
101
 
        branch.repository.lock_read()
102
 
        try:
 
97
        def matches_revid(revid):
 
98
            if revid == NULL_REVISION:
 
99
                return False
 
100
            try:
 
101
                foreign_revid, mapping = parse_revid(revid)
 
102
            except InvalidRevisionId:
 
103
                return False
 
104
            if not isinstance(mapping.vcs, ForeignGit):
 
105
                return False
 
106
            return foreign_revid.startswith(sha1)
 
107
        with branch.repository.lock_read():
103
108
            graph = branch.repository.get_graph()
104
 
            for revid, _ in graph.iter_ancestry([branch.last_revision()]):
105
 
                if revid == NULL_REVISION:
106
 
                    continue
107
 
                try:
108
 
                    foreign_revid, mapping = parse_revid(revid)
109
 
                except InvalidRevisionId:
110
 
                    continue
111
 
                if not isinstance(mapping.vcs, ForeignGit):
112
 
                    continue
113
 
                if foreign_revid.startswith(sha1):
114
 
                    history = self._history(branch, revid)
115
 
                    return RevisionInfo.from_revision_id(branch, revid, history)
 
109
            last_revid = branch.last_revision()
 
110
            if matches_revid(last_revid):
 
111
                return last_revid
 
112
            for revid, _ in graph.iter_ancestry([last_revid]):
 
113
                if matches_revid(revid):
 
114
                    return revid
116
115
            raise InvalidRevisionSpec(self.user_spec, branch)
117
 
        finally:
118
 
            branch.repository.unlock()
119
116
 
120
 
    def _match_on(self, branch, revs):
 
117
    def _as_revision_id(self, context_branch):
121
118
        loc = self.spec.find(':')
122
 
        git_sha1 = self.spec[loc+1:].encode("utf-8")
123
 
        if len(git_sha1) > 40 or not valid_git_sha1(git_sha1):
124
 
            raise InvalidRevisionSpec(self.user_spec, branch)
125
 
        from bzrlib.plugins.git import (
 
119
        git_sha1 = self.spec[loc + 1:].encode("utf-8")
 
120
        if (len(git_sha1) > 40 or len(git_sha1) < 4 or
 
121
                not valid_git_sha1(git_sha1)):
 
122
            raise InvalidRevisionSpec(self.user_spec, context_branch)
 
123
        from . import (
126
124
            lazy_check_versions,
127
125
            )
128
126
        lazy_check_versions()
129
127
        if len(git_sha1) == 40:
130
 
            return self._lookup_git_sha1(branch, git_sha1)
 
128
            return self._lookup_git_sha1(context_branch, git_sha1)
131
129
        else:
132
 
            return self._find_short_git_sha1(branch, git_sha1)
 
130
            return self._find_short_git_sha1(context_branch, git_sha1)
 
131
 
 
132
    def _match_on(self, branch, revs):
 
133
        revid = self._as_revision_id(branch)
 
134
        return RevisionInfo.from_revision_id(branch, revid)
133
135
 
134
136
    def needs_branch(self):
135
137
        return True