Commits in a branch or a PR is said to be well-organized if they have the following qualities:
Each commit contains a single logical change, and this change must stand on its own. i.e. each commit has a single responsibility, and that responsibility must be fully carried out.
For example, if the commit message says
Move delete() from Person class to Address class, the commit cannot contain the addition of
Address class only; it should also contain the deletion of
delete() from the
Person class for it to be a complete implementation what is stated in the commit message.
Each commit has a well-written commit message i.e., it follows these guidelines.
Commits are ordered in a bottom-up fashion, each commit building on top of the previous one towards the end goal of the PR.
Rationale: Reviewers should be able to review one commit at a time.
Ideally, a commit does not modify more than 100 lines of code.
Commits containing mechanical changes (e.g. automated refactorings, cut-paste type code movements, file renames, etc.),
Every commit pass CI. when you merge a series of commits (without squashing), every commit in your push (not just the last commit) should pass CI.
Rationale: Build-breaking commits in the version history hinder the ability to use
git bisect for locating bugs.
Refactor commits before pushing. It is unlikely that you can produce a series of commits that meet all the above criteria in the first try. In such cases, refactor commits until they meet the criteria. This S/O post describes how to refactor commits (even easier to do with visual tools such as SourceTree -- see this video).
When merging branch, the aim is to keep the version history neat so that it is easy to do things such as the following:
Use a merge commit if the commits are well-organized, and the branch tackles only one task. In this case the commit message of the merge commit should explain the full task.
Use a rebase-merge if the commits are well-organized and each commit is an independent task (as opposed to steps or a bigger tasks).
In other cases, consider reorganizing/splitting the branch to match one of the above.