0

Regulations in my industry require strict linear development - therefore no merge commits in master. We also cannot lose authorship, so extreme squashing of commits is difficult. We've spent a lot of time exploring options for maintaining features in branches and have hit a lot of speed bumps. I will summarize the solutions we've tried and the issues we've found with them. I also have an idea for a solution that I would love help fleshing out.

Solutions:

  1. Feature branches are regularly rebased onto the tip of master. No squashing.

    • Drawbacks: Merge conflicts are resolved per commit. Time cost is high as feature branch grows large.

      For example say commit A changes a file significantly, so you resolve a bunch of merge conflicts, then commit B reverts some changes and makes some more changes, so a bunch of those merge resolutions never really needed to happen. Finally commit C deletes the whole file and everything was a complete waste of time

  2. Feature branches are merged regularly. At the end of the release a soft reset to master is used to merge all changes.

    • Drawbacks: Hit by regulations. Authorship of code must be maintained.
  3. (Unattempted) Feature branches are merged regularly. Fancy git tools allow us to imperfectly convert this branch into a rebase style branch at integration time.

    • Idea: Say we have a branch feature/branch that is our "merge style" branch and we want it to be a "rebase style" branch on top of master. We then follow something similar to these steps:

      1. Get a list of all commits in feature/branch that are not in master using

        git log --pretty=format:%H %p --reverse feature/branch ^master

      2. Do some text parsing on that list to get a list of cherry-pick commands

        git cherry-pick <hash> -X theirs (merge commits would have the argument -m # -- I'm not yet sure of which is better for ours vs theirs or which number is best for the -m # command )

      3. Run this list as a batch file on master. This gets us to a point of having possibly sufficient history of authorship.

      4. Checkout features/branch and perform a soft reset to the modified local master. Check all of these changes into the tip of master to get master to a good state.

    • I'm currently stuck on step 3. Even with either strategy ours or theirs, I still get merge conflicts. I imagine I was being overly optimistic to expect the strategy to magically force a cherry-pick.

I'd really appreciate any feedback on the proposed solution - even if it's to ridicule it - and I'd love to hear any new ideas for managing this workflow.

  • 1
    Option #1 is what you'll probably end up using in practice. Note that the "friction" here is roughly the same as with merging, just that the conflicts get peanut buttered across multiple commits in rebase unlike merge, where everything happens in a single merge commit. – Tim Biegeleisen Dec 10 '20 at 23:43
  • Since we can't squash commits, rebasing became a huge time sink for our team. To give you an example let's say commit A changes a file significantly, so you resolve a bunch of merge conflicts, then commit B reverts some changes and makes some more changes, so a bunch of those merge resolutions never really needed to happen. Finally commit C deletes the whole file and everything was a complete waste of time – David Meehan Dec 11 '20 at 00:02

1 Answers1

1

If you do require strict linear development without losing authorship, then choice number 1 is what you'll need to do. If you use a hosting platform such as GitHub or GitLab, then it probably has functionality to do the final rebase for you instead of merging, provided there are no conflicts.

In general, you should not see significantly more conflicts with a rebase than you would with a merge. You will almost certainly see some more, because a merge only considers the two heads and the merge base, and a rebase will apply each individual commit.

You cannot use a git cherry-pick -m because that loses history: it cherry-picks the result of the merge into a single commit instead of all of the merged commits. It is possible to rebase the commits in the branch onto master, but as mentioned, you may see conflicts there that you don't see due to the merge, so you can't guarantee that this will always work. I suspect your regulatory requirements won't allow a human to fix up these conflicts by hand.

I will also say that I'm very interested in your industry and their regulations, because as a Git contributor I find a strict linear history to be an absurd and bizarre regulatory requirement. There may be other reasons to adopt this approach depending on the development team, company, and project, but requiring a linear history is not a legitimate thing to regulate at the industry level.

bk2204
  • 64,793
  • 6
  • 84
  • 100
  • This is true; there are cases when that can happen, although they are unlikely. – bk2204 Dec 11 '20 at 00:40
  • Thanks for the response! Are you saying the git cherry-pick -m is not possible because of the regulatory constraints or because its technically impossible? Losing the branch history could be okay, as long as a history exists on master (if that makes sense). I know it's a bit strange, but a solution that mostly conserves authorship and history is okay even if not perfect. This is because we have a solution for losing authorship - it just causes a ton of overhead that increases the more we do. – David Meehan Dec 11 '20 at 01:30
  • To answer the regulation question.. I can't find the exact line of regulation, but there's a line that basically enforces that the changes in a commit be obvious from a single previous commit. This goes along with code review requirements and enforced independence. So merge commits are blocked company-wide and there are highly paid people that made that decision over my head! – David Meehan Dec 11 '20 at 01:36
  • `git cherry-pick -m` doesn't meet your regulatory requirements; it's mostly equivalent to a squash merge and doesn't preserve history. – bk2204 Dec 11 '20 at 01:43
  • 1
    Next up: long-distance running in the desert when you're not allowed to run at night or drink water. – jthill Dec 11 '20 at 02:53