CWG — a Git-based programming language interpreter
Project description
Coding With Git
Work in progress. This project is in early draft stage. Syntax and semantics are subject to change.
CWG is a programming language where the source code is the git history. Commit messages are statements, branches are control flow blocks, and merges close those blocks. The interpreter walks the commit DAG and executes it as a program.
The goal is to use git as a genuine programming medium. Readable syntax, real execution, built entirely on top of version control primitives.
Concept
| Git construct | Language construct |
|---|---|
git commit -m "..." |
Statement / instruction |
| Branch | Conditional block or loop |
| Merge | Close a block, return to parent scope |
| Tag | Function definition |
cherry-pick |
Function call |
revert |
Exception handler / undo |
git stash |
Push to memory stack |
git stash pop |
Pop from memory stack |
Syntax
CWG executes Python syntax inside commit messages. Commit messages must be valid Python statements for the interpreter to recognize and run them.
Variables, int, string, bool, int operator
git commit -m "x = 5"
git commit -m "name = 'world'"
git commit -m "active = True"
git commit -m "x = x + 1"
If / Else
Branches named if/<name> and else/<name> define conditional blocks. The condition is the first commit of the if/ branch.
git branch if/large
git commit -m "if x > 10:"
git commit -m " print('x is large')"
git checkout main
git branch else/small
git commit -m " print('x is small')"
git checkout main
git merge if/large
git merge else/small
While Loops
Branches named while/<name> define while loops. The first commit in the branch is the while condition.
git commit -m "i = 10"
git branch while/countdown
git commit -m "while i > 0:"
git commit -m " print(i)"
git commit -m " i = i - 1"
git checkout main
git merge while/countdown
git commit -m "print('blastoff')"
For Loops
Branches named for/<name> define for loops. The first commit in the branch is the for header — both for x in iterable: and tuple-unpacking forms like for x, y in pairs: are supported.
git commit -m "total = 0"
git branch for/sum
git commit -m "for i in [1, 2, 3, 4, 5]:"
git commit -m " total = total + i"
git checkout main
git merge for/sum -m "return total"
Functions
Functions are defined as tagged commit ranges and called via cherry-pick.
git tag -a "fn/greet"
git commit -m " print('hello ' + name)"
git commit -m " return"
git tag -a "end-fn/greet"
# call the function
git cherry-pick fn/greet
Branch Naming Conventions
| Prefix | Purpose |
|---|---|
main / master |
Global scope |
if/<name> |
Conditional true block |
else/<name> |
Conditional false block |
while/<name> |
While loop |
for/<name> |
For loop |
fn/<name> |
Function definition |
check/<name> |
Inline conditional (if/elif/else one-liners) |
Scoping
mainholds global scopeif/,else/,while/, andfor/branches each receive a copy of the parent scope at the moment they startelse/always starts from the parent scope — never from theif/branch's scopecheck/branches run directly in the parent scope with no isolation- Variables modified inside a branch are discarded on merge unless explicitly returned
- Returned values are promoted back into the parent scope
Execution Model
CWG uses a first-parent walk to traverse the commit DAG. When cwg run is called, the interpreter walks main from the first commit to HEAD, oldest to newest, applying these rules at every level:
- Regular commit — execute the message as a Python statement, save a state snapshot
- Merge commit — pause, walk the branch's commits as a self-contained block (oldest to newest), execute the block, apply any returned values to parent scope, continue on
main - Revert commit — restore the state snapshot from before the reverted commit, continue
Because branches can contain branches, rule 2 is recursive. The same three rules apply at every level of nesting.
Nothing executes as commits are written. The full history is read first, then executed in one pass.
Merging
When a branch merges back into main, any variables modified inside the branch are discarded unless explicitly returned via the merge commit message.
Multiple variables can be returned comma-separated:
git merge while/countdown -m "return i"
git merge while/multi -m "return i, j, k"
Only the variables named in the return are promoted back into the parent scope. Everything else is dropped.
If no return is specified, the branch is treated as side-effects only — prints and other output still happen, but no state is promoted back. This is valid and intentional, not an error.
Revert and Exception Handling
git revert serves two purposes in CWG: undoing a coding mistake, and handling exceptions.
Pure undo
A revert with no added message restores the scope to what it was just before the target commit ran. This is how you "edit" a mistake without rewriting history.
git commit -m "x = 1"
git commit -m "x = 99" # oops
git revert HEAD # x is now back to 1
The target can be any commit by SHA, not just the previous one:
git revert abc1234 # rolls back state to before abc1234 ran
Exception handler
If you add code to the revert commit message (via git revert <sha> --edit), that code runs only if the target commit raised an error. If the target succeeded, the revert is a no-op.
git commit -m "result = 1 / x" # might fail if x == 0
git revert HEAD --edit
# message becomes:
# result = -1
#
# This reverts commit abc1234.
When x == 0 the original commit raises ZeroDivisionError, the handler runs, and result = -1. When x != 0 the original succeeds and the handler is skipped.
Detection
CWG detects reverts by the auto-generated This reverts commit <sha>. line that git revert produces. Manually writing a commit with a message starting with "revert" does not trigger revert behaviour — you must use the git revert command.
Sample Programs
Hello World
git init hello-world
git commit -m "message = 'hello world'"
git commit -m "print(message)"
# output: hello world
Countdown
git init countdown
git commit -m "i = 10"
git branch while/countdown
git commit -m "while i > 0:"
git commit -m " print(i)"
git commit -m " i = i - 1"
git checkout main
git merge while/countdown
git commit -m "print('blastoff')"
# output: 10 9 8 7 6 5 4 3 2 1 blastoff
FizzBuzz
git init fizzbuzz
git commit -m "i = 1"
git branch while/fizzbuzz
git commit -m "while i <= 20:"
git branch check/fizzbuzz
git commit -m " if i % 15 == 0: print('FizzBuzz')"
git checkout while/fizzbuzz
git merge check/fizzbuzz
git branch check/fizz
git commit -m " elif i % 3 == 0: print('Fizz')"
git checkout while/fizzbuzz
git merge check/fizz
git branch check/buzz
git commit -m " elif i % 5 == 0: print('Buzz')"
git checkout while/fizzbuzz
git merge check/buzz
git branch check/default
git commit -m " else: print(i)"
git checkout while/fizzbuzz
git merge check/default
git commit -m " i = i + 1"
git checkout main
git merge while/fizzbuzz
Data Types
| Type | Example |
|---|---|
| int | x = 5 |
| float | pi = 3.14 |
| string | name = 'alice' |
| bool | flag = True |
| list | nums = [1, 2, 3] |
Installation
Prerequisites
- Python 3.10 or newer
- Git
Setup
Clone the repo, create a virtual environment, and install CWG in editable mode:
git clone <repo-url>
cd CWG-Coding_with_Git
python3 -m venv .venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\activate # Windows
pip install -e .
The pip install -e . step installs CWG itself, makes the cwg command available on your PATH, and pulls in the runtime dependency (GitPython).
To also run the test suite:
pip install pytest pytest-cov
pytest
Hello world
mkdir hello && cd hello
git init
git commit --allow-empty -m "message = 'hello world'"
git commit --allow-empty -m "print(message)"
cwg run .
# output: hello world
Status
This project is a work in progress. See CONTRIBUTING.md for how to get involved.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cwg-0.1.0.tar.gz.
File metadata
- Download URL: cwg-0.1.0.tar.gz
- Upload date:
- Size: 44.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9bf1296c6afe5e2ccbeccfc2a97811d95dba7db308728f7faf66446ecec5604c
|
|
| MD5 |
e2b6a1096c71056b70a22a995146dce8
|
|
| BLAKE2b-256 |
203b12d9fcdd94c132ba7b495c64268ae17e713e2c60d66fea5ec821ab1fb6c5
|
File details
Details for the file cwg-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cwg-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1740a973b1ded1e7e832a8ab6f7437333be236edb26f0212f03c27f0bd28a550
|
|
| MD5 |
541f45e049345721be90c24860e95caf
|
|
| BLAKE2b-256 |
68dacf006dbf9af6aa3771cb716b85981df5d17e5795dd074df0ee2c0b7c9289
|