Mastering SVN: A Comprehensive Guide to ‘svn co’

Okay, here’s a comprehensive article on mastering svn co (Subversion checkout), aiming for the ~5000-word target. Because of the extensive length, I’ll be breaking it down into clear sections, using headings, subheadings, code examples, and illustrative scenarios to enhance readability and practical understanding.

Mastering SVN: A Comprehensive Guide to svn co

Table of Contents

  1. Introduction to Subversion and svn co

    • What is Subversion (SVN)?
    • The Role of Version Control
    • The Purpose of svn co (Checkout)
    • Why is svn co Fundamental?
  2. Basic svn co Usage

    • Syntax and Core Components
    • Simple Checkout Example (No Options)
    • Understanding the Working Copy
    • The .svn Directory (and its importance)
    • Checking Out a Specific Revision
    • Checking Out a Specific Date
  3. Advanced svn co Options

    • Depth Control (--depth)
      • empty
      • files
      • immediates
      • infinity (Default)
      • Practical Use Cases for Depth Control
    • Ignoring Unversioned Items (--ignore-externals)
      • What are Externals?
      • Why Ignore Externals?
    • Sparse Checkouts (--set-depth)
      • Combining --depth and --set-depth for fine-grained control
      • Real-world Example: Large Project, Specific Modules
    • Peg Revisions and Operative Revisions
      • Understanding Peg Revisions
      • Understanding Operative Revisions
      • Syntax and Usage
      • Example: Checking out a file as it existed at a specific revision, even if moved
    • Non-interactive mode (--non-interactive)
    • Quiet mode (--quiet or -q)
    • Configuring Authentication
      • Username and Password (--username, --password)
      • Storing Credentials (and security implications)
      • Using SSH Keys
    • Configuring Proxy Servers (--config-option)
  4. Common svn co Scenarios and Best Practices

    • Checking Out a New Project for the First Time
    • Creating a Branch Working Copy
    • Creating a Tag Working Copy
    • Working with Multiple Repositories
    • Handling Conflicts During Checkout (Unlikely, but possible)
    • Recovering from a Failed Checkout
    • Best Practices for Repository Organization (and how it affects svn co)
    • Using svn co in Automated Scripts
  5. Troubleshooting svn co Issues

    • “Repository UUID does not match” Error
    • “Connection Refused” or “Network is Unreachable” Errors
    • “Checksum Mismatch” Error
    • “Path Not Found” Error
    • “Access Denied” Error
    • “Working Copy Locked” Errors
    • Dealing with Externals Issues
    • Problems with Sparse Checkouts
  6. svn co vs. Other Version Control Systems

    • svn co vs. git clone
      • Centralized vs. Distributed
      • Metadata Storage
      • Working Copy Differences
    • svn co vs. hg clone (Mercurial)
      • Similarities to Git
    • When to Choose SVN (and svn co)
  7. Conclusion: Mastering the Foundation


1. Introduction to Subversion and svn co

  • What is Subversion (SVN)?

    Subversion, often abbreviated as SVN, is a centralized version control system (VCS). Version control systems are essential tools for managing changes to source code, documents, and other files over time. They allow you to track modifications, revert to previous versions, collaborate with others on projects, and maintain a history of all changes. Centralized means that there’s a single, central repository that holds the “truth” of the project’s history. All developers interact with this central repository.

  • The Role of Version Control

    Version control provides several crucial benefits:

    • History Tracking: Every change, who made it, and when it was made is recorded.
    • Reversibility: You can easily revert to any previous state of a file or the entire project.
    • Collaboration: Multiple developers can work on the same files concurrently, with mechanisms to merge changes.
    • Branching and Merging: Create separate lines of development (branches) for new features or bug fixes, then merge them back into the main line (trunk).
    • Backup and Recovery: The repository serves as a backup of your project.
    • Auditing: Track changes for compliance or debugging purposes.
  • The Purpose of svn co (Checkout)

    svn co, short for “svn checkout,” is the Subversion command used to retrieve a working copy of a project (or a part of a project) from the central repository. It’s the gateway to working with a Subversion-managed project. Think of it as downloading a copy of the project from the central server, but with the added benefit of being able to track and submit changes back to the server.

  • Why is svn co Fundamental?

    svn co is fundamental because it’s the first step in almost any Subversion workflow. Without a working copy obtained via svn co, you cannot:

    • Modify files and track changes.
    • Commit changes back to the repository.
    • Update your working copy with changes made by others.
    • Create branches or tags.

    It’s the foundation upon which all other Subversion operations are built.

2. Basic svn co Usage

  • Syntax and Core Components

    The basic syntax of the svn co command is:

    bash
    svn co <repository_url> [<local_path>]

    Let’s break down the components:

    • svn: This invokes the Subversion command-line client.
    • co: This is the “checkout” subcommand.
    • <repository_url>: This is the URL pointing to the location of the Subversion repository. It can be one of the following forms:
      • file:///path/to/repository (Local repository, often used for testing)
      • http://svn.example.com/path/to/repository (Access via HTTP)
      • https://svn.example.com/path/to/repository (Secure access via HTTPS)
      • svn://svn.example.com/path/to/repository (Access via the svnserve daemon)
      • svn+ssh://[email protected]/path/to/repository (Access via SSH)
    • [<local_path>]: This is the optional local directory where the working copy will be created. If omitted, the last component of the repository URL (usually the project name) will be used as the directory name.
  • Simple Checkout Example (No Options)

    Let’s say you have a repository at https://svn.example.com/repos/myproject. To check out the entire project to a local directory named myproject, you would use:

    bash
    svn co https://svn.example.com/repos/myproject

    This command will:

    1. Connect to the repository at the specified URL.
    2. Download the latest revision of the entire myproject directory (including all subdirectories and files).
    3. Create a local directory named myproject in your current working directory.
    4. Place the downloaded files and a hidden .svn directory inside the myproject directory.

    If you want to check out the project to a directory named myproject-dev, you would use:

    bash
    svn co https://svn.example.com/repos/myproject myproject-dev

  • Understanding the Working Copy

    The working copy is your local, modifiable copy of the project. It’s where you make changes, add new files, delete files, and generally work on the project. The working copy is linked to the repository, but it’s not the repository itself. Changes you make in your working copy are not reflected in the repository until you explicitly commit them.

  • The .svn Directory (and its importance)

    The .svn directory is a hidden directory (on Unix-like systems; it may have the “hidden” attribute set on Windows) that Subversion creates within each directory of your working copy. This directory is crucial for Subversion’s operation. It contains:

    • Pristine Copies: A copy of the files as they were when you last checked out or updated. This is used for comparing changes, reverting, and conflict resolution.
    • Metadata: Information about the repository URL, revision numbers, file status (modified, added, deleted, etc.), and other administrative data.
    • Working Copy Lock Information: (in older SVN versions) Used to prevent concurrent modifications in some cases.

    Important: Never manually modify or delete the .svn directory or its contents. Doing so can corrupt your working copy and make it unusable.

  • Checking Out a Specific Revision

    By default, svn co retrieves the latest revision (the most recent version) from the repository. However, you can check out a specific revision using the -r (or --revision) option:

    bash
    svn co -r 123 https://svn.example.com/repos/myproject

    This command will check out revision 123 of the myproject repository. You can specify revisions in several ways:

    • Revision Number: A simple integer (e.g., 123).
    • HEAD: Represents the latest revision in the repository.
    • BASE: The revision you based your local changes on.
    • COMMITTED: The last revision in which an item changed.
    • PREV: The revision just before COMMITTED.
  • Checking Out a Specific Date

    You can also check out a revision based on a date using the -r option with a date enclosed in curly braces:

    bash
    svn co -r {2023-10-26} https://svn.example.com/repos/myproject

    This command will check out the revision that was current at the beginning of October 26, 2023, in the repository’s timezone. You can also specify times:

    bash
    svn co -r {2023-10-26T14:30:00-0500} https://svn.example.com/repos/myproject

    This will get the revision at 2:30 PM on October 26th, 2023 in the specified Timezone.

