What is wrong with this git smudge/clean filter?
I want to apply this filter in my git repository to remov开发者_Go百科e a section from a solution file during checkout and to add this section during commit.
This is the section i want to remove or add:
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection
I have setup this filter in my .git/info/attributes
*.sln filter=SourceControlProvider
and i have added these commands to my config
$ git config filter.SourceControlProvider.smudge "sed -e '/GlobalSection(SubversionScc)/,/EndGlobalSection/d' %"
$ git config filter.SourceControlProvider.clean "sed -n -e '/^Global$/ r ankhsvnsection ' < %"
Well, it does not work. What have i done wrong?
ankhsvnsection is a text file that lies in the same directory as the *.sln file
I see a few issues here:
You have
%
at the end of both filters.
This has no special meaning and will be passed as an extra argument to sed, which will probably generate an error (unless you have a file named%
).
Filters should be “streaming” (read from stdin and write to stdout). Their definition can include%f
, but it should not really be treated as a file to read or write; Git does that part, filters should just read from stdin and write to stdout.Your clean filter tries to redirect stdin from
%f
.
The input data will already be on stdin, there is no need to redirect.The sed program in the clean filter uses the
r
command to access another file.
Filters seem to be run from root of the working tree, but I am not sure if that is guaranteed.The sed command in the clean filter uses
-n
. Its only output will be the contents of theankhsvnsection
file (assuming the input has aGlobal
line).Some versions of sed (at least the (old) BSD version in Mac OS X) do not allow whitespace after the filename of the
r
command (i.e. the space afterankhsvnsection
in the clean filter’s sed program).
After adding, changing, or removing a filter you will probably need to touch, modify, or delete your working tree files before Git will apply the filter. Git’s index records the modification time of working tree files; if they have not changed, then Git will translate git checkout -- file
and git add file
into a no-op.
If you want to see the actual contents of the index (e.g. to check what the clean filter produced), you can use git show :0:path/from/repo/root/to/file
. You can not usually use git diff
for this since it also applies the filters.
These worked for me:
git config filter.SourceControlProvider.smudge "sed -e '/GlobalSection(SubversionScc)/,/EndGlobalSection/d'"
git config filter.SourceControlProvider.clean "sed -e '/^Global\$/ r ankhsvnsection'"
精彩评论