2

Right now we use a very simple system for version control. We have a completely flat master repository for our entire product line. As our codebase grows and we add more products to the product line, this starts to present some serious drawbacks. We'd like to move away from this, especially with out flat style, but there are seemingly fundamental problems with a structured approach, so it'd be great to hear how other people handle these common situations:

  1. Your code's got multiple duplicate files in separate locations. For example, you have:

    ./somedir/source1.c
    ./someotherdir/source1.c
    

All instances of source1.c are the same, so when someone changes source1.c, they shouldn't have to make the same change to every source1.c in each location where it exists. This is kind of where a flat system works, but it means the structure (with somedir and someotherdir have to be created to create the correct file structure.

  1. On the other hand, if you have something like this:

    ./somedir/config
    ./someotherdir/config
    

where both instances of config are unique, and they only share a filename. This presents a big problem in a flat system, you end up doing something like keeping them in a flat repository with unique names, and then renaming them as you recreate the product structure. It seems like this is where a structured file system would make things easier, because there would be no inherent relationship between ./somedir/config and ./someotherdir/config.

Maybe I am approaching this with a fundamentally bad idea of standard idioms, but as I'm sure you are all aware, when you are making big changes to an existing codebase, it has to be more of a transition than a throw-everything-away-and-start-over situation.

  • Can you elaborate on what you mean by "completely flat" do you mean that you have no directories at all? It also maybe relevant to say what version control systems you use, because they differ enough that approaches will change on this point. – Winston Ewert Jul 27 '14 at 0:13
  • My guess is the problem you have with version controlling is a symptom of a bigger configuration management problem.Unfortunately VC tools manage to do simple CM acceptable well, and many presume incorrectly they scale up. – mattnz Jul 27 '14 at 7:27
  • What version control do you use at the moment? Are you using a tool? – Toby Allen Jul 27 '14 at 7:34
2

My experience is with CVS and laterly Subversion, so someone else will need to cover the more modern distributed systems like Git and Mecurial.

Your first question (source.c) is probably better fixed by putting common code into libraries, then linking the libraries into multiple products. That way there is only a single source file to change. SVN does provide a facility that will make a file appear in multiple places in the source tree, but if you plan to bring Continuous integration and automated compile/release into the picture, the cross-couplings become difficult to understand and manage. I much prefer the library approach.

The question about config is not be a problem. To my knowledge all source code control systems use the fully-qualified path to identify the file, so your two files are definitely stored in different places.

2

There are approaches within svn (and another approach). Other tools such as git will handle a symbolic link (and more info). It is fairly common for various version control systems to have some way of handling symbolic links (perforce, hg as two more).

At this point it becomes a question of how you want to structure your code.

All that said, I'm going to put forth at the start that doing symbolic links or the like is often the wrong answer. While you still have a single copy of the file that is the source of all, it is too easy to mangle the link (someone copies an older version of the file on top of it) and make someone's day in the future unhappy.

You have an object file of some sort. Rather than copying the source (or heaven forbid #include "../foo/bar.c forget that I wrote that. Just forget it for your own good. You didn't see it.) link against the object file.

You've got .../common/source1.c and that produces .../common/source1.o and when you link, its something like cc foo.o bar.o qux.o ${PROJECT_ROOT}/common/source1.o and you're good. Don't copy source1.c into the directory with foo, bar, and qux because you don't need it - there are better and more elegant ways of handling this.

If you are in a Java world, make the utils or commons (or whatever you name it) a separate project and let it be a dependency of those that need it. Similar for Go, or Python, or other languages that have a dependency management build tool.

So - keep unique files unique. Copying files into multiple locations violates DRY and will eventually come back to bite you hard. Symbolic links are better, but you have to be disciplined to use them and not clobber them with actual files. Link in the common libraries when you need to - but they are their own project (if they're a proper project).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.