Run file_data_filter on deleted files

The `file_data_filter` method should be called when files are deleted.
In this case the `data` and `file_ctx` keys map to None. This is so
that a filter which modifies file names can apply the same name
transformations before files are deleted.
This commit is contained in:
Frej Drejhammar
2024-02-16 17:12:49 +01:00
parent 21ab3f347b
commit ddfc3a8300
5 changed files with 140 additions and 3 deletions

View File

@@ -179,7 +179,7 @@ values in the dictionary after filters have been run are used to create the git
commit.
```
file_data = {'filename':filename,'file_ctx':file_ctx,'d':d}
file_data = {'filename':filename,'file_ctx':file_ctx,'data':file_contents}
def file_data_filter(self,file_data):
```
@@ -189,6 +189,11 @@ can be modified by any filter. `file_ctx` is the filecontext from the
mercurial python library. After all filters have been run, the values
are used to add the file to the git commit.
The `file_data_filter` method is also called when files are deleted,
but in this case the `data` and `file_ctx` keys map to None. This is
so that a filter which modifies file names can apply the same name
transformations when files are deleted.
Submodules
----------
See README-SUBMODULES.md for how to convert subrepositories into git

View File

@@ -311,9 +311,18 @@ def export_commit(ui,repo,revision,old_marks,max,count,authors,
% (branch, type.encode(), revision + 1, max, len(modified), len(removed))
)
for filename in removed:
for file in removed:
if fn_encoding:
filename=filename.decode(fn_encoding).encode('utf8')
filename=file.decode(fn_encoding).encode('utf8')
else:
filename=file
if plugins and plugins['file_data_filters']:
file_data = {'filename':filename, 'file_ctx':None, 'data':None}
for filter in plugins['file_data_filters']:
filter(file_data)
filename=file_data['filename']
filename=strip_leading_slash(filename)
if filename==b'.hgsub':
remove_gitmodules(ctx)

View File

@@ -0,0 +1,27 @@
blob
mark :1
data 7
a_file
blob
mark :2
data 17
a_file_to_rename
reset refs/heads/master
commit refs/heads/master
mark :3
author Grevious Bodily Harmsworth <gbh@example.com> 1679014800 +0000
committer Grevious Bodily Harmsworth <gbh@example.com> 1679014800 +0000
data 2
r0M 100644 :1 a.txt
M 100644 :2 c.txt
commit refs/heads/master
mark :4
author Grevious Bodily Harmsworth <gbh@example.com> 1679018400 +0000
committer Grevious Bodily Harmsworth <gbh@example.com> 1679018400 +0000
data 2
r1from :3
D c.txt

81
t/file_data_filter.t Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/bash
#
# Copyright (c) 2023 Felipe Contreras
# Copyright (c) 2023 Frej Drejhammar
#
# Check that the file_data_filter is called for removed files.
#
test_description='Smoke 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/rename_file_test_plugin
)
}
setup() {
cat > "$HOME"/.hgrc <<-EOF
[ui]
username = Grevious Bodily Harmsworth <gbh@example.com>
EOF
}
commit0() {
(
cd hgrepo &&
echo "a_file" > a.txt &&
echo "a_file_to_rename" > b.txt &&
hg add a.txt b.txt &&
hg commit -d "2023-03-17 01:00Z" -m "r0"
)
}
commit1() {
(
cd hgrepo &&
hg remove b.txt &&
hg commit -d "2023-03-17 02:00Z" -m "r1"
)
}
make-branch() {
hg branch "$1"
FILE=$(echo "$1" | sha1sum | cut -d " " -f 1)
echo "$1" > $FILE
hg add $FILE
hg commit -d "2023-03-17 $2:00Z" -m "Added file in branch $1"
}
setup
test_expect_success 'all in one' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
commit0 &&
commit1
) &&
git_create gitrepo &&
git_convert hgrepo gitrepo &&
git -C gitrepo fast-export --all > actual &&
test_cmp "$SHARNESS_TEST_DIRECTORY"/file_data_filter.expected actual
'
test_done

View File

@@ -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'] == b'b.txt':
file_data['filename'] = b'c.txt'