views:

158

answers:

4

Hello.

I would like to know how you normally deal with this situation:

I have a set of utility functions. Say..5..10 files. And technically they are static library, cross-platform - SConscript/SConstruct plus Visual Studio project (not solution).

Those utility functions are used in multiple small projects (15+, number increases over time). Each project has a copy of a few files or of an entire library, not a link into one central place. Sometimes project uses one file, two files, some use everything. Normally, utility functions are included as a copy of every file and SConscript/SConstruct or Visual Studio Project (depending on the situation). Each project has a separate git repository. Sometimes one project is derived from other, sometimes it isn't. You work on every one of them, in random order. There are no other people (to make things simpler)

The problem arises when while working on one project you modify those utility function files.
Because each project has a copy of file, this introduces new version, which leads to the mess when you try later (week later, for example) to guess which version has a most complete functionality (i.e. you added a function to a.cpp in one project, and added another function to a.cpp in another project, which created a version fork)

How would you handle this situation to avoid "version hell"? One way I can think of is using symbolic links/hard links, but it isn't perfect - if you delete one central storage, it will all go to hell. And hard links won't work on dual-boot system (although symbolic links will). It looks like what I need is something like advanced git repository, where code for the project is stored in one local repository, but is synchronized with multiple external repositories. But I'm not sure how to do it or if it is possible to do this with git.

So, what do you think?

+1  A: 

The normal simple way would be to have the library as a project in your version control, and if there is a modification, to edit only this project.

Then, other projects that need the library can get the needed files from the library project.

Nikko
A: 

In Subversion you can use externals (it's not GIT I know, but these tips might still help). This is how it works:

  • Split the application specific code (\MYAPP) from the common code (\COMMON)
  • Remove all duplicates from the applications; they should only use the common-code
  • Bring in the common code in the applications by adding \COMMON as an external in \MYAPP

You will also probably have versions of your application. Also introduce versions in the common code. So your application will have the following folders in the repository:

  • \MYAPP\TRUNK
  • \MYAPP\V1
  • \MYAPP\V2

Similarly, add versions to the common-code, either using version numbers, like this:

  • \COMMON\TRUNK
  • \COMMON\V1
  • \COMMON\V2

Or using dates, like this:

  • \COMMON\TRUNK
  • \COMMON\2010JAN01
  • \COMMON\2010MAR28

The externals of \MYAPP\TRUNK should point to \COMMON\TRUNK, that's obvious.

Try to synchronize the versions of the common-code with the versions of the applications, so every time an application version is fixed, also the common-code is fixed, and the application version will point to the relevant common-code external.

E.g. the externals of \MYAPP\V1 may point to \COMMON\2010JAN01.

The advantage of this approach is that every developer can now extend, improve, debug the common-code. Disadvantage is that the compilation time of applications will increase as the common-code will increase.

The alternative (putting libraries in your version system) has the disadvantage that the management (extending, improving, debugging) of the common code is always done separately from the management of the applications, which may prevent developers from writing generic common code at all (and everyone starts to write their own versions of 'generic' classes). On the other hand, if you have a clear and flexible team solely responsible for the common code, the common code will be under much better control in the last alternative.

Patrick
+1  A: 

It is not completely clear to me what you want but maybe git submodules might help : http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html

Peter Tillemans
"It is not completely clear to me what you want". Having separate files in multiple external git repositories, while entire project has it's own repository. I.e. I would like version control system to properly handle files that came from different external sources. At least, ideally. If it isn't possible, I just want to know how other people manage such situations. That's all.
SigTerm
We use libraries in a separate project and link against the compiled binaries. We use semantic versioning in order to keep a semblance of sanity http://semver.org/ (and some automated infrastructure to distribute stuff)
Peter Tillemans
A: 

In Configuration (general) terms, a solution is to have multiple trunks (branches):

  • Release
  • Integration
  • Development

Release
This trunk / branch contains software that has passed Quality Assurance and can be released to a customer. After release, all files are marked as "read-only". The are given a label to identify the files with the release number.

Periodically or on demand the testing guru's will take the latest (tip) version from the Integration trunk and submit to grueling quality tests. This is how an integration version is promoted to a release version.

Integration
This trunk contains the latest working code. It contains bug fixes and new features. The files should be labeled after each bug fix or new feature.

Code is moved into the integration branch after the bug has passed the quality testing or the new feature is fully developed (and tested). A good idea here is to label the integration version with a temporary label before integrating developer's code.

Development These are branches made by developers for fixing bugs or developing new features. This can be a copy of all the files moved onto their local machine or only the files that need to be modified (with links to the Integration trunk for all other files).

When moving between trunks, the code must pass qualification testing, and there must be permission to move to the trunk. For example, unwarranted new features should not be put into the integration branch without authorization.


In your case, the files need to be either checked back into the Integration trunk after they have been modified OR a whole new branch or trunk if the code is too different from the previous version (such as adding new features).

I've been studying GIT and SourceSafe trying to figure out how to implement this schema. The schema is easy to implement in the bigger Configuration Management applications like PVCS and ClearCase. Looks like for GIT, duplicated repositories are necessary (one repository for each trunk). SourceSafe clearly states that it only allows one label per version, so files that have not changed will loose label information.

Thomas Matthews