Skip to content

Commit 8762fee

Browse files
committed
Merge branch 'gh/337'
2 parents 0afd336 + bd707b5 commit 8762fee

File tree

3 files changed

+94
-2
lines changed

3 files changed

+94
-2
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,15 @@ if [ "$3" == "1" ]; then cat; else dos2unix -q; fi
138138
-- End of crlf-filter.sh --
139139
```
140140

141+
Mercurial Largefiles Extension
142+
------------------------------
143+
144+
Mercurial largefiles are exported as ordinary files into git, i.e. not
145+
as git lfs files. In order to make the export work, make sure that
146+
you have all largefiles of all mercurial commits available locally.
147+
This can be ensured by either cloning the mercurial repository with
148+
the option --all-largefiles or by executing the command
149+
'hg lfpull --rev "all()"' inside the mercurial repository.
141150

142151
Plugins
143152
-----------------

hg-fast-export.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22

33
# Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
4+
# Copyright (c) 2025 Siemens
45
# License: MIT <http://www.opensource.org/licenses/mit-license.php>
56

67
from hg2git import setup_repo,fixup_user,get_branch,get_changeset
@@ -11,6 +12,7 @@
1112
import os
1213
from binascii import hexlify
1314
import pluginloader
15+
from hgext.largefiles import lfutil
1416

1517
# silly regex to catch Signed-off-by lines in log message
1618
sob_re=re.compile(b'^Signed-[Oo]ff-[Bb]y: (.+)$')
@@ -162,6 +164,32 @@ def refresh_gitmodules(ctx):
162164
wr(b'M 100644 inline .gitmodules')
163165
wr_data(gitmodules)
164166

167+
def is_largefile(filename):
168+
return filename[:6] == b'.hglf/'
169+
170+
def largefile_orig_name(filename):
171+
return filename[6:]
172+
173+
def largefile_data(ctx, file, filename):
174+
lf_file_ctx=ctx.filectx(file)
175+
lf_hash=lf_file_ctx.data().strip(b'\n')
176+
sys.stderr.write("Detected large file hash %s\n" % lf_hash.decode())
177+
#should detect where the large files are located
178+
file_with_data = lfutil.findfile(ctx.repo(), lf_hash)
179+
if file_with_data is None:
180+
# Autodownloading from the mercurial repository would be an issue as there
181+
# is a good chance that we may need to input some username and password.
182+
# This will surely break fast-export as there will be some unexpected
183+
# output.
184+
sys.stderr.write("Large file wasn't found in local cache.\n")
185+
sys.stderr.write("Please clone with --all-largefiles\n")
186+
sys.stderr.write("or pull all large files with 'hg lfpull --rev "
187+
"\"all()\"'\n")
188+
# closing in the middle of import will revert everything to the last checkpoint
189+
sys.exit(3)
190+
with open(os.path.normpath(file_with_data), 'rb') as file_with_data_handle:
191+
return file_with_data_handle.read()
192+
165193
def export_file_contents(ctx,manifest,files,hgtags,encoding='',plugins={}):
166194
count=0
167195
max=len(files)
@@ -183,8 +211,12 @@ def export_file_contents(ctx,manifest,files,hgtags,encoding='',plugins={}):
183211
b'Ignoring file %s which cannot be tracked by git\n' % filename
184212
)
185213
continue
186-
file_ctx=ctx.filectx(file)
187-
d=file_ctx.data()
214+
if is_largefile(filename):
215+
filename = largefile_orig_name(filename)
216+
d = largefile_data(ctx, file, filename)
217+
else:
218+
file_ctx=ctx.filectx(file)
219+
d=file_ctx.data()
188220

189221
if plugins and plugins['file_data_filters']:
190222
file_data = {'filename':filename,'file_ctx':file_ctx,'data':d}
@@ -327,6 +359,8 @@ def get_branchname(name):
327359
filename=strip_leading_slash(filename)
328360
if filename==b'.hgsub':
329361
remove_gitmodules(ctx)
362+
if is_largefile(filename):
363+
filename=largefile_orig_name(filename)
330364
wr(b'D %s' % filename)
331365

332366
export_file_contents(ctx,man,modified,hgtags,fn_encoding,plugins)

t/main.t

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,53 @@ test_expect_success 'merge' '
9292
test_cmp expected actual
9393
'
9494

95+
test_expect_success 'hg large file' '
96+
test_when_finished "rm -rf hgrepo gitrepo" &&
97+
98+
(
99+
hg init hgrepo &&
100+
cd hgrepo &&
101+
echo "[extensions]" >> .hg/hgrc
102+
echo "largefiles =" >> .hg/hgrc
103+
echo a > content &&
104+
echo a > file1 &&
105+
hg add content &&
106+
hg add --large file1 &&
107+
hg commit -m "origin" &&
108+
109+
echo b > content &&
110+
echo b > file2 &&
111+
hg add --large file2 &&
112+
hg rm file1 &&
113+
hg commit -m "right" &&
114+
115+
hg update -r0 &&
116+
echo c > content &&
117+
hg commit -m "left" &&
118+
119+
HGMERGE=true hg merge -r1 &&
120+
hg commit -m "merge"
121+
) &&
122+
123+
git_clone hgrepo gitrepo &&
124+
125+
cat > expected <<-EOF &&
126+
left
127+
c
128+
tree @:
129+
130+
content
131+
file2
132+
EOF
133+
134+
(
135+
cd gitrepo
136+
git show -q --format='%s' @^ &&
137+
git show @:content &&
138+
git show @:
139+
) > actual &&
140+
141+
test_cmp expected actual
142+
'
143+
95144
test_done

0 commit comments

Comments
 (0)