Bạn có thể thực hiện kiểm tra một phần với Subversion không?


Câu trả lời:


78

Subversion 1.5 giới thiệu kiểm tra thưa thớt có thể là một cái gì đó bạn có thể thấy hữu ích. Từ tài liệu :

... thư mục thưa thớt (hoặc kiểm tra nông ) ... cho phép bạn dễ dàng kiểm tra một bản sao hoạt động hoặc một phần của bản sao làm việc, nông hơn so với đệ quy đầy đủ, với quyền tự do đưa vào các tệp và thư mục con bị bỏ qua trước đó tại thời gian sau


259

Thật vậy, nhờ các bình luận cho bài viết của tôi ở đây, có vẻ như các thư mục thưa thớt là cách để đi. Tôi tin rằng những điều sau đây nên làm:

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

Ngoài ra, --depth immediatesthay vì emptykiểm tra các tập tin và thư mục trunk/projmà không có nội dung của chúng. Bằng cách đó bạn có thể thấy thư mục nào tồn tại trong kho lưu trữ.


Như đã đề cập trong câu trả lời của @ zigdon, bạn cũng có thể thực hiện kiểm tra không đệ quy. Đây là một cách cũ và kém linh hoạt hơn để đạt được hiệu quả tương tự:

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

4
Nếu sau đó tôi phát hành một bản cập nhật svn trên thư mục trung kế thì nó sẽ kéo xuống tất cả các thư mục khác, hay chỉ cập nhật những thư mục đã được lấy?
Rob Walker

2
Tôi nhận được Skipped 'prom/foo'sau svn update --set-depth infinity proj/foo:(
sam

2
Ồ, bạn phải cập nhật cha mẹ (proj / foo) trước khi bạn có thể cập nhật sâu hơn (proj / foo / boo).
sam

4
Đây là một câu trả lời tốt và, thực sự, nên được đánh dấu chính xác. Cảm ơn đã bỏ qua!
Jimbo

1
Bạn có thể cần phải sử dụng một bước trung gian svn update --set-depth immediates projđể nó tạo ra proj / foo để cập nhật.
Craig

6

Hoặc thực hiện kiểm tra không đệ quy / trunk, sau đó chỉ cần cập nhật thủ công trên 3 thư mục bạn cần.


6

Tôi đã viết một kịch bản để tự động hóa kiểm tra thưa thớt phức tạp.

#!/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)

0

Nếu bạn đã có bản sao cục bộ đầy đủ, bạn có thể xóa các thư mục con không mong muốn bằng cách sử dụng --set-depthlệnh.

svn update --set-depth=exclude www

Xem: http://bloss.collab.net/subversion/spzzy-directories-now-with-exinating

Các set-depthhỗ trợ lệnh đường multipile.

Cập nhật bản sao gốc cục bộ sẽ không thay đổi độ sâu của thư mục đã sửa đổi.

Để khôi phục thư mục đang được kiểm tra định kỳ, bạn có thể sử dụng --set-depthlại với param infinite.

svn update --set-depth=infinity www

-1

Sắp xếp Như Bobby nói:

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

sẽ nhận được các thư mục, nhưng bạn sẽ nhận được các thư mục riêng biệt từ góc độ lật đổ. Bạn sẽ phải thực hiện các cam kết và cập nhật riêng biệt trên mỗi thư mục con.

Tôi không tin rằng bạn có thể kiểm tra một phần cây và sau đó làm việc với cây một phần như một thực thể duy nhất.


-10

Không phải trong bất kỳ cách đặc biệt hữu ích, không. Bạn có thể kiểm tra các cây con (như trong đề xuất của Bobby Jack), nhưng sau đó bạn mất khả năng cập nhật / cam kết chúng một cách nguyên tử; để làm điều đó, chúng cần được đặt dưới cha mẹ chung của chúng và ngay khi bạn kiểm tra cha mẹ chung, bạn sẽ tải xuống mọi thứ theo cha mẹ đó. Không đệ quy không phải là một lựa chọn tốt, bởi vì bạn muốn cập nhật và cam kết được đệ quy.


16
-1 cho một câu trả lời đơn giản là sai. Có rất nhiều trường hợp sử dụng trong cuộc sống thực, nơi bạn chỉ muốn làm việc với một tập hợp nhỏ các thành phần trong một dự án lớn và bạn không muốn kiểm tra toàn bộ dự án.
Peter

Vì bạn có thể làm việc với các cây con này một cách độc lập với nhau, nhưng tôi nghĩ DrPizza có nghĩa là các cam kết / cập nhật không nguyên tử trong trường hợp này. Và nó có thể là một vấn đề trong một điều kiện nhất định.
Andry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.