Subversion ile kısmi ödeme yapabilir misiniz?


Yanıtlar:


78

Subversion 1.5, yararlı bulabileceğiniz bir şey olabilecek seyrek kontroller sunar. Gönderen belgeler :

... seyrek dizinler (veya sığ kasalar ) ... daha önce yok sayılan dosyaları ve alt dizinleri getirme özgürlüğüyle, çalışan bir kopyayı veya çalışan bir kopyanın bir bölümünü tam özyinelemeden daha sığ bir şekilde kolayca kontrol etmenizi sağlar. başka zaman.


259

Gerçekten, buradaki yazımın yorumları sayesinde, seyrek dizinler gitmenin yolu gibi görünüyor . Aşağıdakilerin yapması gerektiğine inanıyorum:

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

Alternatif olarak, --depth immediatesyerine emptydosya ve dizinleri dışarı çek trunk/projiçerikleriyle olmadan. Bu şekilde depoda hangi dizinlerin bulunduğunu görebilirsiniz.


@ Zigdon'un cevabında belirtildiği gibi, özyinelemesiz bir ödeme de yapabilirsiniz. Bu, benzer bir etki elde etmenin daha eski ve daha az esnek bir yoludur:

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

4
Daha sonra trunk dizininde bir svn güncellemesi yayınlarsam, diğer tüm klasörleri aşağı çekecek mi yoksa daha önce alınmış olanları güncelleyecek mi?
Rob Walker

2
Ben olsun Skipped 'prom/foo'sonra svn update --set-depth infinity proj/foo:(
sam

2
Oh, daha derine güncelleme yapmadan önce (proj / foo / boo) ebeveyni (proj / foo) güncellemelisiniz.
sam

4
Bu iyi bir cevap ve gerçekten doğru işaretlenmiş cevap olmalı. Pkaeding teşekkürler!
Jimbo

1
svn update --set-depth immediates projGüncelleme için proj / foo yapabilmesi için bir ara adım kullanmanız gerekebilir .
Craig

6

Ya da / trunk özyinelemeli olmayan bir ödeme yapın, sonra ihtiyacınız olan 3 dizin üzerinde el ile güncelleme yapın.


6

Karmaşık seyrek ödemeleri otomatikleştirmek için bir senaryo yazdım.

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

Tam yerel kopyanız zaten varsa, --set-depthkomutu kullanarak istenmeyen alt klasörleri kaldırabilirsiniz .

svn update --set-depth=exclude www

Bkz. Http://blogs.collab.net/subversion/sparse-directories-now-with-exclusion

set-depthKomut destek katları yolları.

Kök yerel kopyanın güncellenmesi, değiştirilen klasörün derinliğini değiştirmez.

Klasörü --set-depthtekrar tekrar kontrol edilmek üzere geri yüklemek için tekrar sonsuzluk parametresi ile kullanabilirsiniz .

svn update --set-depth=infinity www

-1

Bir çeşit. Bobby'nin dediği gibi:

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

klasörleri alır, ancak ayrı bir klasörü alt sürüm perspektifinden alırsınız. Her alt klasörde ayrı taahhütler ve güncellemeler yapmanız gerekecektir.

Kısmi bir ağacı kontrol edebileceğinize ve sonra kısmi ağaçla tek bir varlık olarak çalışabileceğinize inanmıyorum.


-10

Özellikle yararlı bir şekilde değil, hayır. Alt ağaçları kontrol edebilirsiniz (Bobby Jack'in önerisinde olduğu gibi), ancak bunları atomik olarak güncelleme / taahhüt etme yeteneğini kaybedersiniz; bunu yapmak için, ortak ebeveynlerinin altına yerleştirilmeleri gerekir ve ortak ebeveyne göz attığınızda, o ebeveynin altındaki her şeyi indirirsiniz. Özyinelemeli olmayanlar iyi bir seçenek değildir, çünkü güncellemelerin ve taahhütlerin özyinelemesini istiyorsunuz.


16
-1 yanlış olan bir cevap için. Gerçek hayatta, büyük bir projedeki bileşenlerin sadece küçük bir alt kümesi üzerinde çalışmak istediğiniz ve tüm projeyi kontrol etmek istemediğiniz çok sayıda kullanım durumu vardır.
Peter

Çünkü bu alt ağaçlarla birbirinden bağımsız olarak çalışabilirsiniz, ancak DrPizza'nın bu durumda atomik olmayan taahhütler / güncellemeler anlamına geldiğini düşünüyorum. Ve belirli bir durumda bir sorun olabilir.
Andry
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.