svn问题处理

1.问题:svn客户端更新代码报错“svn: This client is too old to work with……”
原因:svn之间的版本差异造成。当我们已经用1.4版本的svn checkout一份work copy后,但某天我们尝试用高版本1.5svn更新,等再切换成1.4svn更新代码时就会出现此错误。具体请见”http://subversion.apache.org/faq.html#working-copy-format-change
解决方法:除了客户端升级之外,我们还可以通过对work copy进行降级处理。如下:

[root@test ~]# svn up /test/web
svn: This client is too old to work with working copy ‘/test/web’. You need
to get a newer Subversion client, or to downgrade this working copy.
See http://subversion.tigris.org/faq.html#working-copy-format-change
for details.

(1)下载脚本change-svn-wc-format.py

[root@test ~]# wget http://svn.apache.org/repos/asf/subversion/trunk/tools/client-side/change-svn-wc-format.py
[root@test ~]# python change-svn-wc-format.py --help
usage: change-svn-wc-format.py WC_PATH SVN_VERSION [--verbose] [--force] [--skip-unknown-format]
       change-svn-wc-format.py --help

Change the format of a Subversion working copy to that of SVN_VERSION.

  --skip-unknown-format    : skip directories with unknown working copy
                             format and continue the update

其中:
WC_PATH 表示你的work copy
SVN_VERSION 表示你当前使用的svn客户端版本号,如版本为1.4.2,就写成1.4
(2)执行命令

[root@test ~]# python change-svn-wc-format.py /web/app.cityrebank.com 1.4 --skip-unknown-format
Converted WC at '/test/web' into format 8 for Subversion 1.4

(3)svn up 再次更新,成功

脚本代码如下:

