문제

trunk/ 아래에 20개의 디렉토리가 있고 각각에 많은 파일이 있고 그 중 3개의 디렉토리만 필요하다면 트렁크 아래에 있는 3개의 디렉토리만으로 Subversion 체크아웃을 수행할 수 있습니까?

도움이 되었습니까?

해결책

Subversion 1.5에는 유용할 수 있는 희소 체크아웃이 도입되었습니다.로부터 선적 서류 비치:

... 희소 디렉토리 (또는 얕은 결제) ...이전에 무시했던 파일과 하위 디렉터리를 나중에 자유롭게 가져올 수 있어 전체 재귀보다 더 얕게 작업 복사본(또는 작업 복사본의 일부)을 쉽게 확인할 수 있습니다.

다른 팁

실제로 여기 내 게시물에 대한 댓글 덕분에 다음과 같습니다. 희소 디렉토리 가는 길입니다.나는 다음이 그렇게 해야 한다고 믿습니다:

svn checkout --depth empty http://svnserver/trunk/proj
svn update --set-depth infinity proj/foo
svn update --set-depth infinity proj/bar
svn update --set-depth infinity proj/baz

대안적으로, --depth immediates 대신에 empty 파일과 디렉토리를 체크아웃합니다. trunk/proj 내용 없이.이렇게 하면 저장소에 어떤 디렉터리가 있는지 확인할 수 있습니다.


@zigdon의 답변에서 언급했듯이 비재귀 체크아웃도 수행할 수 있습니다.이는 유사한 효과를 얻기 위한 오래되고 덜 유연한 방법입니다.

svn checkout --non-recursive http://svnserver/trunk/proj
svn update trunk/foo
svn update trunk/bar
svn update trunk/baz

복잡한 스파스 체크아웃을 자동화하는 스크립트를 작성했습니다.

#!/usr/bin/env python

'''
This script makes a sparse checkout of an SVN tree in the current working directory.

Given a list of paths in an SVN repository, it will:
1. Checkout the common root directory
2. Update with depth=empty for intermediate directories
3. Update with depth=infinity for the leaf directories
'''

import os
import getpass
import pysvn

__author__ = "Karl Ostmo"
__date__ = "July 13, 2011"

# =============================================================================

# XXX The os.path.commonprefix() function does not behave as expected!
# See here: http://mail.python.org/pipermail/python-dev/2002-December/030947.html
# and here: http://nedbatchelder.com/blog/201003/whats_the_point_of_ospathcommonprefix.html
# and here (what ever happened?): http://bugs.python.org/issue400788
from itertools import takewhile
def allnamesequal(name):
    return all(n==name[0] for n in name[1:])

def commonprefix(paths, sep='/'):
    bydirectorylevels = zip(*[p.split(sep) for p in paths])
    return sep.join(x[0] for x in takewhile(allnamesequal, bydirectorylevels))

# =============================================================================
def getSvnClient(options):

    password = options.svn_password
    if not password:
        password = getpass.getpass('Enter SVN password for user "%s": ' % options.svn_username)

    client = pysvn.Client()
    client.callback_get_login = lambda realm, username, may_save: (True, options.svn_username, password, True)
    return client

# =============================================================================
def sparse_update_with_feedback(client, new_update_path):
    revision_list = client.update(new_update_path, depth=pysvn.depth.empty)

# =============================================================================
def sparse_checkout(options, client, repo_url, sparse_path, local_checkout_root):

    path_segments = sparse_path.split(os.sep)
    path_segments.reverse()

    # Update the middle path segments
    new_update_path = local_checkout_root
    while len(path_segments) > 1:
        path_segment = path_segments.pop()
        new_update_path = os.path.join(new_update_path, path_segment)
        sparse_update_with_feedback(client, new_update_path)
        if options.verbose:
            print "Added internal node:", path_segment

    # Update the leaf path segment, fully-recursive
    leaf_segment = path_segments.pop()
    new_update_path = os.path.join(new_update_path, leaf_segment)

    if options.verbose:
        print "Will now update with 'recursive':", new_update_path
    update_revision_list = client.update(new_update_path)

    if options.verbose:
        for revision in update_revision_list:
            print "- Finished updating %s to revision: %d" % (new_update_path, revision.number)

