Run git-clang-format on series of git commits

Viewed 14755

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?

3 Answers

I do this manually right now so the format does not mess up anything. Example: header reorganization is a possibility which can cause compile failures.

Steps start from latest commit. If you start at HEAD~# then the changes almost never unless they are atomic and unrelated. git clang-format only changes the code you changed(and related code blocks) but not other non-touched code.

  1. git clang-format HEAD~1 :result will be files changed. Compile and verify.
  2. git commit these new files as a temp commit.
  3. git rebase -i HEAD~2
  4. Change the new commit to be a "fixup" and finish the rebase.

(you can do this manually on a command line but for some reason I still do this with the editing).

You then repeat the steps for HEAD~2, HEAD~3 until you have finished working your way up to the chain.

Some Notes on this. clang-format will change the same code over and over again in certain cases. It has gotten much rarer but have to ignore them at times.

If you want to apply clang-format only to the changed lines in each commit do the following:

# The first commit you want to edit.
# You can use the following command if it’s a child of origin/master.
export FIRST_COMMIT=$(git rev-list --ancestry-path origin/master..HEAD | tail -n 1)

git filter-branch --tree-filter 'git-clang-format $FIRST_COMMIT^' -- $FIRST_COMMIT..HEAD

This will do the following for each commit:

  1. checkout the commit as it was in the original history
  2. compute the diff to FIRST_COMMIT’s parent (e.g. origin/master). (NOTE: If you only were only to compute the diff to the current commits parent you may undo clang-format changes done on other commits!)
  3. clang-format the affected lines
  4. create a copy of the commit on top of the previous one
Related