hugomodo / hugomodo-best-motherfucking-website

Based on https://thebestmotherfucking.website/
https://hugomodo.github.io/themes/best-motherfucking-website
MIT License
11 stars 3 forks source link

An Advanced Git Branch Structure for Child Themes #3

Closed thombruce closed 5 years ago

thombruce commented 5 years ago

Ignore for now the consideration of releases and focus on feature and standalone branching.

master -> feature/some-feature -> PR -> master

It's at that point, the merging of a pull request into master that we also must automate this:

feature/some-feature -> standalone

Or alternatively:

master -rebase-> standalone

...because in effect standalone should always be only one or a few commits ahead of master. Just those commits that provide standalone functionality.

Imagine it's three steps ahead, because changes have been added iteratively.

standalone = (master + 3)

Consider:

master -(rebase)-> (master + 3)

vs

feature/some-feature -> (master + 3)

The second, merge, approach yields (master + 4), no? Or worse: (master + 3 + divergence)

By merging to master then rebasing standalone instead, we'd ensure it remains only those 3 steps ahead.

Update Against Master

That settles it. Rather than features being merged into standalone, I expect it should be brought up to date with master instead. But we still have options:

master -merge-> standalone
master -rebase-> standalone

Rebase would provide linear history, with the most recent commits on standalone always those that concern standalone behaviour.

Merge however would leave the divergence from master in the past and create a new commit(s) to the end of the standalone chain.

Rebase also requires a force push.

Use Merge and Squash

We should opt to merge and squash into standalone from master. This keeps it up to date with the state of master (rather than adding a different but identical set of feature commits), and more accurately represents the history of the branch without need for force.

git checkout standalone
git merge --squash master

Resultant history:

master >> standalone >> commit >> commit >> commit >> *merge* >> commit...

But that's not the whole story

I have notes elsewhere about this, but standalone is likely to include some file changes that may present an eventual conflict with master, for which reason... I have this saved reference: https://stackoverflow.com/questions/15232000/git-ignore-files-during-merge/16455853#16455853

Should files need ignored, that's the way to do it. However it looks like my notes from that time are describing a different approach (a reverse approach), so we're less likely to need this.

Still, keep note of it!

thombruce commented 5 years ago

Consider that:

thombruce commented 5 years ago

The Final Say

At this point, we have versioned, standalone and versioned standalone branches all working. But a few compromises had to be made.

Rather than merge and squash into standalone from master, we reset standalone to the state of master with every update of master. Then we copy files from the parent. The reason for this...

We had to presume that, of course, the parent might be updated too. So that's sort of two sources... and conflicts would become a bit of a hassle to manage.

So for the time being, we have it setup in such a way as conflicts will not arise.

That should remain the case!

...but I would also like to explore ways in which we'd adapt this to also preserve history on standalone.

Like reset but preserve history and then copy. I think I need to look in greater detail at the git reset options. Like... can I do a soft checkout of master which becomes identical to it, then copy files from parent, then commit, such that the commit then reflects only the real changes which occur.

But for now, that's a luxury not a necessity. Closing.