# Gordion
A multi-repository management tool with a git-like command interface
*The place where the gordian knot is untied*
## Features
- **Deterministic Dependency Management**: Specify exact commits for reproducible builds across your entire dependency tree
- **Diamond Dependency Resolution**: Forces exact version agreement across dependencies
- **Workspace-Based Development**: Work on multiple repositories together with automatic discovery and shared dependencies
- **Cache System**: Separate stable dependencies from actively developed code with per-repository caching
- **Information Loss Protection**: Safeguards against losing uncommitted changes or unpushed commits during updates
- **Git-like Interface**: Familiar commands (`gor add`, `gor commit`, `gor push`) that operate across all repositories
- **Branch Awareness**: Intelligently follows branches when possible while maintaining commit-based versioning
- **Contextual Operations**: Commands respect your current repository context, showing only relevant dependencies
## Why Gordion?
Gordion solves the "diamond dependency problem" in multi-repository projects:
```
A
/ \
B C
\ /
D
```
When repository A depends on B and C, which both depend on D, Gordion ensures all repositories use the same version of D, preventing version conflicts.
### Comparison to Other Tools
- **git submodule**: Creates duplicate repositories in diamond dependencies; Gordion maintains a single version
- **west (Zephyr)**: Requires manifest repo, allows version conflicts; Gordion has contextual manifests and enforces agreement
- **CMake FetchContent**: Build-time only; Gordion manages full development lifecycle with git operations
- **Conan/vcpkg**: Package managers for binaries; Gordion manages source repositories with development workflows
- **Bazel**: Build system with hermetic deps; Solves the diamond dependency problem in a similar way, but now you're stuck using bazel
- **Google Repo**: Requires a manifest repository. Subrepos cannot behave as their own manifest repository. Allows version conflicts.
## Key Commands
- `gor -u` - Update/clone all repositories to their specified versions
- `gor status` - Show status across all repositories
- `gor add <pathspec>` - Stage changes in all repositories
- `gor commit -m <message>` - Commit changes and update dependency versions
- `gor push` - Push changes in all repositories
- `gor -f <repo-name>` - Find path to a specific repository
## Functional Description
### Workspace Definition
The highest directory in a directory tree containing a gordion repository (one with a gordion.yaml) defines a workspace. Every gordion repository under that directory level is part of the workspace. When you clone a new repository there, it automatically becomes part of the workspace. Duplicate repositories (by URL or name) cannot exist within a workspace. All dependencies in a workspace must agree on their tags.
### Workspace Context
When you run `gor status`, it only shows the dependencies for your current root repository. For example, in the diamond dependency graph above, if you are in repository B and run `gor status`, it will show you the status for B and D.
### Cached Repositories
By default, `gor -u` clones to a cache folder, which is hidden from the status command unless you use the `-c` flag. The idea is that stable dependencies can be forgotten once they are hardened and working. For dependencies that you are actively developing or important components of your project, you should move them to your workspace.
Changes to repositories in the cache are not permitted, and `gor -u` will overwrite them.
The cache differs from a workspace because it is managed per-repository. If you are working in repo A, there is a cache associated with it. If you move to repo B, there is a separate cache associated with it, while repos A and B may share one workspace. This means if you work in B and it has a different version of D than C, when you move to C it won't complain because it manages its own version of D. Conflicts only arise when you move to A where they need to agree, or if they are in the workspace where D is automatically shared by B and C.
### Branching
Versioning is strictly controlled by commits to enforce reproducible builds, but the tool still attempts to checkout branches. If the commit is on the default branch, it will checkout that commit on the default branch. If you checkout a different branch from your root working repository, the tool will try to find the commits on that branch. If it can't find them, it will checkout the commit in a detached HEAD state.
### Add/Commit/Push
If you make changes across multiple repositories in your dependency tree, you can run `gor add`, `gor commit`, and `gor push` to manage all of them together. However, all repositories that will receive changes must be in the workspace, not the cache. The workspace is for repositories you're actively developing, while the cache is for dependencies you can essentially forget about.
### Information Loss Protection
`gor -u` guarantees no information can be lost. If the update needs to checkout an earlier commit on a branch, it will only do so if there is already a remote branch that has saved the current commit. If the repository has uncommitted changes that would be lost by the update, the tool will error and notify you rather than proceeding (unless it's a cached dependency). In general, if the tool destroys information during an update that cannot be recovered by conventional git operations, then you've found a bug!
## Installation
```bash
pipx install gordion
```
## Quick Start
1. Create a `gordion.yaml` file in your root repository:
```yaml
repositories:
my-library:
url: https://github.com/myorg/my-library.git
tag: v1.2.3
my-app:
url: https://github.com/myorg/my-app.git
tag: 1234567
```
2. Clone and set up your workspace:
```bash
# Clone repositories defined in gordion.yaml
gor -u
# Check status across all repositories
gor status
# Check status with hidden cache repositories
gor status -c
# Make changes and commit across repos
gor add .
gor commit -m "Update dependencies"
gor push
```
## Requirements
This has only been tested on Ubuntu, but there is no reason it shouldn't work on other operating systems.
# Development Setup
## Prerequisites
```bash
# Install nix
curl -L https://nixos.org/nix/install | sh
```
## For cloning with HTTPS
* Generate a new token with access to `Contents`
* When it asks for username, use token as password
```bash
git config --global color.ui always
```
## Testing
Nox testing:
```bash
nox -s tests
nox -s lint
nox -s tests -- test/test_repository.py -s
nox -s tests -- test/test_tree.py -s
nox -s tests -- test/test_cache.py -s
nox -s tests -- test/test_status.py -s
nox -s tests -- test/test_workspace.py -s
```
## License
MIT License - see LICENSE file for details
## Contributing
https://github.com/jacob-heathorn/gordion
Contributions are welcome! Please feel free to submit a Pull Request.
Raw data
{
"_id": null,
"home_page": null,
"name": "gordion",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "dependencies, git, management, repository, workspace",
"author": null,
"author_email": "Jacob Heathorn <jacob.heathorn@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/aa/21/e1b65e4b60c2b0e678dc4245b85ecc14d08ad5a861b66f0612c1ecf261a8/gordion-1.0.3.tar.gz",
"platform": null,
"description": "# Gordion\n\nA multi-repository management tool with a git-like command interface\n\n*The place where the gordian knot is untied*\n\n## Features\n\n- **Deterministic Dependency Management**: Specify exact commits for reproducible builds across your entire dependency tree\n- **Diamond Dependency Resolution**: Forces exact version agreement across dependencies\n- **Workspace-Based Development**: Work on multiple repositories together with automatic discovery and shared dependencies\n- **Cache System**: Separate stable dependencies from actively developed code with per-repository caching\n- **Information Loss Protection**: Safeguards against losing uncommitted changes or unpushed commits during updates\n- **Git-like Interface**: Familiar commands (`gor add`, `gor commit`, `gor push`) that operate across all repositories\n- **Branch Awareness**: Intelligently follows branches when possible while maintaining commit-based versioning\n- **Contextual Operations**: Commands respect your current repository context, showing only relevant dependencies\n\n## Why Gordion?\n\nGordion solves the \"diamond dependency problem\" in multi-repository projects:\n\n```\n A\n / \\\n B C\n \\ /\n D\n```\n\nWhen repository A depends on B and C, which both depend on D, Gordion ensures all repositories use the same version of D, preventing version conflicts.\n\n### Comparison to Other Tools\n\n- **git submodule**: Creates duplicate repositories in diamond dependencies; Gordion maintains a single version\n- **west (Zephyr)**: Requires manifest repo, allows version conflicts; Gordion has contextual manifests and enforces agreement\n- **CMake FetchContent**: Build-time only; Gordion manages full development lifecycle with git operations\n- **Conan/vcpkg**: Package managers for binaries; Gordion manages source repositories with development workflows\n- **Bazel**: Build system with hermetic deps; Solves the diamond dependency problem in a similar way, but now you're stuck using bazel\n- **Google Repo**: Requires a manifest repository. Subrepos cannot behave as their own manifest repository. Allows version conflicts.\n\n## Key Commands\n\n- `gor -u` - Update/clone all repositories to their specified versions\n- `gor status` - Show status across all repositories\n- `gor add <pathspec>` - Stage changes in all repositories\n- `gor commit -m <message>` - Commit changes and update dependency versions\n- `gor push` - Push changes in all repositories\n- `gor -f <repo-name>` - Find path to a specific repository\n\n## Functional Description\n\n### Workspace Definition\nThe highest directory in a directory tree containing a gordion repository (one with a gordion.yaml) defines a workspace. Every gordion repository under that directory level is part of the workspace. When you clone a new repository there, it automatically becomes part of the workspace. Duplicate repositories (by URL or name) cannot exist within a workspace. All dependencies in a workspace must agree on their tags.\n\n### Workspace Context\nWhen you run `gor status`, it only shows the dependencies for your current root repository. For example, in the diamond dependency graph above, if you are in repository B and run `gor status`, it will show you the status for B and D.\n\n### Cached Repositories\nBy default, `gor -u` clones to a cache folder, which is hidden from the status command unless you use the `-c` flag. The idea is that stable dependencies can be forgotten once they are hardened and working. For dependencies that you are actively developing or important components of your project, you should move them to your workspace.\n\nChanges to repositories in the cache are not permitted, and `gor -u` will overwrite them.\n\nThe cache differs from a workspace because it is managed per-repository. If you are working in repo A, there is a cache associated with it. If you move to repo B, there is a separate cache associated with it, while repos A and B may share one workspace. This means if you work in B and it has a different version of D than C, when you move to C it won't complain because it manages its own version of D. Conflicts only arise when you move to A where they need to agree, or if they are in the workspace where D is automatically shared by B and C.\n\n### Branching\nVersioning is strictly controlled by commits to enforce reproducible builds, but the tool still attempts to checkout branches. If the commit is on the default branch, it will checkout that commit on the default branch. If you checkout a different branch from your root working repository, the tool will try to find the commits on that branch. If it can't find them, it will checkout the commit in a detached HEAD state.\n\n\n### Add/Commit/Push\nIf you make changes across multiple repositories in your dependency tree, you can run `gor add`, `gor commit`, and `gor push` to manage all of them together. However, all repositories that will receive changes must be in the workspace, not the cache. The workspace is for repositories you're actively developing, while the cache is for dependencies you can essentially forget about.\n\n### Information Loss Protection\n`gor -u` guarantees no information can be lost. If the update needs to checkout an earlier commit on a branch, it will only do so if there is already a remote branch that has saved the current commit. If the repository has uncommitted changes that would be lost by the update, the tool will error and notify you rather than proceeding (unless it's a cached dependency). In general, if the tool destroys information during an update that cannot be recovered by conventional git operations, then you've found a bug!\n\n## Installation\n\n```bash\npipx install gordion\n```\n\n## Quick Start\n\n1. Create a `gordion.yaml` file in your root repository:\n\n```yaml\nrepositories:\n my-library:\n url: https://github.com/myorg/my-library.git\n tag: v1.2.3\n my-app:\n url: https://github.com/myorg/my-app.git\n tag: 1234567\n```\n\n2. Clone and set up your workspace:\n\n```bash\n# Clone repositories defined in gordion.yaml\ngor -u\n\n# Check status across all repositories\ngor status\n\n# Check status with hidden cache repositories\ngor status -c\n\n# Make changes and commit across repos\ngor add .\ngor commit -m \"Update dependencies\"\ngor push\n```\n\n## Requirements\nThis has only been tested on Ubuntu, but there is no reason it shouldn't work on other operating systems.\n\n# Development Setup\n\n## Prerequisites\n\n```bash\n# Install nix\ncurl -L https://nixos.org/nix/install | sh\n```\n\n## For cloning with HTTPS\n* Generate a new token with access to `Contents`\n* When it asks for username, use token as password\n\n```bash\ngit config --global color.ui always\n```\n\n## Testing\n\nNox testing:\n```bash\nnox -s tests\nnox -s lint\nnox -s tests -- test/test_repository.py -s\nnox -s tests -- test/test_tree.py -s\nnox -s tests -- test/test_cache.py -s\nnox -s tests -- test/test_status.py -s\nnox -s tests -- test/test_workspace.py -s\n```\n\n## License\n\nMIT License - see LICENSE file for details\n\n## Contributing\n\nhttps://github.com/jacob-heathorn/gordion\n\nContributions are welcome! Please feel free to submit a Pull Request.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A multi-repository management tool with a git-like command interface",
"version": "1.0.3",
"project_urls": {
"Homepage": "https://github.com/jacob-heathorn/gordion"
},
"split_keywords": [
"dependencies",
" git",
" management",
" repository",
" workspace"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5a9add079bb0f63550ef7d77789836d48df6cc3e47956cde24884eeec2a9bda1",
"md5": "0f5beec3c91aae82b42f19e90415444e",
"sha256": "7b2a3e9ac85e14dec9c8a0cfd573c1ddb7f162e992cbb5c4a09cbd1898326c1b"
},
"downloads": -1,
"filename": "gordion-1.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0f5beec3c91aae82b42f19e90415444e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 34809,
"upload_time": "2025-08-06T18:53:03",
"upload_time_iso_8601": "2025-08-06T18:53:03.144137Z",
"url": "https://files.pythonhosted.org/packages/5a/9a/dd079bb0f63550ef7d77789836d48df6cc3e47956cde24884eeec2a9bda1/gordion-1.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "aa21e1b65e4b60c2b0e678dc4245b85ecc14d08ad5a861b66f0612c1ecf261a8",
"md5": "fe3770fe2aedb824e6cb789498d61818",
"sha256": "9a97c09a8d2c5760382e26633f761d54c5b838a9116ca38a6dbe0476933e86dc"
},
"downloads": -1,
"filename": "gordion-1.0.3.tar.gz",
"has_sig": false,
"md5_digest": "fe3770fe2aedb824e6cb789498d61818",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 40951,
"upload_time": "2025-08-06T18:53:04",
"upload_time_iso_8601": "2025-08-06T18:53:04.664084Z",
"url": "https://files.pythonhosted.org/packages/aa/21/e1b65e4b60c2b0e678dc4245b85ecc14d08ad5a861b66f0612c1ecf261a8/gordion-1.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-06 18:53:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jacob-heathorn",
"github_project": "gordion",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "gordion"
}