SVN版本问题:This client is too old to work with working copy

【问题描述】:MyEclipse插件版本1.4,客户端TortoiseSVN 1.6.6,用客户端commit代码之后,无法在MyEclipse下对工程就行update等操作,提示错误信息:This client is too old to work with working copy '.'; please get a newer Subversion client

【问题分析】:网络一气搜集之后,发现问题所在:.svn目录,里面保存着svn需要的一些版本信息,用TortoiseSVN去操作,会在.svn里增加一些文件。如果TortoiseSVN的版本比插件版本要高,那么再回到低版本去工作,就会有兼容性错误,因为老的客户端无法识别那些。

【解决方法】:

方案1(未试验,理论可行):
在线更新安装插件
help->sofeware updates-> find and install

方案2(测试可行):
一、下载:change-svn-wc-format.py(见附件) ,这是一个Python做的script,所以需要先下载Python
注意:1)从目前来看,最好使用Python 2.6,如果是用最新的3.0版本会出现问题。 比如无法打开Script,出现异常等等。2)安装后在环境变量的path中追加python安装路径:"C:/Python26"
二、1)把change-svn-wc-format.py放入C盘根目录,运行-->cmd-->cd C:/
2)执行修改:
  C:/>change-svn-wc-format.py E:/work/sadapter 1.4 --force

参数说明:第一个change-svn-wc-format.py是执行脚本,第二个E:/work/sadapter是工程路径,第三个1.4是要修改到的版本,第四个--force不是必须的,在执行失败的情况下可以加入此参数。
3)结果:一阵processing:
引用
……Checking whether WC format can be converted
Writing WC format
Converted WC at 'E:/work/sadapter' into format 8 for Subversion 1.4

再去MyEclipse下更新done:
引用
……    A  E:/work/sadapter/src/main/resources/efs/sadapter/config/spring/order/orderContext.xml
    D  E:/work/sadapter/src/main/resources/efs/sadapter/config/spring/contract/custRouteContext.xml
    D  E:/work/sadapter/src/main/resources/efs/sadapter/config/spring/contract/custInfo.xml
    D  E:/work/sadapter/src/main/resources/efs/sadapter/config/spring/contract/custAcctContext.xml
    U  E:/work/sadapter/src/main/resources/efs/sadapter/config/spring/contract/contractContext.xml
    U  E:/work/sadapter/src/main/filter-resources/efs/sadapter/config/spring/applicationContext.xml
    Updated to revision 1235.
    ===== File Statistics: =====
    Deleted: 19
    Added: 14
    Updated: 17

或者将下列代码保存成change-svn-wc-format.py文件,chmod +x change-svn-wc-format.py修改执行权限,直接执行:sudo ../change-svn-wc-format.py kernel_imx 1.5

