Câu trả lời:
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
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 immediates
thay vì empty
kiểm tra các tập tin và thư mục trunk/proj
mà 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
Skipped 'prom/foo'
sau svn update --set-depth infinity proj/foo
:(
svn update --set-depth immediates proj
để nó tạo ra proj / foo để cập nhật.
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.
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)
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-depth
lệnh.
svn update --set-depth=exclude www
Xem: http://bloss.collab.net/subversion/spzzy-directories-now-with-exinating
Các set-depth
hỗ 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-depth
lại với param infinite.
svn update --set-depth=infinity www
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.
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.