1
votes

I want to run clang-format on every check in on any edited .cpp and .h file in a git repository and make sure that the "main include file" is on top.

There is a filter option for this in .gitattributes:

*.cpp filter=clang-format-cpp
*.h filter=clang-format-cpp

for which the relevant filter can be locally configured with

git config --global filter.clang-format-cpp.clean 'clang-format -assume-filename=test.cpp'

For clang-format, there is an option IncludeIsMainRegex which will always put the "main include file" on top. E.g. with IncludeIsMainRegex: '(test_?)?$' for a file a.cpp or test_a.cpp, the header a.h will be the main include and hence put on top.

However, when the file is formatted through the git filter/clang-format, this main include is not put on top.

Given

.clang-format:

IncludeIsMainRegex: '(test_?)?$'
IncludeBlocks: Regroup

z.cpp:

#include "z.h"
#include "other.h"
#include <includes.h>
#include <here.h>

Expected

z.cpp:

#include "z.h"

#include "other.h"

#include <here.h>
#include <includes.h>

Result

z.cpp:

#include "other.h"
#include "z.h"

#include <here.h>
#include <includes.h>

The reason is very likely that the file is sent through clang-format with stdin/stdout and therefore clang-format does not know the filename (or rather assumes it's test.cpp) and hence cannot determine the main include.

One alternative approach would be to setup a pre-commit hook and let it correct the file in place upon commit. But having them corrected upon staging is much more streamlined than upon committing.

How can clang-format be integrated in a git workflow to automatically put the main include file on top?

For now I just disabled IncludeIsMainRegex: false and this works stable regardless if clang-format is called on the file or via git filter.

1

1 Answers

0
votes

it is because you don't put Priority, if you set like this :

IncludeBlocks: Regroup
IncludeCategories:
    - Regex: '^".*"'
      Priority: 1

it's work because #include "z.h" is by default 0 priority and if you don't put priority to your regex it take 0 too