0

I'll give some context before jumping to the actual questions: I'm the only developer working on a project, where I have main, develop and staging branches, besides all feature/* and hotfix/* that I could potentially have during development.

The integrations between branches were made via pull requests using GitHub, some of them were made with merge commits, others with squash commits, so the result is that the branches got very messy. For example, I just merged staging to main, then updated (merged) main to both develop and staging. As I'm the only developer, I know that the content at this point for all the three branches is the same, but commit-wise is not: both develop and staging are 382 commits ahead of main.

When I create a pull request to staging over a branch checked out from develop, the pull request shows only the commits about the feature itself, which is good. Buy when I create the pull request to main over staging, a lot of commits that aren't related of this request are showing (because they are commits from develop and staging, but not in main) and making the code review messy, also the changelog management.

For me (and correct me if I'm wrong, please) the perfect scenario would be having main, development and staging with exactly the same content and commit count (i.e., development and staging show 0|0 ahead/behind main). I could delete and recreate both develop and staging branches from main, but (and here comes the first question) is there a way to reset develop and staging branches without recreating them?

The second question is kinda obvious: which way do you think is the cleanest to handle the following pull requests to keep a clean situation in the future?. I think that any merge-based solution will include at least one commit, so maybe the answer goes through rebase.

  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. – Community Oct 20 '22 at 08:27

1 Answers1

2

The reason why it messed up is because you did not create real merges. When you squash-merge, the original branch is not really merged into the target branch so it you try to merge again later, those same changes that had been merged (in a squash) will show up (because they were not really merged, right?)..... so, when you want to merge between those 3 branches, do real merges.

Rule of thumb there goes something like: do not merge-squash branches that are long-lived. squash is fine when you want to merge a feature-branch, for example, because you won't be starting stuff from the original feature branch. It reaches EOL, say. But long-lived branches do need to keep commits that are merged in order when you merge them.

Then.... if you want to have those 2 branches with the same as main (contents and history), just move the branch pointers (remember: in git, branches are just pointers to commits... they can be moved around):

git checkout main
git pull # get the latest from remote main
git push -f origin main:develop main:staging

Now all 3 (remote) branches point to the same commit. The local branches, you would need to move them as well:

git branch -f staging main
git branch -f develop main

And now everything is in sync.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • Thank you very much! the rule of thumb makes complete sense in this scenario. To test the solution you provided me I have to ask for advanced permissions or disable protection hooks (as we work with pull requests I'm not able to force push towards the repo) but it looks like it would work – Juan de la Cruz Garcia Oct 21 '22 at 08:09