I'm working with git flow and a doubt arouse about the master branch. I have development and user acceptance working on develop branch and when I finish the test, I merge the develop with master branch and put into production. My question is if something goes wrong after this merge with master branch, I will not have tested it. What should I do to have the master branch tested? How to ensure that the master is not broken? Is there any pattern?
tl;dr: No, you already tested it.
Details:
In a properly implemented Git-Flow strategy, anything you merge into master should be fully ahead of master 1, so you would never need to test what you'll get after merging into master, as it will be the identical state before and after the merge. (And presumably you have fully tested the branch before merging into master!) The reason this is true is that when hotfix branches are merged into master, they should be immediately merged back down into develop too (or into a release branch if one currently exists). This means there should never be any code that is only on master and not yet in the branch you're about to merge into master. As documented by Git Flow regarding completing hotfix branches:
When finished, the bugfix needs to be merged back into master, but also needs to be merged back into develop, in order to safeguard that the bugfix is included in the next release as well. This is completely similar to how release branches are finished.
And also,
The one exception to the rule here is that, when a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of develop.
Side Note: You mentioned that you are merging develop directly into master, and you can do that if it's working for you, but I just want to point out that typically in Git Flow you use a release branch instead. Doing so enables simultaneous development on develop while you are hardening a release as it awaits deployment. Here's a question that discusses this, and my answer there provides some tips for how to avoid creating release branches in Git Flow, if you normally don't need them.
1 In Git we oftentimes say that one branch is "fully ahead" of another branch when the first branch can reach the tip commit of the second branch. For example, develop is ahead of master if the tip commit of master is in the history of the develop branch. In this case however what we actually mean is that all commits with state changes in master are present on develop, and this distinction exists only because of the --no-ff requirement when merging into master, so it's possible that master might have some merge commits that don't yet exist on develop. Those merge commits do not contain any new state though, so we can say from a practical point of view that develop is fully ahead of master.
From a purity standpoint, my personal preference is to always have every commit on master be present in develop or release before merging into master, so that we can say "fully ahead" and mean it from a commit ID standpoint as well. To achieve this, you can slightly tweak the documented Git Flow by, instead of merging release and hotfix branches back to develop after merging into master, merge master back down into develop. This achieves the identical state but also achieves the "fully ahead" meaning that we like to see in Git. It also means anytime you merge anything into master, you could do a fast forward merge, but we choose to use --no-ff instead to maintain a historical record of when the merge occurred, and exactly what was merged. Using this tweak, the fact that you could have done a fast-forward merge is the proof you need that you don't have re-test master after the merge.
If the master branch changed since you forked the develop branch, you certainly could break master after merging develop (especially if you had to sift through merge conflicts), even if develop was working fine on its own. The way to make sure that master isn't broken after merging is to have good unit tests for master to make sure no existing functionality is broken, and then add and run additional unit tests for develop which test the new feature works after its merged.
Related
I think that it's good idea to build artifact and then deploy it across all environment, test, preprod, prod.
But according to Gitflow we use "release" branches for tests and we merge it to main, develop and delete release branch. So we have "release" artifact and we test it, but as I understand we deploy to prod artifact from tagged main branch. And for me it's strange.
What could be the objective reasons of this?
main <=> prod
The reason for this is simple, however, the usual name of the main branch is master. One needs to have an easy way to refer back to whatever prod contains, because, in the case of hotfixes, you want to branch out from prod, because the issue is reproducible there. It is another matter that there is usually a branch for hotfixes as well.
release branches
Basically, you may have many different things that are being developed at the same time. You probably want to create well-separated partitions of problem-spaces to define your tasks, each such partition would represent a release. So, if you are optimizing some business logic on the one hand and you are polishing the UI on the other hand, then you not necessarily know which one will be released first, so you will have some named branches for those. Having "release" branches is a convention for this. Now, when you are deploying a release to prod, you can merge master into your release branch and perform automatic and/or manual tests. When this is successful, your release branch is merged into your master branch.
Deleting a release branch
Once the work represented by a release branch is successfully completed, it makes sense to remove it after it was merged to avoid wasting storage space on things that are unlikely to change (because they were accepted). Note that if a problem arises with a release later on, you can always checkout the commit hash of the tagged commit that represents the release merge in order to see whether the problem you have seen was already manifesting when the release branch was released.
For our projects have Integration and Master branch. For deployment we cut a RC branch off Integration. Once deploy is complete we create Pull request for RC to Master.
However, now Master shows as 1 ahead because it has a commit that does not exist in Integration. I considered to create Pull request RC to Integration as well, but TFS does not allow it since there are no changes.
Is there a way to avoid this situation with Master? Can behind/ahead only check the code changes and not commits? To fix this I now have to create Pull Master to Integration, and that is a pain for all the projects we do.
Afraid not able to avoid this situation. It's also not possible to make behind/ahead only check the code changes and not commits. Since you are using Pull Request (which execute git merge --no-ff).
To be honest, it's not necessary to resolve Integration branch behind/ahead master.
you can have two mostly independent branches without any problems. The important measure of differences between branches is given by git diff. If this reports no differences, then it's Ok.
You could also take a look at this similar question: VSTS Git: Is it necesary to resolve dev branch behind/ahead master and if so how?
If you insist on avoid the ahead on Master, you may have to create Pull Master to Integration as you have pointed out in the question.
I am setting up DevOps process with TFS and wondering about branching strategy. If I have the following sample branching (image from Guidance: A Branching strategy for Scrum Teams).
I have DevOps process set up (continuous integration and continuous delivery) with continuous integration from MAIN branch (with Jenkins).
How would I handle hotfixes? If developers merge frequently into MAIN branch to verify builds, how do I get the last released code for applying a hot fix? If I were to use Release branches, I would eventually have to integrate hot fix into MAIN branch in order to kick off CI process. However, MAIN branch could contain changes beyond the release.
Please advise on this issue.
Generally a hot fix should gets out from the relevant version on the main branch.
Then need to create a dedicated branch for the hot fix, merge it with the last stable branch.
If it passes the entire QA, unit tests, system tests, etc then merge it back to main branch as the next released version.
you can have a look in the following example when using git the reference is here: git best practice. The source control is not the issue but the main idea. Read carefully the article i believe you'll be able to find what you are looking for.
There are some organization that still working with patches...
I'm not a big fun of this solution, but if this is your case than let me know, because in patches there is a little bit different solution.
It's suggested making all your branches synchronized all the time. When you want to handle hotfixes, you can create a new branch "HotFix" from main. When the hotfixes are completed, you need to merge it from HotFix to Main, and merge from Main to Release.
If you have made any changes in the Release you will need to merge back up to Main in order to finalise the changes.
A hotfix is a patch to released software. If you've got a release branch, creating a hotfix branch off of that is appropriate. After that hotfix is promoted up to Prod, you can then reverse integrate back up the chain to Main. Hotfix -> Release -> Main, and even forward integrate that up to the next sprint, if needed.
Obviously, the answer that you choose depends on your particular requirements; however, typically, you should cut a release from main, and a hot fix from the release branch. Personally, I would say that that code should not go back into the release branch, but be double fixed in a development branch.
The main reason for this is that, once you've released code, that code branch should be locked as it was at release. If you follow this, then you can always go back to a previous state of affairs. As has already been suggested, you may be halfway through changes to a hotfix when the requirement or priorities change; or when the customer reports a bug in the live code. If you maintain a separate branch, you can always access that code.
How to handle this really depends on the release and maintenance strategy or customer agreements you have.
If your release branch happens also to be a maintenance codeline (it seems like it from your description) then create feature branch from it, implement a hot-fix, test, merge back and release a "patch". Ideally you should have CI set also for the "maintenance" branch.
After this you can integrate your hot-fix with main codeline or put the issue on backlog to implement it differently for the future new release.
BTW: Some nice articles here:
https://www.cmcrossroads.com/article/agile-perspective-branching-and-merging
and
http://www.bradapp.com/acme/branching/branch-creation.html
If you are using Agile, then feature branches can be a good option. The only thing is it has to be combined with a ticketing tool like JIRA or AGM. For handling hotfixes in such scenarios, you can have a user story in AGM or JIRA, which upon completion will be merged onto the mainline trunk.
I have a situation where we were working on feature branches against a main development branch ('trunk') and each release cycle, a release branch would be taken from the current development branch.
However, a release was cancelled very late on and instead we were asked to issue the previous release with only some features - after these were all integrated into the main dev branch.
So what happened was the previous release branch was taken as the base of the new mini-release, and we now have to re-apply specific changes that were already made against the development branch. I luckily still have my feature branch and it was never merged. It is based on the development branch, however my branch was taken fairly early on in the release cycle and was not updated by re-merging parent (trunk) changes - so my branch's parent is actually not too dissimilar from the new branch I need to apply it to.
I know TFS has some facilities for re-parenting and baseless merges but what is likely to work best? More importantly if I try re-parenting, can I break my branch or am I safe that I can try things, back them out and try again if there are problems?
My branch is fairly large, maybe 50 changesets applied to quite a few separate modules. I suppose I could try to apply each changeset one-by-one instead?
In my experience, baseless merges are always terrible. In most cases I find diffing and merging the two branches manually via a compare tool (like BeyondCompare) is easier and more reliable than using the TFS tooling.
That being said I would challenge you to consider going to a single main branch. We made the leap (a huge leap for us at the time) but it has paid dividends many times over at this point. The key is being Release Ready:
https://dotnetcatch.com/2016/02/16/are-you-release-ready/
I finished working on a local branch1 and merged it to master.
Now I would like to work on another feature for my application and so I will create a second local branch2, finish to add the feature and merge to master also branch2. This can go on for as long as I need to implement my application with features and until my application is completed.
Suppose now that after all these implementations I would like to make some improvement or change on the topic that was the job of branch1, say the static pages about, help and contact. Is it possible to checkout to and reuse branch1 for these changes or that branch cannot be used anymore and should rather be deleated?
After a while there might be a considerable pileup of old topic branches that I initially may have wanted to keep for these purposes. However these old branches are all outdated, no more a complete reproduction of the master branch as they were when created: is this a prerequisite in order to merge with success?
The branching/merging strategy is yours to decide but you seem to describe a feature-based workflow.
In that case, after you have merged your feature branch branch1 to master, the content/history of this feature is contained in the master branch thanks to the merge. branch1 becomes useless and even obsolete with time so you can safely remove it so that old feature branches don't accumulate in your repository.
If you then look at the improvements you want to add to the functionality introduced by branch1, you can see those improvements as a new feature and therefore create a new feature branch from master to perform those improvements.
How you should organize your workflow is rather subjective and the best strategy often depends on how the project is organized in terms on contributors and how you deploy your changes.
You can use these old branches, but ... you should merge new changes from master before (So you can avoid big merging problems in future). When you need to reincarnate old branch do:
git checkout very-old-branch
git pull ./ master
# do some changes into very-old-branch
git add .
git commit -m 'changes in the very old branch'
# need to merge very old branch with new changes into master again
git checkout master
git pull ./ very-old-branch
git push origin master
But it would be better not to be necromancer and to just create new branch and make changes in it:)
You should take a look on gitflow.
Its a very known workflow for doing such kind of development as you are asking
The full workflow will look like this. In your case you refer to the feature branches (purple ones).
The relevant article is here:
http://nvie.com/posts/a-successful-git-branching-model/
As you can see you keep working on new features all the time and once you done with them you simply merge them back to dev (in your case can be master)