9

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.

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
Michael Carman
  • 30,628
  • 10
  • 74
  • 122
  • 1
    You note in another comment that this isn't actually your use case. Don't be surprised when answers try to solve this use case rather than your actual one. – wnoise Sep 22 '08 at 21:55

8 Answers8

9

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

crashmstr
  • 28,043
  • 9
  • 61
  • 79
3

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.

richq
  • 55,548
  • 20
  • 150
  • 144
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.

Jean
  • 21,329
  • 5
  • 46
  • 64
1

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
Matt
  • 31,662
  • 4
  • 34
  • 33
  • You misunderstand. I want one file with two alternate branches (or "histories" in some other CM systems terminology). I do not want two related but distinct files. – Michael Carman Sep 22 '08 at 20:41
  • In Svn, a branch is just a copy (of a file or a directory). So, when branching just one file, you can either keep it in the same directory (but under a different name as suggested here), or put it into a different directory... I doubt that Subversion offers any other options. History is branched. – Alexander Sep 22 '08 at 21:03
  • 1
    I realize that a branch is just a copy. (SVN's insistence on exposing that in the UI is one of my major gripes with it.) I'm okay with the answer being "you can't do that." I'd rather not use a hammer to drive a screw. I'm just trying to learn what tools are available. – Michael Carman Sep 22 '08 at 21:27
1

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.

Xian
  • 76,121
  • 12
  • 43
  • 49
  • 1
    It's a legitimate task if he has lots of changes to make to that file and wants to be safe yet isolate his teammates from his ongoing work. – Chris Farmer Sep 22 '08 at 20:59
  • There is a point. I've updated the question in an attempt to clarify the use case. – Michael Carman Sep 22 '08 at 21:12
  • Another example--Our project is transitioning from one version of a plugin to another. This requires eclipse properties changes. We keep them checked in. How do we have people run both the old and the new version of the plugin at the same time? It would be nice if a branch were the same as another except for the eclipse config files that must be different. – Bill K Apr 02 '13 at 22:11
1

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()
{
   ...
}
#endif

// foo_linux.c
#ifdef _GNUC
void Foo()
{
   ...
}
#endif

Sometimes if it doesn't fit right, then it's not the right solution.

rlerallut
  • 7,545
  • 5
  • 23
  • 21
  • Yes, I want this as a feature of the VCS. The use case was just an easy to understand example. My real situation is somewhat more complex and not limited to C. So far "not the right solution" has for me meant not SVN. – Michael Carman Sep 22 '08 at 21:20
0

A branch in SVN is just a copy. I believe that to do it the way you are hoping to, you'd have to have each version of the file in a separate directory in the repository, and check it out into your source folder. I.E. treat that file like a separate project.

Zebra North
  • 11,412
  • 7
  • 37
  • 49
0

A branch in Subversion is exactly what you are talking about. All of the files are an exact copy of the trunk, with the exception of the ones you change. This is the "cheap copy" methodology talked about in the SVN Book. The only caveat is the need to merge the trunk into the branch from time to time to insure that the changes made there are reflected in the branch. Of course, if those changes are not desired, no trunk->branch merges need to happen.

One easy way to allow for trunk changes to be merged in automatically(which simulates the Clear Case paradigm) would be to use a pre-commit hook script to merge the trunk changes in prior to the commit.(in fact, this is always a good strategy to prevent code drift).

cdeszaq
  • 30,869
  • 25
  • 117
  • 173