diff --git a/hg-fast-export.py b/hg-fast-export.py index 0dc18ad..59ca228 100755 --- a/hg-fast-export.py +++ b/hg-fast-export.py @@ -194,13 +194,14 @@ def export_file_contents(ctx,manifest,files,hgtags,encoding='',plugins={}): filename=file_data['filename'] file_ctx=file_data['file_ctx'] - wr(b'M %s inline %s' % (gitmode(manifest.flags(file)), - strip_leading_slash(filename))) - wr(b'data %d' % len(d)) # had some trouble with size() - wr(d) - count+=1 - if count%cfg_export_boundary==0: - sys.stderr.buffer.write(b'Exported %d/%d files\n' % (count,max)) + if d is not None: + wr(b'M %s inline %s' % (gitmode(manifest.flags(file)), + strip_leading_slash(filename))) + wr(b'data %d' % len(d)) # had some trouble with size() + wr(d) + count+=1 + if count%cfg_export_boundary==0: + sys.stderr.buffer.write(b'Exported %d/%d files\n' % (count,max)) if max>cfg_export_boundary: sys.stderr.buffer.write(b'Exported %d/%d files\n' % (count,max)) diff --git a/t/file_data_filter-removefiles.expected b/t/file_data_filter-removefiles.expected new file mode 100644 index 0000000..b0681bf --- /dev/null +++ b/t/file_data_filter-removefiles.expected @@ -0,0 +1,27 @@ +blob +mark :1 +data 7 +good_a + +reset refs/heads/master +commit refs/heads/master +mark :2 +author Grevious Bodily Harmsworth 1679014800 +0000 +committer Grevious Bodily Harmsworth 1679014800 +0000 +data 2 +r0M 100644 :1 good_a.txt + +commit refs/heads/master +mark :3 +author Grevious Bodily Harmsworth 1679018400 +0000 +committer Grevious Bodily Harmsworth 1679018400 +0000 +data 2 +r1from :2 + +commit refs/heads/master +mark :4 +author Grevious Bodily Harmsworth 1679022000 +0000 +committer Grevious Bodily Harmsworth 1679022000 +0000 +data 2 +r2from :3 + diff --git a/t/file_data_filter-removefiles.t b/t/file_data_filter-removefiles.t new file mode 100755 index 0000000..2adafae --- /dev/null +++ b/t/file_data_filter-removefiles.t @@ -0,0 +1,90 @@ +#!/bin/bash +# +# Copyright (c) 2023 Felipe Contreras +# Copyright (c) 2023 Frej Drejhammar +# Copyright (c) 2024 Stephan Hohe +# +# Check that files that file_data_filter sets to None are removed from repository +# + +test_description='Remove files from file_data_filter plugin test' + +. "${SHARNESS_TEST_SRCDIR-$(dirname "$0")/sharness}"/sharness.sh || exit 1 + +check() { + echo "$3" > expected && + git -C "$1" show -q --format='%s' "$2" > actual && + test_cmp expected actual +} + +git_create() { + git init -q "$1" +} + +git_convert() { + ( + cd "$2" && + hg-fast-export.sh --repo "../$1" \ + -s --hgtags -n \ + --plugin ../../plugins/removefiles_test_plugin + ) +} + +setup() { + cat > "$HOME"/.hgrc <<-EOF + [ui] + username = Grevious Bodily Harmsworth + EOF +} + +commit0() { + ( + # Test inital revision with suppressed file + cd hgrepo && + echo "good_a" > good_a.txt && + echo "bad_a" > bad_a.txt && + hg add good_a.txt bad_a.txt && + hg commit -d "2023-03-17 01:00Z" -m "r0" + ) +} + +commit1() { + ( + # Test modifying suppressed file + # Test adding suppressed file + cd hgrepo && + echo "bad_a_modif" > bad_a.txt && + echo "bad_b" > bad_b.txt && + hg add bad_b.txt && + hg commit -d "2023-03-17 02:00Z" -m "r1" + ) +} + +commit2() { + ( + # Test removing suppressed file + cd hgrepo && + hg rm bad_a.txt && + hg commit -d "2023-03-17 03:00Z" -m "r2" + ) +} + +setup + +test_expect_success 'all in one' ' + test_when_finished "rm -rf hgrepo gitrepo" && + + ( + hg init hgrepo && + commit0 && + commit1 && + commit2 + ) && + git_create gitrepo && + git_convert hgrepo gitrepo && + git -C gitrepo fast-export --all > actual && + + test_cmp "$SHARNESS_TEST_DIRECTORY"/file_data_filter-removefiles.expected actual +' + +test_done diff --git a/t/plugins/removefiles_test_plugin/__init__.py b/t/plugins/removefiles_test_plugin/__init__.py new file mode 100644 index 0000000..4f56359 --- /dev/null +++ b/t/plugins/removefiles_test_plugin/__init__.py @@ -0,0 +1,15 @@ +import subprocess +import shlex +import sys +from mercurial import node + +def build_filter(args): + return Filter(args) + +class Filter: + def __init__(self, args): + self.filter_contents = shlex.split(args) + + def file_data_filter(self,file_data): + if file_data['filename'].startswith(b'bad'): + file_data['data'] = None