Pregunta

Si tuviera 20 directorios en el tronco/con muchos archivos en cada uno y solo necesitara 3 de esos directorios, ¿sería posible realizar un pago de Subversion con solo esos 3 directorios en el tronco?

¿Fue útil?

Solución

Subversion 1.5 introduce pagos escasos que pueden ser algo que pueda resultarle útil.Desde el documentación:

... directorios dispersos (o cajas superficiales) ...le permite extraer fácilmente una copia de trabajo (o una parte de una copia de trabajo) de manera más superficial que la recursividad completa, con la libertad de incorporar archivos y subdirectorios previamente ignorados en un momento posterior.

Otros consejos

De hecho, gracias a los comentarios a mi publicación aquí, parece que directorios dispersos son el camino a seguir.Creo que lo siguiente debería hacerlo:

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

Alternativamente, --depth immediates en lugar de empty revisa archivos y directorios en trunk/proj sin su contenido.De esa forma podrá ver qué directorios existen en el repositorio.


Como se menciona en la respuesta de @zigdon, también puedes realizar un pago no recursivo.Esta es una forma más antigua y menos flexible de lograr un efecto similar:

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

Escribí un script para automatizar pagos complejos y dispersos.

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

O realice una verificación no recursiva de /trunk, luego simplemente realice una actualización manual en los 3 directorios que necesita.

Si ya tiene la copia local completa, puede eliminar subcarpetas no deseadas usando --set-depth dominio.

svn update --set-depth=exclude www

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

El set-depth El comando admite múltiples rutas.

Actualizar la copia local raíz no cambiará la profundidad de la carpeta modificada.

Para restaurar la carpeta para que esté en proceso de extracción recursiva, puede usar --set-depth nuevamente con parámetro infinito.

svn update --set-depth=infinity www

Algo así como.Como dice Bobby:

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

Obtendrá las carpetas, pero obtendrá carpetas separadas desde una perspectiva de subversión.Tendrá que realizar confirmaciones y actualizaciones por separado en cada subcarpeta.

No creo que se pueda extraer un árbol parcial y luego trabajar con él como una sola entidad.

No de ninguna manera especialmente útil, no.Puede verificar los subárboles (como en la sugerencia de Bobby Jack), pero luego pierde la capacidad de actualizarlos/confirmarlos atómicamente;para hacer eso, deben colocarse bajo su padre común, y tan pronto como revise el padre común, descargará todo bajo ese padre.No recursivo no es una buena opción porque desea que las actualizaciones y las confirmaciones sean recursivas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top