Hi, I'm ThadeusB.

I code stuff. I raise bees. I game.

Embracing Complexity The Case for --no-ff Merge Commits Over Squash and Merge


In the ever-evolving world of software development, the way we manage code changes and collaboration is a subject of ongoing debate. One such discussion revolves around the use of --no-ff merge commits versus squash and merge. While the latter might seem appealing for its simplicity and tidiness, this post argues that --no-ff merge commits offer a more robust and insightful approach, aligning with the values of transparency, learning, and thoughtful development.

Advantages of --no-ff Merge Commits

Preservation of Intellectual Journey

--no-ff maintains the full history of commits, preserving the evolution and thought process behind a change. It’s a record of the development process, reflecting decisions, experiments, and refinements.

Separation of Concerns

By keeping refactoring separate from functional changes, --no-ff allows for more precise analysis and consideration of each part of a change.

Attribution Integrity

--no-ff retains all the metadata about individual commits, including authors, dates, and related issues or pull requests, crucial for acknowledging contributions.

Reduced Risk of Merge Conflicts

--no-ff helps in avoiding the re-introduction of resolved conflicts, particularly in complex workflows with multiple interdependent pull requests.

Flexibility and Reversibility

With --no-ff, you have the option to squash later if needed, offering flexibility in managing the commit history without losing valuable details.

Holistic View with Individual Insight

--no-ff offers a single commit showing the result of the change while also preserving the detailed history of how that change came into being.

Alignment with Engineering Values

The --no-ff approach aligns with principles of thoroughness and transparency, treating the development history as a valuable asset rather than mere noise.

History as a Learning Tool

The detailed history provided by --no-ff is a resource for learning and understanding, rather than something to be tidied away.

Transparency Over Aesthetics

Version control is not just about creating a neat timeline but offering transparency and traceability.

Reflecting the True Nature of Development

Embracing the iterative process of development through --no-ff acknowledges the complexity and richness of software engineering.

Flexible Revert Options

--no-ff provides a robust and flexible way to handle reverts with a single command by specifying the parent of the merge commit.

Balance Between Convenience and Insight

--no-ff provides the context that might be lost in the simplification of squash commits.

Downsides of Squash Merges

Lost History

Squash merges aggressively collapse a series of commits into a single one, destroying the history and thought process behind changes.

Lost Attribution

Important metadata about individual commits, such as authors and dates, are lost, affecting the acknowledgment of contributions.

Introduction of Merge Conflicts

Squash merges can invalidate dependent requests and re-introduce resolved conflicts, especially in workflows with multiple concurrent pull requests.

Difficulty in Collaboration

When multiple developers are working on the same feature branch, squash merges can make it difficult to see who did what, posing challenges to collaboration.


The choice between squash commits and --no-ff isn't just about cleanliness or convenience; it's about how your team values the development process and what you want your version control system to reflect. By opting for --no-ff, you're choosing a path that respects the complexity and collaboration of software development, preserving insights and decisions that might be obscured by a more streamlined approach. It's a choice that aligns with a commitment to transparency, learning, and thoughtful development, rather than simply aiming for the appearance of efficiency or tidiness.