2

I have are requirement that the main branch has only one (potentially big) commit per issue ID. However, to confirm to the best practice of small commits, I also need to create and keep(!) multiple small commits per issue ID.

I have already found an OK solution (I think):

  1. Create a feature branch my-feature-branch from main.
  2. Make multiple small commits to my-feature-branch.
  3. In main: git merge --squash my-feature-branch
  4. main now has the big commit, automatically with a message referring to the small commits, so you can always "zoom in" to the detailed history if needed.
  5. Keep my-feature-branch and stop working on it.
  6. Create a new feature branch my-feature-branch-2 etc.

However, it would still be nicer to not need multiple feature branches for this. It would be nice to just have one extra branch, e.g. main-detailed. The problem is that whenever I git merge --squash main-detailed to master, Git tries to merge the full history of main-detailed, because it does not know that some of that history had already been merged via previous merge --squash commits. Is it still possible somehow to implement the desired workflow?

3
  • 3
    The problem is .... Git not know that some of that history had already been merged sqashing the commits changes the history. So the answer is no, there's no way to have 2 different commit histories also be the same commit history.
    – erik258
    Commented Apr 5, 2023 at 15:30
  • 3
    What is you goal to have one big commit if you see value to have small commits on the other hand ?
    – Ôrel
    Commented Apr 5, 2023 at 15:53
  • @Ôrel: It is a policy I have to adhere to. It has to to with Gerrit code reviews. Commented Apr 5, 2023 at 17:16

1 Answer 1

3

I will assume that main (with the squashed commits) is some sort of "official" view that must not show the details in the history, and that the detailed branch is a "personal" branch that lets you investigate a more useful history for developers.

I suggest that you keep the following history:

0--------A-----------D     <-- main
 \        \           \
  a--b--c--o--d--e--f--o   <-- detailed

The two branches have a common base 0. You develop on branch detailed. The first feature consist of commits a, b, c. When it is ready, you switch to main, then

git merge --squash detailed

to create commit A. Then you switch back to detailed and

git merge main

This does not introduce any new changes, because the tips of the two branches must be equal at this point. You repeat the procedure for the feature consisting of commits d, e, f to create the squash-merge commit D.

The effect of merging main into detailed is that the squash-merges will not consider the already merged feature commits. When you look at the history of main, the detailed commits are invisible, but when you look at the history of detailed, you see all commits, including those in main.

10
  • It works almost exactly as you describe, with one exception regarding "the squash-merges will not consider the already merged feature commits": The already merged commits and also the merge-main-into-detailed commits appear in the auto-generated suggested commit message. This could become a problem after a couple hundred commits. Is there a way to prevent that? Commented Apr 5, 2023 at 18:01
  • 2
    I don't think there is an easy way to do that. If you do the squash-merging in a different repository, and if it is under your control, you could git replace the parent of the first commit of a feature to point to the last squash-merge. For example, git replace --graft d A would pretend that the histories diverged only at A and that d is the very first feature commit.
    – j6t
    Commented Apr 5, 2023 at 18:08
  • So git replace would be run on detailed in a copy of the repository? And then the original repository would squash-merge from that copy? Commented Apr 5, 2023 at 18:57
  • 1
    @Guildenstern I am worried that at some point after years of commits an extremely large auto-generated suggested commit message will slow down or even crash Git or GUIs that wrap Git (e.g. TortoiseGit). So I do not consider the problem solved. Commented May 7, 2023 at 19:27
  • 1
    @Guildenstern: Thanks. I will try that out in a few days (no time now) and reconsider accepting this answer. Commented May 7, 2023 at 19:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.