Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong with this git smudge/clean filter?

I want to apply this filter in my git repository to remove 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

like image 852
mrt181 Avatar asked Mar 21 '11 16:03

mrt181


People also ask

What is Git smudge filter?

In git lfs terms, 'smudge' is the process of getting the actual data for the pointers that are stored locally. By installing git lfs with the --skip-smudge option, you are setting the filter smudge = git-lfs smudge --skip -- %f in the global . gitconfig file in your home directory.

What is smudge in Git LFS?

The Git smudge filter is what converts the LFS pointer stored in Git with the actual large file from the LFS server. If your local repository does not have the LFS object, the smudge filter will have to download it. This means that network issues could affect the smudge filter.

What is a .gitattributes file?

A gitattributes file is a simple text file that gives attributes to pathnames. Each line in gitattributes file is of form: pattern attr1 attr2 ... That is, a pattern followed by an attributes list, separated by whitespaces. Leading and trailing whitespaces are ignored.


1 Answers

I see a few issues here:

  1. 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.

  2. Your clean filter tries to redirect stdin from %f.
    The input data will already be on stdin, there is no need to redirect.

  3. 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.

  4. The sed command in the clean filter uses -n. Its only output will be the contents of the ankhsvnsection file (assuming the input has a Global line).

  5. 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 after ankhsvnsection 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'"
like image 170
Chris Johnsen Avatar answered Oct 02 '22 02:10

Chris Johnsen