Gerrit revision workflow: merge conflicts and re-approval - gerrit

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.

Related

Multiple Applications Same Trunk? Best Practice help required

I did a check if this has been asked before but the closest I found were questions around a single application with different branches for clients.
What is the best strategy for handling multiple applications in version control? Say I have 5 completely separate applications that can require changes at any point. Do I put them all under the same main trunk (origin/master if you will) then branch off as required or should they all get their own trunk?
Let me know if it's not described well and I can add more information.
You should see the Branch strategically:
When should the team add a branch?
You should create branches in the following situations:
When you must release code on a different schedule/cycle than the
existing branches.
When your code requires a different branch policy. If you create a
new branch that has the new policy, you can add strategic value to
your project.
When functionality is released to a customer and your team plans to
make changes that do not affect the planned release cycle.
You should not create a branching for each user story because it
creates a high integration cost. Although makes branching easy, the
overhead of managing branches can become significant if you have many
branches.
In you scenario, It's based on how do you want to manage the applications, different schedule/cycle ... then you need to track in another branch as David mentioned above. And if the size of applications are very large, you can even version control them separately in new team project.
This article for your reference : Branching and Merging: Ten Pretty-Good Practices

How to do a Feature Branching Strategy with TFS

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.

TFS checkout lock best practices

I'm having difficulty convincing others in my organization to stop indiscriminately locking files on checkout. Any ideas where I can find an "official" document explaining why a checkout lock should be used sparingly? Microsoft recommends:
As a best practice, use the Lock type option with discretion and
notify your teammates why you are locking an item, and when you plan
to remove the lock.
but does not go into any details.
Anything that I could point to would be very helpful.
Although I don't have an official Microsoft source, I'm an MVP in Application Lifecycle Management, so hopefully that's enough to make this compelling. :)
Locking text files (i.e. code) on check-out can be a massive impediment to productivity. I've seen it myself when I was working at a time a co-worker wasn't, and they had an exclusive lock on a file. All of a sudden, it's thumb-twiddling time. It's even worse when you're trying to troubleshoot or fix a time-critical issue.
The most common reason why people want to lock a file for exclusive editing is because they don't want to have to perform a messy merge later on.
That is usually symptomatic of one or more things:
The files being exclusively locked are too big (one file with lots of classes in it, a "god class" that does too many things, etc). The resolution for this problem is to refactor code into smaller, more isolated classes according to the Single Responsibility Principle. Or, if you absolutely must, and you're working in the .NET world, abuse the partial keyword to split the same class up across multiple files, although I want to go on the record and state that every time I see this in a codebase it makes me cry a single tear of infinite sorrow.
The files being exclusively locked are in the midst of major, long-term refactoring. The solution here is to isolate major changes within branches, with frequent reverse-integrations of changes from the trunk back to the branch.
The person doing the change just doesn't like merges. I can't help you with that one. If you're holding onto code without committing it for a long enough time that a merge is going to be painful, you're not committing your code often enough. If you're not committing your code because it's not done yet, but the change is ongoing and you don't want to interfere with others' work, then you're not using branches properly.
Can there be times when exclusive locks against code files are good and useful? Probably, but I can't think of a problem that it addresses that can't be addressed by using other, more appropriate source control features.
Use Local workspaces if you can, since they don't enforce exclusive locks.
For me exclusive locks have become usefull when I check-in changes in *.sln or *.csproj files. Otherwise problems arrise when concurrent check-ins are performed, since VS appears to cache these files in memory without saving to disk.

App versions duplication

I have a problem, I have several versions of the same application but the process of duplicating and managing several duplicate applications is becoming very complex, each copy gets unique features by client demand.
What methods are used to simplify this process?
Do I need to have detailed documentation about every App?
I'm trying to separate the code by modules and had them according to the clients demand, am I on the correct path?
Sorry for the bad English, any question just ask, I'm always online.
This can be managed in your code revision system. Git and Mercurial allow you to manage code as "change sets". You could have a branch for each client, and have a main branch (trunk) where you add features for everybody. In the client branches, you add feature sets for individual clients. If you want to merge them back to the trunk, you can. You can also merge from the trunk to branches.
Of course, it's important to develop in a modular way in order to facilitate this approach. Also, unit tests speed things along when you have to merge.

TFS branching, what are the advantages

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/

Resources