Run git-clang-format on series of git commits

Chris Jefferson picture Chris Jefferson · May 15, 2017 · Viewed 8.9k times · Source

I have written a series of git commits, with awful code formatting.
Before I push them to github, I want to run git-clang-format on each commit, to get a nicely formatted code in my history.

Is there some combination of rebase and git-clang-format which will accomplish this?

Answer

VonC picture VonC · Jul 15, 2017

That looks like a job for git filter-branch, which can rewrite the commits you want. Since those commits are not yet pushed, changing their content (and, consequently their SHA1) is not a big deal.
And the effect is similar to what a rebase or cherry-picking would do, except you can run any command for each commit being replayed.

You can run a filter-branch over the last few commits:

See "Reformatting Your Codebase with git filter-branch", by Elliot Chance

git filter-branch --tree-filter 'git-clang-format' -- <SHA1>..HEAD

Considering the git-clang-format syntax, you can apply it only on the changed files in each commits.
For instance, for .cpp files:

git filter-branch --tree-filter 'git-clang-format $(\
  git diff-index --diff-filter=AM --name-only $GIT_COMMIT |\
    grep .cpp)' -- <SHA1>..HEAD

Update 2017, with Git 2.14.x/2.15 (Q4 2017) you have an illustration:

See commit 2118805, commit 6134de6 (14 Aug 2017) by Brandon Williams (mbrandonw).
(Merged by Junio C Hamano -- gitster -- in commit a36f631, 25 Sep 2017)

Makefile: add style build rule

Add the 'style' build rule which will run git-clang-format on the diff between HEAD and the current worktree.
The result is a diff of suggested changes.

.PHONY: style
style:
    git clang-format --style file --diff --extensions c,h