Subversion存储库布局 [英] Subversion Repository Layout

查看:67
本文介绍了Subversion存储库布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大多数Subversion工具都会使用/trunk,/branches和/tags创建默认的存储库布局.该文档还建议不要为每个项目使用单独的存储库,以便可以更轻松地共享代码.

Most subversion tools create a default repository layout with /trunk, /branches and /tags. The documentation also recommends not using separate repositories for each project, so that code can be more easily shared.

遵循该建议,使我拥有了一个具有以下布局的存储库:

Following that advice has led to me having a repository with the following layout:


/trunk
      /Project1
      /Project2
/branches
         /Project1
         /Project2
/tags
     /Project1
     /Project2

,依此类推,您就明白了.随着时间的流逝,我发现这种结构有些笨拙,并且我发现对建议的替代解释是这样的,例如:

and so on, you get the idea. Over time, I've found this structure a bit clumsy and it occurred to me that there's an alternative interpretation of the recommendations, such as:


/Project1
         /trunk
         /branches
         /tags
/Project2
         /trunk
         /branches
         /tags       

那么,人们使用哪种布局,为什么?或者-还有另一种方法可以做我完全错过的事情吗?

So, which layout do people use, and why? Or - is there another way to do things that I've completely missed?

推荐答案

我决定硬着头皮重新整理我的存储库.我写了一个小程序来帮助(下).我遵循的步骤是:

I decided to bite the bullet and restructure my repository. I wrote a small program to assist (below). The steps I followed were:

  1. 制作原始存储库的备份副本.
  2. svn checkout 整个存储库.这花费了很长时间,并且占用了大量磁盘空间.
  3. 在上一步的工作副本上从下面运行程序.
  4. 检查修改后的工作副本并整理所有遗留的问题(例如svn delete过时的 trunk tags branches 文件夹)
  5. svn commit回到存储库.
  1. Make a backup copy of the original repository.
  2. svn checkout the entire repository. This took a long time and a lot of disk space.
  3. Run the program from below on the working copy from the previous step.
  4. Examine the modified working copy and tidy up any left over issues (eg. svn delete the obsolete trunk, tags and branches folders)
  5. svn commit back to the repository.

整个过程耗时,但是我决定采用这种方法,因为修改工作副本比黑客入侵实时存储库要安全得多,而且我可以选择在所有工作副本出错的情况下简单地丢弃工作副本.修复工作副本中的任何问题,并将整个重组作为一个修订提交.

This whole process took time, but I decided to take this approach because modifying a working copy is a lot safer than hacking up a live repository and I had the options to simply throw away the working copy if it all went wrong, to fix any issue in the working copy and commit the entire restructure as a single revision.

这是我用来移动的C#代码.需要SharpSvn库.

Here's the C# code I used to do the moving. Requires SharpSvn library.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using SharpSvn;

/**
 * 
 * Program operation:
 * 1. Parse command line to determine path to working copy root
 * 2. Enumerate folders in the /trunk 
 * 3. Restructure each project folder in /trunk
 * 
 * 
 * Restructure a Project:
 * 1. Get the project name (folder name in /trunk/{Project})
 * 2. SVN Move /trunk/{Project} to /{Project}/trunk
 * 3. Reparent Project, branches
 * 4. Reparent Project, tags
 * 
 * Reparent(project, folder)
 * If /{folder}/{Project} exists
 *   SVN Move /{folder}/{Project} to /{Project}/{Folder}
 * else
 *   Create folder /{Project}/{Folder}
 *   SVN Add /{Project}/{Folder}
 * 
 **/

namespace TiGra.SvnRestructure
{
    /// <summary>
    /// Restructures a Subversion repository from
    ///     /trunk|branches|tags/Project
    /// to
    ///     /Project/trunk|branches|tags
    /// </summary>
    internal class Program
    {
        private static string WorkingCopy;
        private static string SvnUri;
        private static string Branches;
        private static string Tags;
        private static string Trunk;

        private static SvnClient svn;
        private static List<string> Projects;

        private static void Main(string[] args)
        {
            ProcessCommandLine(args);
            CreateSvnClient();
            EnumerateProjectsInTrunk();
            RestructureProjects();
            Console.ReadLine();
        }

        private static void RestructureProjects()
        {
            foreach (var project in Projects)
            {
                RestructureSingleProject(project);
            }
        }

        private static void RestructureSingleProject(string projectPath)
        {
            var projectName = Path.GetFileName(projectPath);
            var projectNewRoot = Path.Combine(WorkingCopy, projectName);
            bool hasBranches = Directory.Exists(Path.Combine(Branches, projectName));
            bool hasTags = Directory.Exists(Path.Combine(Tags, projectName));
            Reparent(Path.Combine(Trunk, projectName), Path.Combine(projectNewRoot, "trunk"));
            if (hasBranches)
                Reparent(Path.Combine(Branches, projectName), Path.Combine(projectNewRoot, "branches"));
            if (hasTags)
                Reparent(Path.Combine(Tags, projectName), Path.Combine(projectNewRoot, "tags"));
        }

        private static void Reparent(string oldPath, string newPath)
        {
            Console.WriteLine(string.Format("Moving {0} --> {1}", oldPath, newPath));
            svn.Move(oldPath, newPath, new SvnMoveArgs(){CreateParents = true});
        }

        private static void EnumerateProjectsInTrunk()
        {
            var list = EnumerateFolders("trunk");
            Projects = list;
        }

        /// <summary>
        /// Enumerates the folders in the specified subdirectory.
        /// </summary>
        /// <param name="trunk">The trunk.</param>
        private static List<string> EnumerateFolders(string root)
        {
            var fullPath = Path.Combine(WorkingCopy, root);
            var folders = Directory.GetDirectories(fullPath, "*.*", SearchOption.TopDirectoryOnly).ToList();
            folders.RemoveAll(s => s.EndsWith(".svn")); // Remove special metadata folders.
            return folders;
        }

        private static void CreateSvnClient()
        {
            svn = new SharpSvn.SvnClient();
        }

        /// <summary>
        /// Processes the command line. There should be exactly one argument,
        /// which is the path to the working copy.
        /// </summary>
        private static void ProcessCommandLine(string[] args)
        {
            if (args.Length != 1)
                throw new ArgumentException("There must be exactly one argument");
            var path = args[0];
            if (!Directory.Exists(path))
                throw new ArgumentException("The specified working copy root could not be found.");
            WorkingCopy = path;
            Branches = Path.Combine(WorkingCopy, "branches");
            Tags = Path.Combine(WorkingCopy, "tags");
            Trunk = Path.Combine(WorkingCopy, "trunk");
        }
    }
}

这篇关于Subversion存储库布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