views:

193

answers:

7

I've always wondered how an actively developed common library used in two or more projects should be stored in version control. I imagine it can be handled differently than a third-party library, since an in-house library is more likely to get hot fixes that should be distributed to many of the projects in version control.

Should its binary files be imported into the projects that use it as it is updated (pretty much like a third party library), or could its source code be checked out together with the projects? Is it possible to have references to other version controlled paths in Subversion or other version control systems?

I'm working in a project now that has common libraries that reside elsewhere in Subversion (and used in many projects) checked in with the project, so any changes made to them in this project are not reflected in their "real" repository. I'm going to suggest some changes to this, but I would like some thoughts on what the best practice for handling these common libraries is.

A: 

If using Subversion, I would use svn:externals, which allow you to create dependencies of one Subversion repo to another.

cpharmston
A: 

Subversion does allow you to have references to other paths, through the use of the svn:externals property.

That said, often you will want a little bit more control over the state of a project than just "take whatever is in the shared library head". In that case, I would suggest committing the compiled library binary into each of the other projects that uses it. That way, you have control over deploying the library to each of its clients.

Avi
+1  A: 

Yes.

Separate reusable "sub-libraries" into separate projects early and often.

Look at open-source practices: most things are many small projects that are pieced together.

Create many small projects.

Avoid checking in binaries. Again, follow open source practices. Keep source in subversion.

Build binaries and put them on a "project share" directory separate from the source.

S.Lott
A: 

The right tool to handle this problem is Maven. Originally developed for Java, it can be used for any existing programming language.

Maven creates a repository on your computer where all of the modules reside. You can also create a public module repository, allowing other people download modules from there.

Each module has a list of dependencies that are automatically resolved (read downloaded). At the build stage of the project, an appropriate for your programming language plugin will put all of the dependencies to specific places to make the source code see them.

Maven is a great multifunctional tool, but It is very hard to master, that's it's only minus.

Max
+1, although I am in doubt this can in practice be used for other languages. And if it can, do maven compatible repositories exist for perl, python, ruby, php, c#, etc?
flybywire
A: 

We keep the code from common libraries in SVN in their own project folders. We also commit the binaries to another "project" folder called Dependencies. We use svn:externals to bring the needed references into projects.

Steve O.
+5  A: 

As others have already mentioned, SVN's externals are a good way to do this. Through them you can reference other parts of your repository (or other repositories, too, FTM). A project can reference the head of some other (library) project or some branch or tag. The latter two make for stability, the former one for always being up-to-date with the library.

I've seen various schemes along these line using CVS (no externals here, so it was checked-in scripts that had to be executed) and SVN. In the company I'm working now we have different top-level folders for projects and shared libraries. The projects can refer the libraries. On the project's trunk these external references usually are to the libraries' heads, on tags and branches projects refer to libraries' tags (or, sometimes, branches).

sbi
For Git it would be **git submodule**
Jakub Narębski
I've started breaking out the general projects and referencing them using `svn:externals` and it works great!
Blixt
@Blixt: Great. Just beware that, AFAIK, commands such as checkin do not recurse into folders checked out through external references. At least they didn't the last time I looked.
sbi
A: 

I don't even understand the question. If foo depends on libbar, why do you want to keep the source for libbar in foo's VCS? You link against libbar or import the bar module, if appropriate for the language. Why would you want to muddle the source tree for your project? My "hello, world!" project depends on libc. So does my "hello, Dolly!" project. Neither project keeps the libc source in their code base. To do so would be insane. Why treat internal libraries any differently than 3rd party libraries in this respect? In short, the best practice is: don't do it. If your library has hot-fixes that need to propagate to your projects, then use dynamic linkage.

William Pursell
Yes, I think you misunderstood the question. The current case in the project I've been involved with is what you describe (the source for LibA is kept in ProjectB, which is bad) but what I'm looking for is a way to keep LibA as LibA and ProjectB as ProjectB. I want, *on the client*, for the code of LibA and ProjectB to reside together in some way so that I can compile the project, but their version control bindings should be kept separate (LibA to LibA and ProjectB to ProjectB.)
Blixt