Si j'avais 20 répertoires sous le tronc / avec beaucoup de fichiers dans chacun et que j'avais besoin de seulement 3 de ces répertoires, serait-il possible de faire une extraction Subversion avec seulement ces 3 répertoires sous le tronc?
Si j'avais 20 répertoires sous le tronc / avec beaucoup de fichiers dans chacun et que j'avais besoin de seulement 3 de ces répertoires, serait-il possible de faire une extraction Subversion avec seulement ces 3 répertoires sous le tronc?
Réponses:
Subversion 1.5 introduit des extractions éparses qui peuvent être quelque chose que vous pourriez trouver utile. De la documentation :
... répertoires clairsemés (ou extractions superficielles ) ... vous permet d'extraire facilement une copie de travail - ou une partie d'une copie de travail - de manière plus superficielle que la récursivité complète, avec la liberté d'importer des fichiers et sous-répertoires précédemment ignorés à un plus tard.
En effet, grâce aux commentaires sur mon article ici, il semble que les répertoires clairsemés soient la voie à suivre. Je pense que ce qui suit devrait le faire:
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
Sinon, --depth immediates
au lieu d' empty
extraire les fichiers et les répertoires trunk/proj
sans leur contenu. De cette façon, vous pouvez voir quels répertoires existent dans le référentiel.
Comme mentionné dans la réponse de @ zigdon, vous pouvez également effectuer une extraction non récursive. Il s'agit d'un moyen plus ancien et moins flexible d'obtenir un effet similaire:
svn checkout --non-recursive http://svnserver/trunk/proj
svn update trunk/foo
svn update trunk/bar
svn update trunk/baz
Skipped 'prom/foo'
après svn update --set-depth infinity proj/foo
:(
svn update --set-depth immediates proj
afin de créer proj / foo pour la mise à jour.
J'ai écrit un script pour automatiser les caisses clairsemées complexes.
#!/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)
Si vous disposez déjà de la copie locale complète, vous pouvez supprimer les sous-dossiers indésirables à l'aide de la --set-depth
commande.
svn update --set-depth=exclude www
Voir: http://blogs.collab.net/subversion/sparse-directories-now-with-exclusion
La set-depth
commande prend en charge les chemins multi-fichiers.
La mise à jour de la copie locale racine ne changera pas la profondeur du dossier modifié.
Pour restaurer le dossier en cours d'extraction récusive, vous pouvez l'utiliser à --set-depth
nouveau avec le paramètre infinity.
svn update --set-depth=infinity www
Sorte de. Comme le dit Bobby:
svn co file:///.../trunk/foo file:///.../trunk/bar file:///.../trunk/hum
obtiendra les dossiers, mais vous obtiendrez des dossiers séparés du point de vue de la subversion. Vous devrez effectuer des validations et des mises à jour distinctes sur chaque sous-dossier.
Je ne pense pas que vous puissiez extraire un arbre partiel, puis travailler avec l'arbre partiel en tant qu'entité unique.
Pas d'une manière particulièrement utile, non. Vous pouvez vérifier les sous-arbres (comme dans la suggestion de Bobby Jack), mais vous perdez alors la possibilité de les mettre à jour / de les valider de manière atomique; pour ce faire, ils doivent être placés sous leur parent commun, et dès que vous vérifiez le parent commun, vous téléchargez tout sous ce parent. La non-récursivité n'est pas une bonne option, car vous voulez que les mises à jour et les validations soient récursives.