0

We have a master branch and many short living feature branches that get merged into master after the customers have accepted the changes.

In addition to that we have long living environment branches for the user acceptance system and the production system, named stage and prod, that are originally branched from master.

Our workflow looks like that:

  • develop feature on feature branch
  • merge feature branch into stage
  • wait for customer acceptance
  • on acceptance merge to master
  • master gets merged into prod the next day

Customer acceptance can take short to very long, so there are several "features" living on stage that are either waiting for acceptance or abandoned. Because if the customer does not accept the change we do not merge the feature to master but sadly it lives on on stage like a zombie :)

Now the question(s):

How would we reset the branch stage to current master without losing the ability to merge the feature branches that are still waiting for acceptance to stage again? The goal here is to get rid of the abandoned "features".

Is this possible without altering history and force-push?

crackmigg
  • 5,571
  • 2
  • 30
  • 40
  • To clarify: we can of course rewrite history and force-push if there is no other option. – crackmigg Feb 16 '17 at 14:47
  • There are many commits and merge commits in the history. The merge commits seem to be a problem that prevent `git revert master^..stage`. – crackmigg Feb 16 '17 at 15:38
  • have you get the answer which help you to solve the problem? If yes, please mark it. And it will help others who have similar questions. – Marina Liu Feb 22 '17 at 06:07
  • @Marina-MSFT oh yes thanks for reminding me of this ticket! Sorry. – crackmigg Feb 24 '17 at 14:40
  • So I added what we did as an answer with more details. Thanks for all suggestions, They helped a lot :) – crackmigg Feb 24 '17 at 14:47

4 Answers4

1

Without rewriting history, the only thing that I can think of would be to revert those commits from the abandoned features.

Stout01
  • 1,116
  • 1
  • 10
  • 20
  • Yes thats a possibility. But the problem is there are many many merges and it would take a lot of time to sort this out. Its two years of work by 20+ people... was hoping for an easier solution :) – crackmigg Feb 16 '17 at 14:46
  • Ah, that is quite a lot of things to revert. I think that this might be what you're looking for then: https://stackoverflow.com/questions/29768207/revert-all-branch-specific-changes-so-the-branch-reflect-master – Stout01 Feb 16 '17 at 14:49
  • I will have a look, many thanks already! Sounds like this would be it if it works :) – crackmigg Feb 16 '17 at 14:53
  • Did not work. `Commit ... is a merge but no -m option was given. revert failed`. I tried this: `git revert -n master..branched`. I will try the "initial post" steps now. – crackmigg Feb 16 '17 at 15:08
  • "initial post" did not work either. There are several errors, I will try to understand them and maybe get it working. – crackmigg Feb 16 '17 at 15:19
1

If you merge features into stage with true merges, it's easy to revert those merges. Simply run git revert on the merge commit, with the appropriate -m argument (usually -m 1).

If you merge features into stage by copying commits or by fast-forwarding, it's more difficult, as you must revert each commit. You can give git revert a range of commits to revert, and it will do all of them in the appropriate—i.e., last-to-first—order. Note that ranges of the form A..B mean "everything reachable from B, except for everything reachable from A", and since A is clearly reachable from itself, this excludes commit A itself. Hence 1234567..fedcba9 includes commit fedcba9 and earlier commits back to 1234567 but excludes 1234567 itself.

If you merge features into stage using git merge --squash, this copies all the commits into one big (but independent) commit, so that you would again simply run git revert on the one copied commit (without -m as it is not a merge commit).

(Note that however you revert these, if you eventually discover that you want the feature after all, it's a bit painful.)

torek
  • 448,244
  • 59
  • 642
  • 775
1

Since all approved features are merge into master, so the first unmerged commit on stage is abandoned feature. Assume F1, F2 and F3 are the living features waiting for customer acceptance on stage branch. And F1 is abandoned feature and F2, F3 are accept features. So it need to get rid of F1 on stage.

          C-----…-----D---F1---F2---F3  stage
         /             \
A---…---B---…---E---…---G       master
                \        \
                 F----…----H    prod

You can use below commands:

git checkout stage
git rebase --onto <commit id for D> <commit id for F1> stage

then the structure will look like:

          C-----…-----D ---F2’---F3’  stage
         /             \
A---…---B---…---E---…---G       master
                \        \
                 F----…----H    prod
Marina Liu
  • 36,876
  • 5
  • 61
  • 74
0

So what we ended up doing was to just delete the branch stage and create a new branch stage from the current master. This way all unmerged features are removed, and because all the feature branches still exists they are also still mergeable to the new stage branch.

So we merged some branches that we know are currently waiting for customer acceptance back to stage and got rid of all the abandoned features.

crackmigg
  • 5,571
  • 2
  • 30
  • 40