{"id":18832636,"url":"https://github.com/datto/git-river","last_synced_at":"2025-07-05T08:08:01.426Z","repository":{"id":40264351,"uuid":"402149487","full_name":"datto/git-river","owner":"datto","description":"Tools for working with upstream repositories","archived":false,"fork":false,"pushed_at":"2022-08-02T16:11:45.000Z","size":75,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-27T18:21:25.377Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-01T17:36:29.000Z","updated_at":"2023-10-22T10:43:00.000Z","dependencies_parsed_at":"2022-07-22T08:22:20.175Z","dependency_job_id":null,"html_url":"https://github.com/datto/git-river","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datto%2Fgit-river","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datto%2Fgit-river/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datto%2Fgit-river/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datto%2Fgit-river/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datto","download_url":"https://codeload.github.com/datto/git-river/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248590123,"owners_count":21129753,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T01:58:35.121Z","updated_at":"2025-04-14T04:24:22.083Z","avatar_url":"https://github.com/datto.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"git river\n=========\n\n`git-river` is a tool designed to make it easier to work with large\nnumbers of GitHub and GitLab projects and \"forking\" workflow that involve\npulling changes from \"upstream\" repositories and pushing to \"downstream\"\nrepositories. \n\n`git-river` will manage a \"workspace\" path you configure, cloning repositories\ninto that directory with a tree-style structure organised by domain, project\nnamespace, and project name.\n\n```\n$ tree ~/workspace\n~/workspace\n├── github.com\n│   └── datto\n│       └── git-river\n└── gitlab.com\n    └── datto\n        └── git-river\n```\n\nLinks\n-----\n\n* [Source code](https://github.com/datto/git-river/)\n* [Packages](https://pypi.org/project/git-river/)\n\nInstallation\n------------\n\n`git-river` requires Python 3.9 or above.\n\n```\npip3 install git-river\n```\n\nUsage\n-----\n\nRun `git-river \u003csubcommand\u003e`. Git's builtin aliasing also allows you to\nrun `git river` instead.\n\nBefore you can use `git-river` you must configure a workspace path by running\n`git-river init PATH` or setting the `GIT_RIVER_WORKSPACE` environment variable.\nThis should point to a directory `git-river` can use to clone git repositories\ninto.\n\nSeveral commands will attempt to discover various names, and usually have an\noption flag to override discovery.\n\n- The \"upstream\" remote is the first of `upstream` or `origin` that exists. Override with `--upstream`.\n- The \"downstream\" remote is the first of `downstream` that exists. Override with `--downstream`.\n- The \"mainline\" branch is the first of `main` or `master` that exists. Override with `--mainline`.\n\n### Subcommands\n\n- `git river clone URL...` clones a repository into the workspace path.\n\n- `git river config` manages the configuration file.\n\n  - `git river config display` prints the loaded configuration as JSON. Credentials are redacted.\n  - `git river config init` creates an initial config file.\n  - `git river config workspace` prints the workspace path.\n\n- `git river forge` manages repositories listed by GitHub and GitLab.\n\n  - `git river forge` runs the `clone` + `archived` + `configure` + `remotes` subcommands.\n  - `git river forge clone` clones repositories.\n  - `git river forge configure` sets git config options.\n  - `git river forge fetch` fetches each git remote.\n  - `git river forge list` displays remote repositories that will be cloned.\n  - `git river forge remotes` sets `upstream`+`downstream` or `origin` remotes.\n  - `git river forge tidy` deletes branches merged into the mainline branch.\n  - `git river forge archived` lists archived repositories that exist locally.\n\n- `git river` also provides some \"loose\" subcommands that work on the repository\n  in the current directory, mostly matching the features from the `forge`\n  subcommand.\n\n  - `git river fetch` fetches all git remotes.\n  - `git river merge` creates the merge result of all `feature/*` branches.\n  - `git river tidy` deletes branches merged into the mainline branch.\n  - `git river restart` rebases the current branch from the upstream remotes mainline branch.\n\nConfiguration\n-------------\n\nConfiguration is a JSON object read from `~/.config/git-river/config.json`. Run\n`git-river config init` to create an example configuration file.\n\n- `path` - path to a directory to use as the \"workspace\".\n- `forges` - a map of forges.\n\nForges have the following options. Only `type` is required - the default\nconfiguration is to use the main public GitHub or GitLab domain without\nauthentication.\n\n- `type` (required) - The type of the instance, either `github` or `gitlab`.\n- `base_url` (optional) - Base url of the instance. Should not include a trailing slash.\n  - Default for GitHub instances is `https://api.github.com`.\n  - Default for GitLab instances is `https://gitlab.com`.\n- `login_or_token` (optional, GitHub only) - Authentication token.\n- `private_token` (optional, GitLab only) - Authentication token.\n- `gitconfig` (default: `{}`) - A key-value map of git config options to set on repositories.\n- `groups` (default: `[]`) - Include repositories from specific groups.\n- `users` (default: `[]`) - Include repositories from specific users.\n- `self` (default: `true`) - Automatically include the authenticated user's repositories.\n\n\n### Example\n\n```json\n{\n  \"workspace\": \"~/Development\",\n  \"forges\": {\n    \"gitlab\": {\n      \"type\": \"gitlab\",\n      \"base_url\": \"https://gitlab.com\",\n      \"private_token\": \"...\",\n      \"groups\": [],\n      \"users\": [],\n      \"self\": true,\n      \"gitconfig\": {\n        \"user.email\": \"user+gitlab@example.invalid\"\n      }\n    },\n    \"github\": {\n      \"type\": \"github\",\n      \"login_or_token\": \"...\",\n      \"groups\": [],\n      \"users\": [],\n      \"gitconfig\": {\n        \"user.email\": \"user+github@example.invalid\"\n      }\n    }\n  }\n}\n```\n\nDevelopment\n-----------\n\n[Poetry][poetry] is used to develop, build, and package git-river. Poetry's\n[documentation][poetry/docs] describes how to install it on your OS. Once you've\ninstalled it, create a virtual environment containing git-river and it's\ndependencies with `poetry install`.\n\nYou can then run the local version of the CLI with `poetry run git-river`.\n\nCode is formatted using [black], run with `poetry run black git_river`.\n\nTypes are checked using [mypy], run with `poetry run mypy git_river`.\n\nTests are written using [pytest], run with `poetry run pytest`.\n\n```bash\n# Download the project and install dependencies\ngit clone https://github.com/datto/git-river.git\ncd git-river\npoetry install\n\n# Use the local version of the CLI\npoetry run git-river ...\n\n# Test, lint and format code\npoetry run black git_river\npoetry run mypy git_river\npoetry run pytest\n```\n\nLicense\n-------\n\nLicensed under the Mozilla Public License Version 2.0.\n\nCopyright Datto, Inc.\n\nAuthored by [Sam Clements](https://github.com/borntyping).\n\n[black]: https://github.com/psf/black\n[mypy]: https://mypy.readthedocs.io/en/stable/\n[poetry/docs]: https://python-poetry.org/docs/\n[poetry]: https://python-poetry.org/\n[pytest]: https://docs.pytest.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatto%2Fgit-river","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatto%2Fgit-river","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatto%2Fgit-river/lists"}