Looking for tips about SubVersion's best practices, branching and the social aspect [closed]
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
开发者_StackOverflow Improve this questionMy team and I currently use Perforce for revision control. We used to submit everything into trunk until one day we needed to add several items into the program, so we created a branch for my boss and a branch for me and another branch for testing. Everything works well until we tried to merge the branches back to trunk. We Visual Studio (VS) and it generates solution files that for some reason, it doesn't work well with Perforce. After a lot of effort, we partially merged the branch into the trunk. I’m thinking to move to subversion. I have Subversion in my local pc and I have no issues with Visual Studio branching and maintenances. I suggested to my boss to move to SVN. While my boss is open to the idea to move half a million of line of code, I need to build a strong case for it. I’m the youngest-recent-grad-programmer, so let say that my ideas need more beef than the others =)
I decided to install SVN in one of our servers and passed the code to it. We are not going to get rid of Perforce anytime soon, but my goal is to kill it in a very slow manner and by perverting my teammates on how easy is SVN to use and I already have one person in my boat.
Since I would be able to configure SVN from scratch, I want to apply the SVN’s best practices. I read the red-bean book and I’m planning to follow their repo’s layout and their backup tips, but I have more questions related to social and branching issues. Below are my questions for social issue,
Is there a way to prevent source conflicts in a social manner? If so, what is the best way to communicate about conflicting changes?
I’m planning to install a CMS into that server as well. So my teammates can write or communicate that they have branches and the like, but I don’t know if there other tools to track the historic health and bugs of our project.
Even though my company practice the flat management approach, how can a rookie like me could convince or enforce social communication to senior programmers without breaking the invisible “senior” hierarchy?
For branching and tagging,
I don’t want other teams to do branching to add a “Hello, World!” code into the program. I want to treat branching as something out of ordinary. Can anyone give me a rule of thumb on when to add create branch? When to merge?
In what case branching a branch is a good idea?
For tagging, my understanding is that tag symbolize a static point of the program ( ie : v1.0, v2.5) is that correct?
If I create a branch and start writing my changes, should my team-mates start syncing from my branch? Or should they still develop in the trunk? Or should they create another branch for themselves?
I apologize for all my questions, but when it comes to revision control, I feel that I’m swimming the gulf of Mexico during the BP cleanup.
In no particular order:
- Your best defense against excessive conflicts is a well-designed project. DRY code that separates concerns makes it possible to implement changes without tearing apart the entire project. If a change in core code requires updates in 50% of your source files, conflicts will be common.
- When you make a change, tread lightly. Don't refactor a function that isn't part of your change requirements just because you don't like the look of it. It's perfectly reasonable for two developers to make changes to the same source as long as they're working on different concerns. SVN merging works very well as long as you're not trying to merge the same change implemented twice by different developers. Make refactoring part of a change plan.
- Evaluate tools that sit on top of SVN and give your team another perspective on code changes. Trac and Fisheye are examples.
- Judiciously use hook scripts to send out notifications or update a project wiki. This works better than reminding people to send notifications manually. Keep in mind, if you notify too often people will ignore your notifications.
- Consider continuous integration so developers are given immediate feedback on their changes. Hudson is a nice tool that integrates with SVN. Continuous integration tools sometimes include integration to social tools as well. Hudson's build notifiers are examples.
- Branches work well for changes that don't fit in a single release development cycle or when the changes will break the project for the rest of the team (always branch versus wait for weeks to check in). Opinions differ on when to branch. Just be sure your team agrees on an approach so the results are consistent.
- Tags are used differently by different teams but by version number or release sounds reasonable.
- Only the developers working on a branch's features should work in that branch.
- Merge early and often from trunk to branch. This makes the final merge back to trunk much easier.
- As long as you're making a change, evaluate distributed version control systems like Git or Mercurial before you make a decision.
I actually like Perforce, and I think Perforce does a better job at tracking merging than Subversion, but there are a few issues with Perforce and one is its integration with third party tools -- especially VisualStudio. And, that (plus the fact that developers don't really like it all that much) has made it hard to recommend at many sites.
If you're going to make a case to start moving to Subversion, I'd say your best tactic is the integration into your current tools, and the fact that Subversion has more integration points with other third party tools.
Here are some points I'd hit:
- Subversion's integration with VisualStudio is cleaner and simpler.
- Subversion integrates into more third party tools. Part of it is that Subversion is simpler and cleaner. There are no views. You don't have to mark files for editing. You can create a working directory anywhere you want. Part of it too is that Subversion is more popular, so most third party tools realize that if they want a shot at being used, they have to integrate with Subversion.
You can also point out the similarities between Subversion and Perforce, and that features you like about Perforce are in Subversion:
- Both Perforce and Subversion practice interfile branching. That's Perforce's term for using directories as branches.
- Both Subversion and Perforce use change lists/change sets (whatever term you use). In Perforce, change sets are in addition to the file versioning. In Subversion, the repository revision is the change set.
- Both Subversion and Perforce practice atomic commits.
Best practice is looking beyond the tools, especially the version control system. You'll need defect tracking tools, a continuous build system, and a release repository. Best practice is about communication and trust:
- Do you trust your build system?
- Can you reliably create the build over and over?
- Do you know what went into your build?
- Does the QA team know what to test? Do they know what defects were fixed in a particular build?
- Do the developers know what defects were found?
- Do your developers know what features they should be adding, or the defects they need to fix?
- How do you know if a particular build has been approved for release?
If you can show how you plan to answer these questions, you can build a strong case for your plans. Show how Subversion fits into these plans. Show how it works better with VisualStudio and how it will make the developer's job better.
I highly recommend that you look into Nant if you're building .NET apps. (I am assuming that you do your official build by opening up VisualStudio and hitting F5 or whatever does the build. If you're not doing this, you're way ahead of 90% of the VisualStudio sites I've seen). You can then use Hudson as your continuous build server. Hudson can also act as a release repository too since it can store the built artifacts. This means that people can easily access the official build.
The great thing is that through Hudson plugins, you can mark which builds are official releases, tag builds, etc. It integrates with Jira, Track, Bugzilla, MantisBT, and dozens of other defect tracking systems. It also works with Redmine which includes a defect tracking system, message board, charts, wiki, etc. That's another tool you can use.
The idea is to define the issues, define the solutions, and show how tools like Subversion can fit into them.
Remember that Best Practice isn't just a single methodology that can be repeated implemented over and over again. It's a way of understanding your project. It's making sure that everyone knows what is going on. It's making sure that everyone has complete trust in the process. It's making sure that you know exactly what is going on in your product.
There are all sorts of hints that people repeat over and over about best practices: Repeatability, catching defects early, automating everything, agile development, taking small bites instead of making massive changes, not breaking the build, etc. But, these are merely means to the end. Keep in mind the big picture.
I also find that it is absolutely important to sell the tools to the people who are using them, and that maybe what you see as a great advantage isn't so great for a developer. Developers want to be able to get the file they need, do their modification, and check in their change. They don't give a damn whether it is Perforce or Subversion or CVS. They don't care about changesets or atomic checkins. They don't care about Interfile branching. They simply want to know they're looking at the right file, and that when they make a change, it is delivered. If you're going to sell Subversion, you tell the developers how it will improve their process and make their lives easier.
Keep things simple too. A light hand with SCM is best. If people find the process arduous, they'll do their best to get around it.
Couriosity just sparkles out of your questions ;) - try not to get lost in doing/thinking too many things at a time.
So to answer them questions ..
1. Is there a way to prevent source conflicts in a social manner? If so, what is the best way to communicate about conflicting changes?
No mainstream Source Control Software that I am aware of brings a well implemented notification about possibly conflicting work before such work gets integrated into one another (merged). Apart from DRY and separation of concerns, as Corbin March mentioned, I think that "update daily", "commit early, commit often" and "branch late" (see below) are bread-and-butter practices.
Commiting early has its limits though. Syntax-Error Free and depending on your bugtracker / task-organizing system, only complete work-artifacts should get committed.
There really is not much social skill required to ask for help when you encounter a source conflict that you can not solve yourself, IMHO.
2. I’m planning to install a CMS into that server as well. So my teammates can write or communicate that they have branches and the like, but I don’t know if there other tools to track the historic health and bugs of our project.
This sounds like a pretty "distributed" approach. Not as in location but as in responsibility. You are creating software products and do some sort of release occasionaly do you? Therefore responsibility should increase and focus the further "downstream" it gets. The only branches the whole team should be familar with are the release branches for fixing things (no features there) and your mainline (trunk). All other things, feature-branches, integration branches, "backup" branches, private branches etc. are to be managed by those requesting or enforcing them. Why should you or colleague "A" care that colleague "B" branched the mainline to develop his experimental feature in peace? Colleague "B" by developing something groundbreaking, has the responsibility for his branch and to keep it COMPATIBLE with the mainline. Either constantly by merging changes from the mainline to his branch or before reintegration of his new code. Research integration branches if you want to know more.
As for the toolset .. Any bugtracker that is well integratable within SVN (Jira, trac, mantis, redmine ..) should do the job. But I do not understand how this part of the question relates to your conflict problems.
3. Even though my company practice the flat management approach, how can a rookie like me could convince or enforce social communication to senior programmers without breaking the invisible “senior” hierarchy?
I think you overestimate the amount of communication that is required in a well oiled workflow. What you mention indicates that you company lacks a workflow where you fight conflicts at the root (see 1. and 2.) which in your case makes more communication necessary, possibly creating unnecessarily high overhead. Having a CMS or some kind of "I work here" flagging-system might still be worthwhile to persue.
You indicated that some senior developers do not like to talk or socialize so much even in conflict cases where better they should. Don't let them get away with this by doing merges for them. Merges should be done by branch-owners. When conflicts aris, at least one of the conflicting sides has to decide upon the changes. Ideally both sides sit down on the diffs together but not a third party initially uninvolved with the source in question. Failure in conflict solving (selecting the wrong changes) might result in build breakage or, even worse, undetected bugs. People need to be aware.
Acting as mediator is not easy if senior developer "A" (merging mainline changes into his branch) curses about conflicts but does not talk to senior developer "B" whose mainline changes are in conflict with his. If it is not like crossing a line for you, try to talk to developer B and convince him to approach A to get the conflict resolved faster and less error-prone.
But again in the end it is developer "A"'s responsibility, not yours. You seem to give an example already to your co-workers. If that is not enough, try to carefully point out that not enough communication was the reason for a broken build when it happens. Maybe talk to one senior in private about your thoughts, be open but not accusive. A "we could to better" sounds nicer than "You guys are doing it wrong". And for you as a younger professional, sentences like "I would feel better about my code if you tell me when it conflicts with yours" might be more appropriate than "You should ask for a second pair of eyes from the right person when you get conflicts", even though the later is more straightforward.
If all this does not help, you might consider talking to your boss or team leader about the barriers you encounter. If he is not a fool he/she will listen.
For branching and tagging
1. I don’t want other teams to do branching to add a “Hello, World!” code into the program. I want to treat branching as something out of ordinary. Can anyone give me a rule of thumb on when to add create branch? When to merge?
For Merging see Question 4. below.
For Branching: You are perfectly right with trying to have as few branches as necessary. Branching comes at a price. Complexity, merging overhead etc. I tend to stick to "branch on incompatible policy". What policy you ask? Each of your main branches should have a set of documented rules attached to them.
Examples:
- tag-2.0.4
- no commit allowed
- release-2
- only fixes for existing features allowed
- checkins should have release-quality
- trunk
- must compile/validate
- Extending developed API allowed
- renaming and deleting API prohibited
- only complete bugtracker-issues
- receives merges from release branches
- feature-apirefactoring
- may alter the developed API and break compatibility
- pulling merges from trunk is feature-developers task
You see there is 3 fictive branches and one tag. The "feature-apirefactoring" is an example for a correctly applied "branch on incompatible policy".
Branches should be used to mitigate risks and increase efficiency by splitting different kinds of development activity. The branch policies individually define what development and risk potentials are acceptable. Want your trunk to be more stable? Define a new policy "Do not introduce W3C validator warnings". If groundbreaking development work has to break this rule for the sake of efficiency or to provide a fast proof-of-concept (we hack away first and cleanup later) it is a good candidate for its own branch.
Whenever you or a co-worker feels the urge to break a rule because it would be more simple or safer to NOT comply to a given policy, you are on a good way to discussing a branch-creation.
2. In what case branching a branch is a good idea? answered above I think :).
Some examples I encountered:
- Branch stable branch from trunk when release gets prepared (no new features)
- Branch integration branch from feature-branch when integration is too complex and time consuming
- branch a "special edition" release branch from an allready stable release that has some exclusive features or certain possibly unstable differences for a special customer.
- branch a translation-branch from your trunk that gets only wording changes and therefore can not break
There is dozen more. The more fine-grained your policies, the more exotic your branching can get.
3. For tagging, my understanding is that tag symbolize a static point of the program ( ie : v1.0, v2.5) is that correct?
Yes. For subversion it can be described as an alias. "/tags/1.7.2" could be the state of the project as it was at revision 30932. You can note down the revision number when a certain release was ready and compare your newer sources to it or create a checkout of this older state. Or you can use the easier to remember tag-name.
A tag in subversion also is nothing but a branch that does not receive any commits.
4. If I create a branch and start writing my changes, should my team-mates start syncing from my branch? Or should they still develop in the trunk? Or should they create another branch for themselves?
Short answer: When ever you are uncertain, use the trunk and do not merge (sync, push, pull) at all.
Long answer: In an ideal world there would be no need for branches as all developers get supplied with all changes the team checks in, instantly when it happens. In an ideal world these changes would not conflict with any developers own uncommitted work. Whatever a developer checks in inside my ideal world is also completely correct, free of flaws and glitches.
Alas, a programmers world is not perfect. Therefore you create branches to shield yourself from changes your co-workers do or you isolate your changes to not stain a clean mainline, sometimes both.
The direction of the flow of change (Your co-workers pull from you or you pull from your co-workers) depends on the riskyness expected in a branch. How much risk would it be to "pull" (merge) changes that get checked in to a release-branch? Looking at the policies defined above it should be bugfixes only. The risk seems low. For most release-branch scenarios merging from them into the turnk is absolutely necessary as you would have to refix the bugs by hand before the next release-branch gets created from your trunk.
How much risk of breaking your own precious work, or having to alter your own code, would lie in merging changes from feature-apirefactoring into your checkout of the trunk? You could develop new functionality, enhancing an api-call your co-worker owning the feature branch decided to replace with a completly new implementation. This might kill the mood.
The Tofu Scale
I think it was the smart people from perforce that first mentioned the "tofu" scale. (you could google it or read these slides http://www.perforce.com/perforce/conferences/us/2005/presentations/Wingerd.pdf).
Additionally to a policy per branch, you estimate their "firmness" and via that their position on the tofu scale.
A feature branch is "soft" as it is in constant flow, not well tested and mostly far away from any paying customer's eyes. It is therefore also more able to absorb changes. If things break you want them to break in "softer" branches.
Your trunk would be "medium" as it is not release ready but better tested than some remote feature branch. (let alone because more developers check out the trunk than feature branches). It might distract developers if huge compatibility-breaking changes appear in the trunk without proper integration, but normal sized checkins can soak in quite well.
Release branches are among the "firmest" branches as they are well established, tested and sometimes only hours away from productive usage. If you break this "slice of tofu" it is a bigger pain to stitch together. On the other hand you have a better feeling about what you are delivering in this branches and higher confidence (if not unit-tested proof) that it works well.
You should order the branches by their position on the tofu scale. Soft to the bottom, firm at the top.
- tags (very firm)
- release-2 (firm)
- trunk (medium)
- feature-apirefactoring (soft)
The best practice saying is "Merge down, Copy up".
Even better "Merge down, Copy up at stable state"
Merge down:
- All commits that went in release-2, you should merge into the trunk as often as possible. (Bugfix-committer should do this)
- All commits into the trunk, including merged down fixes from release branches, you should merge into your feature-branches as often as possible. (Feature-Owner should do this)
"Copy" up:
- When work in a feature-branch is complete "reintegrate" it. Use the SVN --reintegrate merge or do a last merge down into the feature branch and then copy all relevant files. --reintegrate merge is highly recommended.
- When you decide it is time to stabilize your trunk and target a new release soon, you branch your trunk into a new "release-3" for example. In SVN branching is copying and vice versa.
- When your release is bugfixed, tested and working well enough you again copy up into a new release tag
Last but not least read up this best practice document. Again by perforce guys ;) http://www.perforce.com/perforce/papers/bestpractices.html
Search stackoverflow or have a look at my profile for more SVN-releated Q & A.
Oh and knowing how you succeeded in your rightful ambitions would be nice.
Have a nice weekend
C
While Subversion is a nice tool at what it does, its strong point certainly isn't merging. That is mainly because subversion has no mechanism that tracks merges - you cannot see in the history where something was merged.
So my suggestion is to either use a version control system that properly supports merging, or don't do it. You'll save yourself a lot of pain. Git appears to be most popular at the moment (and there appears to be Visual Studio integration, and a port of tortoise svn for Windows). However, Mercurial, Bazaar and the like are also viable choices.
These tools may be slightly more complicated than svn at first, but if you want to branch and merge on a regular basis, it'll be worthwhile.
But even with those tools, merging gets hard if a branch lives long enough. No tool in the world is going to help you with that.
So think hard if you really need to branch, or if you just do with and live with SVN (or perforce).
Not branching and merging is probably easier than it sounds. What you should do is setting up continuous integration (someone already mentioned Hudson) - this will let everyone know when something breaks the tests. If you have that in place, different members of the team can work on different features just fine, even on the same branch.
Continuous integration will work much smoother than fighting with branches and merge tool; though you should have a decent test suite.
If you think about branching for a "big change", don't. Instead develop the big change gradually on the trunk. This will be much easier than trying to integrate a heap of changes after a few weeks.
Finally, if you want to experiment, just branch away, no matter what the tool. Experimental branches will almost never be merged back to main development, anyway ;-) (And yes, I speak from experience)
The only scenario for which you really need advanced branches would be if you have to develop and track several versions/configurations of your product at the same time. In that case you definitively should go for an advanced version control tool.
I've never used perforce, so I can't comment on the differences (better or worse).
However, if you're a Visual Studio user, there is a lot of support for svn-integration (check out ANKHsvn (even works with latest vs2010) and TortoiseSVN a Windows client and shell extension.
Many great points have been made here, but I cannot stress how valuable a Constant Integration server is, which is easy to setup using something like CruiseControl.Net, which has tools like CCTray to accompany it...
Anyway, I diverge, and while this isn't the perfect answer, it should provide some food for thought.
I understand what it can be like to try and work out revision control - I love the analogy, I too sometimes feel like that.
These guys have got some really good advice already, but if you'd like something more practical - maybe with a demonstration - I'd recommend checking out our Subversion webinars. We are covering branching and merging in late January, with an introductory class followed by a more advanced session. This could be a really useful tool if you still feel a bit muddled, as there will be a practical demonstration.
We're also doing a 'Subversion Administration Best Practises' class too if this sounds like something you or one of your team might like to sit in on.
Here's the link: http://www.wandisco.com/webinar/subversion/training for you to have a look, and if anything takes your fancy sign up - it's totally free and we've tried to do classes on topics that developers have asked for. Hope this helps!
Lesley
精彩评论