2

I have a project with a rich git history from multiple users, it is never been auto-formatted and I'd like to run clang-format on it. It is important to preserve git history.

Some examples of what I mean.

When there was a block of code from Joe and then 'a+b' was converted to a + b. It stays the Joe's line in git blame.

When there was

void foo()
{
    return k;
}

and it was formatted to

void foo() { return k; }

It still stays the Joe's code.

etc.

Any known solutions?

Yuki
  • 3,857
  • 5
  • 25
  • 43

2 Answers2

1

Basically, you cannot have it both ways (that is, preserve the history and auto-format wholesale), but you have some options.

1) You could in principle re-create the repository by replaying all the commits one-by-one with auto-formatting applied, but this new repository will be a different one: all the commits SHAs will be different. Some conflicts are possible, especially in case of non-linear history (merges). This may not be a trivial and completely automatic operation.

2) You can also just apply the formatting as a new commit (single, huge one), but this will make using git blame harder.

3) You can also apply auto-formatting on the go as the files are modified during development. This will have somewhat smaller impact, but is not perfect either.

Krzysiek Karbowiak
  • 1,655
  • 1
  • 9
  • 17
1

There are two aspects of "preserving history", both of which can be accomplished with git:

  1. Make changes on top of existing history: this will emburden a git blame with a one single commit of formatting changes. This is easy and no different from your normal workflow. I recommend one single commit and then enforcing formatting as a pre-merge and pre-commit hook on the server and client sides.

  2. Rewrite all history, individually formatting each commit. This makes any references to the pre-rewrite hashes of commits etc. invalid, but gives you a clean git blame/log. This needs some magic using (maybe low-level) git commands to make this happen. Or a "simple" "interactive" rebase where you amend each commit with the formatting changes (although keeping the original committer might rake some extra magic).

A last option is fixing code up as it is committed. This leads to a horrible disarray of styles within a single file and doesn't help anything.

rubenvb
  • 74,642
  • 33
  • 187
  • 332