We have a development branch where the developers check in their workspaces when the a task is finished. They label the check-in. Let's say 3 developers, with labels 1, 2, and 3. Now I want to merge just Label 1 and label 3.
My question is, won't label 3 have all the code from label 1 and 2, also?
It seems to me there is no good way to omit label 2 from the merge.
You are correct, labels include a crosssection across the codebase (though since they're scoped they might not include all files technically). The only way to merge Label 1 and 3 is to look at the respective change sets and select the ones to merge, this process is called cherry-pick-merging. If the changes are neatly combined into a set of consecutive changesets, then this might work.
You can look at the Changeset number that belongs to the files you want to merge in that label (there might be multiple changeset versions associated to a label) and merge the specific changesets.
Relying on cherry-pick-merging is dangerous, since it can be very hard to actually merge two changesets without taking additional changes that happened in between. Either you'll accidentally take too much into the target branch, or the changesets rely on changes in other changesets which you might not be considering to merge.
Unless the team is fully aware that the changes are going to be cherry-picked and develop with this in mind (shelving, checking in working features as single changesets, applying design patterns to check in separate modules that can be easily merged with existing functionality), then it's safer to merge up to a specific changeset or to use feature branches.
Another technique to selectively 'merge' features is to put feature-toggles in your code. Essentially allowing you to release feature 1+2+3 with feature 2 turned off.
Related
I'm trying to propose a new branching strategy for our company and I'm wondering if there might be any edge cases that I haven't accounted for with what I've come up with.
First, Here is our current branching strategy:
Each team has their own development branches, Team 1 and 2 are very small so they do not have a separate QA environment like Team 3. Each Team merges their changes up to Main and back down to their Development branches.
Currently I'm on Team 3, and the strategy I'm looking to replace is specifically under Team 3's section. We are cherry picking changesets from Main to INT to QA to Dev and then all the way back up again. There are no full branch merges and I'm starting to believe that every merge we do is a baseless merge due to the fact that we just cherry pick.
What I'm trying to do is eliminate the need to constantly cherry pick changesets and go back to merging entire branches, here is what I've come up with:
For long running features we will create feature branches and dev will be used to work mostly on bugs and User Stories that are meant to go to production in the next release.
There is no development done in the QA branch, we will only be merging changes up to QA from DEV when they are ready to be tested.
Once all of the tests are passed we will merge to Main and create a version branch off of main for the next release. The version branches will allow us to have a clean branch to perform hotfixes since we have multiple teams merging to main.
The hope is to utilize feature branches and shelvesets as much as possible to eliminate the need to cherrypick changesets and hopefully reduce the crazy amount of merge conflicts we are currently having.
Does this seem like a sound strategy?
Branching per environment is a generally bad practice. You should be building once, then deploying that build through a pipeline of environments. Every time you merge code and create a new build, you're effectively throwing out all of the testing you've done and starting from scratch.
Isolate features under development behind feature toggles. As each feature is considered 'done', merge it into Main, which starts your QA cycle. The other teams should then merge back from Main to their feature branches, in order to continue developing against the same codebase.
If a feature is deemed not-ready-for-production, disable it via the feature toggle, then you can still release the features that are ready. The later you integrate your features together, the higher the chances that someone misses a bug. Having features integrated-but-disabled helps you prove that, at the very least, the disabled feature isn't breaking anything else. It may not work right, but at least it's not breaking the application.
As this model becomes more natural to the teams, you can drop the feature branches entirely and just work right off of trunk.
More reading on feature toggles.
I have some business reasons for wanting to do this but I won't get into those. Basically I have a Team Project with a single branch(I know this is bad) that I have been working on for 6 years now. It has a large number of change sets. I would like to merge first couple thousand change sets into a single one. Is this possible?
All the information on merging change sets seems to be focused on multiple branch situations.
Which you mean is more likely changeset compression. Just like using git squash commit command to clean up local commit histories.
Unfortunately, this is impossible. For now TFS can only merge continuous changesets or single changesets. If this can be done how to handle the changeset history.
TFS to merge multiple, non-continuous changesets.
Thanks for the feedback on this idea. We have reviewed this feedback
and determined that we will not be able to complete this suggestion in
the foreseeable future.
Matt Mitrik TFS Program Manager
You may have to create a independent branch for handling this situation.
We are considering using Gerrit for the large project. At this point it would be interesting to know how people are dealing with merge conflicts of approved changes.
Imagine, that many changes of different size are pending revision simultaneously, and they are being reviewed and verified gradually. Since some of them might be modifying the same piece of code, the conflicts are inevitable. It is not a problem if "integrator" accepts patches manually in a simple workflow, small conflicts can be resolved on the way, but with Gerrit things are different. When the change has been reviewed and approved, in case of merge conflict, as I understand, it will need to be rebased by the author and pushed for revision again, in which case revision process starts again. In the relatively active projects, with more than 50 external contributor commits per week, this might turn into nightmare, if revision of the same patch might be required to be done several times due to merge rejection after each approval and submit, which seems to be not efficient.
Questions:
Am I correct that Gerrit is not a way forward for the large and active stuff where the large number of merge conflicts is expected?
Some merge conflicts can be trivial, is there a way to resolve them without the need of bothering author to recommit the change?
If the change needs to be backported to stable branch(es), I guess the separate change for each branch needs to be pushed for revision, even if the cherry-pick is clean.
General comments about your Gerrit workflow experience are also welcome.
Gerrit is used by some really massive projects, such as Android and the related bsp, kernel, etc repositories. These projects get way more than 50 external commits per week. I think Qualcomm will have several thousand commits in about that amount of time.
There is a setting in Gerrit to auto-merge trivial conflicts. This can be set per-repository. If this option is set, the change is merged in based on your submit strategy (cherry-pick, merge if necessary) after the change has been reviewed and verified and a user presses the 'Submit' button. The best documentation I could find for this is here http://gerrit-documentation.googlecode.com/svn/Documentation/2.3/cmd-create-project.html#_options under the --use-content-merge option.
Yes that is typically how we do things. There are other options (bypassing review, merging branches, etc), but cherry-picking to the needed branches and reviewing works well.
We want to keep our history clean and understandable, and therefore reasonably linear. So we have configured Gerrit to use only fast-forward merging. The only visible merges are for release and support branches (we're using git-flow) which makes things much easier to understand.
However, we have the trivial-rebase plugin installed so that previous review status is automatically applied to the rebased change. This happens regardless of whether rebasing is done in Gerrit (using the Rebase button) or by the developer rebasing locally and re-pushing the change.
In our experience, merge conflicts are actually less common in a large project, due to the much larger number of source files involved. We have around 16,000 files in the repo and 30 full- or part-time developers, so the probablility of editing the same file is quite low.
In any case, if two developers are making changes to the same part of the same file, they really should be talking to each other. If the project architecture requires frequent changes to the same file (eg a registration table of some kind) the architecture needs to be redesigned, to use something like dependency injection, or to generate that source file automatically from fragments as part of the build.
When we hit a merge issue at our company, the developer rebases and pushes to gerrit. If the merge was minimal, he's allowed (by convention) to LGTM the rebase and submit.
We are still debating if/when developers should rebase when updating patchsets. The UI gets confused when comparing between patchsets when the parent changes.
I'm using it for a few weeks after using mercurial for a couple of years with a feature branch merged into default mode and I'm hating gerrit. I find myself with more overhead solving trivial conflicts that are solved automatically by merges on mercurial or git in non-gerrit mode. Then everybody uses the argument android uses gerrit ergo gerrit is good and should work for everybody.
Our Solution is big, with many Projects and files. Our branch has about a dozen changes, but the files changed are spread confusingly across the Solution.
Conveniently, TFS can compare two branches and show you just the dozen changes. This is handy to get your head around just what changed and ignore the rest.
However, from that dialog, I do not see a "Merge" option. As a result, in order to merge the dozen changes we still need to spelunk through the Solution.
Is there an easier way? Surely there must be.
Normally you would merge an entire branch - the TFS engine is clever enough to only change what has actually changed.
I am pretty new to TFS and source control. I unable to understand the advantage of branching. Since i can do the same stuff by creating 2 folder main and development, when I am done with development.I can merge the code using any diff tool with the main branch.
Then whats the point of having branches ? I know there must a huge advantage but i am unable to understand.
(UPDATE: TFS now supports git for version control so the rest of this answer no longer applies)
I would google branch-per-feature.
The main advantage of branching is that you can work on a feature and not be interrupted by anyone else's work. When you are ready, you can merge and see if many features work well together or not. This is usually done as the feature is developed but for small features can be done once the feature is complete.
The advantage is that you have a clear history of what you did to implement something. Without branches, you would have a whole lot of commits mixed together with other features' commits. If QA does not pass a certain feature, you have your work cut out for you to put together another build using just the commits for the other features. The other alternative is to try and fix your feature so that QA passes. This may not be doable on a Friday afternoon.
Feature toggles are another way to omit work but this increases the complexity of code and the toggles may themselves have bugs in them. This is something to be very weary of and see how this became an "acceptable" work-around.
Branches are also used to track changes to multiple versions of releases. Products that are consumed by multiple customers may be in a situation that one set of customers is using 1.0 of the product while others are already on 2.0. If you support both, you should track changes to each by branches that are designated to them. The previous points still apply to developing for these branches.
Having said that, TFS is not ideal at branch-per-feature for a number of reasons. The biggest is that it does not support 3-way merges - it only has what is called a baseless merge. The way history is tracked, TFS cannot show you a common ancestor between the feature branch and where you are trying to merge it to. This leaves you potentially solving a lot of conflicts. In general, a lot of people that use TFS shy away from branching for this reason.
3-way merges are great because they will show you what the common ancestor is, what your changes are and what the changes in the other branch are. This will allow you to make a very educated decision on how to resolve a conflict.
If you have to use TFS, I would suggest using git-tfs to be able to take advantage of 3-way merges and many other features. Some of them include: rerere, rebasing, disconnected model, local history, bisect, and many many more.
Rebase is very useful as it allows you to alter a feature to be based off of another starting point, omit commits, squash commits together, split commits, etc. Once ready you can them merge into an integration or release branch, depending on the workflow you decide upon.
Mercurial is also another one that may be easier to use, but will not be as powerful in the long run.
If you have the opportunity, I would highly recommend moving away from TFS for source control due to a lot of limitations when compared to modern day DVCS.
Here is a nice set of guidelines to follow if you want to effectively manage branching/merging:
http://dymitruk.com/blog/2012/02/05/branch-per-feature/
Hope this helps.
There is a lot of information to read through, but there is TFS Branching Guidance located here if it helps at all - http://tfsbranchingguideiii.codeplex.com/