Subversion source control for Positron
Positron-optimized fork of the SVN extension with enhanced features for data science workflows.
Original extension: JohnstonCode/svn-scm
Prerequisites
Note: This extension leverages your machine's SVN installation,
so you need to install SVN first.
Windows
If you use TortoiseSVN, make sure the option
Command Line Tools is checked during installation and
C:\Program Files\TortoiseSVN\bin is available in PATH.
Feedback & Contributing
- Please report any bugs, suggestions or documentation requests via the
Issues
- Feel free to submit
pull requests
Contributing as a Developer
Want to contribute? Great! See our CONTRIBUTING.md for:
- Development environment setup
- Testing & TDD workflow
- Code style guidelines
- Pull request process
For comprehensive guides, see:
Features
Checkout
You can checkout a SVN repository with the SVN: Checkout command in the Command Palette (Ctrl+Shift+P). You will be asked for the URL of the repository and the parent directory under which to put the local repository.
- Source Control View
- Quick Diffs in gutter
- Status Bar
- Create changelists
- Add files
- Revert edits
- Remove files
- Create branches
- Switch branches
- Create patches
- Diff changes
- Diff with external tools (Beyond Compare, etc.)
- Commit changes/changelists
- See commit messages
Configure external diff tools like Beyond Compare for large files (e.g., CSVs) where built-in diff is insufficient.
Setup:
- Set
svn.diff.tool to path of wrapper batch file (e.g., bcsvn.bat)
- Right-click file in Source Control → Diff with External Tool
- For Beyond Compare setup, see: https://www.scootersoftware.com/kb/vcs#svn
Blame Annotations
View line-by-line revision history directly in the editor.
Features:
- Gutter annotations: colored revision indicators (enabled by default)
- Inline messages: commit details at end of line, GitLens-style (enabled by default)
- Status bar: blame info for current line
- Auto-blame: automatically show blame when files open (enabled by default)
- Hover tooltips: detailed commit info on hover
Configuration:
See all 19 configuration options in Settings → search "svn.blame"
For advanced configuration, see Blame System Documentation.
Positron Integration
Enhanced integration with Posit's Positron IDE for data science workflows.
Connections Pane:
- View SVN repositories alongside database connections
- Quick checkout wizard with URL and directory inputs
- Repository metadata display (branch, revision, remote URL)
Setup: Automatically enabled when running in Positron. No configuration needed.
Privacy: All operations are local. No data sent to Posit or external services. See PRIVACY.md for details.
What is Positron? A next-generation IDE for data science by Posit PBC (creators of RStudio). Fork of VS Code optimized for R, Python, and Julia workflows.
Learn more: https://posit.co/products/ide/positron/
For technical details, see docs/POSITRON_INTEGRATION.md.
Authentication & Security
The extension provides secure authentication with multiple methods and comprehensive credential protection.
Security Warning: Upgrade from v2.17.229 or Earlier
⚠️ CRITICAL: Versions prior to v2.17.230 expose passwords in process listings. Upgrade immediately to v2.17.230+ to eliminate this security risk.
Authentication Methods
Recommended (in priority order):
SSH Key Authentication ⭐ BEST PRACTICE
Password Authentication (Secure with Credential Cache)
- Repository URL:
https://svn.example.com/repo
- Security: Credentials stored in SVN cache (
~/.subversion/auth/, mode 600)
- Setup: Extension prompts for password, automatically caches securely
- When to use: Quick testing, HTTPS-only repositories, personal projects
Public Repository (No Authentication)
- Repository URL:
http://svn.example.com/public-repo
- Security: No credentials needed
- When to use: Open-source projects, publicly accessible repositories
How Credential Caching Works
v2.17.230+ uses SVN's native credential cache for maximum security:
- You enter username/password in VS Code UI prompt
- Extension writes credentials to
~/.subversion/auth/svn.simple/<uuid> (file mode 600)
- SVN commands executed without
--password flag
- SVN reads credentials from cache automatically
- ✅ Result: No password exposure in process list, container logs, or CI/CD logs
Before v2.17.230:
$ ps aux | grep svn
user 12345 svn update --password "MyPassword123" # ❌ EXPOSED
After v2.17.230:
$ ps aux | grep svn
user 12345 svn update --username alice # ✅ SECURE (no password)
Authentication Method Indicators
Extension shows which auth method is active in the Output panel:
[auth: SSH key] - SSH key authentication (most secure)
[auth: password via credential cache] - Cached password (secure)
[auth: none - public repository] - No authentication required
Example output:
[my-project]$ svn update --username alice [auth: password via credential cache]
At revision 1234.
This helps verify your authentication is configured correctly.
Debugging Authentication Issues
Enable Verbose Output
- Open Command Palette (
Ctrl+Shift+P / Cmd+Shift+P)
- Run:
SVN: Show Output
- Check authentication method indicators in logs
Common Issues
Problem: "Authentication failed" but credentials are correct
[repo]$ svn update --username alice [auth: password via credential cache]
svn: E170001: Authentication failed
Solutions:
- Clear credential cache:
rm -rf ~/.subversion/auth/
- Re-enter credentials when prompted
- Verify repository URL is correct
- Check SVN server is accessible:
svn info <repo-url>
Problem: Extension prompts for password repeatedly
ℹ No credentials configured - will prompt if needed
Solutions:
- Ensure credentials are being cached (check
~/.subversion/auth/)
- Verify file permissions:
ls -la ~/.subversion/auth/svn.simple/ (should be 600)
- Try manual SVN command:
svn update (should not prompt if cache works)
Problem: Want to see raw error messages for debugging
Solution: Enable debug mode (⚠️ TEMPORARY ONLY):
{
"svn.debug.disableSanitization": true
}
⚠️ WARNING:
- Debug mode exposes credentials in logs
- Extension shows prominent warning when enabled
- Only enable temporarily for troubleshooting
- Disable immediately after debugging
When enabled, you'll see:
⚠️⚠️⚠️ SECURITY WARNING ⚠️⚠️⚠️
Error sanitization is DISABLED
Credentials WILL BE VISIBLE in logs
Disable: svn.debug.disableSanitization = false
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
Plus a dialog with [Disable Now] button.
Verify Authentication Setup
Check credential cache:
# List cached credentials
ls -la ~/.subversion/auth/svn.simple/
# Should show files with permissions: -rw------- (600)
Check SVN version:
svn --version
# Requires SVN 1.6+ for credential cache
Test repository access:
svn info <your-repo-url>
# Should show repository information without prompting
Best Practices
Production Environments
- ✅ Use SSH keys (
svn+ssh://)
- ✅ Enable MFA on SVN server
- ✅ Keep SVN client updated
- ❌ Never use
svn.debug.disableSanitization in production
- ❌ Avoid HTTP URLs (use HTTPS or svn+ssh://)
Development Workstations
- ✅ Use HTTPS with credential cache for personal projects
- ✅ Use SSH keys for shared/company repositories
- ✅ Protect
~/.subversion/auth/ directory (mode 700)
- ✅ Regularly update extension and SVN client
CI/CD Pipelines
- ✅ Use SSH keys stored in CI/CD secrets
- ✅ Use repository access tokens (if supported by SVN server)
- ❌ Never pass passwords via environment variables
- ❌ Never commit credentials to
.vscode/settings.json
Example GitHub Actions:
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SVN_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
- run: svn checkout svn+ssh://svn.example.com/repo
Security Features
Error Sanitization
- Automatic redaction of passwords, tokens, paths, URLs
- Active by default in all logs and error messages
- Protects against accidental credential exposure
SecretStorage Integration
- Passwords stored in OS keychain (encrypted)
- macOS: Keychain Access
- Windows: Credential Manager
- Linux: Secret Service (gnome-keyring, KWallet)
- Never stored in plaintext in extension settings
Credential Cache Protection
- Files stored with mode 600 (user-only access)
- Automatic cleanup of old credentials
- Isolated per repository/realm
Audit Trail
- All auth operations logged (credentials redacted)
- Authentication method always visible
- Debug mode warnings prevent accidental exposure
Troubleshooting Checklist
- [ ] Check authentication method indicator in Output panel
- [ ] Verify repository URL is correct (HTTPS vs svn+ssh://)
- [ ] Test SVN access outside VS Code:
svn info <repo-url>
- [ ] Check credential cache:
ls ~/.subversion/auth/svn.simple/
- [ ] Verify SVN version:
svn --version (requires 1.6+)
- [ ] Review error messages in Output panel
- [ ] Try clearing cache:
rm -rf ~/.subversion/auth/ and re-enter credentials
- [ ] For persistent issues, enable debug mode temporarily (see above)
Security Resources
For security vulnerabilities, use GitHub Security Advisories.
Credential Storage
The extension supports multiple credential storage modes via svn.auth.credentialMode:
| Mode |
Description |
auto (default) |
System keyring locally, extension storage remotely |
systemKeyring |
Always use OS credential manager |
extensionStorage |
Always use VS Code SecretStorage |
prompt |
Never store credentials |
Auto Mode (Recommended)
The default auto mode automatically selects the best storage:
- Local development: Uses system keyring (macOS Keychain, Windows Credential Manager, gnome-keyring)
- Remote SSH/WSL/Containers: Uses VS Code SecretStorage (works without keyring setup)
System Keyring Mode
Uses native credential managers:
- macOS: Keychain
- Windows: Credential Manager
- Linux: gnome-keyring, gpg-agent
For gpg-agent in SSH sessions, set GPG_TTY:
# Add to ~/.bashrc or ~/.zshrc
export GPG_TTY=$(tty)
Troubleshooting Auth
If password prompts cycle endlessly:
- Try
extensionStorage mode:
{ "svn.auth.credentialMode": "extensionStorage" }
- Restart extension host (Ctrl+Shift+P → "Developer: Restart Extension Host")
- Re-enter credentials when prompted
Auth Method Indicators
Watch the Output panel (SVN) for current mode:
[auth: system keyring (local)] - Using OS credential manager
[auth: extension storage (remote)] - Using VS Code SecretStorage
Settings
Here are all of the extension settings with their default values. To change any of these, add the relevant Config key and value to your VSCode settings.json file. Alternatively search for the config key in the settings UI to change its value.
{
// Timeout in seconds for SVN commands. Increase for slow remote connections.
"svn.auth.commandTimeout": 60,
// How SVN credentials are stored and retrieved.
"svn.auth.credentialMode": "auto" // values: ["auto","systemKeyring","extensionStorage","prompt"],
// Whether auto refreshing is enabled
"svn.autorefresh": true,
// Automatically blame files when opened
"svn.blame.autoBlame": true,
// Date format for blame annotations (relative: '2 days ago', absolute: '2025-11-18')
"svn.blame.dateFormat": "relative" // values: ["relative","absolute"],
// Fetch commit messages for blame (disabling speeds up blame significantly)
"svn.blame.enableLogs": true,
// Enable SVN blame functionality
"svn.blame.enabled": true,
// Date format for gutter annotations
"svn.blame.gutter.dateFormat": "relative" // values: ["relative","absolute"],
// Show blame annotations in editor gutter
"svn.blame.gutter.enabled": true,
// Show colored revision indicators in gutter (left of line numbers)
"svn.blame.gutter.showIcons": true,
// Show text annotations in gutter (author, revision, date)
"svn.blame.gutter.showText": null,
// Gutter template. Available: ${author}, ${revision}, ${date}, ${message}
"svn.blame.gutter.template": "${author} (${revision}) ${date}",
// Show inline blame only for current line (cursor position)
"svn.blame.inline.currentLineOnly": true,
// Show inline blame annotations at end of each line (GitLens-style)
"svn.blame.inline.enabled": true,
// Opacity of inline blame annotations (0.0 to 1.0, default: 0.5)
"svn.blame.inline.opacity": 0.5,
// Fetch and show commit messages in inline annotations (slower)
"svn.blame.inline.showMessage": null,
// Inline annotation template. Variables: ${author}, ${revision}, ${date}, ${message}
"svn.blame.inline.template": " ${author}, ${date} (r${revision}) • ${message}",
// Maximum number of lines before warning about large file (0 to disable)
"svn.blame.largeFileLimit": 3000,
// Show warning before blaming large files
"svn.blame.largeFileWarning": true,
// Show uncommitted changes in blame view
"svn.blame.showWorkingCopyChanges": true,
// Show blame information in status bar
"svn.blame.statusBar.enabled": true,
// Status bar template. Available: ${author}, ${revision}, ${date}, ${message}
"svn.blame.statusBar.template": "$(person) ${author}, $(clock) ${date} - ${message}",
// Select all files when commit changes
"svn.commit.changes.selectedAll": true,
// Check empty message before commit
"svn.commit.checkEmptyMessage": true,
// Set file to status resolved after fix conflicts
"svn.conflicts.autoResolve": null,
"svn.debug.disableSanitization": null,
// Encoding of svn output if the output is not utf-8. When this parameter is null, the encoding is automatically detected. Example: 'windows-1252'.
"svn.default.encoding": null,
// The default location to checkout a svn repository.
"svn.defaultCheckoutDirectory": null,
// When a file is deleted, what SVN should do? `none` - Do nothing, `prompt` - Ask the action, `remove` - automatically remove from SVN
"svn.delete.actionForDeletedFiles": "prompt" // values: ["none","prompt","remove"],
// Ignored files/rules for `svn.delete.actionForDeletedFiles`(Ex.: file.txt or **/*.txt)
"svn.delete.ignoredRulesForDeletedFiles": [],
// Controls whether to automatically detect svn externals.
"svn.detectExternals": true,
// Controls whether to automatically detect svn on ignored folders.
"svn.detectIgnored": true,
// Path to external diff tool (e.g., 'C:\\Program Files\\Beyond Compare 5\\BCompare.exe'). Command uses svn diff --diff-cmd.
"svn.diff.tool": null,
// Show diff changes using latest revision in the repository. Set false to use latest revision in local folder
"svn.diff.withHead": true,
// Whether svn is enabled
"svn.enabled": true,
// Try the experimental encoding detection
"svn.experimental.detect_encoding": null,
// Priority of encoding
"svn.experimental.encoding_priority": [],
// Ignores the warning when SVN is missing
"svn.ignoreMissingSvnWarning": null,
// List of SVN repositories to ignore.
"svn.ignoreRepositories": null,
// Ignores the warning when working copy is too old
"svn.ignoreWorkingCopyIsTooOld": null,
// Regex to detect path for 'branches' in SVN URL, 'null' to disable. Subpath use 'branches/[^/]+/([^/]+)(/.*)?' (Ex.: 'branches/...', 'versions/...')
"svn.layout.branchesRegex": "branches/([^/]+)(/.*)?",
// Regex group position for name of branch
"svn.layout.branchesRegexName": 1,
// Set true to show 'branches/<name>' and false to show only '<name>'
"svn.layout.showFullName": true,
// Regex group position for name of tag
"svn.layout.tagRegexName": 1,
// Regex to detect path for 'tags' in SVN URL, 'null' to disable. Subpath use 'tags/[^/]+/([^/]+)(/.*)?'. (Ex.: 'tags/...', 'stamps/...')
"svn.layout.tagsRegex": "tags/([^/]+)(/.*)?",
// Regex to detect path for 'trunk' in SVN URL, 'null' to disable. (Ex.: '(trunk)', '(main)')
"svn.layout.trunkRegex": "(trunk)(/.*)?",
// Regex group position for name of trunk
"svn.layout.trunkRegexName": 1,
// Show colored dots for commit authors in history view (helps distinguish authors visually)
"svn.log.authorColors": true,
// Number of commit messages to log
"svn.log.length": 50,
// Maximum depth to find subfolders using SVN
"svn.multipleFolders.depth": 4,
// Allow to find subfolders using SVN
"svn.multipleFolders.enabled": null,
// Folders to ignore using SVN
"svn.multipleFolders.ignore": ["**/.git","**/.hg","**/vendor","**/node_modules"],
// How often to log authentication mode in SVN output panel.
"svn.output.authLogging": "once" // values: ["once","always","never"],
// Path to the svn executable
"svn.path": null,
// Maximum XML tags to parse (increase for very large repos with 100k+ files). Set to 0 for unlimited.
"svn.performance.maxXmlTags": 500000,
// Only show previous commits for a given user. Requires svn >= 1.8
"svn.previousCommitsUser": null,
// Refresh remote changes on refresh command
"svn.refresh.remoteChanges": null,
// Set the interval in seconds to check changed files on remote repository and show in statusbar. 0 to disable
"svn.remoteChanges.checkFrequency": 300,
// Show the output window when the extension starts
"svn.showOutput": null,
// Show the update message when update is run
"svn.showUpdateMessage": true,
// Set left click functionality on changes resource state
"svn.sourceControl.changesLeftClick": "open diff" // values: ["open","open diff"],
// Combine the svn external in the main if is from the same server.
"svn.sourceControl.combineExternalIfSameServer": null,
// Allow to count unversioned files in status count
"svn.sourceControl.countUnversioned": true,
// Hide unversioned files in Source Control UI
"svn.sourceControl.hideUnversioned": null,
// Ignore unversioned files like .gitignore, Configuring this will overlook the default ignore rule
"svn.sourceControl.ignore": [],
// Changelists to ignore on commit
"svn.sourceControl.ignoreOnCommit": ["ignore-on-commit"],
// Changelists to ignore on status count
"svn.sourceControl.ignoreOnStatusCount": ["ignore-on-commit"],
// Show confirmation dialog before removing items from disk
"svn.sparse.confirmExclude": true,
// Timeout for download operations in minutes. Large folders may need longer timeouts.
"svn.sparse.downloadTimeoutMinutes": 10,
// Warn before downloading files larger than this size (in MB). Set to 0 to disable.
"svn.sparse.largeFileWarningMb": 10,
// Timeout for folder pre-scan in seconds. Pre-scan counts files for progress display.
"svn.sparse.preScanTimeoutSeconds": 30,
// Set to ignore externals definitions on update (add --ignore-externals)
"svn.update.ignoreExternals": true
}