# =============================================================================
def group_sparse_checkout(options, client, repo_url, sparse_path_list, local_checkout_root):

    if not sparse_path_list:
        print "Nothing to do!"
        return

    checkout_path = None
    if len(sparse_path_list) > 1:
        checkout_path = commonprefix(sparse_path_list)
    else:
        checkout_path = sparse_path_list[0].split(os.sep)[0]



    root_checkout_url = os.path.join(repo_url, checkout_path).replace("\\", "/")
    revision = client.checkout(root_checkout_url, local_checkout_root, depth=pysvn.depth.empty)

    checkout_path_segments = checkout_path.split(os.sep)
    for sparse_path in sparse_path_list:

        # Remove the leading path segments
        path_segments = sparse_path.split(os.sep)
        start_segment_index = 0
        for i, segment in enumerate(checkout_path_segments):
            if segment == path_segments[i]:
                start_segment_index += 1
            else:
                break

        pruned_path = os.sep.join(path_segments[start_segment_index:])
        sparse_checkout(options, client, repo_url, pruned_path, local_checkout_root)

# =============================================================================
if __name__ == "__main__":

    from optparse import OptionParser
    usage = """%prog  [path2] [more paths...]"""

    default_repo_url = "http://svn.example.com/MyRepository"
    default_checkout_path = "sparse_trunk"

    parser = OptionParser(usage)
    parser.add_option("-r", "--repo_url", type="str", default=default_repo_url, dest="repo_url", help='Repository URL (default: "%s")' % default_repo_url)
    parser.add_option("-l", "--local_path", type="str", default=default_checkout_path, dest="local_path", help='Local checkout path (default: "%s")' % default_checkout_path)

    default_username = getpass.getuser()
    parser.add_option("-u", "--username", type="str", default=default_username, dest="svn_username", help='SVN login username (default: "%s")' % default_username)
    parser.add_option("-p", "--password", type="str", dest="svn_password", help="SVN login password")

    parser.add_option("-v", "--verbose", action="store_true", default=False, dest="verbose", help="Verbose output")
    (options, args) = parser.parse_args()

    client = getSvnClient(options)
    group_sparse_checkout(
        options,
        client,
        options.repo_url,
        map(os.path.relpath, args),
        options.local_path)

또는 /trunk의 비재귀 체크아웃을 수행한 다음 필요한 3개 디렉터리에 대해 수동 업데이트를 수행하세요.

전체 로컬 복사본이 이미 있는 경우 다음을 사용하여 원하지 않는 하위 폴더를 제거할 수 있습니다. --set-depth 명령.

svn update --set-depth=exclude www

보다: http://blogs.collab.net/subversion/sparse-directories-now-with-exclusion

그만큼 set-depth 명령은 다중 경로를 지원합니다.

루트 로컬 복사본을 업데이트해도 수정된 폴더의 깊이는 변경되지 않습니다.

폴더를 재귀적으로 체크아웃하도록 복원하려면 다음을 사용할 수 있습니다. --set-depth 다시 무한대 매개변수를 사용합니다.

svn update --set-depth=infinity www

일종의.바비가 말했듯이 :

svn co file:///.../trunk/foo file:///.../trunk/bar file:///.../trunk/hum

폴더를 얻게 되지만 전복 관점에서는 별도의 폴더를 얻게 됩니다.각 하위 폴더에 대해 별도의 커밋과 업데이트를 진행해야 합니다.

부분 트리를 체크아웃한 다음 부분 트리를 단일 엔터티로 사용하여 작업할 수 있다고 생각하지 않습니다.

특별히 유용한 방법은 아닙니다.Bobby Jack의 제안처럼 하위 트리를 확인할 수 있지만 원자적으로 업데이트/커밋하는 기능을 잃게 됩니다.그렇게 하려면 공통 상위 항목을 공통 상위 항목 아래에 배치해야 하며, 공통 상위 항목을 체크아웃하자마자 해당 상위 항목 아래의 모든 항목을 다운로드하게 됩니다.업데이트와 커밋이 재귀적으로 수행되기를 원하기 때문에 비재귀는 좋은 옵션이 아닙니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top