ExternalProject: avoid triggering Git "clean" filter with UPDATE_COMMAND

Summary: I want to make the ExternalProject “update” step a simple Git command, so that my user-wide Git filter “clean” is not triggered. The default ExternalProject “update” step triggers Git filter “clean”, which in my case errors the update step.

Does this method seem appropriate? I don’t need the usual ExternalProject generalizations for out-of-build SOURCE_DIR.


I have a user-wide ~/.gitconfig that strips Jupyter notebooks using a Git filter like:

[filter "strip-notebook-output"]
clean = "jupyter nbconvert --ClearOutputPreprocessor.enabled=True --ClearMetadataPreprocessor.enabled=True --to=notebook --stdin --stdout --log-level=ERROR"
smudge = "cat"
required

Even if I remove the “required” line, ExternalProject check fails because the filter still edits the .ipynb files at the ExternalProject “update” step. This is of course for a remote project that contains .ipynb files (even though I’m not using them in the CMake project). The Git error is like

error: Your local changes to the following files would be overwritten by merge:
...
Please commit your changes or stash them before you merge.
Aborting
The stash entry is kept in case you need it again.

A workaround I found is:

ExternalProject_Add(myproj
...
UPDATE_COMMAND git -C <SOURCE_DIR> checkout --detach "myTag"
)

In my project I will always be using a remote Git repo under CMAKE_BINARY_DIR with default ExternalProject setings.

I don’t think I need the safeguards that seem aimed at cases where <SOURCE_DIR> is a directory outside of PROJECT_BINARY_DIR.

Does this approach seem reasonable?


Another thing I tried that did NOT work was adding an ExternalProject step:

  ExternalProject_Add_Step(myproj gitOverride
    DEPENDERS update
    COMMAND git -C <SOURCE_DIR> config --local filter.strip-notebook-output.clean cat
    COMMENT "CMake ExternalProject: override git config to strip notebook output"
    LOG true
    INDEPENDENT true
)

that Step technique would seem like it should work, except it seems ExternalProject subsequently overwrites the file build/myproj-prefix/src/myproj/.git/config.

I don’t think there’s a general way to “turn off” filters without -c commands to clone (as this will also perform a checkout). git-lfs has an environment variable to no-op itself. Maybe your filter could be a script that does so around the “real” command?

Solution: I made a pre-commit hook instead of a filter, since I only use it on commit. This avoids any changes to CMake script.

That sounds much better anyways as now everyone gets the “cleaned” output. Thanks for reporting back.