0

The scenarios is as following. I will use t1,t2,t3 and etc. to represent different time:

I have two branches to represent my environments DEV branch, MASTER branch.

t1: I created a Feature_001 branch from MASTER

t2: I added commits in the Feature_001 branch and merged my code into DEV and pushed it.

t3: for some reason, my manager told me to stop the development of the Feature_001 branch

t4: One month passed. My colleague Clair created a Feature_002 branch from MASTER.

t5: Clair added commits in the Feature_002 branch and attempted to merge her code into DEV branch and pushed it. However, a conflict shows up when she pushed.

t6: Clair then pulled and merged the changes from the DEV branch into her Feature_002 branch (my problem happens in this moment). She made a new commit to solve the conflict in the Feature_002 branch. After that, Clair merged her code into DEV and pushed.

t7: After testing, Clair's manager says it's OK to merge into MASTER branch now. So, Clair merged the Feature_002 branch into the MASTER branch.

t8: Although the Feature_002 Clair developed is functioning in the production, the Feature_001 unintentionally shows up in the production, too, because the Feature_002 branch once merged code from DEV to itself to solve conflicts. Our manager was shocked and started to question who dared to let the Feature_001 go out to production!?

t9: meeting and meeting forever to discuss what happened ...

If you follow well on the scenario, you can find because of the conflicts between feature branches, Feature_002 branch will include changes in the Feature_001 branch after Clair pulled the code from DEV.

My question is how to keep two feature branches independently while enabling us to solve conflicts between them?

Any feedback and discussion is much appreciated.

EDIT 20180925:

I want to adjust the situation a bit. Feature_001 branch can be unwanted or just be under development for a long time. Let's make it be under development for a long time while Feature_002 was tested first and merged into MASTER real quick. However, now, again, MASTER branch have both Feature_001 and Feature_002 changes there when we don't want Feature_001 to be in production.

Sheng-yu Tsai
  • 41
  • 1
  • 7

4 Answers4

1

I see a number of problems there. If feature 001 was not to be developed anymore.... even discarded, say, it should have been taken out of dev branch. Given that it wasn't, when you merge dev (through feature 002) onto master (yet another problem, my guess is that this shouldn't happen) then, because feature 001 hadn't been taken out, it landed in master.

So.... how to avoid it? Everybody will say a different thing. My take? When you got the notice that feature 0001 was to be stopped, it should have been taken out of dev branch (either by rewriting dev history to avoid the merge or by reverting 0001 revisions). And then, I guess you shouldn't merge from dev into master... but that's just a guess cause it really depends on your workflow.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • You might misunderstand some points. No one ever merged from DEV to MASTER. Clair merged Feature_002 into DEV. Then, Clair merged Feature_002 into MASTER. – Sheng-yu Tsai Sep 24 '18 at 20:39
  • t6 says exactly otherwise: dev was merged (by means of a pull) into her feature 002 branch. Then on t7 feature 002 (including changes that were on dev) was merged into master. – eftshift0 Sep 24 '18 at 20:43
  • still, these two directions are: 1. DEV -> Feature_002 2. Feature_002 -> MASTER There is no direct merge from DEV -> MASTER – Sheng-yu Tsai Sep 25 '18 at 04:31
  • Sure.... and that to git still makes no difference because you are landing revisions from _dev_ into master when you merge feature 002. Check the history of **master** and let us know if there are changes that were developed for feature 001... let me use my foretelling powers to tell you... let me close my eyes for a couple of second.... yes, there are. – eftshift0 Sep 25 '18 at 04:46
  • Yes, now we are on the same page. If you're talking about commit level, then I can be sure we are addressing the same thing. Thanks. – Sheng-yu Tsai Sep 25 '18 at 05:14
  • Could you help on another situation where Feature_001 is under development for a long time while Feature_002 got tested first and merged to MASTER real quick. In this case, we don't want to revert changes made by Feature_001 in DEV. How can we solve this scenario? – Sheng-yu Tsai Sep 25 '18 at 05:16
  • I think it's a workflow problem. Say.... feature 002 was developed from master. That's fine. Then you wanted to merge it into dev.... so you merged dev onto feature 002 and then you pushed into dev. That's all fine. Here's the problem: you want to merge feature 002 _into master_ now. If you tried to merge feature 002 (as you did), you would end up with changes from dev into feature 002 (because you merged dev into 002... hope this sounds familiar). The way you can avoid it is by merging the _original work_ from feature 002 _before_ it was merged with dev. – eftshift0 Sep 25 '18 at 05:25
  • That's why it's always a good idea to keep feature branches "clean" without merges (at least, the original work) so that it can be rebased/cherry-picked into other branches without issues. – eftshift0 Sep 25 '18 at 05:27
  • I would like to have more discussion on the solution you suggest. "The way you can avoid it is by merging the original work from feature 002 before it was merged with dev." – Sheng-yu Tsai Sep 25 '18 at 15:46
  • If I merge the original work from Feature_002 into MASTER before it was merged with dev, it means this feature is never tested in DEV. Am I correct? Please correct me if I understand it wrong. – Sheng-yu Tsai Sep 25 '18 at 15:48
  • 1
    That's a conflict you solve _on dev_, **not** on feature 002 branch. feature 002 branch remains the way it is without merging anything from a branch as explosive (apparently) as _dev_. That way you make sure you keep the branch "pristine". Then, when you have tested on dev feature 002 and it gets a go, you can merge it into master and life goes on with its happy and sad times. – eftshift0 Sep 25 '18 at 15:50
  • I understand this approach now. It seems great. One last question, it means we will create a commit for conflicts in DEV branch directly. Am I right? – Sheng-yu Tsai Sep 25 '18 at 15:53
  • Sure... merging dev into feature 002 or doing it the other way around will bring up the exact same conflicts. – eftshift0 Sep 25 '18 at 15:56
  • Ok. Then, a follow-up question. Because in my current company, we have four stages DEV,QA,STAGE, and PROD. If we go with this approach, we will have to solve the conflict when we merge Feature_001 into each branch(DEV,QA,STAGE,PROD). It introduces another tedious work. What's your thoughts on this? Thanks. – Sheng-yu Tsai Sep 25 '18 at 16:01
  • Having to deal with conflicts is just a fact of every developer. Depending on where you are pulling things from, you might get or you might not get them. For example, on dev you got the conflict because feature 001 (still laying around on dev when it probably should have been removed while it was still a work in progress) and feature 002 touched the same piece of code. But if you merge feature 002 into master (where feature 001 is _not_), then there would be no conflict. If things reach prod from master, you won't get a conflict out of feature 002. – eftshift0 Sep 25 '18 at 16:16
