Say I have this git history:
* 894a016 (HEAD -> feature) Add radius() method
* 6a62db6 (master) Add circle.h
Where circle.h
in feature
looks like:
#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;
}
};
I want to format my entire repo, master and feature branches, without causing too many conflicts.
I can make new commits to any branch, but ideally would not need to rebase
feature branches (if this is the only way that's fine—I'm doing this for a team so I'm just trying to keep things as painless as possible).
How do I format my trunk branch and my feature branches without creating unexpected conflicts?
Formatting both branches does not work, for example:
* 2e654d8 (HEAD -> feature) Run clang-format
* 894a016 Add radius() method
| * 25fab84 (master) Run clang-format
|/
* 6a62db6 Add circle.h
Results in conflicts when trying to merge. For example, git checkout feature && git merge master
gives this conflict:
#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
};
I think I found an acceptable answer. This works for this toy example, I'll do more tests and see if it works on a larger scale.
Given this (slightly more complex) history:
* c9ede4f (master) Add area to print()
| * c859a1d (feature) Add radius to print()
|/
* 58ead7c Add print()
* 427a8ba Add circle.h
(this particular history actually gives good conflicts when formatting all branches, but I believe this solution works in the general case)
Auto-format master
(tag the commits before and after formatting for ease)
$ git checkout master
$ git tag before_auto_format
$ clang-format -i *
$ git commit -am "Run clang-format"
$ git tag after_auto_format
Merge the pre-format master
into feature
and resolve conflicts like normal
$ git checkout feature
$ git merge before_auto_format
$ vi circle.h
$ git add .
$ git commit
Merge after_auto_format
into feature
. Discard the changes and do the formatting manually.
$ git merge after_auto_format --no-commit
$ git checkout HEAD .
$ clang-format -i *
$ git add .
$ git commit
The final history looks like:
* 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
I believe this achieves the desired effect of syncing the feature branch with the trunk, auto-formatting both, and not causing unexpected conflicts.
If anyone has better alternatives, I'm all ears.