gitversion-controlpvcs

Creating tags//branches in version control with only some files


I'm already working with PVCS control version, but I'm about to start a new project and would like to migrate to Git/SVN keeping the same structure as I had.

The code is C, and it's structured so that each C "object" has its own tag, in which there are only it's C files and the neccesary H files to compile.

Is it possible in Git/SVN to create a branch from the trunk that contains only the necessary files for that "object" to compile, make a tag, and merge the changes into the trunk?

I've tried Git, but every time I create a branch, I have all the files, including C and H files from other "objects" that I don't need.

I don't know if there's another VCS that allows to create these kind of partial tags.


Solution

  • PVCS appears to be file-oriented (like CVS or RCS), with a centralized store (like CVS) and locking (also like CVS).

    SVN is commit-oriented (and centralized) but treats branches as file sub-trees, with a merge model rather than a lock model (though actually SVN offers file locking as well). In some cases, this may be compatible with the way you're using tags. But it may not: if you tag individual files differently despite being in the same file system location, e.g., dir/sub/file1.c has tags A and B while dir/sub/file2.c has entirely different tags D and E, that's not going to play well together either.

    Git and other modern VCSes are distributed rather than centralized, and commit-oriented. When the system is distributed, the whole concept of locking a file is pretty much toast: there's no central authority declaring who has the lock. So these all use merge models. Git furthermore has no concept of trunk: branches are all equal—or more precisely, branches don't really mean anything at all. What matters in Git is the commit graph, with the branch names really being a supplemental trick to remember how to work your way through the graph.

    (Combining this with the idea of reachability provides Git the ability to discard unwanted objects: unlike some other modern graph-directed version control systems, commits are no more special than any other internal object. This can be a bit disorienting, to put it mildly: in other commit-oriented VCSes, once you make a commit, it's permanently affixed to a single branch and you can always find it in that branch. So Git is even more of a leap here than, say, Mercurial.)

    Any time you have a file-oriented version control system, it's easy to pick out particular files, because that's how the VCS works underneath. Once you go to a commit model, the "work area" (whatever it gets called in that particular VCS—Git uses the phrase work-tree or working directory or anything along those lines) must be matched to the specific commit, because you're not getting version V of fileX.c, you're getting all the files that make up version V. It is, in theory, possible to combine this with sparse checkout and multiple work-areas, so that work area 1 has version V1 of sparsely extracted file1.c, work area 2 has version V2 of sparsely extracted file2.c, and so on; but you'll be fighting with the model all the time. This is probably not a good idea.

    In the end, I think that unless you stick with a file-oriented VCS, you will have to change your workflow.