Skip to main content
header

header

ygit

A tiny (yocto) git client for MicroPython microcontrollers / other memory-constrained environments (<100k) like the $6 ESP32. It speaks to git HTTP/HTTPS servers using the ubiquitous smart client protocol. I use it to remotely deploy/update code.

Install

$ wget https://raw.githubusercontent.com/keredson/ygit/main/ygit.py
$ mpy-cross ygit.py
$ ampy -p /dev/ttyUSB0 put ygit.mpy

Get Started

To clone a repo, run:

>>> repo = ygit.clone('https://github.com/turfptax/ugit_test.git')

If you don’t want to clone into the root directory of your device, pass a target directory as a second argument. This will produce a shallow clone (at HEAD) by default. It will not delete any files in the target directory, but it will overwrite them if conflicting. The normal git files you’d expect (config, *.pack, IDX) will be in .ygit. You only need to run this once.

To update:

>>> repo.pull()

Which is the same as:

>>> repo.fetch()
>>> repo.checkout()

These are incremental operations. It will only download git objects you don’t already have, and only update files when their SHA1 values don’t match.

API

# make a new clone
repo = ygit.clone(repo, directory='.', shallow=True, cone=None,
                  quiet=False, ref='HEAD', username=None, password=None)

# control an already cloned repository
repo = ygit.Repo(directory='.')

# control
repo.checkout(ref='HEAD')
repo.pull(shallow=True, quiet=False, ref='HEAD')
repo.fetch(shallow=True, quiet=False, ref='HEAD')
repo.status(ref='HEAD')
repo.tags()
repo.branches()
repo.pulls()
repo.update_authentication(username, password)
repo.log()

A ref is one of: - HEAD - a commit (ex: 7b36b4cb1616694d8562f3adea656a709b9831d9) - a branch / tag / pull

Read the full documentation.

Design

Shallow Cloning

By default clones are shallow to save space. If you try to checkout an unknown ref, ygit will fetch a new packfile from the original server.

Subdirectory Cloning

Usually I don’t want to clone an entire project onto my ESP32. The python I want on the device is in a subdirectory of a larger project. The cone argument will take a path, and only files in that directory will be checked out (as if it were the top level).

TODO: Do a blob filter to only fetch objects we intend to check out.

Authentication

Supply a username/password to clone(). The credentials will be stored on the device, AES encrypted with the machine id as the key. For GitHub, use your personal access token as the password (just like w/ regular git).

Tests

  • Prereq: Run nginx -c "$(pwd)/misc/test_nginx.conf" -e stderr in the background for the local teets.

  • pytest test_localhost.py (runs local tests)

  • pytest test_gh.py (runs github tests)

  • pytest test_micropython.py (WARNING: will wipe all files except boot.py from your MicroPython device at /dev/ttyUSB0.)

As a convenience, running python test_micropython.py (note python instead of pytest) will run only the reset device code. I typically run python test_micropython.py && picocom /dev/ttyUSB0 -b 115200 when making a change.

Example Run

$ picocom /dev/ttyUSB0 -b 115200

MicroPython v1.19.1 on 2022-06-18; ESP32 module with ESP32
Type "help()" for more information.

>>> import ygit
>>> repo = ygit.clone('https://github.com/keredson/ygit.git','ygit')
cloning https://github.com/keredson/ygit.git into ygit @ HEAD
fetching: https://github.com/keredson/ygit.git @ HEAD
fetching commit: bc0f8c042d06f3c78be2066af11419357d1b6e0e
Enumerating objects: 26, done.
Counting objects:   3% (1/26)
[...]
Counting objects: 100% (26/26), done.
Compressing objects:   8% (2/24)
[...]
Compressing objects: 100% (24/24), done.
>>>>>>>>>>>>>>>>>>>>>>>
Total 26 (delta 0), reused 15 (delta 0), pack-reused 0
##########################
checking out bc0f8c042d06f3c78be2066af11419357d1b6e0e
writing: ygit/.gitignore (BLOB)
writing: ygit/.readthedocs.yml (BLOB)
writing: ygit/LICENSE (BLOB)
writing: ygit/README.md (BLOB)
writing: ygit/deploy.sh (BLOB)
writing: ygit/pyproject.toml (BLOB)
writing: ygit/requirements.txt (BLOB)
writing: ygit/setup.py (BLOB)
writing: ygit/test_gh.py (BLOB)
writing: ygit/test_localhost.py (BLOB)
writing: ygit/test_micropython.py (BLOB)
writing: ygit/ygit.py (BLOB)
writing: ygit/docs/Makefile (BLOB)
writing: ygit/docs/api.rst (BLOB)
writing: ygit/docs/conf.py (BLOB)
writing: ygit/docs/index.rst (BLOB)
writing: ygit/docs/make.bat (BLOB)
writing: ygit/docs/usage.rst (BLOB)
writing: ygit/docs/source/api.rst (BLOB)
writing: ygit/docs/source/conf.py (BLOB)
writing: ygit/docs/source/index.rst (BLOB)
writing: ygit/docs/source/usage.rst (BLOB)
writing: ygit/misc/header.png (BLOB)
writing: ygit/misc/header.xcf (BLOB)
writing: ygit/misc/test_nginx.conf (BLOB)
>>>
>>> repo.pull()
fetching: https://github.com/keredson/ygit.git @ HEAD
fetching commit: bc0f8c042d06f3c78be2066af11419357d1b6e0e
up to date!

Metadata

Release files for ygit 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ygit 0.4.0
File Size Uploaded Provenance Actions
ygit-0.4.0.tar.gz 24.3 kB Without provenance Details for ygit-0.4.0.tar.gz

Release files / ygit-0.4.0.tar.gz

Download URL ygit-0.4.0.tar.gz
Size 24.3 kB
Tags Source
SHA-256 checksum
How to use checksums
1f526813698a691a382e196c5146dac950419302b2d833eb3ab04107082378d4
BLAKE2b-256 checksum
How to use checksums
a8ce3987a2c0bfe7bfe3cbd60567dcca71575d958ca27184c25961917abe50c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.7

Security for ygit 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page