01.#!/usr/bin/env python   
02.#   
03.# change-svn-wc-format.py: Change the format of a Subversion working copy.   
04.#   
05.# ====================================================================   
06.#    Licensed to the Apache Software Foundation (ASF) under one   
07.#    or more contributor license agreements.  See the NOTICE file   
08.#    distributed with this work for additional information   
09.#    regarding copyright ownership.  The ASF licenses this file   
10.#    to you under the Apache License, Version 2.0 (the   
11.#    "License"); you may not use this file except in compliance   
12.#    with the License.  You may obtain a copy of the License at   
13.#   
14.#      http://www.apache.org/licenses/LICENSE-2.0   
15.#   
16.#    Unless required by applicable law or agreed to in writing,   
17.#    software distributed under the License is distributed on an   
18.#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY   
19.#    KIND, either express or implied.  See the License for the   
20.#    specific language governing permissions and limitations   
21.#    under the License.   
22.# ====================================================================   
23.  
24.import sys  
25.import os  
26.import getopt  
27.try:  
28.  my_getopt = getopt.gnu_getopt  
29.except AttributeError:  
30.  my_getopt = getopt.getopt  
31.  
32.### The entries file parser in subversion/tests/cmdline/svntest/entry.py   
33.### handles the XML-based WC entries file format used by Subversion   
34.### 1.3 and lower.  It could be rolled into this script.   
35.  
36.LATEST_FORMATS = { "1.4" : 8,  
37.                   "1.5" : 9,  
38.                   "1.6" : 10,  
39.                   # Do NOT add format 11 here.  See comment in must_retain_fields   
40.                   # for why.   
41.                 }  
42.  
43.def usage_and_exit(error_msg=None):  
44.  """Write usage information and exit.  If ERROR_MSG is provide, that 
45.  error message is printed first (to stderr), the usage info goes to 
46.  stderr, and the script exits with a non-zero status.  Otherwise, 
47.  usage info goes to stdout and the script exits with a zero status."""  
48.  progname = os.path.basename(sys.argv[0])  
49.  
50.  stream = error_msg and sys.stderr or sys.stdout  
51.  if error_msg:  
52.    stream.write("ERROR: %s/n/n" % error_msg)  
53.  stream.write("""/ 
54.usage: %s WC_PATH SVN_VERSION [--verbose] [--force] [--skip-unknown-format] 
55.       %s --help 
56. 
57.Change the format of a Subversion working copy to that of SVN_VERSION. 
58. 
59.  --skip-unknown-format    : skip directories with unknown working copy 
60.                             format and continue the update 
61. 
62.""" % (progname, progname))  
63.  stream.flush()  
64.  sys.exit(error_msg and 1 or 0)  
65.  
66.def get_adm_dir():  
67.  """Return the name of Subversion's administrative directory, 
68.  adjusted for the SVN_ASP_DOT_NET_HACK environment variable.  See 
69.  <http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt> 
70.  for details."""  
71.  return "SVN_ASP_DOT_NET_HACK" in os.environ and "_svn" or ".svn"  
72.  
73.class WCFormatConverter:  
74.  "Performs WC format conversions."  
75.  root_path = None  
76.  error_on_unrecognized = True  
77.  force = False  
78.  verbosity = 0  
79.  
80.  def write_dir_format(self, format_nbr, dirname, paths):  
81.    """Attempt to write the WC format FORMAT_NBR to the entries file 
82.    for DIRNAME.  Throws LossyConversionException when not in --force 
83.    mode, and unconvertable WC data is encountered."""  
84.  
85.    # Avoid iterating in unversioned directories.   
86.    if not (get_adm_dir() in paths):  
87.      del paths[:]  
88.      return  
89.  
90.    # Process the entries file for this versioned directory.   
91.    if self.verbosity:  
92.      print("Processing directory '%s'" % dirname)  
93.    entries = Entries(os.path.join(dirname, get_adm_dir(), "entries"))  
94.    entries_parsed = True  
95.    if self.verbosity:  
96.      print("Parsing file '%s'" % entries.path)  
97.    try:  
98.      entries.parse(self.verbosity)  
99.    except UnrecognizedWCFormatException, e:  
100.      if self.error_on_unrecognized:  
101.        raise  
102.      sys.stderr.write("%s, skipping/n" % e)  
103.      sys.stderr.flush()  
104.      entries_parsed = False  
105.  
106.    if entries_parsed:  
107.      format = Format(os.path.join(dirname, get_adm_dir(), "format"))  
108.      if self.verbosity:  
109.        print("Updating file '%s'" % format.path)  
110.      format.write_format(format_nbr, self.verbosity)  
111.    else:  
112.      if self.verbosity:  
113.        print("Skipping file '%s'" % format.path)  
114.  
115.    if self.verbosity:  
116.      print("Checking whether WC format can be converted")  
117.    try:  
118.      entries.assert_valid_format(format_nbr, self.verbosity)  
119.    except LossyConversionException, e:  
120.      # In --force mode, ignore complaints about lossy conversion.   
121.      if self.force:  
122.        print("WARNING: WC format conversion will be lossy. Dropping "/  
123.              "field(s) %s " % ", ".join(e.lossy_fields))  
124.      else:  
125.        raise  
126.  
127.    if self.verbosity:  
128.      print("Writing WC format")  
129.    entries.write_format(format_nbr)  
130.  
131.  def change_wc_format(self, format_nbr):  
132.    """Walk all paths in a WC tree, and change their format to 
133.    FORMAT_NBR.  Throw LossyConversionException or NotImplementedError 
134.    if the WC format should not be converted, or is unrecognized."""  
135.    for dirpath, dirs, files in os.walk(self.root_path):  
136.      self.write_dir_format(format_nbr, dirpath, dirs + files)  
137.  
138.class Entries:  
139.  """Represents a .svn/entries file. 
140. 
141.  'The entries file' section in subversion/libsvn_wc/README is a 
142.  useful reference."""  
143.  
144.  # The name and index of each field composing an entry's record.   
145.  entry_fields = (  
146.    "name",  
147.    "kind",  
148.    "revision",  
149.    "url",  
150.    "repos",  
151.    "schedule",  
152.    "text-time",  
153.    "checksum",  
154.    "committed-date",  
155.    "committed-rev",  
156.    "last-author",  
157.    "has-props",  
158.    "has-prop-mods",  
159.    "cachable-props",  
160.    "present-props",  
161.    "conflict-old",  
162.    "conflict-new",  
163.    "conflict-wrk",  
164.    "prop-reject-file",  
165.    "copied",  
166.    "copyfrom-url",  
167.    "copyfrom-rev",  
168.    "deleted",  
169.    "absent",  
170.    "incomplete",  
171.    "uuid",  
172.    "lock-token",  
173.    "lock-owner",  
174.    "lock-comment",  
175.    "lock-creation-date",  
176.    "changelist",  
177.    "keep-local",  
178.    "working-size",  
179.    "depth",  
180.    "tree-conflicts",  
181.    "file-external",  
182.  )  
183.  
184.  # The format number.   
185.  format_nbr = -1  
186.  
187.  # How many bytes the format number takes in the file.  (The format number   
188.  # may have leading zeroes after using this script to convert format 10 to   
189.  # format 9 -- which would write the format number as '09'.)   
190.  format_nbr_bytes = -1  
191.  
192.  def __init__(self, path):  
193.    self.path = path  
194.    self.entries = []  
195.  
196.  def parse(self, verbosity=0):  
197.    """Parse the entries file.  Throw NotImplementedError if the WC 
198.    format is unrecognized."""  
199.  
200.    input = open(self.path, "r")  
201.  
202.    # Read WC format number from INPUT.  Validate that it   
203.    # is a supported format for conversion.   
204.    format_line = input.readline()  
205.    try:  
206.      self.format_nbr = int(format_line)  
207.      self.format_nbr_bytes = len(format_line.rstrip()) # remove '/n'   
208.    except ValueError:  
209.      self.format_nbr = -1  
210.      self.format_nbr_bytes = -1  
211.    if not self.format_nbr in LATEST_FORMATS.values():  
212.      raise UnrecognizedWCFormatException(self.format_nbr, self.path)  
213.  
214.    # Parse file into individual entries, to later inspect for   
215.    # non-convertable data.   
216.    entry = None  
217.    while True:  
218.      entry = self.parse_entry(input, verbosity)  
219.      if entry is None:  
220.        break  
221.      self.entries.append(entry)  
222.  
223.    input.close()  
224.  
225.  def assert_valid_format(self, format_nbr, verbosity=0):  
226.    if verbosity >= 2:  
227.      print("Validating format for entries file '%s'" % self.path)  
228.    for entry in self.entries:  
229.      if verbosity >= 3:  
230.        print("Validating format for entry '%s'" % entry.get_name())  
231.      try:  
232.        entry.assert_valid_format(format_nbr)  
233.      except LossyConversionException:  
234.        if verbosity >= 3:  
235.          sys.stderr.write("Offending entry:/n%s/n" % entry)  
236.          sys.stderr.flush()  
237.        raise  
238.  
239.  def parse_entry(self, input, verbosity=0):  
240.    "Read an individual entry from INPUT stream."  
241.    entry = None  
242.  
243.    while True:  
244.      line = input.readline()  
245.      if line in ("", "/x0c/n"):  
246.        # EOF or end of entry terminator encountered.   
247.        break  
248.  
249.      if entry is None:  
250.        entry = Entry()  
251.  
252.      # Retain the field value, ditching its field terminator ("/x0a").   
253.      entry.fields.append(line[:-1])  
254.  
255.    if entry is not None and verbosity >= 3:  
256.      sys.stdout.write(str(entry))  
257.      print("-" * 76)  
258.    return entry  
259.  
260.  def write_format(self, format_nbr):  
261.    # Overwrite all bytes of the format number (which are the first bytes in   
262.    # the file).  Overwrite format '10' by format '09', which will be converted   
263.    # to '9' by Subversion when it rewrites the file.  (Subversion 1.4 and later   
264.    # ignore leading zeroes in the format number.)   
265.    assert len(str(format_nbr)) <= self.format_nbr_bytes  
266.    format_string = '%0' + str(self.format_nbr_bytes) + 'd'  
267.  
268.    os.chmod(self.path, 0600)  
269.    output = open(self.path, "r+", 0)  
270.    output.write(format_string % format_nbr)  
271.    output.close()  
272.    os.chmod(self.path, 0400)  
273.  
274.class Entry:  
275.  "Describes an entry in a WC."  
276.  
277.  # Maps format numbers to indices of fields within an entry's record that must   
278.  # be retained when downgrading to that format.   
279.  must_retain_fields = {  
280.      # Not in 1.4: changelist, keep-local, depth, tree-conflicts, file-externals   
281.      8  : (30, 31, 33, 34, 35),  
282.      # Not in 1.5: tree-conflicts, file-externals   
283.      9  : (34, 35),  
284.      10 : (),  
285.      # Downgrading from format 11 (1.7-dev) to format 10 is not possible,   
286.      # because 11 does not use has-props and cachable-props (but 10 does).   
287.      # Naively downgrading in that situation causes properties to disappear   
288.      # from the wc.   
289.      #   
290.      # Downgrading from the 1.7 SQLite-based format to format 10 is not   
291.      # implemented.   
292.      }  
293.  
294.  def __init__(self):  
295.    self.fields = []  
296.  
297.  def assert_valid_format(self, format_nbr):  
298.    "Assure that conversion will be non-lossy by examining fields."  
299.  
300.    # Check whether lossy conversion is being attempted.   
301.    lossy_fields = []  
302.    for field_index in self.must_retain_fields[format_nbr]:  
303.      if len(self.fields) - 1 >= field_index and self.fields[field_index]:  
304.        lossy_fields.append(Entries.entry_fields[field_index])  
305.    if lossy_fields:  
306.      raise LossyConversionException(lossy_fields,  
307.        "Lossy WC format conversion requested for entry '%s'/n"  
308.        "Data for the following field(s) is unsupported by older versions "  
309.        "of/nSubversion, and is likely to be subsequently discarded, and/or "  
310.        "have/nunexpected side-effects: %s/n/n"  
311.        "WC format conversion was cancelled, use the --force option to "  
312.        "override/nthe default behavior."  
313.        % (self.get_name(), ", ".join(lossy_fields)))  
314.  
315.  def get_name(self):  
316.    "Return the name of this entry."  
317.    return len(self.fields) > 0 and self.fields[0] or ""  
318.  
319.  def __str__(self):  
320.    "Return all fields from this entry as a multi-line string."  
321.    rep = ""  
322.    for i in range(0, len(self.fields)):  
323.      rep += "[%s] %s/n" % (Entries.entry_fields[i], self.fields[i])  
324.    return rep  
325.  
326.class Format:  
327.  """Represents a .svn/format file."""  
328.  
329.  def __init__(self, path):  
330.    self.path = path  
331.  
332.  def write_format(self, format_nbr, verbosity=0):  
333.    format_string = '%d/n'  
334.    if os.path.exists(self.path):  
335.      if verbosity >= 1:  
336.        print("%s will be updated." % self.path)  
337.      os.chmod(self.path,0600)  
338.    else:  
339.      if verbosity >= 1:  
340.        print("%s does not exist, creating it." % self.path)  
341.    format = open(self.path, "w")  
342.    format.write(format_string % format_nbr)  
343.    format.close()  
344.    os.chmod(self.path, 0400)  
345.  
346.class LocalException(Exception):  
347.  """Root of local exception class hierarchy."""  
348.  pass  
349.  
350.class LossyConversionException(LocalException):  
351.  "Exception thrown when a lossy WC format conversion is requested."  
352.  def __init__(self, lossy_fields, str):  
353.    self.lossy_fields = lossy_fields  
354.    self.str = str  
355.  def __str__(self):  
356.    return self.str  
357.  
358.class UnrecognizedWCFormatException(LocalException):  
359.  def __init__(self, format, path):  
360.    self.format = format  
361.    self.path = path  
362.  def __str__(self):  
363.    return ("Unrecognized WC format %d in '%s'; "  
364.            "only formats 8, 9, and 10 can be supported") % (self.format, self.path)  
365.  
366.  
367.def main():  
368.  try:  
369.    opts, args = my_getopt(sys.argv[1:], "vh?",  
370.                           ["debug", "force", "skip-unknown-format",  
371.                            "verbose", "help"])  
372.  except:  
373.    usage_and_exit("Unable to process arguments/options")  
374.  
375.  converter = WCFormatConverter()  
376.  
377.  # Process arguments.   
378.  if len(args) == 2:  
379.    converter.root_path = args[0]  
380.    svn_version = args[1]  
381.  else:  
382.    usage_and_exit()  
383.  
384.  # Process options.   
385.  debug = False  
386.  for opt, value in opts:  
387.    if opt in ("--help", "-h", "-?"):  
388.      usage_and_exit()  
389.    elif opt == "--force":  
390.      converter.force = True  
391.    elif opt == "--skip-unknown-format":  
392.      converter.error_on_unrecognized = False  
393.    elif opt in ("--verbose", "-v"):  
394.      converter.verbosity += 1  
395.    elif opt == "--debug":  
396.      debug = True  
397.    else:  
398.      usage_and_exit("Unknown option '%s'" % opt)  
399.  
400.  try:  
401.    new_format_nbr = LATEST_FORMATS[svn_version]  
402.  except KeyError:  
403.    usage_and_exit("Unsupported version number '%s'; "  
404.                   "only 1.4, 1.5, and 1.6 can be supported" % svn_version)  
405.  
406.  try:  
407.    converter.change_wc_format(new_format_nbr)  
408.  except LocalException, e:  
409.    if debug:  
410.      raise  
411.    sys.stderr.write("%s/n" % e)  
412.    sys.stderr.flush()  
413.    sys.exit(1)  
414.  
415.  print("Converted WC at '%s' into format %d for Subversion %s" % /  
416.        (converter.root_path, new_format_nbr, svn_version))  
417.  
418.if __name__ == "__main__":  
419.  main()  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值