# git_mirror
Make all your local git repos look like Github or Gitlab.
(has nothing to do with keeping identical copies of repos on different remote servers, maybe I'll change the name.)
Supports
- clone all
- pull all
- prune unnecessary branches
- update branch from main
- checking for unpushed changes
- copy template files to all repos (PENDING)
Does not support running arbitrary scripts in each repo.
Goal is for tools to be built-in, to be easy, safe.
Also supports parallel execution for some commands.
## Why not just plain git?
If you support 30 distinct repos across 3 different source control hosts, you'd need to open 30 tabs, cd to 30 repos,
run 30 git commands (pull, get latest from main, etc) and then feel that this was a good use of time.
## Note!
Upcoming 0.3.4 to 1.0.0 will break backwards as I switch to (sub-)subcommands.
## Installation
```bash
pipx install git-mirror
# Interactively initialize configuration
git_mirror init
# Interactively select command for Github
gh_mirror menu
```
Requires .env file with Github or Gitlab token.
```bash
GITHUB_ACCESS_TOKEN=PAT
GITLAB_ACCESS_TOKEN=PAT
SELFHOSTED_ACCESS_TOKEN=PAT
```
## Usage
CLI tool. Run in the directory with your pyproject.toml file.
You have forgotten to clone some repos on your secondary laptop. Run `git_mirror clone-all`.
You probably made changes and forgot to pull them. Run `git_mirror pull-all`.
You have made changes to many repos and can't remember which. Run `git_mirror local-changes`.
You have pushed changes to many repos and forgot if you deployed them to pypi or not. Run `git_mirror build-status`.
Github doesn't summarize failing builds across all repos. Run `git_mirror build-status`.
Your local folder has a bunch of stray folders that aren't even repos. Run `git_mirror not-repo`.
You care about some repos more than others, use config to focus on a subset of repos. (PENDING FEATURE)
```text
usage: git_mirror [-h] [-V] [--menu MENU]
{show-account,list-repos,clone-all,pull-all,local-changes,not-repo,update-from-main,prune-all,sync-config,build-status,list-config,pypi-status,cross-repo-report,cross-repo-sync,cross-repo-init,menu,init}
...
Make your local git repos look like github or gitlab. See readme for how this differs from the many other multi-repo tools.
positional arguments:
{show-account,list-repos,clone-all,pull-all,local-changes,not-repo,update-from-main,prune-all,sync-config,build-status,list-config,pypi-status,cross-repo-report,cross-repo-sync,cross-repo-init,menu,init}
Subcommands.
show-account Show source code host user account information.
list-repos List repositories.
clone-all Clone all repositories.
pull-all Pull all repositories.
local-changes List local changes.
not-repo List directories that are not repositories.
update-from-main Update from main branch.
prune-all Prune all repositories not found remotely.
sync-config Sync configuration with source code host.
build-status Show build status.
list-config List configuration.
pypi-status Show pypi deployment status.
cross-repo-report Show cross repo sync report.
cross-repo-sync Sync files across repos.
cross-repo-init Initialize cross repo sync.
menu Show menu.
init Initialize configuration.
options:
-h, --help show this help message and exit
-V, --version Show program's version number and exit.
--menu MENU Choose a command via menu.
Examples:
# Interactively initialize configuration
git_mirror init
# Interactively select command
git_mirror menu
```
## Config
Either run `git_mirror init` to interactively setup the config, or add a section to `~/git_mirror.toml`.
```toml
[tool.git-mirror.github]
user_name = "matthewdeanmartin"
pypi_owner_name = "Matthew Martin"
target_dir = "f:/github/"
include_private = false
include_forks = false
[tool.git-mirror.gitlab]
user_name = "matthewdeanmartin"
url = "http://gitlab.com"
pypi_owner_name = "Matthew Martin"
target_dir = "f:/gitlab/"
include_private = true
include_forks = false
group_id = 542
[tool.git-mirror.selfhosted]
type = "gitlab"
user_name = "mmartin"
url = "http://git.example.com"
pypi_owner_name = "Matthew Martin"
target_dir = "e:/self/"
include_private = true
include_forks = false
```
## Examples
```bash
git_mirror clone-all # Clone everything to target directory, unless it already exists
git_mirror pull-all # Execute pull on all repos.
git_mirror local-changes # Show local, uncommitted, unpushed changes
git_mirror not-repo # Show what stray folders in the target folder have accumulated that aren't even repos.
git_mirror build-status # What github actions are failing, passing.
git_mirror sync-config # Copy the list of all your repos to the config file so you can mark them for ignore or tag them.
```
## Prior Art
Do actions across multiple repos
- [gita](https://github.com/nosarthur/gita) - multi-repo git tool
- [mani](https://github.com/alajmo/mani) - Stores bash snippets in a yaml file. Rust
- [meta](https://github.com/mateodelnorte/meta) - Node based
[See also this huge list of similar tools](https://myrepos.branchable.com/)
Do git host things on the command line
- [gh](https://cli.github.com/) - github cli
- [glab](https://docs.gitlab.com/ee/editor_extensions/gitlab_cli/) - gitlab cli
## Documentation
- [TODO](https://github.com/matthewdeanmartin/git_mirror/blob/main/docs/TODO.md)
Raw data
{
"_id": null,
"home_page": "https://github.com/matthewdeanmartin/git_mirror",
"name": "git-mirror",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "git, gitlab, github, polyrepo",
"author": "Matthew Martin",
"author_email": "matthewdeanmartin@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/31/7d/34f73e34890c4e5901592432d3c33844cfeef5872dcbc77b5be7b88b0e57/git_mirror-0.3.8.tar.gz",
"platform": null,
"description": "# git_mirror\n\nMake all your local git repos look like Github or Gitlab.\n\n(has nothing to do with keeping identical copies of repos on different remote servers, maybe I'll change the name.)\n\nSupports\n\n- clone all\n- pull all\n- prune unnecessary branches\n- update branch from main\n- checking for unpushed changes\n- copy template files to all repos (PENDING)\n\nDoes not support running arbitrary scripts in each repo.\n\nGoal is for tools to be built-in, to be easy, safe.\n\nAlso supports parallel execution for some commands.\n\n## Why not just plain git?\nIf you support 30 distinct repos across 3 different source control hosts, you'd need to open 30 tabs, cd to 30 repos,\nrun 30 git commands (pull, get latest from main, etc) and then feel that this was a good use of time.\n\n## Note!\nUpcoming 0.3.4 to 1.0.0 will break backwards as I switch to (sub-)subcommands.\n\n## Installation\n\n```bash\npipx install git-mirror\n# Interactively initialize configuration\ngit_mirror init\n# Interactively select command for Github\ngh_mirror menu\n```\n\nRequires .env file with Github or Gitlab token.\n\n```bash\nGITHUB_ACCESS_TOKEN=PAT\nGITLAB_ACCESS_TOKEN=PAT\nSELFHOSTED_ACCESS_TOKEN=PAT\n```\n\n## Usage\n\nCLI tool. Run in the directory with your pyproject.toml file.\n\nYou have forgotten to clone some repos on your secondary laptop. Run `git_mirror clone-all`.\n\nYou probably made changes and forgot to pull them. Run `git_mirror pull-all`.\n\nYou have made changes to many repos and can't remember which. Run `git_mirror local-changes`.\n\nYou have pushed changes to many repos and forgot if you deployed them to pypi or not. Run `git_mirror build-status`.\n\nGithub doesn't summarize failing builds across all repos. Run `git_mirror build-status`.\n\nYour local folder has a bunch of stray folders that aren't even repos. Run `git_mirror not-repo`.\n\nYou care about some repos more than others, use config to focus on a subset of repos. (PENDING FEATURE)\n\n```text\nusage: git_mirror [-h] [-V] [--menu MENU]\n {show-account,list-repos,clone-all,pull-all,local-changes,not-repo,update-from-main,prune-all,sync-config,build-status,list-config,pypi-status,cross-repo-report,cross-repo-sync,cross-repo-init,menu,init}\n ...\n\nMake your local git repos look like github or gitlab. See readme for how this differs from the many other multi-repo tools.\n\npositional arguments:\n {show-account,list-repos,clone-all,pull-all,local-changes,not-repo,update-from-main,prune-all,sync-config,build-status,list-config,pypi-status,cross-repo-report,cross-repo-sync,cross-repo-init,menu,init}\n Subcommands.\n show-account Show source code host user account information.\n list-repos List repositories.\n clone-all Clone all repositories.\n pull-all Pull all repositories.\n local-changes List local changes.\n not-repo List directories that are not repositories.\n update-from-main Update from main branch.\n prune-all Prune all repositories not found remotely.\n sync-config Sync configuration with source code host.\n build-status Show build status.\n list-config List configuration.\n pypi-status Show pypi deployment status.\n cross-repo-report Show cross repo sync report.\n cross-repo-sync Sync files across repos.\n cross-repo-init Initialize cross repo sync.\n menu Show menu.\n init Initialize configuration.\n\noptions:\n -h, --help show this help message and exit\n -V, --version Show program's version number and exit.\n --menu MENU Choose a command via menu.\n\n Examples:\n\n # Interactively initialize configuration\n git_mirror init\n\n # Interactively select command\n git_mirror menu\n```\n\n## Config\n\nEither run `git_mirror init` to interactively setup the config, or add a section to `~/git_mirror.toml`.\n\n```toml\n[tool.git-mirror.github]\nuser_name = \"matthewdeanmartin\"\npypi_owner_name = \"Matthew Martin\"\ntarget_dir = \"f:/github/\"\ninclude_private = false\ninclude_forks = false\n\n[tool.git-mirror.gitlab]\nuser_name = \"matthewdeanmartin\"\nurl = \"http://gitlab.com\"\npypi_owner_name = \"Matthew Martin\"\ntarget_dir = \"f:/gitlab/\"\ninclude_private = true\ninclude_forks = false\ngroup_id = 542\n\n[tool.git-mirror.selfhosted]\ntype = \"gitlab\"\nuser_name = \"mmartin\"\nurl = \"http://git.example.com\"\npypi_owner_name = \"Matthew Martin\"\ntarget_dir = \"e:/self/\"\ninclude_private = true\ninclude_forks = false\n```\n\n## Examples\n\n```bash\ngit_mirror clone-all # Clone everything to target directory, unless it already exists\ngit_mirror pull-all # Execute pull on all repos.\ngit_mirror local-changes # Show local, uncommitted, unpushed changes\ngit_mirror not-repo # Show what stray folders in the target folder have accumulated that aren't even repos.\ngit_mirror build-status # What github actions are failing, passing.\ngit_mirror sync-config # Copy the list of all your repos to the config file so you can mark them for ignore or tag them.\n```\n\n## Prior Art\n\nDo actions across multiple repos\n\n- [gita](https://github.com/nosarthur/gita) - multi-repo git tool\n- [mani](https://github.com/alajmo/mani) - Stores bash snippets in a yaml file. Rust\n- [meta](https://github.com/mateodelnorte/meta) - Node based\n\n[See also this huge list of similar tools](https://myrepos.branchable.com/)\n\nDo git host things on the command line\n\n- [gh](https://cli.github.com/) - github cli\n- [glab](https://docs.gitlab.com/ee/editor_extensions/gitlab_cli/) - gitlab cli\n\n## Documentation\n\n- [TODO](https://github.com/matthewdeanmartin/git_mirror/blob/main/docs/TODO.md)\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Make your local git repos look like github or gitlab. See readme for how this differs from the many other multi-repo tools.",
"version": "0.3.8",
"project_urls": {
"Bug Tracker": "https://github.com/matthewdeanmartin/git_mirror/issues",
"Change Log": "https://github.com/matthewdeanmartin/git_mirror/blob/main/CHANGELOG.md",
"Documentation": "https://matthewdeanmartin.github.io/git_mirror/git_mirror/index.html",
"Homepage": "https://github.com/matthewdeanmartin/git_mirror",
"Repository": "https://github.com/matthewdeanmartin/git_mirror"
},
"split_keywords": [
"git",
" gitlab",
" github",
" polyrepo"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "407999ca5e36fb3ca229a9a7a3ac54c6a027f3b4c0624b3b69198d2ea97c0a51",
"md5": "8abb5b1330b2e83e3bfff864f7ec93fe",
"sha256": "4bbe921c78c2cb92c06d90e58de5270f496950ffeca3ea0d4a5b05c94d2094c5"
},
"downloads": -1,
"filename": "git_mirror-0.3.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8abb5b1330b2e83e3bfff864f7ec93fe",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 51512,
"upload_time": "2024-05-15T18:05:45",
"upload_time_iso_8601": "2024-05-15T18:05:45.680240Z",
"url": "https://files.pythonhosted.org/packages/40/79/99ca5e36fb3ca229a9a7a3ac54c6a027f3b4c0624b3b69198d2ea97c0a51/git_mirror-0.3.8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "317d34f73e34890c4e5901592432d3c33844cfeef5872dcbc77b5be7b88b0e57",
"md5": "44830c83d6a6c2d7919292e686def61e",
"sha256": "7c1ad53d9f23c3c9bf5dfdc1ca55c0fdbdcbfc30bc4f80e86def2683cd906abe"
},
"downloads": -1,
"filename": "git_mirror-0.3.8.tar.gz",
"has_sig": false,
"md5_digest": "44830c83d6a6c2d7919292e686def61e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 43028,
"upload_time": "2024-05-15T18:05:47",
"upload_time_iso_8601": "2024-05-15T18:05:47.118436Z",
"url": "https://files.pythonhosted.org/packages/31/7d/34f73e34890c4e5901592432d3c33844cfeef5872dcbc77b5be7b88b0e57/git_mirror-0.3.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-05-15 18:05:47",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "matthewdeanmartin",
"github_project": "git_mirror",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "git-mirror"
}