{"id":13419619,"url":"https://github.com/guyzmo/git-repo","last_synced_at":"2025-05-15T08:11:24.803Z","repository":{"id":57434796,"uuid":"54787116","full_name":"guyzmo/git-repo","owner":"guyzmo","description":"Git-Repo: CLI utility to manage git services from your workspace","archived":false,"fork":false,"pushed_at":"2024-03-07T04:22:27.000Z","size":1056,"stargazers_count":846,"open_issues_count":48,"forks_count":89,"subscribers_count":28,"default_branch":"devel","last_synced_at":"2025-04-14T14:59:40.862Z","etag":null,"topics":["bitbucket","cli","cli-utilities","gist","git","gitea","github","gitlab","gogs","issue","pull-request","pypi","python","python3","snippet","utility"],"latest_commit_sha":null,"homepage":"https://webchat.freenode.net/?channels=#git-repo","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guyzmo.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-26T16:05:52.000Z","updated_at":"2025-04-09T11:08:33.000Z","dependencies_parsed_at":"2024-06-18T18:39:35.067Z","dependency_job_id":"27e9b401-10b8-4c63-8a88-852862ae5c05","html_url":"https://github.com/guyzmo/git-repo","commit_stats":{"total_commits":417,"total_committers":20,"mean_commits":20.85,"dds":"0.36690647482014394","last_synced_commit":"2974c3f52bc64fa8a467ac2b0e9a485ba7ed333b"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guyzmo%2Fgit-repo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guyzmo%2Fgit-repo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guyzmo%2Fgit-repo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guyzmo%2Fgit-repo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guyzmo","download_url":"https://codeload.github.com/guyzmo/git-repo/tar.gz/refs/heads/devel","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254301555,"owners_count":22047905,"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":["bitbucket","cli","cli-utilities","gist","git","gitea","github","gitlab","gogs","issue","pull-request","pypi","python","python3","snippet","utility"],"created_at":"2024-07-30T22:01:18.522Z","updated_at":"2025-05-15T08:11:24.778Z","avatar_url":"https://github.com/guyzmo.png","language":"Python","readme":"## Git-Repo: git services CLI utility\n\n* To get the sources:\n  * https://github.com/guyzmo/git-repo\n  * https://gitlab.com/guyzmo/git-repo\n  * https://bitbucket.org/guyzmo/git-repo\n* Issues: https://github.com/guyzmo/git-repo/issues\n* Meet the community, come chat:\n  * on IRC: [#git-repo @freenode](https://webchat.freenode.net/?channels=#git-repo)\n  * on Matrix: [#git-repo:matrix.org](https://riot.im/app/#/room/#git-repo:matrix.org)\n  * on Gitter: [git-services/git-repo](https://gitter.im/git-services/git-repo)\n* [![Issues in Ready](https://badge.waffle.io/guyzmo/git-repo.png?label=ready\u0026title=Ready)](https://waffle.io/guyzmo/git-repo) [![Issues in Progress](https://badge.waffle.io/guyzmo/git-repo.png?label=in%20progress\u0026title=Progress)](https://waffle.io/guyzmo/git-repo) [![Show Travis Build Status](https://travis-ci.org/guyzmo/git-repo.svg)](https://travis-ci.org/guyzmo/git-repo)\n* [![Pypi Version](https://img.shields.io/pypi/v/git-repo.svg) ![Pypi Downloads](https://img.shields.io/pypi/dm/git-repo.svg)](https://pypi.python.org/pypi/git-repo)\n\n## Looking for help\n\nFor the past few months I've been really busy coding on stuff that puts food on the table…\nAnd sadly, I cannot give this project all the love it deserves. Which is why it's taken me months\nto spend a few hours merge and release the PRs featured in this repository.\n\nI'm still using this project daily, but I'm not having enough time to keep on putting all the\neffort needed to make it shine (SSH keys, issues support…)\n\nSo I'd like to share the maintenance responsibility with someone or more people. If you're\ninterested, please ping me on IRC or by mail (which is in all my commits). I'm always happy\nto guide through the code's design!\n\n### Usage\n\n#### main commands\n\nControl your remote git hosting services from the `git` commandline. The usage is\nvery simple (full usage list [in the sources][1]). To clone a new project, out of GitHub, just issue:\n\n[1]:https://github.com/guyzmo/git-repo/blob/devel/git_repo/repo.py#L4,L35\n\n    % git hub clone guyzmo/git-repo\n\nBut that works also with a project from GitLab, Bitbucket, your own GitLab or Gogs:\n\n    % git lab clone guyzmo/git-repo\n    % git bb clone guyzmo/git-repo\n    % git myprecious clone guyzmo/git-repo\n    % git gg clone guyzmo/git-repo\n\nIf you want to choose the default branch to clone:\n\n    % git lab clone guyzmo/git-repo master\n\nThough sometimes, as you're starting a new project, you want to create a new\nrepository to push to:\n\n    % git hub create guyzmo/git-repo\n\nactually the namespace is facultative, as per default you can (and want to)\nonly create new repositories within your own account.\n\nYou might also want to add an existing remote ref to your workspace, and that\ncan be easily done with:\n\n    % git lab add guyzmo/git-repo\n\nWhich will add `https://gitlab.com/guyzmo/git-repo` as the `gitlab` remote!\n\nAlso, you can fork a repository using:\n\n    % git hub fork neovim/neovim\n\nand of course, you can delete it using:\n\n    % git bb delete guyzmo/git-repo\n\nAlso, you can open the repository's page, using the `open` command:\n\n    % git lab open guyzmo/git-repo\n    Successfully fetched branch `2` of `guyzmo/git-repo` into `request-2`!\n\n#### Requests for merges *(aka Pull Requests aka Merge Requests)*\n\nOnce you're all set with your repository, you can check requests to merge\n(aka Pull Requests on github) using the `request` command:\n\n    % git hub request guyzmo/git-repo list\n    List of open requests to merge:\n    id     title                                                           URL\n    2     prefer gitrepo.\u003ctarget\u003e.token \u003e privatekey, docs                https://api.github.com/repos/guyzmo/git-repo/issues/2\n\nAnd fetch it locally to check and/or amend it before merging:\n\n    % git hub request guyzmo/git-repo fetch 2\n\nOr you can create a request by doing a:\n\n    % git hub request create guyzmo/git-repo myfeature master -t 'My neat feature' -m 'So much to say about that feature…'\n\nYou can create the request also by simply calling:\n\n    % git hub request create\n\nThat command has a bit of automagic, it will:\n\n1. lookup the namespace and project of the current branch (or at least on the `github` \n   remote, if called with `hub`), and take this as the source of the request ;\n2. for the target of the request it will lookup and take:\n  * the parent if current project has a parent\n  * or itself, if does not ;\n3. it will take the currently loaded branch for the source\n4. and the default one for the target\n5. call the service to ask for a request to merge from source onto target.\n\n#### Gists or snippets\n\nFinally, another extra feature you can play with is the gist handling:\n\n    % git hub gist list\n    id                                                              title\n    https://gist.github.com/4a0dd9177524b2b125e9166640666737        This is a test gist\n\nThen you can list files within it:\n\n    % git hub gist list a7ce4fddba7744ddf335\n    language         size  name\n    Python           1048  unicode_combined.py\n    % git hub -v gist list https://gist.github.com/4a0dd9177524b2b125e9166640666737\n    language         size  name\n    Markdown         16    README.md\n    Text             14    LICENSE\n    reStructuredText 17    README.rst\n\nto output it locally, you can use the fetch command (and specify the file if there's more than one):\n\n    % git hub gist fetch https://gist.github.com/a7ce4fddba7744ddf335 \u003e mygist.py\n    % git hub gist fetch 4a0dd9177524b2b125e9166640666737 LICENSE \u003e LICENSE_from_gist\n\nbut for more thorough modifications or consulting, you can as well clone it:\n\n    % git hub gist clone 4a0dd9177524b2b125e9166640666737\n    Pulling from github |████████████████████████████████|\n    Successfully cloned `4a0dd9177524b2b125e9166640666737` into `./4a0dd9177524b2b125e9166640666737`!\n\nAnd when you're done you just get rid of it:\n\n    % git hub gist -f delete 4a0dd9177524b2b125e9166640666737\n    Successfully deleted gist!\n\n\u003e *Nota Bene*: Thanks to `git` CLI flexibility, by installing `git-repo` you directly\n\u003e have access to the tool using `git-repo hub …` or `git repo hub …`. For the\n\u003e `git hub …` call, you have to set up aliases, see below how to configure that.\n\n#### Remotes\n\nTraditionally, `origin` is being used as the remote name for the code hosted on a \nservice, but because of the nature of `git-repo` there is no single `origin` but\nit encourages to use multiple ones, and also leave you in control of wherever\n`origin` points to.\n\nThis is why when you clone from a service or create a new repo on a service,\nit's using a special remote that carries the name of the service:\n\n    % git hub clone foo/bar; cd bar\n    % git status -sb | head -1\n    ## master...github/master\n                ^^^^^^\n    % git lab create bar\n    % git push gitlab master\n\nAnd as a bonus, each time it's adding a new remote, it's updating the `all` remote,\nso that you can push your code to all your remote repositories in one command:\n\n    % git push all master\n    \nAnother special remote is the `upstream`. When you do a fork of a project, current\nspecial remote with a service name will be renamed as `upstream` and the newly\nforked project is now the one with the service name:\n\n    % git lab clone foo/bar; cd bar\n    % git remote\n    all\n    gitlab\n    % git lab fork\n    % git remote\n    all\n    gitlab\n    upstream\n\nFinally, if you want to link other existing projects, you can, the `add` command\nis there for that:\n\n    % git bb add foo/bar\n    % # if the name is identical to current project, you don't need to add a name\n    % git hub add\n    % git gg add foo/bar gitea --alone\n\nUse the `--alone` switch if you don't want to add that project in the `all`\nspecial remote.\n\nAnd of course the above commands is just sugar around regular git commands,\nso the above can also be done with:\n\n    % git remote add gitbucket https://gitbucket.local:8080/foo/bar\n    % # the command to append the URL to the all remote, --alone skips this step\n    % git remote set-url --add all https://gitbucket.local:8080/foo/bar\n\nAnd to remove a remote, just do:\n\n    % git remote remove github\n\n### Installation\n\nYou can get the tool using pypi (use `pip3` if you have both Python2 and Python3 installed):\n\n    % pip install git-repo\n\nor by getting the sources and running:\n\n    % python3 setup.py install\n\n### Configuration\n\nTo configure `git-repo` you simply have to call the following command:\n\n    % git repo config\n\nand a wizard will run you through getting the authentication token for the\nservice, add the command alias or the name of the remote. Though, configuring\ncustom services is still not handled by the wizard…\n\nBut if you prefer manual configuration you'll have to tweak your\n`~/.gitconfig`. For each service you've got an account on, you have to make a\nsection in the gitconfig:\n\n    [gitrepo \"gitlab\"]\n        token = YourVerySecretKey\n\n    [gitrepo \"github\"]\n        token = YourOtherVerySecretKey\n\n    [gitrepo \"bitbucket\"]\n        username = ford.prefect\n        token = YourSecretAppKey\n\n    [gitrepo \"gogs\"]\n        fqdn = UrlOfYourGogs\n        token = YourVerySecretKey\n\nHere, we're setting the basics: just the private token. Notice that the token needed for Bitbucket are an App-token, not to be confused with an OAuth-token, which are also avaiable from the Butbucket settings.\n\nYou also have the ability to set up an alias:\n\n    [gitrepo \"bitbucket\"]\n        alias = bit\n        username = ford.prefect\n        token = YourSecretAppKey\n\nthat will change the command you use for a name you'll prefer to handle actions\nfor the service you use:\n\n    % git-repo bit clone guyzmo/git-repo\n\nAlso, you can setup your own GitLab self-hosted server, using that configuration:\n\n    [gitrepo \"myprecious\"]\n        type = gitlab\n        token = YourSuperPrivateKey\n        fqdn = gitlab.example.org\n        # Set this only if you use a self-signed certificate and experience problems\n        insecure = true\n\nFinally, to make it really cool, you can make a few aliases in your gitconfig:\n\n    [alias]\n        hub = repo hub\n        lab = repo lab\n        bb = repo bb\n        perso = repo perso\n\nSo you can run the tool as a git subcommand:\n\n    git hub clone guyzmo/git-repo\n\nFor those who like to keep all dotfiles in a git repository, it'd be horrendous to\nstore tokens that offer access to your social accounts in a repository… And I'm not\neven talking about those who want to share your dotfiles. But don't worry, once\nit's all configured, you can fire up your [favorite editor](http://www.vim.org) and\nmove all the `[gitrepo …]` sections into a new file, like `~/.gitconfig-repos`.\n\nYour can run the following command to do this automagically:\n\n    python -m git_repo.extract_config\n\nif you want to use another path, you can change the defaults:\n\n    python -m git_repo.extract_config ~/.gitconfig-repos ~/.gitconfig\n\n### Configuring Gerrit\n\nPlease note: when configuration wizard will ask you for password, do not provide\nyour Gerrit account password, but enter `HTTP password` instead. You can setup\nit on [Settings \u003e HTTP Password page](https://review.gerrithub.io/#/settings/http-password)\n\nYou may also need to tweak your `~/.gitconfig`:\n* set `ro-suffix` if your Gerrit isn't served at server root. For example, set\n  `ro-suffix` to `/r` if your Gerrit is hosted at `https://review.host.com/r`\n* set `ssh-port` parameter to set custom port for ssh connection to Gerrit (default: 29418)\n* set `auth-type`: basic (default) or digest\n\n### Development\n\nFor development, start a virtualenv and from within install the devel requirements:\n\n    % virtualenv var\n    % var/bin/pip install -r requirements-test.txt\n\nand then you'll have the executable in `bin`:\n\n    % var/bin/git-repo --help\n\nand to run the tests:\n\n    % var/bin/py.test --cov=git_repo --cov-report term-missing --capture=sys tests\n\nN.B.: *Buildout is no longer supported for development*\n\n#### Verbose running\n\nYou can repeat the `-v` argument several times to increase the level of verbosity\nof `git-repo`. The more arguments you give, the more details you'll have.\n\n* `-v` will set the debugging level to `DEBUG`, giving some execution info ;\n* `-vv` will print out all the git commands that are being executed ;\n* `-vvv` will give more verbose insight on the git layer ;\n* `-vvvv` will output all the HTTP exchanges with the different APIs ;\n* `-vvvvv` will printout how were parsed the arguments.\n\n##### Testing\n\nTo run the tests:\n\n    % bin/py.test\n\nYou can use the following options for py.test to help you debug when tests fail:\n\n* `-v` will show more details upon errors\n* `-x` will stop upon the first failure\n* `--pdb` will launch the debugger where an exception has been launched\n\nThe tests use recordings of exchanged HTTP data, so that we don't need real credentials\nand a real connection, when testing the API on minor changes. Those recordings are\ncalled cassettes, thanks to the [betamax](https://github.com/sigmavirus24/betamax) framework\nbeing in use in the test suites.\n\nWhen running existing tests, based on the provided cassettes, you don't need any\nsetting. Also, if you've got a configuration in `~/.gitconfig`, the tests will use\nthem. Anyway, you can use environment variables for those settings (environment\nvariables will have precedence over the configuration settings):\n\nTo use your own credentials, you can setup the following environment variables:\n\n* `GITHUB_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on GitHub\n* `GITLAB_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on GitLab\n* `BITBUCKET_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on Bitbucket\n* `GOGS_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on Gogs\n* `PRIVATE_KEY_GITHUB` your private token you've setup on GitHub for your account\n* `PRIVATE_KEY_GITLAB` your private token you've setup on GitLab for your account\n* `PRIVATE_KEY_BITBUCKET` your private token you've setup on Bitbucket for your account\n* `PRIVATE_KEY_GOGS` your private token you've setup on Gogs for your account\n\n### TODO\n\n* [x] make a `git-repo fork` action\n* [x] make it possible to choose method (SSH or HTTPS)\n* [x] handle default branches properly\n* [x] make a nice way to push to all remotes at once\n* [x] refactor the code into multiple modules\n* [x] add regression tests (and actually find a smart way to implement them…)\n* [x] add travis build\n* [x] show a nice progress bar, while it's fetching (cf [#15](https://github.com/guyzmo/git-repo/issues/15))\n* [x] add support for handling gists (cf [#12](https://github.com/guyzmo/git-repo/issues/12), cf [#13](https://github.com/guyzmo/git-repo/issues/13))\n* [x] add support for handling pull requests (cf [#10](https://github.com/guyzmo/git-repo/issues/10), [#11](https://github.com/guyzmo/git-repo/issues/11))\n* [x] add application token support for bitbucket (cf [#14](https://github.com/guyzmo/git-repo/issues/14))\n* [x] add support for gogs (cf [#18](https://github.com/guyzmo/git-repo/issues/18))\n* [x] add support for gitbucket (cf [#142](https://github.com/guyzmo/git-repo/issues/142))\n* [ ] add support for managing SSH keys (cf [#22](https://github.com/guyzmo/git-repo/issues/22))\n* [ ] add support for issues (cf [#104](https://github.com/guyzmo/git-repo/issues/104))\n* [ ] add support for gerrit (cf [#19](https://github.com/guyzmo/git-repo/issues/19))\n* [ ] do what's needed to make a nice documentation [#146](https://github.com/guyzmo/git-repo/issues/146)\n* for more features, write an issue or, even better, a PR!\n\n# Contributors\n\nThe project and original idea has been brought and is maintained by:\n\n* Bernard [@guyzmo](https://github.com/guyzmo) Pratz — [commits](https://github.com/guyzmo/git-repo/commits?author=guyzmo)\n\nWith code contributions coming from:\n\n* [@PyHedgehog](https://github.com/pyhedgehog) — [commits](https://github.com/guyzmo/git-repo/commits?author=pyhedgehog)\n* [@guyhughes](https://github.com/guyhughes) — [commits](https://github.com/guyzmo/git-repo/commits?author=guyhughes)\n* [@buaazp](https://github.com/buaazp) — [commits](https://github.com/guyzmo/git-repo/commits?author=buaazp)\n* [@peterazmanov](https://github.com/peterazmanov) — [commits](https://github.com/guyzmo/git-repo/commits?author=peterazmanov)\n* [@Crazybus](https://github.com/Crazybus) — [commits](https://github.com/guyzmo/git-repo/commits?author=Crazybus)\n* [@rnestler](https://github.com/rnestler) — [commits](https://github.com/guyzmo/git-repo/commits/devel?author=rnestler)\n* [@jayvdb](https://github.com/jayvdb) — [commits](https://github.com/guyzmo/git-repo/commits/devel?author=jayvdb)\n* [@kounoike](https://github.com/kounoike) — [commits](https://github.com/guyzmo/git-repo/commits/devel?author=kounoike)\n* [@AmandaCameron](https://github.com/AmandaCameron) — [commits](https://github.com/guyzmo/git-repo/commits/devel?author=AmandaCameron)\n* [@fa7ad](https://github.com/fa7ad) — [commits](https://github.com/guyzmo/git-repo/commits/devel?author=fa7ad)\n\n### License\n\n    Copyright ©2016,2017 Bernard `Guyzmo` Pratz \u003cguyzmo+git-repo+pub@m0g.net\u003e\n\n    This program is free software; you can redistribute it and/or\n    modify it under the terms of the GNU General Public License\n    as published by the Free Software Foundation; either version 2\n    of the License, or (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\nSee the LICENSE file for the full license.\n\n♥\n","funding_links":[],"categories":["Python","cli"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguyzmo%2Fgit-repo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguyzmo%2Fgit-repo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguyzmo%2Fgit-repo/lists"}