3. Advanced svn co Options

  • Depth Control (--depth)

    The --depth option controls how much of the repository tree is checked out. This is particularly useful for large repositories where you only need to work with a subset of the files. The possible values for --depth are:

    • empty: Checks out only the specified directory itself, without any files or subdirectories. This creates an empty placeholder directory.
    • files: Checks out the specified directory and its immediate files, but not any subdirectories.
    • immediates: Checks out the specified directory, its immediate files, and its immediate subdirectories (but not the contents of those subdirectories).
    • infinity (Default): Checks out the specified directory and all its contents, recursively. This is the standard behavior if --depth is not specified.

    • Practical Use Cases for Depth Control

      • Large Repositories: Avoid downloading the entire history of a massive project when you only need a small part.
      • Build Systems: Check out only the necessary files for a specific build configuration.
      • Selective Updates: Update only specific parts of a working copy without downloading everything.
    • Example:
      Imagine a repository with the following structure:

      /trunk
      /src
      /module1
      /module2
      /docs
      /tests

      To check out only the src directory and its immediate files (but not the contents of module1 and module2):

      bash
      svn co --depth files https://svn.example.com/repos/myproject/trunk/src src_working_copy

      This would create a directory src_working_copy with any top-level files from the src directory, but the directories module1 and module2 will not be checked out (although empty directories will be created as placeholders).

  • Ignoring Unversioned Items (--ignore-externals)

    • What are Externals?

      Subversion externals (svn:externals) are a mechanism to include files or directories from other repositories (or different locations within the same repository) into your working copy. They are defined using the svn:externals property on a directory.

    • Why Ignore Externals?

      Sometimes, you might not need or want to check out the external dependencies. For example:

      • Speed: External repositories might be slow to access.
      • Dependencies: You might not need the external dependencies for your current task.
      • Control: You might want to use a specific version of the external dependency, different from the one defined in the svn:externals property.

      The --ignore-externals option tells svn co to skip checking out any external dependencies:

      bash
      svn co --ignore-externals https://svn.example.com/repos/myproject

  • Sparse Checkouts (--set-depth)

    Sparse checkouts provide fine-grained control over which parts of a repository are included in your working copy. While --depth controls the initial checkout depth, --set-depth allows you to modify the depth of existing directories within your working copy after the initial checkout.

    • Combining --depth and --set-depth for fine-grained control

      You can use --depth on the initial svn co and then use svn update --set-depth to adjust the depth of specific directories. This is powerful for creating complex working copy layouts.

    • Real-world Example: Large Project, Specific Modules

      Let’s revisit the previous repository structure:

      /trunk
      /src
      /module1
      /module2
      /docs
      /tests

      Suppose you primarily work on module1 and occasionally need to access files in docs. You could do the following:
      1. Initial Checkout (only the top-level structure):
      bash
      svn co --depth immediates https://svn.example.com/repos/myproject/trunk myproject
      cd myproject

      1. Expand src/module1 fully:

        bash
        svn update --set-depth infinity src/module1

      2. Get only the files in docs:

        bash
        svn update --set-depth files docs

        Now, your working copy will have:

      3. src/module1: Fully checked out (all files and subdirectories).

      4. docs: Only the files directly within docs are checked out (subdirectories are empty placeholders).
      5. src/module2 and tests: Empty placeholder directories.
        This approach minimizes the amount of data downloaded and keeps your working copy focused on the areas you actively use.
  • Peg Revisions and Operative Revisions

    • Understanding Peg Revisions
      A peg revision specifies which revision of a file or directory you’re interested in, regardless of where it might have been moved or renamed in the repository’s history. It “pegs” your operation to a specific point in time for that item.

    • Understanding Operative Revisions
      An operative revision (or revision range) specifies when you want the operation to occur, relative to the peg revision. It determines which version of the item, as determined by the peg revision, you actually get.

    • Syntax and Usage
      You specify a peg revision using the @ symbol after the URL, followed by the revision number or keyword.

      bash
      svn co <repository_url>@<peg_revision> [<local_path>] [-r <operative_revision>]

      • If you only specify a peg revision, the operative revision defaults to HEAD.
      • If you specify both, the operative revision determines which version within the history of the item identified by the peg revision is used.
    • Example: Checking out a file as it existed at a specific revision, even if moved

      Imagine a file foo.txt was moved from /trunk/dirA/foo.txt to /trunk/dirB/foo.txt in revision 100. You want to check out the file as it existed in revision 90 (when it was still in dirA).

      bash
      svn co https://svn.example.com/repos/myproject/trunk/dirA/foo.txt@90

      This command uses foo.txt@90 as the peg revision. Since no operative revision is given, it defaults to HEAD. Subversion will find the item named foo.txt as of revision 90 (in dirA), and then check out the latest version of that item (which, in this case, will be revision 90, because that’s where the peg says the file existed).
      If you had wanted Revision 80 of the file as it was known in revision 90 (the peg revision), you would add the -r argument:
      bash
      svn co https://svn.example.com/repos/myproject/trunk/dirA/foo.txt@90 -r 80

  • Non-interactive mode (--non-interactive)
    This option prevents svn from prompting for any input, such as authentication credentials or conflict resolution choices. It is essential when running Subversion commands in scripts or automated environments. If any input is required, and --non-interactive is specified, the command will typically fail.

    bash
    svn co --non-interactive https://svn.example.com/repos/myproject

  • Quiet mode (--quiet or -q)
    The --quiet option suppresses most informational output from the svn co command, only showing errors or critical messages. This is useful for cleaning up the output in scripts or when you only care about the final result.

    bash
    svn co -q https://svn.example.com/repos/myproject

  • Configuring Authentication

    Accessing Subversion repositories often requires authentication. svn co provides several ways to handle this:

    • Username and Password (--username, --password)

      You can provide your username and password directly on the command line:

      bash
      svn co --username myuser --password mypassword https://svn.example.com/repos/myproject

      Security Warning: Using --password on the command line is highly discouraged because your password will be visible in your shell history and process list. It’s much better to use other authentication methods.

    • Storing Credentials (and security implications)

      Subversion can store your credentials (encrypted) in your user’s Subversion configuration directory. This avoids repeatedly typing your password. The first time you authenticate successfully, Subversion will usually ask if you want to store your credentials. You can control this behavior in the servers configuration file.

      • Location:

        • Linux/macOS: ~/.subversion/servers
        • Windows: %APPDATA%\Subversion\servers
      • Security: While the credentials are encrypted, they are still stored on your local machine. If your machine is compromised, your credentials could be stolen. Consider the security implications carefully.

    • Using SSH Keys

      If your repository is accessed via svn+ssh://, you can use SSH keys for authentication. This is generally the most secure and convenient method.

      1. Generate an SSH Key Pair: If you don’t already have one, use ssh-keygen to generate a public/private key pair.
      2. Add Your Public Key to the Server: Copy your public key (usually ~/.ssh/id_rsa.pub) to the authorized_keys file on the Subversion server (in the appropriate user’s home directory).
      3. Use the svn+ssh:// URL: When checking out, use the svn+ssh:// URL format:

        bash
        svn co svn+ssh://[email protected]/path/to/repository

        Subversion will automatically use your SSH keys for authentication. You may be prompted for your SSH key passphrase if you have one.

  • Configuring Proxy Servers (--config-option)

    If you are behind a proxy server, you need to configure Subversion to use it. You can do this using the --config-option option, which allows you to set arbitrary configuration options.

    bash
    svn co --config-option servers:global:http-proxy-host=myproxy.example.com \
    --config-option servers:global:http-proxy-port=8080 \
    --config-option servers:global:http-proxy-username=myuser \
    --config-option servers:global:http-proxy-password=mypassword \
    https://svn.example.com/repos/myproject

    It’s generally better to set these options permanently in your servers configuration file rather than on the command line every time. Edit the servers file (see location above) and add a [global] section:

    “`
    [global]
    http-proxy-host = myproxy.example.com
    http-proxy-port = 8080
    http-proxy-username = myuser
    http-proxy-password = mypassword

    Add any other global settings here

    “`

