git-remote-hg 1.0.3__tar.gz → 1.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {git-remote-hg-1.0.3/git_remote_hg.egg-info → git_remote_hg-1.0.5}/PKG-INFO +11 -5
- {git-remote-hg-1.0.3 → git_remote_hg-1.0.5}/git-hg-helper +77 -8
- {git-remote-hg-1.0.3 → git_remote_hg-1.0.5}/git-remote-hg +165 -95
- {git-remote-hg-1.0.3 → git_remote_hg-1.0.5/git_remote_hg.egg-info}/PKG-INFO +11 -5
- {git-remote-hg-1.0.3 → git_remote_hg-1.0.5}/git_remote_hg.egg-info/SOURCES.txt +3 -1
- git_remote_hg-1.0.5/git_remote_hg.egg-info/top_level.txt +1 -0
- git_remote_hg-1.0.5/p3/bin/activate_this.py +34 -0
- git_remote_hg-1.0.5/setup.cfg +9 -0
- {git-remote-hg-1.0.3 → git_remote_hg-1.0.5}/setup.py +1 -1
- git-remote-hg-1.0.3/git_remote_hg.egg-info/top_level.txt +0 -1
- git-remote-hg-1.0.3/setup.cfg +0 -4
- {git-remote-hg-1.0.3 → git_remote_hg-1.0.5}/LICENSE +0 -0
- {git-remote-hg-1.0.3 → git_remote_hg-1.0.5}/git_remote_hg.egg-info/dependency_links.txt +0 -0
@@ -1,13 +1,12 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: git-remote-hg
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.5
|
4
4
|
Summary: access hg repositories as git remotes
|
5
5
|
Home-page: http://github.com/mnauw/git-remote-hg
|
6
6
|
Author: Mark Nauwelaerts
|
7
7
|
Author-email: mnauw@users.sourceforge.net
|
8
8
|
License: GPLv2
|
9
9
|
Keywords: git hg mercurial
|
10
|
-
Platform: UNKNOWN
|
11
10
|
Classifier: Programming Language :: Python
|
12
11
|
Classifier: Programming Language :: Python :: 2
|
13
12
|
Classifier: Programming Language :: Python :: 2.7
|
@@ -18,6 +17,15 @@ Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
|
|
18
17
|
Classifier: Development Status :: 5 - Production/Stable
|
19
18
|
Classifier: Intended Audience :: Developers
|
20
19
|
License-File: LICENSE
|
20
|
+
Dynamic: author
|
21
|
+
Dynamic: author-email
|
22
|
+
Dynamic: classifier
|
23
|
+
Dynamic: description
|
24
|
+
Dynamic: home-page
|
25
|
+
Dynamic: keywords
|
26
|
+
Dynamic: license
|
27
|
+
Dynamic: license-file
|
28
|
+
Dynamic: summary
|
21
29
|
|
22
30
|
|
23
31
|
'git-remote-hg' is a gitremote protocol helper for Mercurial.
|
@@ -25,5 +33,3 @@ It allows you to clone, fetch and push to and from Mercurial repositories as if
|
|
25
33
|
they were Git ones using a hg::some-url URL.
|
26
34
|
|
27
35
|
See the homepage for much more explanation.
|
28
|
-
|
29
|
-
|
@@ -5,6 +5,11 @@
|
|
5
5
|
|
6
6
|
from mercurial import hg, ui, commands, util
|
7
7
|
from mercurial import context, subrepo
|
8
|
+
try:
|
9
|
+
# hg >= 5.8
|
10
|
+
from mercurial.utils import urlutil
|
11
|
+
except ImportError:
|
12
|
+
from mercurial import util as urlutil
|
8
13
|
|
9
14
|
import re
|
10
15
|
import sys
|
@@ -51,7 +56,13 @@ if sys.version_info[0] == 3:
|
|
51
56
|
stdout = sys.stdout.buffer
|
52
57
|
stderr = sys.stderr.buffer
|
53
58
|
getcwd = os.getcwdb
|
54
|
-
|
59
|
+
@staticmethod
|
60
|
+
def getenvb(val, default):
|
61
|
+
result = os.getenv(val.decode(), default.decode() if hasattr(default, 'decode') else default)
|
62
|
+
# if result is a string, get bytes instead
|
63
|
+
result = result.encode() if hasattr(result, 'encode') else result
|
64
|
+
return result
|
65
|
+
getenv = os.getenvb if os.supports_bytes_environ else getenvb
|
55
66
|
else:
|
56
67
|
class compat(basecompat):
|
57
68
|
# life was simple in those days ...
|
@@ -86,11 +97,27 @@ def debug(msg, *args):
|
|
86
97
|
def log(msg, *args):
|
87
98
|
logger.log(logging.LOG, msg, *args)
|
88
99
|
|
100
|
+
# new style way to import a source file
|
101
|
+
def _imp_load_source(module_name, file_path):
|
102
|
+
import importlib.util
|
103
|
+
loader = importlib.machinery.SourceFileLoader(module_name, file_path)
|
104
|
+
spec = importlib.util.spec_from_loader(module_name, loader)
|
105
|
+
module = importlib.util.module_from_spec(spec)
|
106
|
+
sys.modules[module_name] = module
|
107
|
+
spec.loader.exec_module(module)
|
108
|
+
return module
|
109
|
+
|
89
110
|
def import_sibling(mod, filename):
|
90
|
-
import imp
|
91
111
|
mydir = os.path.dirname(__file__)
|
92
112
|
sys.dont_write_bytecode = True
|
93
|
-
|
113
|
+
vi = sys.version_info
|
114
|
+
ff = os.path.join(mydir, filename)
|
115
|
+
if vi.major >= 3 and vi.minor >= 5:
|
116
|
+
return _imp_load_source(mod, ff)
|
117
|
+
else:
|
118
|
+
import imp
|
119
|
+
return imp.load_source(mod, ff)
|
120
|
+
|
94
121
|
|
95
122
|
class GitHgRepo:
|
96
123
|
|
@@ -135,7 +162,7 @@ class GitHgRepo:
|
|
135
162
|
process = self.start_cmd(args, **kwargs)
|
136
163
|
output = process.communicate()[0]
|
137
164
|
if check and process.returncode != 0:
|
138
|
-
die(b'command failed: %s' % b' '.join([compat.to_b(a) for a in
|
165
|
+
die(b'git command failed: %s' % b' '.join([compat.to_b(a) for a in args]))
|
139
166
|
return output
|
140
167
|
|
141
168
|
def get_config(self, config, getall=False):
|
@@ -216,9 +243,12 @@ class GitHgRepo:
|
|
216
243
|
warn(b'failed to find local hg for remote %s' % (r))
|
217
244
|
continue
|
218
245
|
else:
|
246
|
+
npath = os.path.abspath(hg_path)
|
247
|
+
# use relative path if possible
|
248
|
+
if check_version(4, 2):
|
249
|
+
npath = os.path.join(b'..', b'..', b'..', b'.hg')
|
219
250
|
# make sure the shared path is always up-to-date
|
220
|
-
util.writefile(os.path.join(local_hg, b'sharedpath'),
|
221
|
-
os.path.abspath(hg_path))
|
251
|
+
util.writefile(os.path.join(local_hg, b'sharedpath'), npath)
|
222
252
|
self.hg_repos[r] = os.path.join(local_path)
|
223
253
|
|
224
254
|
log('%s determined hg_repos %s', self.identity(), self.hg_repos)
|
@@ -308,11 +338,11 @@ class GitHgRepo:
|
|
308
338
|
if not kind in (b'hg', b'git'):
|
309
339
|
warn('skipping unsupported subrepo type %s' % kind)
|
310
340
|
continue
|
311
|
-
if not
|
341
|
+
if not urlutil.url(src).isabs():
|
312
342
|
parent = self.get_hg_repo_url(remote)
|
313
343
|
if not parent:
|
314
344
|
die(b'could not determine repo url of %s' % remote)
|
315
|
-
parent =
|
345
|
+
parent = urlutil.url(parent)
|
316
346
|
parent.path = posixpath.join(parent.path or b'', src)
|
317
347
|
parent.path = posixpath.normpath(parent.path)
|
318
348
|
src = bytes(parent)
|
@@ -544,6 +574,43 @@ class GcCommand(SubCommand):
|
|
544
574
|
gm.store()
|
545
575
|
|
546
576
|
|
577
|
+
class MapFileCommand(SubCommand):
|
578
|
+
|
579
|
+
def argumentparser(self):
|
580
|
+
usage = '%%(prog)s %s [options] <remote>' % (self.subcommand)
|
581
|
+
p = argparse.ArgumentParser(usage=usage)
|
582
|
+
p.add_argument('--output', required=True,
|
583
|
+
help='mapfile to write')
|
584
|
+
p.epilog = textwrap.dedent("""\
|
585
|
+
Writes a so-called git-mapfile, as used internally by hg-git.
|
586
|
+
This files consists of lines of format `<githexsha> <hghexsha>`.
|
587
|
+
|
588
|
+
As such, the result could be used to coax hg-git in some manner.
|
589
|
+
However, as git-remote-hg and hg-git may (likely) produce different
|
590
|
+
commits (either git or hg), mixed use of both tools is not recommended.
|
591
|
+
""")
|
592
|
+
return p
|
593
|
+
|
594
|
+
def do(self, options, args):
|
595
|
+
remotehg = import_sibling('remotehg', 'git-remote-hg')
|
596
|
+
|
597
|
+
if not args or len(args) != 1:
|
598
|
+
self.usage('expect 1 remote')
|
599
|
+
|
600
|
+
remote = args[0]
|
601
|
+
hgpath = remotehg.select_marks_dir(remote, self.githgrepo.gitdir, False)
|
602
|
+
puts(b"Loading hg marks ...")
|
603
|
+
hgm = remotehg.Marks(os.path.join(hgpath, b'marks-hg'), None)
|
604
|
+
puts(b"Loading git marks ...")
|
605
|
+
gm = GitMarks(os.path.join(hgpath, b'marks-git'))
|
606
|
+
puts(b"Writing mapfile ...")
|
607
|
+
with open(options.output, 'wb') as f:
|
608
|
+
for c, m in gm.marks.items():
|
609
|
+
hgc = hgm.rev_marks.get(m, None)
|
610
|
+
if hgc:
|
611
|
+
f.write(b'%s %s\n' % (c, hgc))
|
612
|
+
|
613
|
+
|
547
614
|
class SubRepoCommand(SubCommand):
|
548
615
|
|
549
616
|
def writestate(repo, state):
|
@@ -910,6 +977,7 @@ def get_subcommands():
|
|
910
977
|
b'repo': RepoCommand,
|
911
978
|
b'gc': GcCommand,
|
912
979
|
b'sub': SubRepoCommand,
|
980
|
+
b'mapfile': MapFileCommand,
|
913
981
|
b'help' : HelpCommand
|
914
982
|
}
|
915
983
|
# add remote named subcommands
|
@@ -932,6 +1000,7 @@ def do_usage():
|
|
932
1000
|
gc \t perform maintenance and consistency cleanup on repo tracking marks
|
933
1001
|
sub \t manage subrepos
|
934
1002
|
repo \t show local hg repo backing a remote
|
1003
|
+
mapfile \t dump a hg-git git-mapfile
|
935
1004
|
|
936
1005
|
If the subcommand is the name of a remote hg repo, then any remaining arguments
|
937
1006
|
are considered a "hg command", e.g. hg heads, or thg, and it is then executed
|
@@ -86,7 +86,13 @@ if sys.version_info[0] == 3:
|
|
86
86
|
stdout = sys.stdout.buffer
|
87
87
|
stderr = sys.stderr.buffer
|
88
88
|
getcwd = os.getcwdb
|
89
|
-
|
89
|
+
@staticmethod
|
90
|
+
def getenvb(val, default):
|
91
|
+
result = os.getenv(val.decode(), default.decode() if hasattr(default, 'decode') else default)
|
92
|
+
# if result is a string, get bytes instead
|
93
|
+
result = result.encode() if hasattr(result, 'encode') else result
|
94
|
+
return result
|
95
|
+
getenv = os.getenvb if os.supports_bytes_environ else getenvb
|
90
96
|
urlparse = urllib.parse.urlparse
|
91
97
|
urljoin = urllib.parse.urljoin
|
92
98
|
else:
|
@@ -116,6 +122,27 @@ else:
|
|
116
122
|
urlparse = staticmethod(_urlparse)
|
117
123
|
urljoin = staticmethod(_urljoin)
|
118
124
|
|
125
|
+
# new style way to import a source file
|
126
|
+
def _imp_load_source(module_name, file_path):
|
127
|
+
import importlib.util
|
128
|
+
loader = importlib.machinery.SourceFileLoader(module_name, file_path)
|
129
|
+
spec = importlib.util.spec_from_loader(module_name, loader)
|
130
|
+
module = importlib.util.module_from_spec(spec)
|
131
|
+
sys.modules[module_name] = module
|
132
|
+
spec.loader.exec_module(module)
|
133
|
+
return module
|
134
|
+
|
135
|
+
def import_sibling(mod, filename):
|
136
|
+
mydir = os.path.dirname(__file__)
|
137
|
+
sys.dont_write_bytecode = True
|
138
|
+
vi = sys.version_info
|
139
|
+
ff = os.path.join(mydir, filename)
|
140
|
+
if vi.major >= 3 and vi.minor >= 5:
|
141
|
+
return _imp_load_source(mod, ff)
|
142
|
+
else:
|
143
|
+
import imp
|
144
|
+
return imp.load_source(mod, ff)
|
145
|
+
|
119
146
|
#
|
120
147
|
# If you want to see Mercurial revisions as Git commit notes:
|
121
148
|
# git config core.notesRef refs/notes/hg
|
@@ -141,11 +168,11 @@ else:
|
|
141
168
|
# Commits are modified to preserve hg information and allow bidirectionality.
|
142
169
|
#
|
143
170
|
|
144
|
-
NAME_RE = re.compile(
|
145
|
-
AUTHOR_RE = re.compile(
|
171
|
+
NAME_RE = re.compile(br'^([^<>]+)')
|
172
|
+
AUTHOR_RE = re.compile(br'^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
|
146
173
|
EMAIL_RE = re.compile(br'([^ \t<>]+@[^ \t<>]+)')
|
147
|
-
AUTHOR_HG_RE = re.compile(
|
148
|
-
RAW_AUTHOR_RE = re.compile(
|
174
|
+
AUTHOR_HG_RE = re.compile(br'^(.*?) ?<(.*?)(?:>(.*))?$')
|
175
|
+
RAW_AUTHOR_RE = re.compile(br'^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
|
149
176
|
|
150
177
|
VERSION = 2
|
151
178
|
|
@@ -153,6 +180,9 @@ def die(msg):
|
|
153
180
|
compat.stderr.write(b'ERROR: %s\n' % compat.to_b(msg, 'utf-8'))
|
154
181
|
sys.exit(1)
|
155
182
|
|
183
|
+
def debug(*args):
|
184
|
+
compat.stderr.write(b'DEBUG: %s\n' % compat.to_b(repr(args)))
|
185
|
+
|
156
186
|
def warn(msg):
|
157
187
|
compat.stderr.write(b'WARNING: %s\n' % compat.to_b(msg, 'utf-8'))
|
158
188
|
compat.stderr.flush()
|
@@ -231,27 +261,17 @@ def get_rev_hg(commit):
|
|
231
261
|
|
232
262
|
class Marks:
|
233
263
|
|
234
|
-
def __init__(self, path,
|
264
|
+
def __init__(self, path, _repo=None):
|
235
265
|
self.path = path
|
236
|
-
self.repo = repo
|
237
266
|
self.clear()
|
238
267
|
self.load()
|
239
268
|
|
240
|
-
if self.version < VERSION:
|
241
|
-
if self.version == 1:
|
242
|
-
self.upgrade_one()
|
243
|
-
|
244
|
-
# upgraded?
|
245
|
-
if self.version < VERSION:
|
246
|
-
self.clear()
|
247
|
-
self.version = VERSION
|
248
|
-
|
249
269
|
def clear(self):
|
250
270
|
self.tips = {}
|
251
271
|
self.marks = {}
|
252
272
|
self.rev_marks = {}
|
253
273
|
self.last_mark = 0
|
254
|
-
self.version =
|
274
|
+
self.version = VERSION
|
255
275
|
self.last_note = 0
|
256
276
|
|
257
277
|
def load(self):
|
@@ -267,20 +287,12 @@ class Marks:
|
|
267
287
|
self.tips = []
|
268
288
|
self.marks = marks
|
269
289
|
self.last_mark = tmp['last-mark']
|
270
|
-
self.version = tmp
|
290
|
+
self.version = tmp['version']
|
271
291
|
self.last_note = 0
|
272
292
|
|
273
293
|
for rev, mark in compat.iteritems(self.marks):
|
274
294
|
self.rev_marks[mark] = rev
|
275
295
|
|
276
|
-
def upgrade_one(self):
|
277
|
-
def get_id(rev):
|
278
|
-
return hghex(self.repo.changelog.node(int(rev)))
|
279
|
-
self.tips = dict((name, get_id(rev)) for name, rev in compat.iteritems(self.tips))
|
280
|
-
self.marks = dict((get_id(rev), mark) for rev, mark in compat.iteritems(self.marks))
|
281
|
-
self.rev_marks = dict((mark, get_id(rev)) for mark, rev in compat.iteritems(self.rev_marks))
|
282
|
-
self.version = 2
|
283
|
-
|
284
296
|
def dict(self):
|
285
297
|
return { 'tips': self.tips, 'marks': self.marks,
|
286
298
|
'last-mark': self.last_mark, 'version': self.version,
|
@@ -383,7 +395,7 @@ class Parser:
|
|
383
395
|
return None
|
384
396
|
_, name, email, date, tz = m.groups()
|
385
397
|
if name and b'ext:' in name:
|
386
|
-
m = re.match(
|
398
|
+
m = re.match(br'^(.+?) ext:\((.+)\)$', name)
|
387
399
|
if m:
|
388
400
|
name = m.group(1)
|
389
401
|
ex = compat.urlunquote(m.group(2))
|
@@ -402,40 +414,38 @@ class Parser:
|
|
402
414
|
return (user, int(date), hgtz(tz))
|
403
415
|
|
404
416
|
def fix_file_path(path):
|
405
|
-
def posix_path(path):
|
406
|
-
if os.sep == '/':
|
407
|
-
return path
|
408
|
-
# even Git for Windows expects forward
|
409
|
-
return path.replace(compat.to_b(os.sep), b'/')
|
410
|
-
# also converts forward slash to backwards slash on Win
|
411
417
|
path = os.path.normpath(path)
|
412
|
-
if
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
puts(b"mark :%u" % mark)
|
430
|
-
puts(b"data %d" % len(d))
|
431
|
-
puts(d)
|
418
|
+
if os.path.isabs(path):
|
419
|
+
path = os.path.relpath(path, b'/')
|
420
|
+
if os.sep == '/':
|
421
|
+
return path
|
422
|
+
# even Git for Windows expects forward
|
423
|
+
return path.replace(compat.to_b(os.sep), b'/')
|
424
|
+
|
425
|
+
def export_file(ctx, fname):
|
426
|
+
f = ctx.filectx(fname)
|
427
|
+
fid = node.hex(f.filenode())
|
428
|
+
|
429
|
+
if fid in filenodes:
|
430
|
+
mark = filenodes[fid]
|
431
|
+
else:
|
432
|
+
mark = marks.next_mark()
|
433
|
+
filenodes[fid] = mark
|
434
|
+
d = f.data()
|
432
435
|
|
433
|
-
|
434
|
-
|
436
|
+
puts(b"blob")
|
437
|
+
puts(b"mark :%u" % mark)
|
438
|
+
puts(b"data %d" % len(d))
|
439
|
+
puts(f.data())
|
435
440
|
|
436
|
-
|
441
|
+
path = fixup_path_to_git(fix_file_path(f.path()))
|
442
|
+
return (gitmode(f.flags()), mark, path)
|
437
443
|
|
438
444
|
def get_filechanges(repo, ctx, parent):
|
445
|
+
if hasattr(parent, 'status'):
|
446
|
+
stat = parent.status(ctx)
|
447
|
+
return stat.modified + stat.added, stat.removed
|
448
|
+
|
439
449
|
modified = set()
|
440
450
|
added = set()
|
441
451
|
removed = set()
|
@@ -477,7 +487,7 @@ def fixup_user_git(user):
|
|
477
487
|
def fixup_user_hg(user):
|
478
488
|
def sanitize(name):
|
479
489
|
# stole this from hg-git
|
480
|
-
return re.sub(
|
490
|
+
return re.sub(br'[<>\n]', b'?', name.lstrip(b'< ').rstrip(b'> '))
|
481
491
|
|
482
492
|
m = AUTHOR_HG_RE.match(user)
|
483
493
|
if m:
|
@@ -508,6 +518,51 @@ def fixup_user(user):
|
|
508
518
|
|
509
519
|
return b'%s <%s>' % (name, mail)
|
510
520
|
|
521
|
+
# (recent) git fast-import does not accept .git or .gitmodule component names
|
522
|
+
# (anywhere, case-insensitive)
|
523
|
+
# in any case, surprising things may happen, so add some front-end replacement magic;
|
524
|
+
# transform of (hg) .git(0 or more suffix) to (git) .git(1 or more suffix)
|
525
|
+
# (likewise so for any invalid git keyword)
|
526
|
+
def fixup_dotfile_path(path, suffix, add):
|
527
|
+
def subst(part):
|
528
|
+
if (not part) or part[0] != ord(b'.'):
|
529
|
+
return part
|
530
|
+
for prefix in (b'.git', b'.gitmodules'):
|
531
|
+
pl = len(prefix)
|
532
|
+
tail = len(part) - pl
|
533
|
+
if tail < 0:
|
534
|
+
continue
|
535
|
+
if part[0:pl].lower() == prefix and part[pl:] == suffix * tail:
|
536
|
+
if add:
|
537
|
+
return part + suffix
|
538
|
+
elif tail == 0:
|
539
|
+
# .git should not occur in git space
|
540
|
+
# so complain
|
541
|
+
if pl == 3:
|
542
|
+
die('invalid path component %s' % part)
|
543
|
+
else:
|
544
|
+
# but .gitmodules might
|
545
|
+
# leave as-is, it is handled/ignored elsewhere
|
546
|
+
return part
|
547
|
+
else:
|
548
|
+
return part[0:-1]
|
549
|
+
return part
|
550
|
+
# quick optimization check;
|
551
|
+
if (not path) or (path[0] != ord(b'.') and path.find(b'/.') < 0):
|
552
|
+
return path
|
553
|
+
sep = b'/'
|
554
|
+
return sep.join((subst(part) for part in path.split(sep)))
|
555
|
+
|
556
|
+
def fixup_path_to_git(path):
|
557
|
+
if not dotfile_suffix:
|
558
|
+
return path
|
559
|
+
return fixup_dotfile_path(path, dotfile_suffix, True)
|
560
|
+
|
561
|
+
def fixup_path_from_git(path):
|
562
|
+
if not dotfile_suffix:
|
563
|
+
return path
|
564
|
+
return fixup_dotfile_path(path, dotfile_suffix, False)
|
565
|
+
|
511
566
|
def updatebookmarks(repo, peer):
|
512
567
|
remotemarks = peer.listkeys(b'bookmarks')
|
513
568
|
|
@@ -579,18 +634,6 @@ def get_repo(url, alias):
|
|
579
634
|
else:
|
580
635
|
shared_path = os.path.join(gitdir, b'hg')
|
581
636
|
|
582
|
-
# check and upgrade old organization
|
583
|
-
hg_path = os.path.join(shared_path, b'.hg')
|
584
|
-
if os.path.exists(shared_path) and not os.path.exists(hg_path):
|
585
|
-
repos = os.listdir(shared_path)
|
586
|
-
for x in repos:
|
587
|
-
local_hg = os.path.join(shared_path, x, b'clone', b'.hg')
|
588
|
-
if not os.path.exists(local_hg):
|
589
|
-
continue
|
590
|
-
if not os.path.exists(hg_path):
|
591
|
-
shutil.move(local_hg, hg_path)
|
592
|
-
shutil.rmtree(os.path.join(shared_path, x, b'clone'))
|
593
|
-
|
594
637
|
# setup shared repo (if not there)
|
595
638
|
try:
|
596
639
|
hg.peer(myui, {}, shared_path, create=True)
|
@@ -601,8 +644,13 @@ def get_repo(url, alias):
|
|
601
644
|
os.makedirs(dirname)
|
602
645
|
|
603
646
|
local_path = os.path.join(dirname, b'clone')
|
647
|
+
kwargs = {}
|
648
|
+
hg_path = os.path.join(shared_path, b'.hg')
|
649
|
+
if check_version(4, 2):
|
650
|
+
kwargs = {'relative': True}
|
651
|
+
hg_path = os.path.join(b'..', b'..', b'..', b'.hg')
|
604
652
|
if not os.path.exists(local_path):
|
605
|
-
hg.share(myui, shared_path, local_path, update=False)
|
653
|
+
hg.share(myui, shared_path, local_path, update=False, **kwargs)
|
606
654
|
else:
|
607
655
|
# make sure the shared path is always up-to-date
|
608
656
|
util.writefile(os.path.join(local_path, b'.hg', b'sharedpath'), hg_path)
|
@@ -711,11 +759,16 @@ def export_ref(repo, name, kind, head):
|
|
711
759
|
if rename:
|
712
760
|
renames.append((rename[0], f))
|
713
761
|
|
762
|
+
# NOTE no longer used in hg-git, a HG:rename extra header is used
|
714
763
|
for e in renames:
|
715
764
|
extra_msg += b"rename : %s => %s\n" % e
|
716
765
|
|
717
766
|
for key, value in compat.iteritems(extra):
|
718
|
-
if key in (b'author', b'committer', b'encoding', b'message', b'branch', b'hg-git'):
|
767
|
+
if key in (b'author', b'committer', b'encoding', b'message', b'branch', b'hg-git', b'transplant_source'):
|
768
|
+
continue
|
769
|
+
elif key == b'hg-git-rename-source' and value == b'git':
|
770
|
+
# extra data that hg-git might put there unconditionally
|
771
|
+
# or that we put in there to be compatible
|
719
772
|
continue
|
720
773
|
else:
|
721
774
|
extra_msg += b"extra : %s : %s\n" % (key, compat.urlquote(value))
|
@@ -726,7 +779,7 @@ def export_ref(repo, name, kind, head):
|
|
726
779
|
if len(parents) == 0:
|
727
780
|
puts(b'reset %s/%s' % (prefix, ename))
|
728
781
|
|
729
|
-
modified_final =
|
782
|
+
modified_final = [export_file(c, fname) for fname in modified]
|
730
783
|
|
731
784
|
puts(b"commit %s/%s" % (prefix, ename))
|
732
785
|
puts(b"mark :%d" % (marks.get_mark(c.hex())))
|
@@ -741,7 +794,7 @@ def export_ref(repo, name, kind, head):
|
|
741
794
|
puts(b"merge :%u" % (rev_to_mark(parents[1])))
|
742
795
|
|
743
796
|
for f in removed:
|
744
|
-
puts(b"D %s" % (fix_file_path(f)))
|
797
|
+
puts(b"D %s" % fixup_path_to_git(fix_file_path(f)))
|
745
798
|
for f in modified_final:
|
746
799
|
puts(b"M %s :%u %s" % f)
|
747
800
|
puts()
|
@@ -839,8 +892,11 @@ def do_list(parser, branchmap):
|
|
839
892
|
|
840
893
|
for branch, heads in compat.iteritems(branchmap):
|
841
894
|
# only open heads
|
842
|
-
|
843
|
-
|
895
|
+
try:
|
896
|
+
heads = [h for h in heads if b'close' not in repo.changelog.read(h)[5]]
|
897
|
+
if heads:
|
898
|
+
branches[branch] = heads
|
899
|
+
except error.LookupError:
|
844
900
|
branches[branch] = heads
|
845
901
|
|
846
902
|
list_head(repo, cur)
|
@@ -1031,6 +1087,7 @@ def parse_commit(parser):
|
|
1031
1087
|
else:
|
1032
1088
|
die(b'Unknown file command: %s' % line)
|
1033
1089
|
path = c_style_unescape(path)
|
1090
|
+
path = fixup_path_from_git(path)
|
1034
1091
|
files[path] = files.get(path, {})
|
1035
1092
|
files[path].update(f)
|
1036
1093
|
|
@@ -1135,10 +1192,20 @@ def parse_commit(parser):
|
|
1135
1192
|
extra[b'branch'] = hgref(branch)
|
1136
1193
|
|
1137
1194
|
if mode == 'hg':
|
1195
|
+
# add some extra that hg-git adds (almost) unconditionally
|
1196
|
+
# see also https://foss.heptapod.net/mercurial/hg-git/-/merge_requests/211
|
1197
|
+
# NOTE it could be changed to another value below
|
1198
|
+
# actually, it is *almost* unconditionally, and only done if the commit
|
1199
|
+
# is deduced to originate in git. However, the latter is based on
|
1200
|
+
# presence/absence of HG markers in commit "extra headers".
|
1201
|
+
# The latter can not be handled here, and so this can not be correctly
|
1202
|
+
# reproduced.
|
1203
|
+
# extra[b'hg-git-rename-source'] = b'git'
|
1138
1204
|
i = data.find(b'\n--HG--\n')
|
1139
1205
|
if i >= 0:
|
1140
1206
|
tmp = data[i + len(b'\n--HG--\n'):].strip()
|
1141
1207
|
for k, v in [e.split(b' : ', 1) for e in tmp.split(b'\n')]:
|
1208
|
+
# NOTE no longer used in hg-git, a HG:rename extra header is used
|
1142
1209
|
if k == b'rename':
|
1143
1210
|
old, new = v.split(b' => ', 1)
|
1144
1211
|
files[new]['rename'] = old
|
@@ -1326,7 +1393,10 @@ def checkheads(repo, remote, p_revs, force):
|
|
1326
1393
|
def push_unsafe(repo, remote, p_revs, force):
|
1327
1394
|
|
1328
1395
|
fci = discovery.findcommonincoming
|
1329
|
-
|
1396
|
+
if check_version(4, 5):
|
1397
|
+
commoninc = fci(repo, remote, force=force, ancestorsof=list(p_revs))
|
1398
|
+
else:
|
1399
|
+
commoninc = fci(repo, remote, force=force)
|
1330
1400
|
common, _, remoteheads = commoninc
|
1331
1401
|
fco = discovery.findcommonoutgoing
|
1332
1402
|
outgoing = fco(repo, remote, onlyheads=list(p_revs), commoninc=commoninc, force=force)
|
@@ -1357,12 +1427,6 @@ def push_unsafe(repo, remote, p_revs, force):
|
|
1357
1427
|
else:
|
1358
1428
|
ret = remote.addchangegroup(cg, b'push', repo.url())
|
1359
1429
|
|
1360
|
-
phases = remote.listkeys(b'phases')
|
1361
|
-
if phases:
|
1362
|
-
for head in p_revs:
|
1363
|
-
# update to public
|
1364
|
-
remote.pushkey(b'phases', hghex(head), b'1', b'0')
|
1365
|
-
|
1366
1430
|
return ret
|
1367
1431
|
|
1368
1432
|
def push(repo, remote, p_revs, force):
|
@@ -1397,6 +1461,7 @@ def do_push_hg(parser):
|
|
1397
1461
|
global parsed_refs, parsed_tags
|
1398
1462
|
p_bmarks = []
|
1399
1463
|
p_revs = {}
|
1464
|
+
ok_refs = []
|
1400
1465
|
|
1401
1466
|
parsed_refs = {}
|
1402
1467
|
parsed_tags = {}
|
@@ -1443,7 +1508,7 @@ def do_push_hg(parser):
|
|
1443
1508
|
continue
|
1444
1509
|
|
1445
1510
|
p_revs[bnode] = ref
|
1446
|
-
|
1511
|
+
ok_refs.append(ref)
|
1447
1512
|
elif ref.startswith(b'refs/heads/'):
|
1448
1513
|
bmark = ref[len(b'refs/heads/'):]
|
1449
1514
|
new = node
|
@@ -1453,14 +1518,14 @@ def do_push_hg(parser):
|
|
1453
1518
|
puts(b"ok %s up to date" % ref)
|
1454
1519
|
continue
|
1455
1520
|
|
1456
|
-
|
1521
|
+
ok_refs.append(ref)
|
1457
1522
|
if not bookmark_is_fake(bmark, parser.repo._bookmarks):
|
1458
1523
|
p_bmarks.append((ref, bmark, old, new))
|
1459
1524
|
|
1460
1525
|
p_revs[bnode] = ref
|
1461
1526
|
elif ref.startswith(b'refs/tags/'):
|
1462
1527
|
if dry_run:
|
1463
|
-
|
1528
|
+
ok_refs.append(ref)
|
1464
1529
|
continue
|
1465
1530
|
tag = ref[len(b'refs/tags/'):]
|
1466
1531
|
tag = hgref(tag)
|
@@ -1487,14 +1552,15 @@ def do_push_hg(parser):
|
|
1487
1552
|
fp.write(b'%s %s\n' % (node, tag))
|
1488
1553
|
fp.close()
|
1489
1554
|
p_revs[bnode] = ref
|
1490
|
-
|
1555
|
+
ok_refs.append(ref)
|
1491
1556
|
else:
|
1492
1557
|
# transport-helper/fast-export bugs
|
1493
1558
|
continue
|
1494
1559
|
|
1495
1560
|
if dry_run:
|
1496
|
-
if peer:
|
1497
|
-
|
1561
|
+
if not peer or checkheads(parser.repo, peer, p_revs, force_push):
|
1562
|
+
for ref in ok_refs:
|
1563
|
+
puts(b"ok %s" % ref)
|
1498
1564
|
return
|
1499
1565
|
|
1500
1566
|
success = True
|
@@ -1515,12 +1581,18 @@ def do_push_hg(parser):
|
|
1515
1581
|
if not peer.pushkey(b'bookmarks', bmark, old, new):
|
1516
1582
|
success = False
|
1517
1583
|
puts(b"error %s" % ref)
|
1584
|
+
ok_refs.remove(ref)
|
1518
1585
|
else:
|
1519
1586
|
# update local bookmarks
|
1520
1587
|
for ref, bmark, old, new in p_bmarks:
|
1521
1588
|
if not bookmarks.pushbookmark(parser.repo, bmark, old, new):
|
1522
1589
|
success = False
|
1523
1590
|
puts(b"error %s" % ref)
|
1591
|
+
ok_refs.remove(ref)
|
1592
|
+
|
1593
|
+
# update rest of the refs
|
1594
|
+
for ref in ok_refs:
|
1595
|
+
puts(b"ok %s" % ref)
|
1524
1596
|
|
1525
1597
|
return success
|
1526
1598
|
|
@@ -1604,10 +1676,7 @@ def do_push_refspec(parser, refspec, revs):
|
|
1604
1676
|
tmpfastexport = open(os.path.join(marksdir, b'git-fast-export-%d' % (os.getpid())), 'w+b')
|
1605
1677
|
subprocess.check_call(cmd, stdin=None, stdout=tmpfastexport)
|
1606
1678
|
try:
|
1607
|
-
|
1608
|
-
sys.dont_write_bytecode = True
|
1609
|
-
ctx.hghelper = imp.load_source('hghelper', \
|
1610
|
-
os.path.join(os.path.dirname(__file__), 'git-hg-helper'))
|
1679
|
+
ctx.hghelper = import_sibling('hghelper', 'git-hg-helper')
|
1611
1680
|
ctx.hghelper.init_git(gitdir)
|
1612
1681
|
ctx.gitmarks = ctx.hghelper.GitMarks(tmpmarks)
|
1613
1682
|
# let processing know it should not bother pushing if not requested
|
@@ -1729,8 +1798,7 @@ def fix_path(alias, repo, orig_url):
|
|
1729
1798
|
url = compat.urlparse(orig_url, b'file')
|
1730
1799
|
if url.scheme != b'file' or os.path.isabs(os.path.expanduser(url.path)):
|
1731
1800
|
return
|
1732
|
-
|
1733
|
-
cmd = ['git', 'config', b'remote.%s.url' % alias, b"hg::%s" % abs_url]
|
1801
|
+
cmd = ['git', 'config', b'remote.%s.url' % alias, b"hg::%s" % os.path.abspath(orig_url)]
|
1734
1802
|
subprocess.call(cmd)
|
1735
1803
|
|
1736
1804
|
def select_private_refs(alias):
|
@@ -1845,6 +1913,7 @@ def main(args):
|
|
1845
1913
|
global capability_push
|
1846
1914
|
global remove_username_quotes
|
1847
1915
|
global marksdir
|
1916
|
+
global dotfile_suffix
|
1848
1917
|
|
1849
1918
|
marks = None
|
1850
1919
|
is_tmp = False
|
@@ -1864,6 +1933,7 @@ def main(args):
|
|
1864
1933
|
track_branches = get_config_bool('remote-hg.track-branches', True)
|
1865
1934
|
capability_push = get_config_bool('remote-hg.capability-push', True)
|
1866
1935
|
remove_username_quotes = get_config_bool('remote-hg.remove-username-quotes', True)
|
1936
|
+
dotfile_suffix = get_config('remote-hg.dotfile-suffix').strip() or b'_'
|
1867
1937
|
force_push = False
|
1868
1938
|
|
1869
1939
|
if hg_git_compat:
|
@@ -1908,7 +1978,7 @@ def main(args):
|
|
1908
1978
|
fix_path(alias, peer or repo, url)
|
1909
1979
|
|
1910
1980
|
marks_path = os.path.join(marksdir, b'marks-hg')
|
1911
|
-
marks = Marks(marks_path
|
1981
|
+
marks = Marks(marks_path)
|
1912
1982
|
|
1913
1983
|
if sys.platform == 'win32':
|
1914
1984
|
import msvcrt
|
@@ -1,13 +1,12 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: git-remote-hg
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.5
|
4
4
|
Summary: access hg repositories as git remotes
|
5
5
|
Home-page: http://github.com/mnauw/git-remote-hg
|
6
6
|
Author: Mark Nauwelaerts
|
7
7
|
Author-email: mnauw@users.sourceforge.net
|
8
8
|
License: GPLv2
|
9
9
|
Keywords: git hg mercurial
|
10
|
-
Platform: UNKNOWN
|
11
10
|
Classifier: Programming Language :: Python
|
12
11
|
Classifier: Programming Language :: Python :: 2
|
13
12
|
Classifier: Programming Language :: Python :: 2.7
|
@@ -18,6 +17,15 @@ Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
|
|
18
17
|
Classifier: Development Status :: 5 - Production/Stable
|
19
18
|
Classifier: Intended Audience :: Developers
|
20
19
|
License-File: LICENSE
|
20
|
+
Dynamic: author
|
21
|
+
Dynamic: author-email
|
22
|
+
Dynamic: classifier
|
23
|
+
Dynamic: description
|
24
|
+
Dynamic: home-page
|
25
|
+
Dynamic: keywords
|
26
|
+
Dynamic: license
|
27
|
+
Dynamic: license-file
|
28
|
+
Dynamic: summary
|
21
29
|
|
22
30
|
|
23
31
|
'git-remote-hg' is a gitremote protocol helper for Mercurial.
|
@@ -25,5 +33,3 @@ It allows you to clone, fetch and push to and from Mercurial repositories as if
|
|
25
33
|
they were Git ones using a hg::some-url URL.
|
26
34
|
|
27
35
|
See the homepage for much more explanation.
|
28
|
-
|
29
|
-
|
@@ -1,8 +1,10 @@
|
|
1
1
|
LICENSE
|
2
2
|
git-hg-helper
|
3
3
|
git-remote-hg
|
4
|
+
setup.cfg
|
4
5
|
setup.py
|
5
6
|
git_remote_hg.egg-info/PKG-INFO
|
6
7
|
git_remote_hg.egg-info/SOURCES.txt
|
7
8
|
git_remote_hg.egg-info/dependency_links.txt
|
8
|
-
git_remote_hg.egg-info/top_level.txt
|
9
|
+
git_remote_hg.egg-info/top_level.txt
|
10
|
+
p3/bin/activate_this.py
|
@@ -0,0 +1 @@
|
|
1
|
+
p3
|
@@ -0,0 +1,34 @@
|
|
1
|
+
"""By using execfile(this_file, dict(__file__=this_file)) you will
|
2
|
+
activate this virtualenv environment.
|
3
|
+
|
4
|
+
This can be used when you must use an existing Python interpreter, not
|
5
|
+
the virtualenv bin/python
|
6
|
+
"""
|
7
|
+
|
8
|
+
try:
|
9
|
+
__file__
|
10
|
+
except NameError:
|
11
|
+
raise AssertionError(
|
12
|
+
"You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
|
13
|
+
import sys
|
14
|
+
import os
|
15
|
+
|
16
|
+
old_os_path = os.environ.get('PATH', '')
|
17
|
+
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
|
18
|
+
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
19
|
+
if sys.platform == 'win32':
|
20
|
+
site_packages = os.path.join(base, 'Lib', 'site-packages')
|
21
|
+
else:
|
22
|
+
site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
|
23
|
+
prev_sys_path = list(sys.path)
|
24
|
+
import site
|
25
|
+
site.addsitedir(site_packages)
|
26
|
+
sys.real_prefix = sys.prefix
|
27
|
+
sys.prefix = base
|
28
|
+
# Move the added items to the front of the path:
|
29
|
+
new_sys_path = []
|
30
|
+
for item in list(sys.path):
|
31
|
+
if item not in prev_sys_path:
|
32
|
+
new_sys_path.append(item)
|
33
|
+
sys.path.remove(item)
|
34
|
+
sys.path[:0] = new_sys_path
|
@@ -1 +0,0 @@
|
|
1
|
-
|
git-remote-hg-1.0.3/setup.cfg
DELETED
File without changes
|
File without changes
|