1

If the changes from Feature_001 weren't intended to be released to production, it shouldn't have been merged to DEV. The changes should have been left on the Feature_001 branch. If the decision to not release Feature_001 was made after it was merged to development, the changes should have been reverted. As long as it is present on DEV, other users who pull from DEV will have the changes in their branch.

AJC
  • 981
  • 10
  • 17
  • Let's say now we decide to revert everything coming from Feature_001 in DEV. How should we do it? It's not recommended to make commits directly in DEV branch. However, we still want to keep our Feature_001 branch for the future. What's you thought on this? – Sheng-yu Tsai Sep 24 '18 at 20:38
  • You can create new branch based off development to revert the changes. Or if you use something like gitlab, it gives this option to revert that as a separate merge request (which is what we do at work in scenarios like this) – AJC Sep 24 '18 at 20:42
  • Thanks AJC, that's a very useful way to revert codes in Gitlab. Additionally, I would like to adjust the scenarios above. Let's say the Feature_001 is not wanted, it's under developing for a long time. We still want the code in the DEV. However, Feature_002 gets tested first and merged back to MASTER. However, again, in MASTER, both Feature_001 and Feature_002 are there. How can I solve this situation? – Sheng-yu Tsai Sep 25 '18 at 04:29
  • i didn't really understand your question. Did you say, Feature_001 is not wanted but is in DEV? My understanding is DEV at any point should have only code that is ready to be released. At least our process here is, master will always have the same code as that is in PRO. DEV should have only tested, signed off and deployable code. Anything that is not tested or not signed off by the product team shouldn't be in dev at all. Please correct me if I misunderstood your question. – AJC Sep 25 '18 at 14:56
  • Feature_001 is wanted and is now in DEV. I'll provide a scene to describe the example more. I am the developer of Feature_001. However, I took a week-long sick leave. While I was in the hospital, my colleague Clair merged her code to DEV and then to MASTER. In this situation, it's valid that changes of Feature_001 stayed in the DEV. However, we will still face the issue addressed in my original post. – Sheng-yu Tsai Sep 25 '18 at 15:40
  • Like I said in my comment above, merge to DEV ONLY IF it can be released to PRO. And once it is merged to DEV, any user working on branches off DEV would have your changes and once they merge to master, your changes will move to master too. If the changes shouldn't go to master, it should either be not merged to DEV or should be reverted from DEV. – AJC Sep 25 '18 at 15:47
  • To provide more information, in my current company, we have four environments, DEV,QA,STAGE,PROD. Let's say Feature_001 is now in STAGE branch. However, I took a leave for one week. Then Clair merged her Feature_002 into DEV,QA,STAGE and PROD in this week. According to your suggestion, I will have to revert all the changes in three branches (DEV,QA,STAGE) just because of my one-week leave. It's not a very systematical way and not flexible enough for this situation. What's more, it takes weeks to go through each environment, too. – Sheng-yu Tsai Sep 25 '18 at 15:59
  • I am not an expert, so I don't know how to explain this better. If your change is not ready for PRO, it SHOULD NOT be in DEV, it should be on feature branch. It doesn't matter whether you took leave or not. If you merged to DEV, any developer who works off development will have your changes, and if their branch is ready to be merged to master, your changes would be merged inadvertently. So merge your branch to DEV and all subsequent branches ONLY when the changes are ready to be deployed. – AJC Sep 25 '18 at 16:09
  • Hi AJC, I guess you do not take in the new information I provided. If it's ok, I would like to suggest you take some time to understand my description. All the codes are ready to be deployed, they just have to go through different stages for testing to make sure everything is fine. So, again, Feature_001 and Feature_002 are ALL READY for deployment. They just go through each stage at different pace. – Sheng-yu Tsai Sep 25 '18 at 16:14
  • Once it is in STAGE (tested and signed off) and is ready to be deployed, what is the problem in this getting merged to MASTER by someone else? – AJC Sep 25 '18 at 16:22
  • In our place, dev have our own feature branches, and QA tests the changes on an environment based off the feature branch first. If things look good, the dev will merge the branch to DEV. On code freeze, we create a release candidate for the release, out of DEV branch and any changes that DEV branch had until then, will be moved to RC. Any new changes in DEV would be included for the next release only. QA will test on this RC version and signs off. Then when the RC is finally deployed to PRO all the changes in RC is merged to DEV by one of the leads. – AJC Sep 25 '18 at 16:22
  • Once it's in STAGE, how long it's gonna take for testing in STAGE is beyond our team's control. So, it may stay there for weeks until we get notified that it's ok to go to MASTER. – Sheng-yu Tsai Sep 25 '18 at 17:05
  • Thanks for the sharing about your git flow model. I will give it a thought and come back to you with some feedbacks. Thanks a lot. – Sheng-yu Tsai Sep 25 '18 at 17:10
