Version control with jm proj: a complete guide
jm proj is version control and publishing for your projects, right from the terminal. The top-level verbs (jm proj init, commit, branch, merge, push…) are a real, content-addressed version-control system that lives in a local .jm folder — commits, branches, line-level merges, blame and all. Publishing a downloadable release is its own group, jm proj release. This guide walks through both, with copy-paste examples.
Setup
Install the jm CLI from the site, then sign in once — it opens your browser to authorize, just like gh:
jm auth login
That is all the setup you need. Everything below works offline except the sync commands (push, pull, clone, fetch).
Your first repository
Start version control in any folder, stage some files, and commit:
jm proj init # create a .jm repository here
jm proj add . # stage everything (or: jm proj add file.py)
jm proj commit -m "First commit"
jm proj status # what is staged vs unstaged
jm proj log # commit history
jm proj add stages changes into an index, exactly like git. A plain commit records what is staged; commit -a stages every tracked change first, so a one-liner is:
jm proj commit -a -m "Fix the parser"
Seeing what changed
jm proj diff # working tree vs last commit
jm proj diff HEAD~1 HEAD # between two commits
jm proj diff --stat # just a summary of files + line counts
jm proj show HEAD # a commit's message and full diff
jm proj blame src/main.py # who last changed each line
Branches and merging
Create a branch, switch to it, and merge it back. The merge is a real line-level 3-way merge: edits to different parts of the same file merge automatically, and conflict markers appear only where two changes actually overlap.
jm proj branch feature # create a branch
jm proj checkout feature # switch to it
# ...edit, commit...
jm proj checkout main
jm proj merge feature # fast-forward or a 3-way merge
If a merge conflicts, jm proj writes the usual <<<<<<< / ======= / >>>>>>> markers into the affected files and pauses. Resolve them, then commit — the result becomes a proper two-parent merge commit:
# edit the conflicted files to resolve them
jm proj commit -m "Merge feature"
Rebase
Replay your branch's commits on top of another, for a linear history. It pauses on conflict so you can resolve and continue — or bail out entirely:
jm proj checkout feature
jm proj rebase main # replay feature onto main
jm proj rebase --continue # after resolving a conflict
jm proj rebase --abort # give up and restore the original branch
Undo, tag, and rescue work
jm proj tag v1.0 # tag the current commit
jm proj revert <commit> # a new commit that undoes another
jm proj reset --hard <commit> # move HEAD, index and working tree
jm proj cherry-pick <commit> # replay one commit onto HEAD
jm proj stash # shelve uncommitted work (untracked files too)
jm proj stash list
jm proj stash pop # bring it back
Working with a remote
Every project on JM Tech Power has a server-side object store. Clone one, push your commits, and pull others' work — pull is a fetch plus a line-level merge:
jm proj clone owner/my-tool # clone a project's repository
jm proj push # push commits to the project
jm proj fetch # download objects/refs without merging
jm proj pull # fetch + merge the remote branch
Publishing a release
Version control is for your history; a release is a downloadable, browsable snapshot for the world. That lives under jm proj release. Scaffold a manifest, then publish:
jm proj release init --name "My Tool" --category Tools --os Linux --license MIT
# ...build...
jm proj release push --notes "First release" --highlight "Initial launch"
The first push creates the project and writes its id, owner and slug back into jm.toml; later pushes publish a new version. Browse any published project's source without cloning:
jm proj release ls owner/my-tool # list source files
jm proj release cat owner/my-tool README.md
jm proj release releases owner/my-tool # every version
jm proj release diff owner/my-tool # source diff between the latest two
Collaboration
Fork a project, open a pull request from your fork, and use stars and issues — GitHub-style, from the terminal:
jm proj fork owner/my-tool
jm proj pr-create owner/my-tool --from you/my-tool --title "Add dark mode"
jm proj pulls owner/my-tool
jm proj star owner/my-tool
jm proj issues owner/my-tool
jm proj issue-create owner/my-tool --title "Crash on start" --body "Steps: ..."
A complete example
Start a tool, version it, publish it, then ship a fix on a branch:
mkdir my-tool && cd my-tool
jm proj init
echo "print('hello')" > main.py
jm proj add . && jm proj commit -m "First cut"
# publish a downloadable release
jm proj release init --name "My Tool" --category Tools --os Linux --license MIT
jm proj release push --notes "v0.1.0"
# fix a bug on a branch and merge it
jm proj branch fix-crash
jm proj checkout fix-crash
# ...edit main.py...
jm proj commit -a -m "Fix crash on empty input"
jm proj checkout main
jm proj merge fix-crash
# share it: push commits and publish the new release
jm proj push
jm proj release push --notes "v0.1.1" --highlight "Fix crash on empty input"
Cheat sheet
- Track:
init,add,rm,mv,commit,status,stash - History:
log,show,diff,blame,tag - Branch:
branch,checkout,merge,rebase,cherry-pick - Undo:
reset,revert - Remote:
clone,push,fetch,pull - Publish:
release init,release push,release ls/cat/diff/releases - Collaborate:
fork,pr-create,pulls,star,issues
Run jm proj <command> -h for the full options on any command, or jm readme for the complete manual.
Comments (0)
Please login to post comments
LoginNo comments yet. Be the first to comment!