A terminal UI for syncing files from a source folder to a destination folder on Windows.
Built with Bubble Tea (Go TUI framework).
CopyTUI is a one-way folder sync tool: it copies files from a source to a destination, detecting what changed and letting you resolve conflicts before anything is written.
SOURCE (reference) ------> DESTINATION (local copy)
- Copy mode (default): copies new/updated files to the destination. Files only in the destination are left untouched.
- Mirror mode: like Copy, but also deletes files in the destination that no longer exist in the source. Makes the destination an exact mirror.
- Conflict detection: when the destination file is newer than the source (or same time but different size), CopyTUI flags it as a conflict and asks you to decide.
- Per-file conflict resolution: for each conflict, choose:
[s]Source wins (overwrite destination)[e]Dest wins (keep destination file)[x]Skip (do nothing)
- Bulk resolution: resolve all remaining conflicts at once with
[S],[E], or[X]. - Dry run: preview what would happen without modifying any files.
- Modification time preserved: copied files keep the original timestamp, so re-running detects no changes (idempotent).
Requires Go 1.26+.
cd D:\Dev\CopyTUI
go build -o copytui.exe .This produces copytui.exe in the project root.
copytui.exeOr pre-fill the paths:
copytui.exe "D:\MyFolder" "E:\Backup\MyFolder"-
Setup screen: type the source and destination paths (or edit them if pre-filled). Toggle mode with
[m], toggle dry-run with[d]. Press[Enter]to scan. -
Review screen: see every planned action (COPY, DELETE, SKIP, CONFLICT) with file sizes. Navigate with Up/Down. Filter by type with
[1]-[5]. Resolve conflicts with[s]/[e]/[x]. Press[Enter]to proceed. -
Confirm screen: summary of what will happen. Press
[Y]to execute or[N]to go back. -
Sync screen: live progress bar and per-file status.
-
Done screen: success/failure count. Press
[Q]to quit or[R]to start over.
| Key | Action |
|---|---|
Tab |
Switch between source/dest input fields |
Enter |
Scan / proceed to next screen |
m |
Toggle Copy / Mirror mode |
d |
Toggle Dry Run |
Up/Down |
Navigate file list |
1-5 |
Filter: All / Conflicts / Copy / Delete / Skip |
s/e/x |
Resolve conflict: source / dest / skip |
S/E/X |
Bulk resolve all conflicts |
Y |
Confirm sync |
N / Esc |
Go back |
R |
Restart (on done screen) |
Q / Ctrl+C |
Quit |
For each file present in both source and destination:
| Condition | Result |
|---|---|
| Same size + same mtime (within 2s) | SKIP |
| Source is newer | COPY (safe overwrite) |
| Destination is newer | CONFLICT |
| Same mtime but different size | CONFLICT |
For files only in the source: always COPY.
For files only in the destination:
- Copy mode: ignored (kept).
- Mirror mode: DELETE.
CopyTUI/
main.go # Entry point, CLI flags
internal/
fsync/
engine.go # Sync engine: scan, diff, execute
engine_test.go # Unit tests
tui/
model.go # Bubble Tea model (all screens)
hack/
test_sync.go # Headless test harness
go.mod
go.sum
copytui.exe # Built binary
go test ./internal/fsync/ -vTests cover: copy mode (new/identical/newer/conflict files), mirror mode (orphan deletion), dry run (no filesystem changes), and byte formatting.
- One-way sync only (source -> dest). Not bidirectional.
- Conflict detection is based on file size and modification time, not content hashing. Two files with the same size and mtime but different content will be considered identical.
- No network paths (UNC
\\server\share) tested -- local drives only. - Large files are copied in full (no delta/block-level sync).