code-porter: A Code Workspace Migration Tool
Switching computers and copying dozens of projects by hand? You're either lazy or stupid. I wrote code-porter: auto-scan, smart packing (bundle/zip), dirty repos keep uncommitted changes, one uvx command. Zero dependencies, cross-platform, plug in a USB stick and you're done. Don't ask why I don't use rsync—does it understand your project structure?
目录9 个章节
Introduction
Recently I switched from Windows to a MacBook Pro and ran into a practical problem: I had dozens of projects scattered across various directories—Python, TypeScript, Go, C#. Some were proper Git repos; some were experimental code AI had generated for me that didn't even have a .git.
In theory, you'd just push Git repos to a remote and copy the non-Git projects. In practice: some repos had uncommitted changes, some had no remote configured at all, and some were shallow clones that couldn't be bundled directly. Handling them one by one? A nightmare.
I'd tried scp and rsync before, but Windows support for these tools is an absolute disaster—error after error, practically unusable. What about just zipping up the project directories? That doesn't work either—the .venv and node_modules in each project easily run to several GB, and excluding them one by one would drive you insane.
So I wrote code-porter, a purely local code workspace migration tool. It automatically scans project directories, smartly decides the packing strategy for each project, then one-click exports them as git bundles or zip archives. On the import side, you only need a manifest file to restore them in batch.
Why not cloud sync? Because my projects add up to tens of GB, iCloud sync would take forever, and some projects have
.envfiles I don't want to risk uploading to the cloud. Purely local, copy to a USB stick and you're done—lowest hassle.
Tool Overview
code-porter's core idea is simple:
- Scan: Walk directories, identify project types and Git status
- Export: Pick the optimal packing strategy (bundle / zip) based on project state
- Import: Read the manifest and one-click restore to the target machine
Three commands handle everything:
# 扫描,看看有哪些项目
uvx code-porter scan ~/code ~/lab
# 导出,打包成 bundle + zip
uvx code-porter export ~/code ~/lab ./exports/backup
# 导入,在新机器上恢复
uvx code-porter import ./exports/backup/manifest.json ~/code/imported
Zero install: Run it directly via uvx—no need to install a Python environment or any dependencies in advance. uvx is a command that ships with uv, one line and you're done.
Smart Packing Strategy
This is code-porter's core design. It doesn't mindlessly zip everything; it picks the optimal strategy based on each project's actual state:
| Project State | Packing Strategy | Notes |
|---|---|---|
| Clean Git repo (has commits) | git bundle | Preserves full history, branches, and tags |
| Dirty Git repo (uncommitted changes) | bundle + worktree overlay zip | bundle keeps history; overlay zip keeps the working tree |
| Non-Git project | zip | Pack directly; read .gitignore to exclude junk files |
| Empty Git repo (no commits) | zip | bundle is meaningless; fall back to zip |
| Shallow clone | zip | A shallow clone cannot produce a valid bundle; fall back |
The killer feature is the overlay zip mechanism: for Git repos with uncommitted changes, the tool exports both a bundle (full Git history) and a worktree overlay zip (current working-tree files). On import it clones the bundle first, then extracts the overlay on top, so your uncommitted changes are fully preserved.
# 导出后的目录结构
exports/backup/
manifest.json # 清单文件,记录每个项目的元数据
artifacts/
my-app-a1b2c3d4.bundle # 干净仓库 → bundle
my-app-a1b2c3d4.worktree.zip # 脏仓库的 overlay
experiment-e5f6g7h8.zip # 非 Git 项目 → zip
Project Detection
The tool identifies projects of different language stacks by looking for marker files:
- Python:
pyproject.toml - Node.js:
package.json - Go:
go.mod - Rust:
Cargo.toml - .NET:
*.sln
During a scan it fully analyzes each project:
- Whether it's a Git repo, whether it has a remote, whether the working tree is clean
- Directory size, whether large directories exist (configurable threshold, default 500MB)
- Whether it hits default exclude directories (
node_modules,.venv,dist, etc.) - Whether it's worth exporting, and the recommended packing strategy
# 扫描并输出 JSON 报告,方便进一步分析
uvx code-porter scan ~/code --json-output scan-report.json
Cross-Platform Compatibility
This tool was designed with cross-platform use in mind from the start. My own use case was Windows → macOS, so:
- manifest path compatibility: Paths in the exported
manifest.jsonuse backslashes\on Windows and forward slashes/on macOS. Import handles this automatically—no manual conversion. - CI dual-platform tests: GitHub Actions runs tests on both Ubuntu and Windows to ensure consistent behavior across the two platforms.
- Purely local: Does not depend on any network service, does not call any cloud API, does not store any credentials. How you transfer is entirely up to you—USB stick, SMB share, iCloud Drive, whatever.
Fault-Tolerant Design
In real use, unexpected situations always come up. code-porter's design principle is one project's failure doesn't affect the overall flow:
git bundle createfails? Automatically fall back to zip export- Discovers a shallow clone during export? Fall back to zip
- One project fails to export? Log the error, continue with the next
- A package is corrupted on import? Skip it, keep importing the rest
Failed projects are marked failed in the results but don't appear in the manifest, so the import side won't try to process them.
Default Exclude List
The following directories are automatically excluded when packing, so you don't copy several GB of dependency packages along:
node_modules # Node.js 依赖
.venv # Python 虚拟环境
dist # 构建产物
build # 构建产物
target # Rust 构建产物
.next # Next.js 缓存
.cache # 各种缓存
.git # Git 元数据(bundle 已包含)
For zip exports, it also reads .gitignore at the project root and layers it on top of the default exclude list. In other words, files you exclude in .gitignore are also excluded when packing.
You can append custom excludes with the --exclude flag:
uvx code-porter export ~/code ./exports --exclude .idea --exclude .vscode
Progress Bars
The scan, export, and import commands all have Rich progress bars showing the project currently being processed and elapsed time. When you have a lot of projects, this experience is way better than sitting there waiting.
If you don't need the progress bar (e.g. running in CI), just add --no-progress.
Wrap-up
The core problem code-porter solves: when you have a large number of scattered projects to migrate, doing it by hand is painful and easy to miss things.
It doesn't try to be a heavyweight DevOps tool. It just focuses on doing one thing well: scan → smart packing → manifest-driven import. The whole process is purely local, zero-dependency, and cross-platform.
The tool is still in Alpha, but the core scan, export, and import flow is fully usable. My real-world scenario (Windows → MacBook, migrating dozens of projects) already works end to end.
If you're in a similar situation—switching computers, organizing projects, backing up a workspace—give it a try:
# 一行命令体验
uvx code-porter scan ~/code
The project is open source on GitHub: star-plan/code-porter. Issues and PRs welcome.
PS: Why not
rsyncorscp? Because they don't know which things are projects, which are junk directories, and which have uncommitted changes. They just copy files; they don't understand the concept of a "project". code-porter's value is that it understands a developer's project structure and makes smart decisions accordingly.
_EOF_
code-porter: A Code Workspace Migration Tool
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
重启sentry+升级ExceptionLess版本,docker排坑记录
折腾的过程真的是究极折磨,写这篇文章仿佛又被折磨了一遍……
2024-07-19 · DevOps · 约 1 分钟
Sentry的安装、配置、使用
前言 上一篇文章介绍了ExceptionLess这个日志收集系统:ExceptionLess的安装、配置、使用 由于ExceptionLess官方提供的客户端只有.Net/.NetCore平台和js的,本文继续介绍另一个日志收集系统:Sentry Sentry 是一个实时事件日志记录和聚合平台。(官方说的是错误监控 Error Monitor)它专门用于监视错误和提取执行适当的事后操作所需的所有信
2022-07-23 · DevOps · 约 1 分钟
Traefik,想说爱你不容易:一场动态反向代理的心累之旅
如果说 Nginx 是稳重的老好人,那 Traefik 就像一个特立独行的极客。它不按常理出牌,拒绝繁琐配置文件,宣称“自动发现,一切皆自动”,用 Docker label 就能配好反向代理,听起来是不是很优雅?
2025-04-16 · DevOps · 约 1 分钟
关于DevOps
前天写了Gitlab安装配置的文章,把之前在Gitee企业版上的大部分项目迁移到本地Gitlab管理,用着还不错~ 随着项目的规模逐渐变大以及手头上开发维护的项目逐渐变多,DevOps的重要性也逐渐凸显,目前我们开发、测试和部署的流程还是相对原始,意识到这点之后我开了一个新的博客分类(DevOps),边学边记录~ https://zh.m.wikipedia.org/zh-sg/DevOps
2022-07-21 · DevOps · 约 1 分钟
讨论
共 0 条加载评论中…