Last active
August 26, 2025 10:57
-
-
Save pordyna/75a90a90880827a720f9046f8377ce71 to your computer and use it in GitHub Desktop.
rsync with vscode that ignores all git ignored files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| /* workspace settings | |
| Put this in your worspace settings (.vscode/settings.json) | |
| */ | |
| "customsettings.rsync-tasks.remote_folder": "~/your_project", | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| /* | |
| Tasks for syncing files between local and remote machines using rsync. | |
| Put this in your User tasks.json file to make the commands available | |
| across workspaces. | |
| Put the following in your workspace settings.json file to set the remote folder: | |
| "customsettings.rsync-tasks.remote_folder": "/path/to/remote/folder" | |
| This way you can have different romete paths for different workspaces/projects. | |
| To use, open the command palette (Ctrl+Shift+P) and type "Tasks: Run Task". | |
| Then select the task you want to run. | |
| */ | |
| // See https://go.microsoft.com/fwlink/?LinkId=733558 | |
| // for the documentation about the tasks.json format | |
| "version": "2.0.0", | |
| "tasks": [ | |
| { | |
| // Generates .rsync-exclude file from local gitignore files | |
| // Finds all git repositories in workspace and combines their ignored files | |
| // Output: .rsync-exclude with relative paths from workspace root | |
| "label": "Generate .rsync-exclude (local)", | |
| "type": "shell", | |
| "command": "bash", | |
| "args": [ | |
| "-c", | |
| "find '${workspaceFolder}' -name '.git' -type d | while read gitdir; do repo=\"$(dirname \"$gitdir\")\"; echo \"# From $repo\"; git -C \"$repo\" ls-files --ignored --exclude-standard --others 2>/dev/null | sed \"s|^|$(realpath --relative-to='${workspaceFolder}' \"$repo\")/|\"; done > '${workspaceFolder}/.rsync-exclude'" | |
| ], | |
| "group": "build", | |
| "presentation": { | |
| "echo": true, | |
| "reveal": "silent", | |
| "focus": false, | |
| "panel": "shared" | |
| }, | |
| "problemMatcher": [] | |
| }, | |
| { | |
| // Generates .rsync-exclude file on remote machine from remote gitignore files | |
| // Uses SSH to find all git repos on remote and combine their ignored files | |
| // Output: .rsync-exclude on remote with relative paths from remote folder | |
| "label": "Generate .rsync-exclude (remote)", | |
| "type": "shell", | |
| "command": "ssh", | |
| "args": [ | |
| "${input:remote}", | |
| "find '${config:customsettings.rsync-tasks.remote_folder}' -name '.git' -type d | while read gitdir; do repo=\"$(dirname \"$gitdir\")\"; echo \"# From $repo\"; git -C \"$repo\" ls-files --ignored --exclude-standard --others 2>/dev/null | sed \"s|^|$(realpath --relative-to='${config:customsettings.rsync-tasks.remote_folder}' \"$repo\")/|\"; done > '${config:customsettings.rsync-tasks.remote_folder}/.rsync-exclude'" | |
| ], | |
| "group": "build", | |
| "presentation": { | |
| "echo": true, | |
| "reveal": "silent", | |
| "focus": false, | |
| "panel": "shared" | |
| }, | |
| "problemMatcher": [] | |
| }, | |
| { | |
| // Downloads the remote .rsync-exclude file to local as .rsync-exclude-remote | |
| // Depends on "Generate .rsync-exclude (remote)" to ensure file exists | |
| // Used by Sync Down tasks to exclude files based on remote gitignore | |
| "label": "Download .rsync-exclude from remote", | |
| "type": "shell", | |
| "command": "scp", | |
| "args": [ | |
| "${input:remote}:${config:customsettings.rsync-tasks.remote_folder}/.rsync-exclude", | |
| "${workspaceFolder}/.rsync-exclude-remote" | |
| ], | |
| "dependsOn": "Generate .rsync-exclude (remote)", | |
| "dependsOrder": "sequence", | |
| "group": "build", | |
| "presentation": { | |
| "echo": true, | |
| "reveal": "silent", | |
| "focus": false, | |
| "panel": "shared" | |
| }, | |
| "problemMatcher": [] | |
| }, | |
| { | |
| // Main sync up task: syncs local files to remote | |
| // Uses local .rsync-exclude file (generated from local gitignore files) | |
| // Includes backup functionality and excludes system files | |
| "label": "Sync Up", | |
| "type": "shell", | |
| "command": "rsync", | |
| "args": [ | |
| "-avrhb", | |
| "--backup-dir=.rsync_backups", | |
| "--exclude-from=${workspaceFolder}/.rsync-exclude", | |
| "--exclude='.rsync_backups'", | |
| "--exclude='.rsync-exclude'", | |
| "--exclude='.git/'", | |
| "--exclude='*/.git/'", | |
| "--exclude='.vscode/'", | |
| "--exclude='*/.idea/'", | |
| "--exclude='.idea/'", | |
| "--exclude='.venv/'", | |
| "--delete", | |
| "${workspaceFolder}/${config:customsettings.rsync-tasks.local_inner_path}", | |
| "${input:remote}:${config:customsettings.rsync-tasks.remote_folder}/" | |
| ], | |
| "dependsOn": "Generate .rsync-exclude (local)", | |
| "dependsOrder": "sequence", | |
| "problemMatcher": [] | |
| }, | |
| { | |
| // Main sync down task: syncs remote files to local | |
| // Uses remote .rsync-exclude file (downloaded from remote gitignore files) | |
| // Includes backup functionality and excludes system files | |
| "label": "Sync Down", | |
| "type": "shell", | |
| "command": "rsync", | |
| "args": [ | |
| "-avrhb", | |
| "--backup-dir=.rsync_backups", | |
| "--exclude-from=${workspaceFolder}/.rsync-exclude-remote", | |
| "--exclude='.rsync_backups'", | |
| "--exclude='.rsync-exclude-remote'", | |
| "--exclude='.git/'", | |
| "--exclude='*/.git/'", | |
| "--exclude='.vscode/'", | |
| "--exclude='*/.idea/'", | |
| "--exclude='.idea/'", | |
| "--exclude='.venv/'", | |
| "--delete", | |
| "${input:remote}:${config:customsettings.rsync-tasks.remote_folder}/", | |
| "${workspaceFolder}/${config:customsettings.rsync-tasks.local_inner_path}" | |
| ], | |
| "dependsOn": "Download .rsync-exclude from remote", | |
| "dependsOrder": "sequence", | |
| "problemMatcher": [] | |
| }, | |
| { | |
| // Sync up task with update mode: only transfers newer files | |
| // Uses -u flag to skip files that are newer on destination | |
| // Hidden from task list but used by "Sync newer" composite task | |
| "label": "Sync Up (update)", | |
| "hide": true, | |
| "type": "shell", | |
| "command": "rsync", | |
| "args": [ | |
| "-avrhbu", | |
| "--backup-dir=.rsync_backups", | |
| "--exclude-from=${workspaceFolder}/.rsync-exclude", | |
| "--exclude='.rsync_backups'", | |
| "--exclude='.rsync-exclude'", | |
| "--exclude='.git/'", | |
| "--exclude='*/.git/'", | |
| "--exclude='.vscode/'", | |
| "--exclude='*/.idea/'", | |
| "--exclude='.idea/'", | |
| "--exclude='.venv/'", | |
| "--delete", | |
| "${workspaceFolder}/${config:customsettings.rsync-tasks.local_inner_path}", | |
| "${input:remote}:${config:customsettings.rsync-tasks.remote_folder}/" | |
| ], | |
| "dependsOn": "Generate .rsync-exclude (local)", | |
| "dependsOrder": "sequence", | |
| "problemMatcher": [] | |
| }, | |
| { | |
| // Sync down task with update mode: only transfers newer files | |
| // Uses -u flag to skip files that are newer on destination | |
| // Hidden from task list but used by "Sync newer" composite task | |
| "label": "Sync Down (update)", | |
| "hide": true, | |
| "type": "shell", | |
| "command": "rsync", | |
| "args": [ | |
| "-avrhbu", | |
| "--backup-dir=.rsync_backups", | |
| "--exclude-from=${workspaceFolder}/.rsync-exclude-remote", | |
| "--exclude='.rsync_backups'", | |
| "--exclude='.rsync-exclude-remote'", | |
| "--exclude='.git/'", | |
| "--exclude='*/.git/'", | |
| "--exclude='.vscode/'", | |
| "--exclude='*/.idea/'", | |
| "--exclude='.idea/'", | |
| "--exclude='.venv/'", | |
| "--delete", | |
| "${input:remote}:${config:customsettings.rsync-tasks.remote_folder}/", | |
| "${workspaceFolder}/${config:customsettings.rsync-tasks.local_inner_path}" | |
| ], | |
| "dependsOn": "Download .rsync-exclude from remote", | |
| "dependsOrder": "sequence", | |
| "problemMatcher": [] | |
| }, | |
| { | |
| // Composite task that runs both sync directions with update mode | |
| // First syncs newer local files to remote, then newer remote files to local | |
| // Useful for bidirectional sync when you're not sure which direction has newer files | |
| "label": "Sync newer", | |
| "dependsOrder": "sequence", | |
| "dependsOn": [ | |
| "Sync Up (update)", | |
| "Sync Down (update)" | |
| ], | |
| "problemMatcher": [] | |
| } | |
| ], | |
| "inputs": [ | |
| { | |
| // Input for selecting which remote host to sync with | |
| // Add more options here as needed for different remote environments | |
| "type": "pickString", | |
| "id": "remote", | |
| "description": "Remote host", | |
| "options": [ | |
| "perlmutter", | |
| "hemera5", | |
| "hemera5-jump" | |
| ], | |
| "default": "perlmutter" | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment