- Summarizing history: squashing "implemented subfeature A.A" and "implemented subfeature A.B" into "implemented feature A"
- Rewriting history: moving commits around, changing the base commit, and so on
In my opinion summarizing history is acceptable, you're making a creative decision that certain information will not be useful in the review/when trying to understand the code in the future.
Rewriting, on the other hand, is essentially lying. You're creating repository states that never existed, and which you have never tested. In the worst case, consider the following history:
* F: (master) Merge branch 'component2'
|\
| * E: (component2) Fixed component 2's integration with 1
| * D: (component2) Merge branch 'master' into component2
| |\
| |/
|/|
* | C: (master) Refactored component 1's API
| * B: (component2) Implemented component 2 that depends on 1
|/
* A: (master) Base
Yes, it could probably be completely linearized, but that would be a horrible idea. Commit B will leave the repository in a completely nonsensical state. Sure, you could squash in E to mitigate it (since, luckily, nothing else happened in component 2 in the meantime), but then you're still stuck explaining what will likely look like a bunch of really weird design decisions compared to if you had designed against component 1's new API immediately.Historical context matters. If in doubt, don't rebase. Never `git pull --rebase` blindly.