Skip to content

Instantly share code, notes, and snippets.

@mzpqnxow
Created March 15, 2025 16:46
Show Gist options
  • Save mzpqnxow/353b6dc4c7d9a273e2253f4d03def0cb to your computer and use it in GitHub Desktop.
Save mzpqnxow/353b6dc4c7d9a273e2253f4d03def0cb to your computer and use it in GitHub Desktop.
Rebuild local files from pristine SVN
#
# This is roughly equivalent to `svn export`
# Useful when you have a .svn directory but are unable to reach the SVN
# repository that it came from (e.g. a network-based one)
# If you have /tmp/someworking/.svn:
# $ python rebuild.py /tmp/someworking /tmp/rebuilt
# That will unpack all of the pristine files into /tmp/rebuilt
#
# mzpqnxow (by way of LLMs, with a few minor fixes)
#
import os
import sqlite3
import shutil
def rebuild_working_copy(wc_path: str) -> None:
"""
Rebuilds the working copy from the .svn metadata.
Args:
wc_path: The root directory of your working copy (the directory that contains the .svn folder).
"""
svn_dir = os.path.join(wc_path, ".svn")
db_path = os.path.join(svn_dir, "wc.db")
pristine_path = os.path.join(svn_dir, "pristine")
if not os.path.exists(db_path):
print("wc.db not found. Is this a valid SVN working copy?")
return
# Connect to the wc.db SQLite database.
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# In SVN 1.7 and later, the NODES table holds the metadata.
# We'll select all items at the base layer (op_depth = 0) to get the original state.
cursor.execute("SELECT local_relpath, checksum, kind FROM NODES WHERE op_depth = 0")
rows = cursor.fetchall()
for local_relpath, checksum, kind in rows:
# Build the target path in the working copy.
target_path = os.path.join(wc_path, local_relpath)
if kind == "dir":
# Create the directory if it doesn't exist.
if not os.path.exists(target_path):
os.makedirs(target_path)
print(f"Created directory: {target_path}")
elif kind == "file":
# Files are stored in the pristine store.
# The checksum is stored as "sha1-<hash>".
if checksum.startswith("sha1-"):
hash_val = checksum[5:]
elif checksum.startswith("$sha1$"):
hash_val = checksum[6:]
else:
hash_val = checksum
# The file is located under .svn/pristine/<first two hash chars>/<hash_val>.svn-base
# subdir = hash_val[6:]
subdir = hash_val[0:2]
pristine_file = os.path.join(pristine_path, subdir, f"{hash_val}.svn-base")
if os.path.exists(pristine_file):
# Make sure the target directory exists.
os.makedirs(os.path.dirname(target_path), exist_ok=True)
shutil.copy2(pristine_file, target_path)
print(f"Recovered file: {target_path}")
else:
print(f"WARNING: Pristine file not found for {target_path} (expected at {pristine_file})")
else:
print(f"Unknown item kind: {kind} for path: {local_relpath}")
conn.close()
if __name__ == '__main__':
# Change this path to the root of your working copy
working_copy_path = "./"
rebuild_working_copy(working_copy_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment