Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I branch an individual file in SVN?

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.

like image 451
Michael Carman Avatar asked Sep 22 '08 20:09

Michael Carman


3 Answers

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

like image 76
crashmstr Avatar answered Oct 24 '22 09:10

crashmstr


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.

like image 32
richq Avatar answered Oct 24 '22 11:10

richq


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.

like image 31
Jean Avatar answered Oct 24 '22 11:10

Jean