[root@test ~]# vim change-svn-wc-format.py
#!/usr/bin/env python
#
# change-svn-wc-format.py: Change the format of a Subversion working copy.
#
# ====================================================================
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you under the Apache License, Version 2.0 (the
#    "License"); you may not use this file except in compliance
#    with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing,
#    software distributed under the License is distributed on an
#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#    KIND, either express or implied.  See the License for the
#    specific language governing permissions and limitations
#    under the License.
# ====================================================================

import sys
import os
import getopt
try:
  my_getopt = getopt.gnu_getopt
except AttributeError:
  my_getopt = getopt.getopt

### The entries file parser in subversion/tests/cmdline/svntest/entry.py
### handles the XML-based WC entries file format used by Subversion
### 1.3 and lower.  It could be rolled into this script.

LATEST_FORMATS = { "1.4" : 8,
                   "1.5" : 9,
                   "1.6" : 10,
                   # Do NOT add format 11 here.  See comment in must_retain_fields
                   # for why.
                 }

def usage_and_exit(error_msg=None):
  """Write usage information and exit.  If ERROR_MSG is provide, that
  error message is printed first (to stderr), the usage info goes to
  stderr, and the script exits with a non-zero status.  Otherwise,
  usage info goes to stdout and the script exits with a zero status."""
  progname = os.path.basename(sys.argv[0])

  stream = error_msg and sys.stderr or sys.stdout
  if error_msg:
    stream.write("ERROR: %s\n\n" % error_msg)
  stream.write("""\
usage: %s WC_PATH SVN_VERSION [--verbose] [--force] [--skip-unknown-format]
       %s --help

Change the format of a Subversion working copy to that of SVN_VERSION.

  --skip-unknown-format    : skip directories with unknown working copy
                             format and continue the update

""" % (progname, progname))
  stream.flush()
  sys.exit(error_msg and 1 or 0)

def get_adm_dir():
  """Return the name of Subversion's administrative directory,
  adjusted for the SVN_ASP_DOT_NET_HACK environment variable.  See
  <http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt>
  for details."""
  return "SVN_ASP_DOT_NET_HACK" in os.environ and "_svn" or ".svn"

class WCFormatConverter:
  "Performs WC format conversions."
  root_path = None
  error_on_unrecognized = True
  force = False
  verbosity = 0

  def write_dir_format(self, format_nbr, dirname, paths):
    """Attempt to write the WC format FORMAT_NBR to the entries file
    for DIRNAME.  Throws LossyConversionException when not in --force
    mode, and unconvertable WC data is encountered."""

    # Avoid iterating in unversioned directories.
    if not (get_adm_dir() in paths):
      del paths[:]
      return

    # Process the entries file for this versioned directory.
    if self.verbosity:
      print("Processing directory '%s'" % dirname)
    entries = Entries(os.path.join(dirname, get_adm_dir(), "entries"))
    entries_parsed = True
    if self.verbosity:
      print("Parsing file '%s'" % entries.path)
    try:
      entries.parse(self.verbosity)
    except UnrecognizedWCFormatException, e:
      if self.error_on_unrecognized:
        raise
      sys.stderr.write("%s, skipping\n" % e)
      sys.stderr.flush()
      entries_parsed = False

    if entries_parsed:
      format = Format(os.path.join(dirname, get_adm_dir(), "format"))
      if self.verbosity:
        print("Updating file '%s'" % format.path)
      format.write_format(format_nbr, self.verbosity)
    else:
      if self.verbosity:
        print("Skipping file '%s'" % format.path)

    if self.verbosity:
      print("Checking whether WC format can be converted")
    try:
      entries.assert_valid_format(format_nbr, self.verbosity)
    except LossyConversionException, e:
      # In --force mode, ignore complaints about lossy conversion.
      if self.force:
        print("WARNING: WC format conversion will be lossy. Dropping "\
              "field(s) %s " % ", ".join(e.lossy_fields))
      else:
        raise

    if self.verbosity:
      print("Writing WC format")
    entries.write_format(format_nbr)

  def change_wc_format(self, format_nbr):
    """Walk all paths in a WC tree, and change their format to
    FORMAT_NBR.  Throw LossyConversionException or NotImplementedError
    if the WC format should not be converted, or is unrecognized."""
    for dirpath, dirs, files in os.walk(self.root_path):
      self.write_dir_format(format_nbr, dirpath, dirs + files)

class Entries:
  """Represents a .svn/entries file.

  'The entries file' section in subversion/libsvn_wc/README is a
  useful reference."""

  # The name and index of each field composing an entry's record.
  entry_fields = (
    "name",
    "kind",
    "revision",
    "url",
    "repos",
    "schedule",
    "text-time",
    "checksum",
    "committed-date",
    "committed-rev",
    "last-author",
    "has-props",
    "has-prop-mods",
    "cachable-props",
    "present-props",
    "conflict-old",
    "conflict-new",
    "conflict-wrk",
    "prop-reject-file",
    "copied",
    "copyfrom-url",
    "copyfrom-rev",
    "deleted",
    "absent",
    "incomplete",
    "uuid",
    "lock-token",
    "lock-owner",
    "lock-comment",
    "lock-creation-date",
    "changelist",
    "keep-local",
    "working-size",
    "depth",
    "tree-conflicts",
    "file-external",
  )

  # The format number.
  format_nbr = -1

  # How many bytes the format number takes in the file.  (The format number
  # may have leading zeroes after using this script to convert format 10 to
  # format 9 -- which would write the format number as '09'.)
  format_nbr_bytes = -1

  def __init__(self, path):
    self.path = path
    self.entries = []

  def parse(self, verbosity=0):
    """Parse the entries file.  Throw NotImplementedError if the WC
    format is unrecognized."""

    input = open(self.path, "r")

    # Read WC format number from INPUT.  Validate that it
    # is a supported format for conversion.
    format_line = input.readline()
    try:
      self.format_nbr = int(format_line)
      self.format_nbr_bytes = len(format_line.rstrip()) # remove '\n'
    except ValueError:
      self.format_nbr = -1
      self.format_nbr_bytes = -1
    if not self.format_nbr in LATEST_FORMATS.values():
      raise UnrecognizedWCFormatException(self.format_nbr, self.path)

    # Parse file into individual entries, to later inspect for
    # non-convertable data.
    entry = None
    while True:
      entry = self.parse_entry(input, verbosity)
      if entry is None:
        break
      self.entries.append(entry)

    input.close()

  def assert_valid_format(self, format_nbr, verbosity=0):
    if verbosity >= 2:
      print("Validating format for entries file '%s'" % self.path)
    for entry in self.entries:
      if verbosity >= 3:
        print("Validating format for entry '%s'" % entry.get_name())
      try:
        entry.assert_valid_format(format_nbr)
      except LossyConversionException:
        if verbosity >= 3:
          sys.stderr.write("Offending entry:\n%s\n" % entry)
          sys.stderr.flush()
        raise

  def parse_entry(self, input, verbosity=0):
    "Read an individual entry from INPUT stream."
    entry = None

    while True:
      line = input.readline()
      if line in ("", "\x0c\n"):
        # EOF or end of entry terminator encountered.
        break

      if entry is None:
        entry = Entry()

      # Retain the field value, ditching its field terminator ("\x0a").
      entry.fields.append(line[:-1])

    if entry is not None and verbosity >= 3:
      sys.stdout.write(str(entry))
      print("-" * 76)
    return entry

  def write_format(self, format_nbr):
    # Overwrite all bytes of the format number (which are the first bytes in
    # the file).  Overwrite format '10' by format '09', which will be converted
    # to '9' by Subversion when it rewrites the file.  (Subversion 1.4 and later
    # ignore leading zeroes in the format number.)
    assert len(str(format_nbr)) <= self.format_nbr_bytes
    format_string = '%0' + str(self.format_nbr_bytes) + 'd'

    os.chmod(self.path, 0600)
    output = open(self.path, "r+", 0)
    output.write(format_string % format_nbr)
    output.close()
    os.chmod(self.path, 0400)

class Entry:
  "Describes an entry in a WC."

  # Maps format numbers to indices of fields within an entry's record that must
  # be retained when downgrading to that format.
  must_retain_fields = {
      # Not in 1.4: changelist, keep-local, depth, tree-conflicts, file-externals
      8  : (30, 31, 33, 34, 35),
      # Not in 1.5: tree-conflicts, file-externals
      9  : (34, 35),
      10 : (),
      # Downgrading from format 11 (1.7-dev) to format 10 is not possible,
      # because 11 does not use has-props and cachable-props (but 10 does).
      # Naively downgrading in that situation causes properties to disappear
      # from the wc.
      #
      # Downgrading from the 1.7 SQLite-based format to format 10 is not
      # implemented.
      }

  def __init__(self):
    self.fields = []

  def assert_valid_format(self, format_nbr):
    "Assure that conversion will be non-lossy by examining fields."

    # Check whether lossy conversion is being attempted.
    lossy_fields = []
    for field_index in self.must_retain_fields[format_nbr]:
      if len(self.fields) - 1 >= field_index and self.fields[field_index]:
        lossy_fields.append(Entries.entry_fields[field_index])
    if lossy_fields:
      raise LossyConversionException(lossy_fields,
        "Lossy WC format conversion requested for entry '%s'\n"
        "Data for the following field(s) is unsupported by older versions "
        "of\nSubversion, and is likely to be subsequently discarded, and/or "
        "have\nunexpected side-effects: %s\n\n"
        "WC format conversion was cancelled, use the --force option to "
        "override\nthe default behavior."
        % (self.get_name(), ", ".join(lossy_fields)))

  def get_name(self):
    "Return the name of this entry."
    return len(self.fields) > 0 and self.fields[0] or ""

  def __str__(self):
    "Return all fields from this entry as a multi-line string."
    rep = ""
    for i in range(0, len(self.fields)):
      rep += "[%s] %s\n" % (Entries.entry_fields[i], self.fields[i])
    return rep

class Format:
  """Represents a .svn/format file."""

  def __init__(self, path):
    self.path = path

  def write_format(self, format_nbr, verbosity=0):
    format_string = '%d\n'
    if os.path.exists(self.path):
      if verbosity >= 1:
        print("%s will be updated." % self.path)
      os.chmod(self.path,0600)
    else:
      if verbosity >= 1:
        print("%s does not exist, creating it." % self.path)
    format = open(self.path, "w")
    format.write(format_string % format_nbr)
    format.close()
    os.chmod(self.path, 0400)

class LocalException(Exception):
  """Root of local exception class hierarchy."""
  pass

class LossyConversionException(LocalException):
  "Exception thrown when a lossy WC format conversion is requested."
  def __init__(self, lossy_fields, str):
    self.lossy_fields = lossy_fields
    self.str = str
  def __str__(self):
    return self.str

class UnrecognizedWCFormatException(LocalException):
  def __init__(self, format, path):
    self.format = format
    self.path = path
  def __str__(self):
    return ("Unrecognized WC format %d in '%s'; "
            "only formats 8, 9, and 10 can be supported") % (self.format, self.path)


def main():
  try:
    opts, args = my_getopt(sys.argv[1:], "vh?",
                           ["debug", "force", "skip-unknown-format",
                            "verbose", "help"])
  except:
    usage_and_exit("Unable to process arguments/options")

  converter = WCFormatConverter()

  # Process arguments.
  if len(args) == 2:
    converter.root_path = args[0]
    svn_version = args[1]
  else:
    usage_and_exit()

  # Process options.
  debug = False
  for opt, value in opts:
    if opt in ("--help", "-h", "-?"):
      usage_and_exit()
    elif opt == "--force":
      converter.force = True
    elif opt == "--skip-unknown-format":
      converter.error_on_unrecognized = False
    elif opt in ("--verbose", "-v"):
      converter.verbosity += 1
    elif opt == "--debug":
      debug = True
    else:
      usage_and_exit("Unknown option '%s'" % opt)

  try:
    new_format_nbr = LATEST_FORMATS[svn_version]
  except KeyError:
    usage_and_exit("Unsupported version number '%s'; "
                   "only 1.4, 1.5, and 1.6 can be supported" % svn_version)

  try:
    converter.change_wc_format(new_format_nbr)
  except LocalException, e:
    if debug:
      raise
    sys.stderr.write("%s\n" % e)
    sys.stderr.flush()
    sys.exit(1)

  print("Converted WC at '%s' into format %d for Subversion %s" % \
        (converter.root_path, new_format_nbr, svn_version))

if __name__ == "__main__":
  main()
针对打不开chm格式的网友 转换后为网页格式的<SVN操作手册中文版> 目录 译者序 前言 序言 读者 怎样阅读本书 本书约定 排版习惯 图标 本书组织结构 Subversion 1.1的新特性,svn客户端和linux下命令行。 目录 1. 简介 1.1. 什么是 TortoiseSVN? 1.2. TortoiseSVN 的历史 1.3. TortoiseSVN 的特性 1.4. 安装 TortoiseSVN 1.4.1. 系统要求 1.4.2. 安装 1.4.3. 语言包 1.4.4. 拼写检查器 2. Basic Version-Control Concepts 2.1. 版本库 2.2. 版本模型 2.2.1. 文件共享的问题 2.2.2. 锁定-修改-解锁 方案 2.2.3. 复制-修改-合并 方案 2.2.4. Subversion 怎么做? 2.3. Subversion 实战 2.3.1. 工作副本 2.3.2. 版本库的 URL 2.3.3. 修订版本 2.3.4. 工作副本怎样跟踪版本库 2.4. 摘要 3. 版本库 3.1. 创建版本库 3.1.1. 使用命令行工具创建版本库 3.1.2. 使用 TortoiseSVN 创建版本库 3.1.3. 本地访问版本库 3.1.4. 访问网络共享磁盘上的版本库 3.1.5. 版本库布局 3.2. 版本库备份 3.3. 服务器端钩子脚本 3.4. 检出链接 3.5. Accessing the Repository 3.6. 基于 svnserve 的服务器 3.6.1. 简介 3.6.2. 安装 svnserve 3.6.3. 运行 svnserve 3.6.3.1. 以服务形式运行 svnserve 3.6.4. svnserve 与基本认证 3.6.5. 使用 SASL 以便更安全 3.6.5.1. 什么是 SASL? 3.6.5.2. SASL 认证 3.6.5.3. SASL 加密 3.6.6. 使用 svn+ssh 认证 3.6.7. svnserve 基于路径的授权 3.7. 基于 Apache 的服务器 3.7.1. 简介 3.7.2. 安装 Apache 3.7.3. 安装 Subversion 3.7.4. 配置 3.7.5. 多版本库 3.7.6. 路径为基础的授权 3.7.7. 使用 Windows 域认证 3.7.8. 多重认证源 3.7.9. 用 SSL 使服务器更安全 3.7.10. 在虚拟 SSL 主机中使用客户端证书 4. 日常使用指南 4.1. 开始 4.1.1. 图标重载 4.1.2. 右键菜单 4.1.3. 拖放 4.1.4. 常用快捷方式 4.1.5. 认证 4.1.6. 最大化窗口 4.2. 导入数据到版本库 4.2.1. 导入 4.2.2. 导入适当的位置 4.2.3. 专用文件 4.3. 检出工作副本 4.3.1. 检出深度 4.4. 将你的修改提交到版本库 4.4.1. 提交对话框 4.4.2. 修改列表 4.4.3. Excluding Items from the Commit List 4.4.4. 提交日志信息 4.4.5. 提交进程 4.5. 用来自别人的修改更新你的工作副本 4.6. 解决冲突 4.6.1. File Conflicts 4.6.2. Tree Conflicts 4.6.2.1. Local delete, incoming edit upon update 4.6.2.2. Local edit, incoming delete upon update 4.6.2.3. Local delete, incoming delete upon update 4.6.2.4. Local missing, incoming edit upon merge 4.6.2.5. Local edit, incoming delete upon merge 4.6.2.6. Local delete, incoming delete upon merge 4.7. 获得状态信息 4.7.1. 图标重载 4.7.2. 在 Windows 资源管理器中的 TortoiseSVN 列 4.7.3. 本地与远程状态 4.7.4. 查看差别 4.8. 修改列表 4.9. 版本日志对话框 4.9.1. 调用版本日志对话框 4.9.2. 版本日志动作 4.9.3. 获得更多信息 4.9.4. 获取更多的日志信息 4.9.5. 当前工作副本的版本 4.9.6. 合并跟踪特性 4.9.7. 修改日志消息和作者 4.9.8. 过滤日志信息 4.9.9. 统计信息 4.9.9.1. 统计页 4.9.9.2. 作者提交次数统计页 4.9.9.3. 按日期提交统计页 4.9.10. 离线方式 4.9.11. 刷新视图 4.10. 查看差异 4.10.1. 文件差异 4.10.2. 行结束符和空白选项 4.10.3. 比较文件夹 4.10.4. 使用 TortoiseIDiff 进行比较的图像 4.10.5. 其他的比较/合并工具 4.11. 添加新文件和目录 4.12. Copying/Moving/Renaming Files and Folders 4.13. 忽略文件和目录 4.13.1. 忽略列表中的模式匹配 4.14. 删除、移动和改名 4.14.1. 正在删除文件/文件夹 4.14.2. 移动文件和文件夹 4.14.3. 改变文件名称大小写 4.14.4. 处理文件名称大小写冲突 4.14.5. 修复文件改名 4.14.6. 删除未版本控制的文件 4.15. 撤消更改 4.16. 清理 4.17. 项目设置 4.17.1. Subversion 属性 4.17.1.1. svn:keywords 4.17.1.2. 增加和编辑属性 4.17.1.3. Exporting and Importing Properties 4.17.1.4. 二进制属性 4.17.1.5. 自动属性设置 4.17.2. TortoiseSVN 项目属性 4.18. External Items 4.18.1. External Folders 4.18.2. External Files 4.19. 分支/标记 4.19.1. 创建一个分支或标记 4.19.2. 检出或者切换 4.20. 正在合并 4.20.1. 合并指定版本范围 4.20.2. 复兴分支 4.20.3. 合并两个不同的目录树 4.20.4. 合并选项 4.20.5. 预览合并结果 4.20.6. 合并跟踪 4.20.7. 子合并期间处理冲突 4.20.8. Merge a Completed Branch 4.20.9. Feature Branch Maintenance 4.21. 锁 4.21.1. 锁定在Subverion中是如何工作的 4.21.2. 取得锁定 4.21.3. 释放锁定 4.21.4. 检查锁定状态 4.21.5. 让非锁定的文件变成只读 4.21.6. 锁定钩子脚本 4.22. 创建并应用补丁 4.22.1. 创建一个补丁文件 4.22.2. 应用一个补丁文件 4.23. 谁修改了哪一行? 4.23.1. 追溯文件 4.23.2. 追溯不同点 4.24. 版本库浏览器 4.25. 版本分支图 4.25.1. 版本图节点 4.25.2. Changing the View 4.25.3. 使用图 4.25.4. 刷新视图 4.25.5. Pruning Trees 4.26. 导出一个Subversion工作副本 4.26.1. 从版本控制里移除删除工作副本 4.27. 重新定位工作副本 4.28. 与 BUG 跟踪系统/问题跟踪集成 4.28.1. Adding Issue Numbers to Log Messages 4.28.1.1. Issue Number in Text Box 4.28.1.2. Issue Numbers Using Regular Expressions 4.28.2. Getting Information from the Issue Tracker 4.29. 与基于 WEB 的版本库浏览器集成 4.30. TortoiseSVN的设置 4.30.1. 常规设置 4.30.1.1. 右键菜单配置 4.30.1.2. TSVN对话框设置一 4.30.1.3. TSVN对话框设置二 4.30.1.4. TortoiseSVN 颜色设置 4.30.2. Revision Graph Settings 4.30.2.1. Revision Graph Colors 4.30.3. 图标叠加设置 4.30.3.1. 图标集选择 4.30.4. 网络设置 4.30.5. 外部程序设置 4.30.5.1. 差异查看器 4.30.5.2. 合并工具 4.30.5.3. 差异查看/合并工具的高级设置 4.30.5.4. 统一的差异查看器 4.30.6. 已保存数据的设置 4.30.7. 日志缓存 4.30.7.1. Cached Repositories 4.30.7.2. 日志缓存统计 4.30.8. 客户端钩子脚本 4.30.8.1. Issue Tracker Integration 4.30.9. TortoiseBlame 的设置 4.30.10. 注册表设置 4.30.11. Subversion 的工作文件夹 4.31. 最后步骤 5. SubWCRev 程序 5.1. SubWCRev 命令行 5.2. 关键字替换 5.3. 关键字例子 5.4. COM 接口 A. 常见问题(FAQ) B. 如何实现 … B.1. 一次移动或复制多个文件 B.2. 强制用户写日志 B.2.1. 服务器端的钩子脚本(Hook-script) B.2.2. 工程(Project)属性 B.3. 从版本库里更新选定的文件到本地 B.4. Roll back (Undo) revisions in the repository B.4.1. 使用版本日志对话框 B.4.2. 使用合并对话框 B.4.3. 使用 svndumpfilter B.5. Compare two revisions of a file or folder B.6. 包含一个普通的子项目 B.6.1. 使用 svn:externals B.6.2. 使用嵌套工作副本 B.6.3. 使用相对位置 B.7. 创建到版本库的快捷方式 B.8. 忽略已经版本控制的文件 B.9. 从工作副本删除版本信息 B.10. 删除工作副本 C. Useful Tips For Administrators C.1. 通过组策略部署 TortoiseSVN C.2. 重定向升级检查 C.3. 设置 SVN_ASP_DOT_NET_HACK 环境变量 C.4. 禁用上下文菜单 D. TortoiseSVN 操作 D.1. TortoiseSVN 命令 D.2. TortoiseIDiff 命令 E. 命令行交叉索引 E.1. 约定和基本规则 E.2. TortoiseSVN 命令 E.2.1. 检出 E.2.2. 更新 E.2.3. 更新到版本 E.2.4. 提交 E.2.5. 差异 E.2.6. 显示日志 E.2.7. 检查所作的修改 E.2.8. 版本图 E.2.9. 版本库浏览器 E.2.10. 编辑冲突 E.2.11. 已解决 E.2.12. 改名 E.2.13. 删除 E.2.14. 恢复 E.2.15. 清理 E.2.16. 获得锁 E.2.17. 释放锁 E.2.18. 分支/标记 E.2.19. 切换 E.2.20. 合并 E.2.21. 输出 E.2.22. 重新定位 E.2.23. 在当前位置创建版本库 E.2.24. 添加 E.2.25. 导入 E.2.26. 追溯 E.2.27. 加入忽略列表 E.2.28. 创建补丁 E.2.29. 应用补丁(Apply Patch) F. 实现细节 F.1. 图标重载 G. 用 SSH 使服务器更安全 G.1. 配置 Linux 服务器 G.2. 配置 Windows 服务器 G.3. 用于 TortoiseSVN 的 SSH 客户端工具 G.4. 创建 OpenSSH 证书 G.4.1. 使用 ssh-keygen 创建密钥 G.4.2. 使用 PuTTYgen 创建密钥 G.5. 使用 PuTTY 测试 G.6. 使用 TortoiseSVN 测试 SSH G.7. SSH 配置参数 6. IBugtraqProvider interface 6.1. The IBugtraqProvider interface 6.2. The IBugtraqProvider2 interface
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值