Why are release branches made from develop and not master branch? - branch

Git-flow explains the following process for release branches -
Release branch should be forked from develop branch
Release branch should merged back into master branch, and a tag created from master branch.
My question is why is why should release branches be forked from develop and not master? Is there any benefit from doing so?
I can instead
Merge my develop into master
Fork a release from master and then tag the master...
How will that affect the version management?

You almost answered your question in one of your comments:
the purpose of master is to be a replica of a production ready stable code
Let me elaborate on that:
(1) That statement is correct. master is production-ready. According to git-flow every commit (being a merge from a release or hotfix branch) leads to a new release.
(2) If you merge develop directly onto master you might end up with instabilities. That's what we create a release branch for. We use the latest version of develop but test them, make some bug fixes, adjust configurations etc.
Only when everything is fine we actually merge onto master and therefore deploy to our users.
A final - but very important - note here:
git-flow is just one of many ways to organise your code. It's not a this is the one and only solution for everyone and everything. It's just a suggestions, a framework. Adjust it to your needs or use a completely different framework / idea if it does not work for you. I rarely used git-flow in the past 15 years exactly the way it's documented. We always made some adjustments.
One of them btw being very closely related to your question: We would deploy from release and only if that deployment works and reached our clients (Apple's review process, I tell you!) we would merge to master and tag that release.

Related

What is the difference between promoting a release, and creating a new one?

When running a deployment in bamboo, it gives the option between 'promoting' a release or creating an old one. Is this just jargon for 'reuse' or is something else happening?
I've not found anything in the Atlassian docs, and only this came up:
You should create a new release if there were changes in your code since the last version. If you need to promote code from one environment to another, using the "Promote" feature is definitely the way to go.
I think that makes sense if you replace 'promote' with 'reuse' makes sense.
If you want to reuse some old releases, then you tell Bamboo promote(reuse) the previously built releases. In this sense, with promote Bamboo means reuse.
From Build Result you can always create new release to deploy, but always the latest build result.

Can Liquibase or Flyway handle multi non-linear versioning scenario?

Here is a tough one.
v1.1 has a table with index i.
v2.1 contains this table and index as well.
A bug was discovered and in v1.1.0.1 we changes the code and as a result, decided to drop the index.
We created a corresponding patch for v2.1, v2.1.0.6.
The customer applied patch v1.1.0.1 and a few weeks later upgraded to v2.1 (without patch 6)
As v2.1 code base performs better with the index we have a "broken" application.
I can't force my customers to apply the latest patch.
I can't force the developers to avoid such scenarios.
Can Liquibase or Flyway handle this scenario?
I guess these kind of problems are more organizational and not tool-specific. If you support multiple Version (A branch 1.0 and a newer one 2.0) and provide patches for both (which is totally legitimate approach - don't get me wrong here) you will probably have to provide upgrade notes for all these versions and maybe a matrix that shows from which version to which you can go (and what you can't do).
I just happened to upgrade an older version of Atlassian's Jira Bugtracker and had to find out that they do provide upgrade notes for all versions.
That would have meant to go from one version to the next to finally arrive at the latest version (I was on version 4.x and wanted to go to the latest 5.x) and obey all upgrade notes in between. (Btw, I skipped all this and set it up as a complete fresh installation to avoid this.)
Just to give you an impression, here is a page that shows all these upgrade notes:
https://confluence.atlassian.com/display/JIRA/Important+Version-Specific+Upgrade+Notes
So I guess you could provide a small script that recreates the index if somebody wants to go from version 1.1.0.1 to 2.1 and state in upgrade notes that it needs to be applied.
Since you asked if liquibase (or flyway) can support this, maybe it is helpful to mention that liquibase (I only know liquibase) has a something called preConditions. Which means you can run a changeset (resp. an sql) based on the fact that an (e.g.) index exists <indexExists>.
That could help to re-create the index if it is missing.
But since version 2.1 has already been released (before knowing that the index might be dropped in a future bugfix) there is no chance to add this feature to the upgrade procedure of version 2.1.
Liquibase will handle the drop index change across branches fine, but since you are going from a version that contains code (a drop index change) to one that does not expect that you are going to end up with your broken app state.
With liquibase, changes are completely independent of each other and independent of any versioning. You can think of the liquibase changelog as an ordered list of changes to make that each have a unique identifier. When you do an update, liquibase checks each change in turn to see if it has been ran and runs it if it has not.
Any "versioning" is purely within your codebase and branching scheme, liquibase does not care.
Imagine you start out with your 1.1.0 release that looks like:
change a
change b
change c
when you deploy 1.1.0, the customer database will know changes a,b, and c were ran.
You have v2.1 with new changesets to the end of your changelog file, so it looks like:
change a
change b
change c
change x
change y
change z
and all 2.1 customers database know that a,b,c,x,y,z are applied.
When you create 1.1.0.1 with changeset d that drops your index, you end up with this changelog in the 1.1.0.1 branch:
change a
change b
change c
change d
But when you upgrade your 1.1.0.1 customers to 2.1, liquibase just compares the defined changesets of (a,b,c,x,y,z) against the known changesets of (a,b,c,d) and runs x,y,z. It doesn't care that there is an already ran changeset of d, it does nothing about that.
The liquibase diff support can be used as a bit of a sanity check and would be able to report that there is a missing index compared to some "correct" database, but that is not something you would normally do in a production deployment scenario.
The answer may be a bit late, but I will share my experience. We also came across the same problem in our project. We dealt with it in the next way:
Since releases in our project were not made often, we marked each changeset in liquibase particular context. The value was the exact version migration (like v6.2.1-v6.2.2). We passed value to liquibase though jndi properties, so customer was able to specify them. So during upgrade customer was responsible for setting right value for migration scope for each upgrade. Liquibase context can accept list of values. So in the end, context looked like this:
context=v5.1-5.2,v5.3-5.3.1,v5.3.1-5.4,v6.2.1-v6.2.2

Mature Branch Strategy On TFS

My team are finally moving from SourceSafe to TFS 2010, and we are trying to work out our strategy.
We need to be able to put bug fixes into the next service release whilst still working on the current service release. Basically, at some point we will stop bug fixing going in the current release (except a few critical ones) and pilot that release for a week or two. During this time we still want to be fixing bugs so we put them into the next service release. This is separate from the development that will be going into the next major release.
We like the look of the mature branching strategy that involves having a service release branch off of main, a hot fix branch off of service release, and a release branch off of hot fix. What we would then do is have the release branch as the one that we are piloting and still be able to add bug fixes to the service release branch. Then when we finish with the pilot and have made the last critical changes we merge the release branch back into main, via the hot fix and service release branches, and then create a new hot fix and release branch from the service release branch, which will be our next service release.
The big problem I have with this is that I want anything that goes into main to be fully tested. The release branch will be but as we merge it back into main it will pick up any changes that we have checked into the hot fix and service release branches. These changes will not have been tested at this point.
To get around this we are planning on making the devs shelve their changes in the service release branch until after the release has been merged into main. This doesn't seem like the best idea to me, but I can't think of anything else to do to handle this.
Has anyone else had to do something similar and have a better way of handling this?

How to interpret merge information in TFS log output (or: how can I know which changesets is part of a build?)

First the question, then some background.
We're using Visual Studio 2008, C# 3.0 and .NET 3.5, and TFS 2008 as our VCS.
If I execute this command against our TFS database, to show information about a merge commit:
tf changeset 13469 /noprompt
I get output like this (redacted):
Changeset: 13469
User: Lasse
Date: 12. november 2010 14:06:06
Comment:
Some text here.
Items:
merge, edit $/path/to/target/filename.txt
... more merged files
... some blurb about reviewer texts, etc. nothing important/useful here
This was merged from a different path in the same database, but this information is not available here.
For instance, if I merged from $/path/to/main/ down to $/path/to/branch/, the path to the main project is not available in the merge changeset. (note, please don't say that I'm merging the wrong way, it doesn't matter in this case so I just made it simple.)
So, the question is this: Is there any way I can find out where that changeset was merged from? Which branch it came from? ... and which changeset it originated as in that branch (like 13468? 13462? 13453? ...)
Background
We haven't used much branching and merging so far, except for simple stuff like "tagging" a release.
From now on we're looking at using branching much more active, but this creates a challenge.
Let's say I open up our bug tracker, take the topmost bug, fixes it, and checks it in. This is done in one branch, let's say this is the master branch.
Now, at some point, a tester is going to verify that the hotfix we're going to release has this bug fixed, so he opens up our product and wants to verify before he starts that the bugfix has actually gone into this build.
When we didn't use branching, we simply took the changeset number of the commit that ultimately fixed a case and typed that into the case itself. Additionally, our product was built with a build-number (4th part of version number) identical to the changeset that was the latest changeset that became part of the build.
This way, the tester could simply look at the case, the version number and easily deduce if the build had that changeset or not. If the changeset number in the version number was equal to or higher than the one in the case, the changeset was part of that build.
With branches, that doesn't work. If I commit changeset X on the master branch, but forget to merge, the tester can't simply say "If I run version X or higher, I go that fix" any more.
Note that we're not using TFS work items, so there's no easy built-in way to link commits and cases.
The reason I asked about the TFS history output was that I assume that if I can see that changeset 13469 really came from another branch, and corresponds to changeset 13462 there, and the programmer has noted 13462 on the case, I can say "13462 is now part of the build, because it was merged to the right branch, became 13469, and the build output has version 13470."
In other words, I could build a tool that as part of the build looked at the history of the database and grabbed all the necessary information and stored it in a database, so that I could take cases on our ready-to-test list and compare against the version number of the executable the tester was running, and just list all cases that is both ready to test and part of that build.
So my question is really this: Does anyone have any hints to how we can solve this? Perhaps we're boneheaded and needs to be told the right way to do this, so if you got any good ideas, let me know.
I hear and feel your lament here, as we've run into the same limitation. With TFS 2008, there's no easy way to see that history. With TFS 2010, and the branch visualizer, it gets easier.
If this is something you really need, you could potentially write it yourself using the TFS API. You would have to walk your way back through the various changesets for the files. It would be relatively straightforward to code:
Get merge changeset
Get prior merge changeset
Determine merge source from the first changeset
Get history for the file between the dates of the two changesets.
I've done this manually before, but you could either do this in C# code, or, alternatively, write a PowerShell script to do this.

Darcs conflicts

I installed Darcs a few days ago and have a doubt.
I am the only programmer and I usually work on two or three instances of the application, making new feautures. The problems cames because this instances modify the same source code file, so when I finished them and send to main repository they make a conflict.
Is there any way to deal with this? Can I write the same file in multiple instances without making conflict when pushing to main repository?
thanks
First of all when changes occurs at different places of the file there is generally no conflicts when merging. When two patches can be merged without conflicts one says that they commute. In your case it happens that you've modified the same part of the file in two different branches. In this case darcs don't allow you to "push" the second patch that makes the conflict.
There is two ways to resolve such a confilct, but you have to start to locally merge the both patches to get the conflict in your working repo. To do this just pull the patches from the main repository. Then you have to edit the offended file and resolve the conflict.
The first way is simple and the prefered solution, you have to "amend-record" the patch that is not yet on the main repository (look at the usage of the "darcs amend-record" command).
The other solution is to record a resolution patch, by calling "darcs record" and then pushing both the conflicting patch and the resolution patch. This solution tends to complicate the history and can make some later operations longer. However when the branch has been heavily distributed this solution becomes needed.