Automatically back up your PCSX2 memory card (.ps2) files to a remote Git repository whenever they change. This script monitors your PCSX2 memory card folder and automatically commits and pushes save file changes to your Git repository with intelligent batching and retry mechanisms.
- 🔄 Automatic Detection: Watches for changes and additions to
.ps2files in your memory card folder - 📝 Smart Filtering: Only
.ps2files are processed, ignoring Git files and temporary files - ⏱️ Intelligent Batching: Groups multiple rapid changes into single commits using a 5-second debounce delay
- 🔄 Retry Mechanism: Automatically retries failed pushes up to 3 times with 2-second delays
- 🔒 Git Lock Handling: Automatically removes Git lock files and performs lightweight cleanup
- 🌐 Internet Check: Verifies internet connection before starting
- 📁 File Validation: Ensures files exist and are not locked before processing
- 🛑 Graceful Shutdown: On exit (
Ctrl+C), attempts to push any pending changes - 🚀 Force Commit: Uses
--allow-emptyto ensure commits are created even when Git thinks there are no changes
-
Prerequisites
- Bun installed on your system
- Git configured with proper credentials for your repository
- PCSX2 memory card folder already set up
-
Install Dependencies
bun add chokidar
-
Place the Script Save the script file (e.g.,
script.js) in a convenient location (doesn't need to be in the memory card folder)
-
Set the Watch Folder Update the path in the script to match your PCSX2 memory card folder:
const WATCH_FOLDER = "C:\\PCSX2\\memcards";
-
Initialize Git Repository If not already done, initialize a Git repo in your memory card folder:
cd "C:\PCSX2\memcards" git init git remote add origin https://github.com/yourusername/your-repo.git git branch -M main git add . git commit -m "Initial save upload" git push -u origin main
-
Configure Git Identity Set your Git username and email if not already configured:
git config --global user.name "Your Name" git config --global user.email "[email protected]"
Start the watcher using Bun:
bun script.jsOn Startup:
🌐 Internet connected. Proceeding to start the script...
📁 Initializing file watcher for PCSX2 saves...
✅ Monitoring: C:\PCSX2\memcards
Starting PCSX2 save auto-push service.
When Files Change:
📝 Queuing file: Mcd001.ps2
⏰ Debounce period ended, processing queued files...
🔄 Processing 1 file(s): Mcd001.ps2
🧹 Performing lightweight Git cleanup...
✅ Git updated from remote
➕ Adding: Mcd001.ps2
📝 Force committing with message: "Update saves: Mcd001.ps2 - 2025-07-06T10:30:00.000Z"
🚀 Pushing to origin/main...
✅ Push complete for: Mcd001.ps2
To stop the script, press Ctrl+C. Any pending changes will be processed before shutdown.
-
Internet Connectivity Check The script first verifies internet connection by attempting to reach Google. If offline, it exits immediately.
-
File System Monitoring Uses
chokidarwith polling mode to reliably detect changes to.ps2files. The watcher:- Ignores hidden files, Git files, and temporary files
- Uses a 5-second stability threshold to ensure files are fully written
- Polls every 3 seconds for changes
-
Change Queue System When changes are detected:
- Files are added to a queue (
changeQueue) - A 5-second debounce timer starts/resets
- When the timer expires, all queued files are processed together
- Files are added to a queue (
-
Git Operations For each batch of files:
- Performs lightweight Git cleanup (removes lock files, pulls latest changes)
- Validates each file exists and waits for file locks to release
- Adds files to Git staging area
- Creates a commit with timestamp and file list
- Pushes to
origin/main
-
Error Handling & Retries
- Failed operations are retried up to 3 times with 2-second delays
- Git lock files are automatically removed
- Missing files are skipped with warnings
- Detailed error logging for troubleshooting
-
Graceful Shutdown On
Ctrl+C, the script processes any remaining queued files before exiting.
const MAX_RETRIES = 3; // Number of retry attempts
const RETRY_DELAY = 2000; // Delay between retries (ms)
const DEBOUNCE_DELAY = 5000; // Batching delay (ms)Change the file extension check in queueFile():
if (!fileName.endsWith(".ps2")) {
// Add other extensions: .sav, .mcr, etc.
return;
}Modify the commit message in gitPush():
const commitMessage = `Update saves: ${existingFiles.join(", ")} - ${new Date().toISOString()}`;Adjust the chokidar configuration:
const watcher = chokidar.watch(WATCH_FOLDER, {
persistent: true,
usePolling: true,
interval: 3000, // Polling interval
ignoreInitial: true,
ignored: ["**/.git/**", "**/.*", "**/tmp_*"],
awaitWriteFinish: {
stabilityThreshold: 5000, // Wait time for file stability
pollInterval: 500,
},
});"No internet connection detected"
- Ensure you have an active internet connection
- Check if firewall is blocking the script
- Try running as administrator
"Git lock file removed" messages
- This is normal - the script automatically handles Git lock files
- If persistent, ensure no other Git operations are running
"File not found, skipping"
- PCSX2 might be using temporary files during save operations
- The script waits for file stability before processing
Authentication errors
- Configure Git credentials:
git config --global credential.helper store - Or use SSH keys for authentication
- Ensure your repository remote URL is correct
Permission denied errors
- Run the script as administrator
- Check folder permissions for the memory card directory
The script provides detailed logging for troubleshooting:
- File queue operations
- Git command execution
- Error messages with context
- Retry attempts and status
- Polling Mode: Uses file system polling for reliability across different systems
- Debounce Batching: Groups rapid changes to avoid excessive commits
- File Lock Detection: Waits for files to be fully written before processing
- Lightweight Operations: Minimal Git operations to reduce overhead
This project is free and open-source. You're welcome to use, modify, and distribute it as needed.