4. Common svn co Scenarios and Best Practices

  • Checking Out a New Project for the First Time

    This is the most basic scenario, as covered earlier:

    bash
    svn co <repository_url> [<local_path>]

  • Creating a Branch Working Copy

    To work on a branch, you check out the branch’s URL:

    bash
    svn co https://svn.example.com/repos/myproject/branches/myfeaturebranch myfeaturebranch-workingcopy

  • Creating a Tag Working Copy

    Tags are typically read-only snapshots, but you can check them out to examine their contents:

    bash
    svn co https://svn.example.com/repos/myproject/tags/v1.0 v1.0-workingcopy

    Remember that you typically should not commit changes to a tag working copy.

  • Working with Multiple Repositories

    You can have working copies from multiple, unrelated repositories. Each working copy will have its own .svn directory and be independent of the others. There is no special command required, just check out each one as needed.

  • Handling Conflicts During Checkout (Unlikely, but possible)

    Conflicts during svn co are rare. They usually only occur if:
    * The local directory you’re checking out into already exists and contains files with the same names as files in the repository, and those files are not managed by Subversion.
    * The repository structure has changed dramatically since the revision you’re trying to checkout (e.g., major directory renames), and you’re using a peg revision.

    If a conflict occurs, Subversion will report it. You’ll need to resolve the conflict manually by:
    * Deciding whether to keep the local file, the repository file, or merge them.
    * Removing the conflicting local files.
    * Using svn resolve (though this is more common during svn update).

  • Recovering from a Failed Checkout

    If a checkout fails partway through (e.g., due to a network interruption), you might have an incomplete working copy. You can usually try the svn co command again. Subversion is designed to be resilient, and it should be able to resume the checkout where it left off. If the checkout keeps failing, you might have network issues or server issues.

    In more severe cases, you might need to delete the partially created working copy directory and start over.

  • Best Practices for Repository Organization (and how it affects svn co)

    A well-organized repository makes it easier to find and check out the code you need. The standard Subversion layout is:

    /trunk (Main line of development)
    /branches (Separate lines for features, bug fixes, etc.)
    /tags (Snapshots of specific releases)

    • Consistency: Use a consistent naming convention for branches and tags.
    • Modularity: If your project has multiple modules, consider organizing them into separate directories within the repository. This allows for more granular checkouts.
    • Documentation: Include a README file in the root of your repository to explain the structure and how to check out the project.
  • Using svn co in Automated Scripts

    svn co can be used in shell scripts, build scripts, and other automated processes. Key considerations for scripting:

    • --non-interactive: Always use --non-interactive to prevent prompts.
    • Error Handling: Check the exit code of the svn co command. An exit code of 0 indicates success; any other value indicates an error. Your script should handle errors gracefully.
    • Authentication: Use SSH keys or store credentials securely (avoiding --password in the script).
    • Output Redirection: Redirect the output of svn co to a log file or use --quiet to suppress output.

    Example script snippet (Bash):

    “`bash

    !/bin/bash

    REPO_URL=”https://svn.example.com/repos/myproject”
    LOCAL_PATH=”myproject-workingcopy”

    if ! svn co –non-interactive “$REPO_URL” “$LOCAL_PATH”; then
    echo “Error: Checkout failed!”
    exit 1
    fi

    echo “Checkout successful.”
    exit 0
    “`

