(Note: This question is not specific to Subversion - I'm just using it here as an example.)
I know that the "svn update" command (or whatever the similar command is in other systems) will update your working copy with any changes to files from the repository. I also know that it's a best practice in source control to periodically do an svn update to make sure you've got the most recent set of changes before you ultimately commit (check in) those changes.
An alternative approach to this best practice (maybe it would be a worst practice :>) would be to manage potentia开发者_JAVA技巧l conflicts only at commit (check-in) time, rather than periodically during the period that you're editing the file.
It seems like the best practice is taking a "pessimistic" approach of managing conflicts early and often, vs. an "optimistic" approach of managing conflicts only at commit time and managing all accumulated conflicts at that later time.
Am I stating the intent of the best practice vs. the alternative correctly?
Personally I update my working copy every day when starting work. I find that conflicts are found early and resolved quickly that way.
Yes, it's good to be pessimistic. Earlier, smaller, less comprehensive changes are easier for
- A. SVN's automerges (or TFS's or whatever) and
- B. easier when you the human has to resolve the conflicts.
It depends of course on how many other developers are in the same code and how likely they are to be working with the module you're working on. (I'm currently the only one working my my project, for example. I don't refresh nearly as often as when others are in there too.)
Right, with the rise of distributed version control approaches, there has been more and more of a tendancy to "go dark" as some would say, to go off and work on your own stuff and worry about merging it in later.
Many people, myself included, would say that this results in more conflicts that are more difficult to resolve, since you are essentially operating in a different branch and therefore going in a different direction.
Regular updates makes sure you don't go to far off the path of everyone else, but many other people feel that this undermines the flexibility of distributed version control.
Another way is to work in your own branch, not the trunk. That way, the only merging is done when your feature/bug-fix/whatever is done. No one else will be committing on your branch, so you are safe until you are done.
There is something of a middle ground -- you can keep your changes in a branch, separate from the trunk changes that are in progress. This is super-easy in git and less easy (I would say) in subversion. What this lets you do is pull the changes from trunk regularly without automatically "risking" your local changes being messed up by conflicts with the trunk commits. This, I think, is at the heart of why you wouldn't want to pull updates -- namely, because you're not ready for them. You would see that changes have occurred, though, which is a very good thing. Having your changes on a separate branch means that you can attempt to merge the upstream changes, but if they don't match, you can abort that merge and keep working for a bit on your code until you're ready to really spend the effort to resolve the conflicts.
It is definitely true that the earlier you realign your code to be compatible with the trunk (by svn update or merging in the changes), the easier it is to resolve the conflicts. It is pretty awful to wait until you're ready to deliver changes to discover that everything has moved from under you -- you'll spend much more time digging through logs, trying to figure out what the changes are and how you can properly apply them to the code you already thought was fine, and then you need to need to retest your code with the new changes! If you had been merging all along, you would already have tested this build.
- update each time you sit in front of the PC
- update before each commit
=> years of trouble-free SCM usage.
Update as often as you feel necessary. At least every morning. And, every time your team mates tell you to. Every time you otherwise know someone committed something in the area you work.
Before you commit. Never ever commit something until you have updated to the latest repository version and be as sure as possible your commit doesn't break anything.
Sounds about right. Of course, if you commit often instead of waiting until you have tons of changes, the two approaches amount to the same thing.
I think it all depends on the number of dependencies in the code and the number of developers working on the same code at the same time. If you have few developers working on that same code then you can go a longer period of time without "merging" with the code from the repository. I personally like to wait until the end of my development, so long as it's not going to take me weeks to finish. If it takes you weeks to finish you should split up your functionality into smaller pieces and use a more incremental approach which allows you to check in your new code and merge more frequently.
Like mentioned several times above, my advice is similar:
- Update often, as much as possible but at least once a day, and
- Commit often, idem (but of course you must have a compiled/running/tested feature)
The second point is very important as well: as soon as "something" is working, it must be committed, the literature says "don't go blind", i.e., don't keep development on your hard drive for one month until it is perfect (it never is anyway :-) )
This is the basic idea behind Continuous Integration (lots of material on Martin Fowler's site and very clear explanations).
Too last points:
- Regarding "syntactic" conflicts, don't worry about them, they are rare and easily fixed,
- Regarding "semantic" or "architectural" conflicts, it is even more important to discover them as soon as possible, hence the above motto: update often, commit often, merge often (for people using DVCS), and test often the integrated function in order to discover those potential semantic conflicts.
At my previous work, some people in product departments would refuse to update every day (even less several time a day) because they were saying: "the trunk is broken, if I update, I will loose my day". They were right! This is not acceptable! This is why it is very important to emphasize that only working code should be committed (or pushed for DVCS people): to help to enforce this I setup daily builds, which would start at every commit (using the free software buildbot tool but dozens similar tools exist). With on-commit builds and tests, it is easier to unsure that the trunk is not broken; whenever a build or a (simple) test fails, the person(s) who has (have) just committed receive(s) an email and they must fix the problem immediately or revert. And the web summary (called waterfall in the buildbot vocabulary) is here for everyone to see. To summarize, it is really a state of mind to have and a mutual trust to build among developers, but once you've got to this point, believe me, you will never want to come back: developments are faster yet coordinated, and people are happy to contribute to the same code instead of working on their workstation alone for one month! It is worth trying to take this path (IMHO).
精彩评论