如何在不引起冲突的情况下自动格式化 master 和 feature 分支?

How do I auto-format master and feature branches without causing conflicts?

假设我有这个 git 历史:

* 894a016 (HEAD -> feature) Add radius() method
* 6a62db6 (master) Add circle.h

feature 中的 circle.h 看起来像:

#include <iostream>
using namespace std;

class Circle {
  double radius;

public:
  Circle(double r)
            : radius(
                r) {
  }
  double area() {
    return radius
          * radius
          * 3.14159265;
  }

  double radius() {
      return    radius;
  }
};

我想格式化我的整个 repo、master 和 feature 分支,而不引起太多冲突。

我可以对任何分支进行新的提交,但理想情况下不需要 rebase 特性分支(如果这是唯一可行的方法——我正在为团队做这件事,所以我只是努力让事情尽可能轻松)。

如何在不产生意外冲突的情况下格式化主干分支和功能分支?

格式化两个分支不起作用,例如:

* 2e654d8 (HEAD -> feature) Run clang-format
* 894a016 Add radius() method
| * 25fab84 (master) Run clang-format
|/
* 6a62db6 Add circle.h

尝试合并时导致冲突。例如,git checkout feature && git merge master 给出了这个冲突:

#include <iostream>
using namespace std;

class Circle {
  double radius;

public:
  Circle(double r) : radius(r) {}
  double area() { return radius * radius * 3.14159265; }
<<<<<<< HEAD

  double radius() { return radius; }
=======
>>>>>>> master
};

我想我找到了一个可以接受的答案。这适用于这个玩具示例,我会做更多测试,看看它是否适用于更大的规模。

鉴于此(稍微更复杂)历史:

* c9ede4f (master) Add area to print()
| * c859a1d (feature) Add radius to print()
|/
* 58ead7c Add print()
* 427a8ba Add circle.h

(这个特定的历史在格式化所有分支时实际上给出了很好的冲突,但我相信这个解决方案在一般情况下有效)

  1. 自动格式化master(为便于格式化前后标记提交)

    $ git checkout master
    $ git tag before_auto_format
    $ clang-format -i *
    $ git commit -am "Run clang-format"
    $ git tag after_auto_format
    
  2. 将预格式化master合并到feature中,像正常一样解决冲突

    $ git checkout feature
    $ git merge before_auto_format
    $ vi circle.h
    $ git add .
    $ git commit
    
  3. after_auto_format 合并到 feature。放弃更改并手动进行格式化。

    $ git merge after_auto_format --no-commit
    $ git checkout HEAD .
    $ clang-format -i *
    $ git add .
    $ git commit
    

最终的历史是这样的:

*   09f2448 (feature) Merge tag 'after_auto_format' into feature
|\
| * e5e964b (tag: after_auto_format, master) Run clang-format
* | 1ef1b9b Merge tag 'before_auto_format' into feature
|\|
| * c9ede4f (tag: before_auto_format) Add area to print()
* | c859a1d Add radius to print()
|/
* 58ead7c Add print()
* 427a8ba Add circle.h

我相信这达到了将功能分支与主干同步、自动格式化两者并且不会引起意外冲突的预期效果。

如果有人有更好的选择,我会洗耳恭听。