def replace_in_file(filename, old, new): """Replace all occurrences of the string OLD with the string NEW in the file at path FILENAME. Raise an error if nothing changes.""" # Note: we can't use '/' as a delimiter in the substitution command. if run_cmd('perl', '-pi.bak', '-e', "s," + old + "," + new + ",", filename) != 0: raise FixError("failed to substitute '" + old + "' with '" + new + "' in file '" + filename + "'.") if run_cmd_quiet('cmp', '--quiet', filename, filename + '.bak') != 1: raise FixError("failed to substitute '" + old + "' with '" + new + "' in file '" + filename + "'.") verbose_print("Replaced '" + old + "' in file '" + filename + "'\n" + " with '" + new + "'") os.remove(filename + '.bak')
def fix_one_error(repo_dir, rev): """Verify, and if there is an error we know how to fix, then fix it. Return False if no error, True if fixed, exception if can't fix.""" # Capture the output of 'svnadmin verify' (ignoring any debug-build output) svnadmin_err = grab_stderr([SVNADMIN, 'verify', '-q', '-r'+rev, repo_dir]) if svnadmin_err == []: return False try: if handle_one_error(repo_dir, rev, svnadmin_err): return True else: verbose_print("Unrecognized error message; trying 'svnlook' instead.") except FixError as e: print('warning:', e) verbose_print("Trying 'svnlook' instead.") # At this point, we've got an 'svnadmin' error that we don't know how to # handle. Before giving up, see if 'svnlook' gives a different error, # one that we *can* handle. # Capture the output of 'svnlook tree' (ignoring any debug-build output) svnlook_err = grab_stderr([SVNLOOK, 'tree', '-r'+rev, repo_dir]) if svnlook_err == []: print('warning: svnlook did not find an error') else: if handle_one_error(repo_dir, rev, svnlook_err): return True else: verbose_print("Unrecognized error message.") raise FixError("unable to fix r" + str(rev))
def check_formats(repo_dir): """Check that REPO_DIR isn't newer than we know how to handle.""" repos_format = int(open(os.path.join(repo_dir, 'format')).readline()) if repos_format not in [3,5]: raise FixError("Repository '%s' too new (format %d); try the version at %s" % (repo_dir, repos_format, URL)) fs_type = open(os.path.join(repo_dir, 'db', 'fs-type')).read().rstrip() if fs_type != 'fsfs': raise FixError("Repository '%s' has wrong FS backend: " "found '%s', expected '%s'" % (repo_dir, fs_type, 'fsfs')) fsfs_format = int(open(os.path.join(repo_dir, 'db', 'format')).readline()) if fsfs_format > MAX_FSFS_FORMAT: raise FixError("Filesystem '%s' is too new (format %d); try the version at %s" % (os.path.join(repo_dir, 'db'), fsfs_format, URL))
def check_formats(repo): """Check that REPO_DIR isn't newer than we know how to handle.""" if repo.repo_format not in [3, 5]: raise FixError( "Repository '%s' too new (format %d); try the version at %s" % (repo.path, repo.repo_format, URL)) if repo.fs_type != 'fsfs': raise FixError("Repository '%s' has wrong FS backend: " "found '%s', expected '%s'" % (repo.path, repo.fs_type, 'fsfs')) if repo.db_format > MAX_FSFS_FORMAT: raise FixError( "Filesystem '%s' is too new (format %d); try the version at %s" % (os.path.join(repo.path, 'db'), repo.db_format, URL))
def fix_id(repo_dir, rev, bad_id): # Find the GOOD_ID to replace BAD_ID. good_id = find_good_id(repo_dir, bad_id) # Replacement ID must be the same length, otherwise I don't know how to # reconstruct the file so as to preserve all offsets. if len(good_id) != len(bad_id): raise FixError("Can't handle a replacement ID with a different length: " + "bad id '" + bad_id + "', good id '" + good_id + "'") if good_id == bad_id: raise FixError("The ID supplied is already correct: " + "good id '" + good_id + "'") print "Fixing id: " + bad_id + " -> " + good_id replace_in_rev_file(repo_dir, rev, bad_id, good_id) fixed_ids[bad_id] = good_id
def replace_in_file(filename, old, new): """Replace the string OLD with the string NEW in file FILE. Replace all occurrences. Raise an error if nothing changes.""" verbose_print("Replacing '" + old + "' in file '" + filename + "'\n" + " with '" + new + "'") # Note: we can't use '/' as a delimiter in the substitution command. run_cmd('perl', '-pi.bak', '-e', "s," + old + "," + new + ",", filename) if run_cmd_quiet('cmp', '--quiet', filename, filename + '.bak') == 0: raise FixError("'" + filename + "' is unchanged after sed substitution.") os.remove(filename + '.bak')
def fix_rep_ref(repo_dir, rev, prefix, rep_rev, bad_offset, rep_size): """Fix a "DELTA <REP_REV> <BAD_OFFSET> <REP_SIZE>" or "text: <REP_REV> <BAD_OFFSET> <REP_SIZE> ..." line in the revision file for REV in REPO_DIR, where <BAD_OFFSET> is wrong. PREFIX is 'DELTA' or 'text:'. """ good_offset = find_good_rep_header(repo_dir, rep_rev, rep_size) old_line = ' '.join([prefix, rep_rev, bad_offset, rep_size]) new_line = ' '.join([prefix, rep_rev, good_offset, rep_size]) if good_offset == bad_offset: raise FixError("Attempting to fix a rep ref that appears to be correct: " + old_line) replace_in_rev_file(repo_dir, rev, old_line, new_line) print("Fixed rep ref:", old_line, "->", new_line)
pass # At this point, we've got an 'svnadmin' error that we don't know how to # handle. Before giving up, see if 'svnlook' gives a different error, # one that we *can* handle. # Capture the output of 'svnlook tree' (ignoring any debug-build output) svnlook_err = grab_stderr([SVNLOOK, 'tree', '-r'+rev, repo_dir]) if svnlook_err == []: print 'warning: svnlook did not find an error' else: if handle_one_error(repo_dir, rev, svnlook_err): return True raise FixError("unfixable error:\n " + "\n ".join(svnadmin_err)) def check_formats(repo_dir): """Check that REPO_DIR isn't newer than we know how to handle.""" repos_format = int(open(os.path.join(repo_dir, 'format')).readline()) if repos_format not in [3,5]: raise FixError("Repository '%s' too new (format %d); try the version at %s" % (repo_dir, repos_format, URL)) fs_type = open(os.path.join(repo_dir, 'db', 'fs-type')).read().rstrip() if fs_type != 'fsfs': raise FixError("Repository '%s' has wrong FS backend: " "found '%s', expected '%s'" % (repo_dir, fs_type, 'fsfs')) fsfs_format = int(open(os.path.join(repo_dir, 'db', 'format')).readline())
# At this point, we've got an 'svnadmin' error that we don't know how to # handle. Before giving up, see if 'svnlook' gives a different error, # one that we *can* handle. # Capture the output of 'svnlook tree' (ignoring any debug-build output) svnlook_err = grab_stderr([SVNLOOK, 'tree', '-r' + rev, repo_dir]) if svnlook_err == []: print 'warning: svnlook did not find an error' else: if handle_one_error(repo_dir, rev, svnlook_err): return True else: verbose_print("Unrecognized error message.") raise FixError("unable to fix r" + str(rev)) def check_formats(repo_dir): """Check that REPO_DIR isn't newer than we know how to handle.""" repos_format = int(open(os.path.join(repo_dir, 'format')).readline()) if repos_format not in [3, 5]: raise FixError( "Repository '%s' too new (format %d); try the version at %s" % (repo_dir, repos_format, URL)) fs_type = open(os.path.join(repo_dir, 'db', 'fs-type')).read().rstrip() if fs_type != 'fsfs': raise FixError("Repository '%s' has wrong FS backend: " "found '%s', expected '%s'" %