5. Troubleshooting svn co Issues

  • “Repository UUID does not match” Error

    This error occurs when the UUID (Universally Unique Identifier) of the repository in your working copy’s .svn directory doesn’t match the UUID of the repository you’re trying to access. This usually happens when:

    • The repository has been recreated or restored from a backup, resulting in a new UUID.
    • You’re trying to access a different repository with the same URL (less common).

    Solution:

    1. svn relocate (if the repository URL is the same, but the UUID has changed):

      bash
      svn relocate <new_repository_url> # Use the SAME URL, but force the UUID update

      Note: As of Subversion 1.7, svn relocate is deprecated for switching repository URLs. This is only used for updating the UUID.

    2. svn switch (if the repository URL has changed):

      bash
      svn switch <new_repository_url>

    3. Fresh Checkout: If svn relocate or svn switch don’t work, the safest solution is to delete the existing working copy and do a fresh svn co from the correct repository URL.

  • “Connection Refused” or “Network is Unreachable” Errors

    These errors indicate that your client cannot connect to the Subversion server. Possible causes:

    • Network Connectivity: You might not have a working internet connection, or there might be a firewall blocking access to the server.
    • Server Down: The Subversion server might be temporarily unavailable.
    • Incorrect URL: You might have a typo in the repository URL.
    • Proxy Server: You might need to configure Subversion to use a proxy server (see the --config-option section above).
    • DNS Issues: Your computer might be unable to resolve the hostname in the repository URL.

    Solutions:

    1. Check Network Connectivity: Verify that you can access other websites.
    2. Ping the Server: Try to ping the server’s hostname (if you know it) to see if it’s reachable.
    3. Verify the URL: Double-check the repository URL for typos.
    4. Contact the Server Administrator: If you suspect the server is down, contact the person or team responsible for managing the Subversion server.
    5. Configure Proxy Settings: If you’re behind a proxy, configure Subversion’s proxy settings.
    6. Check DNS Resolution: Use nslookup or dig to verify that the hostname resolves correctly.
  • “Checksum Mismatch” Error

    This error indicates that the downloaded file’s checksum (a cryptographic hash used to verify data integrity) doesn’t match the expected checksum. This can happen due to:

    • Network Corruption: Data corruption during the download process.
    • Server-Side Issues: A problem with the repository itself (rare).
    • Disk errors on your client computer.

    Solutions:

    1. Retry the Checkout: Try the svn co command again. A temporary network glitch might have caused the problem.
    2. Clean up the working copy and retry: If it still fails try running svn cleanup in the partially checked-out directory (if one exists), and then try svn co again.
    3. Check Disk Space and Health: Ensure you have enough free disk space and that your hard drive is healthy.
    4. Contact the Server Administrator: If the problem persists, there might be an issue with the repository.
  • “Path Not Found” Error

    This error means that the specified path within the repository doesn’t exist. Possible causes:

    • Typo in the URL: You might have made a mistake when typing the repository URL or path.
    • Incorrect Path: The directory or file you’re trying to check out might not exist at the specified location in the repository.
    • Permissions: You may not have read access to that specific part of the repository.

    Solutions:

    1. Double-Check the URL: Carefully review the URL for typos.
    2. Browse the Repository: If you have access to a web-based repository browser (like ViewVC or a web interface provided by your Subversion hosting provider), use it to verify the path. You can also use svn ls <repository_url> to list the contents of a directory in the repository.
    3. Verify Permissions: Make sure your user account has permission to read the path in question.
  • “Access Denied” Error

    This error means that you don’t have the necessary permissions to access the repository or the specified path within the repository.

    Solutions:

    1. Check Authentication: Make sure you’re providing the correct username and password (or using the correct SSH keys).
    2. Contact the Server Administrator: The server administrator needs to grant you the appropriate permissions to access the repository.
  • “Working Copy Locked” Errors

    In older versions of Subversion (pre-1.7), working copies could become “locked” if a Subversion operation was interrupted. This would prevent further operations on the working copy. Newer versions of Subversion use a different locking mechanism that is much more robust and less prone to problems.

    Solutions (for older versions):

    1. svn cleanup: The svn cleanup command is designed to resolve most locking issues. Run it in the root directory of your working copy:

      bash
      svn cleanup

      2. Manual Unlock (Rarely Needed, Use with Caution):
      If svn cleanup doesn’t work, you can try manually removing the lock files. This is risky and can corrupt your working copy if done incorrectly. The lock files are usually located in the .svn/lock file, and the .svn/wc.db file. Only do this if you understand the risks and have a backup of your working copy. It’s generally best to try a fresh checkout first.

  • Dealing with Externals Issues

    Problems with externals can manifest in various ways, such as:

    • External Repository Unavailable: The external repository might be down or inaccessible.
    • Incorrect External Definition: The svn:externals property might be misconfigured.
    • Authentication Issues: You might not have the necessary credentials to access the external repository.
    • Recursive Externals: Externals that point to other externals can create complex dependencies and potential problems.

    Solutions:

    1. Check Network Connectivity: Ensure you can access the external repository.
    2. Verify the svn:externals Property: Use svn propget svn:externals <directory> to examine the external definitions. Make sure the URLs are correct and that you have access to the external repositories.
    3. Use --ignore-externals: If you don’t need the external dependencies, use the --ignore-externals option to skip them.
    4. Update Externals: If you’ve made changes to the external repository, use svn update to update your working copy with the latest changes.
    5. Simplify Externals: Avoid deeply nested or recursive externals if possible.
  • Problems with Sparse Checkouts

    • Unexpected Empty Directories: You may get empty directories for items that haven’t been fully checked out. This is normal behavior with sparse checkouts. Use svn update --set-depth to expand the depth as needed.
    • Confusing Updates: If you’re not careful, you can end up with a working copy that’s a mix of different depths, making it difficult to understand what’s checked out and what’s not. Use svn info to check the depth of specific directories.
    • Accidentally Committing Empty Directories: Be careful not to accidentally commit empty directories that were created as placeholders for sparse checkouts.

6. svn co vs. Other Version Control Systems

  • svn co vs. git clone

    The most significant difference is between Subversion’s *central

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top