Tutorial :How do I branch an individual file in SVN?



Question:

The subversion concept of branching appears to be focused on creating an [un]stable fork of the entire repository on which to do development. Is there a mechanism for creating branches of individual files?

For a use case, think of a common header (*.h) file that has multiple platform-specific source (*.c) implementations. This type of branch is a permanent one. All of these branches would see ongoing development with occasional cross-branch merging. This is in sharp contrast to unstable development/stable release branches which generally have a finite lifespan.

I do not want to branch the entire repository (cheap or not) as it would create an unreasonable amount of maintenance to continuously merge between the trunk and all the branches. At present I'm using ClearCase, which has a different concept of branching that makes this easy. I've been asked to consider transitioning to SVN but this paradigm difference is important. I'm much more concerned about being able to easily create alternate versions for individual files than about things like cutting a stable release branch.


Solution:1

Sadly, I think the real answer here is that ClearCase handles this situation a lot better than Subversion. With subversion, you have to branch everything, but ClearCase allows a kind of "lazy branch" idea that means only a certain group of files are branched, the rest of them still follow the trunk (or whichever branch you specify).

The other solutions provided here don't really work as you intend, they are just copying the file to a different path. Now you have to do odd things to actually use that file.

Erm, sorry. That wasn't really a very good answer. But there isn't a good solution to this with Subversion. Its model is branch and merge.

Edit: OK, so expanding on what crashmstr said. You could do this:

svn cp $REP/trunk/file.h $REP/branched_files/file.h  svn co $REP/trunk  svn switch $REP/branched_files/file.h file.h  

But wow!, is that prone to errors. Whenever you do a svn st you will see this:

svn st      S  file.h  

A bit noisy that. And when you want to branch a few files or modules within a large source repository it will start to get very messy.

Actually, there's probably a decent project in here for simulating something like ClearCase's branched files with svn properties and switching, writing a wrapper around the bog standard svn client to deal with all the mess.


Solution:2

You don't have to branch the entire repository. You could make branches of folders in your project (such as an include folder). As others have noted, you can also do a "copy" of just a single file. Once you have a copy of a file or folder, you "switch" to the branched file or folder to work on the branch version.

If you create a separate branches folder in the repository, you could copy your branched files there via server side commands:

  svn copy svn://server/project/header.h svn://server/branched_files/header.h  

Then you could switch that file to use the branches_files repository path


Solution:3

Here is how I understand your problem. You have the following tree:

  time.h  time.c  

and you need to decline it for multiple architectures :

  time.h is comon  time.c (for x386), time.c (for ia64), time.c (for alpha),...  

Also in your current VCS you can do this by creating as many branches from time.c as needed and when you checkout the files from the VCS you automatically check the latest time.h from the common trunk and the latest time.c from the branch you are working on.

The problem you are concerned about is that if you use SVN when checking out a branch you will have to merge time.h from trunk very often or risk working on an older file (as compared to the trunk) that amount of overhead is not acceptable to you.

Depending on the structure of your source code, there might be a solution though. imagine that you have

   /  /headers/  /headers/test.h  /source/  /source/test.c  

Then you could branch /, and use the svn:externals feature to link your headers to the trunk's head. It only works on directories and bears some limitations with regard to committing back to test.h (you have to go in the header directory for it to work) but it could work.


Solution:4

A Subversion "branch" is just a copy of something in your repository. So if you wanted to branch a file you'd just do:

svn copy myfile.c myfile_branch.c  


Solution:5

I don't think there is much point in branching a single file? There is no way to test it with the trunk code?

You could take a patch instead if you want to back out changes and apply them later on.


Solution:6

Are you sure you really need this feature in your VCS ?

Why not use the C preprocessor and #ifdef away the code you don't need ? Or any similar tool.

something like:

// foo.h:  void Foo();    // foo_win32.c  #ifdef _WIN32  void Foo()  {     ...  }  





        
Previous
Next Post »