annotate src/hggit_serve.py @ 8:fe3c9fae4d4d

Add support for pushes, and improve authentication. Now you can `git push` to a Mercurial repository! Also we check permissions much more precisely.
author Paul Fisher <paul@pfish.zone>
date Sun, 15 Feb 2026 22:26:15 -0500
parents 4f42fdbb25f2
children 5000914da3ff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
1 from __future__ import annotations
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
2
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
3 import binascii
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
4 import email.parser
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
5 import email.policy
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
6 import re
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
7 import shutil
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
8 import subprocess
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
9 import typing as t
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
10
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
11 import dulwich.refs
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
12 import mercurial.error as hgerr
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
13 from hggit import git_handler
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
14 from mercurial import extensions
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
15 from mercurial import registrar
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
16 from mercurial import wireprotoserver
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
17 from mercurial.thirdparty import attr
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
18
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
19 if t.TYPE_CHECKING:
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
20 import mercurial.hgweb.hgweb_mod_inner as web_inner
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
21 import mercurial.hgweb.request as hgreq
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
22 import mercurial.interfaces.repository as hgrepo
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
23 import mercurial.ui as hgui
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
24
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
25 class GittyRepo(hgrepo.IRepo, t.Protocol):
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
26 githandler: git_handler.GitHandler
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
27
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
28 PermissionCheck = t.Callable[
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
29 [web_inner.requestcontext, hgreq.parsedrequest, bytes],
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
30 None,
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
31 ]
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
32
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
33
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
34 def _is_gitty(repo: hgrepo.IRepo) -> t.TypeGuard[GittyRepo]:
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
35 """Ensures that we have hg-git installed and active."""
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
36 return hasattr(repo, 'githandler')
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
37
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
38
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
39 _CGI_VAR = re.compile(rb'[A-Z0-9_]+$')
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
40 """Environment variables that we need to pass to git-as-cgi."""
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
41
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
42
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
43 def _build_git_environ(
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
44 req_ctx: web_inner.requestcontext,
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
45 request: hgreq.parsedrequest,
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
46 ) -> dict[bytes, bytes]:
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
47 """Builds the environment to be sent to Git to serve HTTP."""
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
48 fixed = {
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
49 k: v
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
50 for (k, v) in request.rawenv.items()
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
51 if isinstance(v, bytes) and _CGI_VAR.match(k)
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
52 }
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
53 fixed.update(
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
54 {
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
55 b'GIT_HTTP_EXPORT_ALL': b'yes',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
56 b'GIT_PROJECT_ROOT': req_ctx.repo.path,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
57 b'PATH_INFO': b'/git/' + request.dispatchpath,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
58 # Since Mercurial is taking care of authorization checking,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
59 # we tell Git to always allow push.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
60 b'GIT_CONFIG_COUNT': b'1',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
61 b'GIT_CONFIG_KEY_0': b'http.receivepack',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
62 b'GIT_CONFIG_VALUE_0': b'true',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
63 }
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
64 )
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
65 return fixed
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
66
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
67
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
68 def _parse_cgi_response(
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
69 output: t.IO[bytes],
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
70 ) -> tuple[bytes, dict[bytes, bytes], t.IO[bytes]]:
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
71 """Parses a CGI response into a status, headers, and everyhting else."""
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
72 parser = email.parser.BytesFeedParser(policy=email.policy.HTTP)
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
73 while line := output.readline():
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
74 if not line.rstrip(b'\r\n'):
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
75 # We've reached the end of the headers.
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
76 # Leave the rest in the output for later.
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
77 break
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
78 parser.feed(line)
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
79 msg = parser.close()
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
80 status = msg.get('Status', '200 OK I guess').encode('utf-8')
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
81 del msg['Status'] # this won't raise an exception
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
82 byte_headers = {
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
83 k.encode('utf-8'): v.encode('utf-8') for (k, v) in msg.items()
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
84 }
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
85 return status, byte_headers, output
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
86
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
87
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
88 _PULL = b'pull'
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
89 _PUSH = b'push'
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
90
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
91 _SERVICE_PERMISSIONS = {
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
92 b'git-upload-pack': _PULL,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
93 b'git-receive-pack': _PUSH,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
94 }
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
95 """The Mercurial permission corresponding to each Git action.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
96
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
97 These seem backwards because the direction of up/download is relative to
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
98 the server, so when the client pulls, the server is *uploading*,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
99 and when the client pushes, the server is *downloading*.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
100 """
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
101
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
102
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
103 def _git_service_permission(request: hgreq.parsedrequest) -> bytes | None:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
104 """Figures out what Mercurial permission corresponds to a request from Git.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
105
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
106 If the request is a supported Git action, returns the permission it needs.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
107 If the request is not a Git action, returns None.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
108 """
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
109 if perm := _SERVICE_PERMISSIONS.get(request.dispatchpath):
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
110 return perm
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
111 if request.dispatchpath != b'info/refs':
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
112 return None
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
113 qs = request.querystring
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
114 service = qs.removeprefix(b'service=')
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
115 if qs == service:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
116 # Nothing was stripped.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
117 return None
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
118 return _SERVICE_PERMISSIONS.get(service)
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
119
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
120
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
121 def _handle_git_protocol(
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
122 original: t.Callable[..., bool],
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
123 req_ctx: web_inner.requestcontext,
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
124 request: hgreq.parsedrequest,
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
125 response: hgreq.wsgiresponse,
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
126 check_permission: PermissionCheck,
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
127 ) -> bool:
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
128 """Intercepts requests from Git, if needed."""
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
129 perm = _git_service_permission(request)
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
130 repo: hgrepo.IRepo = req_ctx.repo
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
131 if not perm or not _is_gitty(repo):
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
132 # We only handle Git requests to Gitty repos.
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
133 return original(req_ctx, request, response, check_permission)
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
134
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
135 # Permission workaround: Mercurial requires POSTs for push,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
136 # but the advertisement request from Git will be a GET.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
137 # We just lie to Mercurial about what we're doing.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
138 check_permission(
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
139 req_ctx,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
140 (
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
141 attr.evolve(req_ctx.req, method=b'POST')
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
142 if perm == _PUSH
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
143 else req_ctx.req
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
144 ),
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
145 perm,
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
146 )
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
147 cgi_env = _build_git_environ(req_ctx, request)
5
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
148 content_length_hdr = request.headers.get(b'content-length', b'0')
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
149 try:
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
150 content_length = int(content_length_hdr)
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
151 except ValueError as ve:
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
152 raise hgerr.InputError(
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
153 f'Invalid content-length {content_length_hdr!r}'.encode()
5
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
154 ) from ve
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
155 http_backend = repo.ui.configlist(
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
156 b'hggit-serve', b'http-backend', default=(b'git', b'http-backend')
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
157 )
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
158 call = subprocess.Popen(
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
159 http_backend,
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
160 close_fds=True,
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
161 stdin=subprocess.PIPE,
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
162 stdout=subprocess.PIPE,
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
163 stderr=subprocess.DEVNULL,
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
164 env=cgi_env,
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
165 text=False,
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
166 )
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
167 assert call.stdout
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
168 assert call.stdin
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
169 # Git will not start writing output until stdin is fully closed.
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
170 with call.stdin:
5
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
171 if content_length:
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
172 shutil.copyfileobj(
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
173 request.bodyfh, call.stdin, length=content_length
c43ce246240b Really fix content-length for real for serious.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
174 )
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
175
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
176 status, headers, rest = _parse_cgi_response(call.stdout)
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
177 response.status = status
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
178 for k, v in headers.items():
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
179 response.headers[k] = v
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
180
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
181 def write_the_rest() -> t.Iterator[bytes]:
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
182 with call, rest:
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
183 while more := rest.read(1024 * 1024):
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
184 yield more
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
185 if perm == _PUSH:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
186 _importing_enter(repo)
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
187 try:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
188 gh = repo.githandler
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
189 gh.import_git_objects(
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
190 b'git-push', remote_names=(), refs=gh.git.refs.as_dict()
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
191 )
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
192 finally:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
193 _importing_exit(repo)
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
194
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
195 response.setbodygen(write_the_rest())
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
196 response.sendresponse()
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
197 return True
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
198
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
199
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
200 #
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
201 # Stuff so that we don't try to export revisions while we're importing.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
202 #
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
203
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
204 _ILEVEL_ATTR = '@hggit_import_level'
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
205 """An attribute that tracks how many "levels deep" we are into importing.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
206
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
207 We set this on the repository object when we're importing and remove it
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
208 when we're done. It's not just a bool in case somebody sets up some crazy
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
209 recursive hook situation where we start importing inside another import.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
210 """
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
211
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
212
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
213 def _importing_enter(repo: hgrepo.IRepo) -> None:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
214 """Call this before you start importing from Git."""
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
215 level = getattr(repo, _ILEVEL_ATTR, 0) + 1
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
216 setattr(repo, _ILEVEL_ATTR, level)
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
217
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
218
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
219 def _is_importing(repo: hgrepo.IRepo) -> None:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
220 """Call this to check if you're currently importing."""
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
221 return hasattr(repo, _ILEVEL_ATTR)
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
222
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
223
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
224 def _importing_exit(repo: hgrepo.IRepo) -> None:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
225 """Call this after you finish importing from Git."""
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
226 level = getattr(repo, _ILEVEL_ATTR) - 1
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
227 if level:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
228 setattr(repo, _ILEVEL_ATTR, level)
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
229 else:
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
230 delattr(repo, _ILEVEL_ATTR)
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
231
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
232
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
233 #
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
234 # Export handling.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
235 #
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
236
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
237
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
238 def _clean_all_refs(refs: dulwich.refs.RefsContainer) -> None:
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
239 """Removes all refs from the Git repository."""
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
240
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
241
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
242 def _set_head(ui: hgui.ui, repo: GittyRepo, at_name: bytes) -> None:
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
243 """Creates a HEAD reference in Git referring to the current HEAD."""
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
244 # By default, we use '@', since that's what will be auto checked out.
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
245 current = b'@'
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
246 if current not in repo._bookmarks:
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
247 current = repo._bookmarks.active or current
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
248
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
249 # We'll be moving this (possibly fake) bookmark into Git.
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
250 git_current = current
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
251 if current == b'@':
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
252 # @ is a special keyword in Git, so we can't use it as a bookmark.
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
253 git_current = at_name
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
254 git_branch = dulwich.refs.LOCAL_BRANCH_PREFIX + git_current
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
255 if not dulwich.refs.check_ref_format(git_branch):
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
256 # We can't export this ref to Git. Give up.
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
257 ui.warn(f'{git_branch!r} is not a valid branch name for Git.'.encode())
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
258 return
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
259 try:
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
260 # Maybe this is a real bookmark?
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
261 hgnode = repo._bookmarks[current]
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
262 except KeyError:
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
263 # Not a real bookmark. Assume we want the tip of the current branch.
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
264 branch = repo.dirstate.branch()
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
265 try:
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
266 hgnode = repo.branchtip(branch)
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
267 except hgerr.RepoLookupError:
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
268 # This branch somehow doesn't exist???
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
269 ui.warn(f"{branch!r} doesn't seem to exist?".encode())
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
270 return
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
271 hgsha = binascii.hexlify(hgnode)
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
272 gitsha = repo.githandler.map_git_get(hgsha)
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
273 if not gitsha:
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
274 # No Git SHA to match this Hg sha. Give up.
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
275 ui.warn(f'revision {hgsha!r} was not exported to Git'.encode())
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
276 return
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
277 refs = repo.githandler.git.refs
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
278 refs.add_packed_refs({git_branch: gitsha})
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
279 refs.set_symbolic_ref(b'HEAD', git_branch)
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
280
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
281
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
282 def fix_refs_hook(ui: hgui.ui, repo: hgrepo.IRepo, **__: object) -> None:
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
283 """Exports to Git and sets up for serving. See ``_fix_refs``."""
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
284 if not _is_gitty(repo):
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
285 return
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
286 _fix_refs(ui, repo)
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
287
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
288
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
289 def _fix_refs(ui: hgui.ui, repo: GittyRepo) -> None:
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
290 """After a git export, fix up the refs.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
291
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
292 This ensures that there are no leftover refs from older, removed bookmarks
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
293 and that there is a proper HEAD set so that cloning works.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
294 """
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
295 refs = repo.githandler.git.refs
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
296 # dump to allkeys so we explicitly are iterating over a snapshot
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
297 # and not over something while we mutate
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
298 for ref in refs.allkeys():
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
299 refs.remove_if_equals(ref, None)
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
300 repo.githandler.export_hg_tags()
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
301 repo.githandler.update_references()
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
302 default_branch_name = ui.config(
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
303 b'hggit-serve', b'default-branch', b'default'
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
304 )
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
305 _set_head(ui, repo, default_branch_name)
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
306
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
307
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
308 def export_hook(ui: hgui.ui, repo: hgrepo.IRepo, **__: object) -> None:
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
309 """Maybe exports the repository to get after we get new revs."""
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
310 if not _is_gitty(repo):
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
311 return
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
312 auto_export = ui.config(b'hggit-serve', b'auto-export')
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
313 if auto_export == b'never':
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
314 return
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
315 if auto_export == b'always' or git_handler.has_gitrepo(repo):
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
316 if _is_importing(repo):
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
317 ui.note(b'currently importing revs from git; not exporting\n')
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
318 return
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
319 repo.githandler.export_commits()
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
320 _fix_refs(ui, repo)
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
321
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
322
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
323 #
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
324 # Interfacing with Mercurial
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
325 #
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
326
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
327 __version__ = '0.2.0'
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
328 testedwith = b'7.1 7.2'
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
329 minimumhgversion = b'7.1'
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
330
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
331 cmdtable: dict[bytes, object] = {}
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
332
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
333 command = registrar.command(cmdtable)
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
334
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
335
0
c1dc9d21fa57 First cut at serving hg repos with git.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
336 def uisetup(_: hgui.ui) -> None:
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
337 extensions.wrapfunction(
4
5ad58438318a Fix issue where sometimes reads would be cut off.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
338 wireprotoserver, 'handlewsgirequest', _handle_git_protocol
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
339 )
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
340
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
341
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
342 def uipopulate(ui: hgui.ui) -> None:
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
343 # Fix up our tags after a Git export.
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
344 ui.setconfig(
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
345 b'hooks', b'post-git-export.__gitserve_add_tag__', fix_refs_hook
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
346 )
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
347 # Whenever we get new revisions, export them to the Git repository.
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
348 ui.setconfig(b'hooks', b'txnclose.__gitserve_export__', export_hook)
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
349 # Don't step on ourselves when importing data from Git.
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
350 ui.setconfig(
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
351 b'hooks',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
352 b'pre-git-import.__gitserve_suppress_export__',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
353 lambda _, repo, **__: _importing_enter(repo),
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
354 )
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
355 ui.setconfig(
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
356 b'hooks',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
357 b'post-git-import.__gitserve_suppress_export__',
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
358 lambda _, repo, **__: _importing_exit(repo),
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
359 )
1
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
360
a39dd69b8972 Create a more-or-less real package and make it work (?)
Paul Fisher <paul@pfish.zone>
parents: 0
diff changeset
361
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
362 __all__ = (
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
363 '__version__',
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
364 'cmdtable',
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
365 'command',
8
fe3c9fae4d4d Add support for pushes, and improve authentication.
Paul Fisher <paul@pfish.zone>
parents: 7
diff changeset
366 'minimumhgversion',
6
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
367 'testedwith',
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
368 'uipopulate',
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
369 'uisetup',
7113e0ac3662 fix refs on git-export; clean up how gitserve export works.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
370 )