0

The branch Feature_001 shouldn't have merged to DEV until Feature_001 was completed and pull request approved. The conflicts will have to be resolved once Feature_001 is merged into DEV not before, this will avoid the problem you encountered, where Feature_002 branch had some commited code from Feature_001. Ideally the Feature_001 should either be small or broken down into smaller features such as Feature-001-S-xxxxxx-MyStoryDescription for easy tracking. Additionally, since your branch Feature-001 might have many commits, it is recommended to squash your commits before doing pull request and rebase your branch when a merge conflicts occurs. Happy coding!

HaroldSer
  • 2,025
  • 2
  • 12
  • 23
0

I understand that you are not using GitFlow, because you created your feature branches since master (in Gitflow it should be develop), and you are pushing changes not ready to be released in develop (in GitFlow, the release branch is created since develop).

Hence, thinking in your actual flow, to avoid these issues we can:

  1. Avoid to push changes not ready to production to develop. Test your code in your local machine. If you really need to test your code in some specific environment, "borrow" the environment and deploy your feature branch only.

  2. Create features that only works if some flag is activated, for example a flag FEATURE_ACTIVE in db. It should have the value Y in qa (to test) and N in production (to avoid issues).

  3. NOT RECOMENDABLE. If for some reason, you still need to push changes not ready for production to develop. When you face a conflict, you can create a temporary branch that solves the conflict between two branches and then, merge it to develop. This allows you to maintain the branches independently. The author of the branch that will be deployed later, should be aware of the merge of the other branch to the branch master, after that he can pull the changes from master and also merge the temporary branch into it to keep the branches clean. For example in this case, your friend should have created a new branch since Feature_002 called Feature_001_002_temp and then merge the branch Feature_001 into it, solve the conflicts and merge it to develop. Any additional change to Feature_002 should pass throug this temporary branch until Feature_002 goes to prod. Be very careful with the changes, some conflicts such as deletions, values of constants could break your app.