Quickly clone an entire org/users repositories into one directory - Supports GitHub, GitLab, Bitbucket, and more

ghorg

Go Report Card GoDoc Mentioned in Awesome Go License

ghorg allows you to quickly clone all of an orgs, or users repos into a single directory. This can be useful in many situations including

  1. Searching an orgs/users codebase with ack, silver searcher, grep etc..
  2. Bash scripting
  3. Creating backups
  4. Onboarding
  5. Performing Audits

When running ghorg a second time, all local changes in your *_ghorg directory will be overwritten by whats on GitHub. If you are working out of this directory, make sure you rename it before running a second time otherwise all of your changes will be lost.

ghorg cli example

Supported Providers

  • GitHub
  • GitLab
  • Bitbucket
  • Gitea

The terminology used in ghorg is that of GitHub, mainly orgs/repos. GitLab and BitBucket use different terminology. There is a handy chart thanks to GitLab that translates terminology here

Install

Homebrew

optional

$ brew update
$ brew upgrade git

required

$ brew install gabrie30/utils/ghorg
$ mkdir -p $HOME/.config/ghorg
$ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > $HOME/.config/ghorg/conf.yaml
$ vi $HOME/.config/ghorg/conf.yaml # (optional but recommended)

Golang

# ensure $HOME/go/bin is in your path ($ echo $PATH | grep $HOME/go/bin)
$ go get github.com/gabrie30/ghorg
$ mkdir -p $HOME/.config/ghorg
$ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > $HOME/.config/ghorg/conf.yaml
$ vi $HOME/.config/ghorg/conf.yaml # (optional but recommended)

Use

# note: to view/set all available flags/features see sample-conf.yaml and for more examples see ./examples
$ ghorg clone someorg
$ ghorg clone someorg --concurrency=50 --token=bGVhdmUgYSBjb21tZW50IG9uIGlzc3VlIDY2
$ ghorg clone someuser --clone-type=user --protocol=ssh --branch=develop --color=off
$ ghorg clone gitlab-group --scm=gitlab --base-url=https://gitlab.internal.yourcompany.com --preserve-dir
$ ghorg clone gitlab-group/gitlab-subgroup --scm=gitlab --base-url=https://gitlab.internal.yourcompany.com
$ ghorg clone --help
# view cloned resources
$ ghorg ls
$ ghorg ls someorg

Setup and Configuration

Configuration for each clone can be set in two ways. The first is in $HOME/.config/ghorg/conf.yaml. This file should be created from the sample-conf.yaml by copying into $HOME/.config/ghorg/conf.yaml. The second method of configuration is setting flags via the cli, run $ ghorg clone --help for a list of flags. A flag set on the command line will overwrite any setting in the conf.yaml

github setup

  1. Create Personal Access Token with all repo scopes. Update GHORG_GITHUB_TOKEN in your ghorg/conf.yaml, as a cli flag, or add to your osx keychain.

gitlab setup

  1. Create Personal Access Token with the read_api scope (or api for self-managed GitLab older than 12.10). This token can be added to your ghorg/conf.yaml, as a cli flag, or your osx keychain.
  2. Update the GitLab Specific config in your ghorg/conf.yaml or via cli flags
  3. Update GHORG_SCM_TYPE to gitlab in your ghorg/conf.yaml or via cli flags
  4. See examples/gitlab.md on how to run

gitea setup

  1. Create Access Token (Settings -> Applications -> Generate Token)
  2. Update GHORG_GITEA_TOKEN in your ghorg/conf.yaml or use the (--token, -t) flag.
  3. Update GHORG_SCM_TYPE to gitea in your ghorg/conf.yaml or via cli flags

bitbucket setup

  1. To configure with bitbucket you will need to create a new app password and update your $HOME/.config/ghorg/conf.yaml here or use the (--token, -t) and (--bitbucket-username) flags.
  2. Update SCM type to bitbucket in your ghorg/conf.yaml or via cli flags

osx default github/gitlab token used

NOTE: cloning via https rather than ssh is the ghorg default, this is because a token must be present to retreive the list of repos. However, if you run into trouble cloning via https and genearlly clone via ssh, try switching --protocol ssh

$ security find-internet-password -s github.com  | grep "acct" | awk -F\" '{ print $4 }'
$ security find-internet-password -s gitlab.com  | grep "acct" | awk -F\" '{ print $4 }'

It's recommended to store github/gitlab tokens in the osxkeychain, if this command returns anything other than your token see Troubleshooting section below. However, you can always add your token to the $HOME/.config/ghorg/conf.yaml or use the (--token, -t) flags.

Ignoring Repos

  • To ignore any archived repos while cloning use the --skip-archived flag (not bitbucket)

  • To ignore specific repos create a ghorgignore file inside $HOME/.config/ghorg. Each line in this file is considered a substring and will be compared against each repos clone url. If the clone url contains a substring in the ghorgignore it will be excluded from cloning. To prevent accidentally excluding a repo, you should make each line as specific as possible, eg. https://github.com/gabrie30/ghorg.git or [email protected]:gabrie30/ghorg.git depending on how you clone.

    # Create ghorgignore
    touch $HOME/.config/ghorg/ghorgignore
    
    # update file
    vi $HOME/.config/ghorg/ghorgignore

Known issues

  • When cloning if you see something like Username for 'https://gitlab.com': the command won't finish. I haven't been able to identify the reason for this occuring. The fix for this is to make sure your token is in the osxkeychain. See the troubleshooting section for how to set this up, or try cloning via ssh (--protocol=ssh).

  • If you are cloning a large org you may see Error: open /dev/null: too many open files which means you need to increase your ulimits, there are lots of docs online for this. For mac the quick and dirty is below

    # reset the soft and hard file limit boundaries
    $ sudo launchctl limit maxfiles 65536 200000
    
    # actually now set the ulimit boundary
    $ ulimit -n 20000
    

    Another solution is to decrease the number of concurrent clones. Use the --concurrency flag to set to lower than 25 (the default)

Troubleshooting

  • If the security command does not return your token, follow this GitHub Documentation. For GitHub tokens you will need to set your token as your username and set nothing as the password when prompted. For GitLab you will need to set your token for both the username and password when prompted. This will correctly store your credentials in the keychain. If you are still having problems see this StackOverflow Post
  • If your GitHub account is behind 2fa follow this Github Documentation
  • GitHub Personal Access Token only finding public repos - Give your token all the repo permissions
  • Make sure your $ git --version is >= 2.19.0

Updating brew tap

Comments
  • Exit status 128

    Exit status 128

    Describe the bug ============ Issues ============ Problem trying to clone Repo: https://***.git Error: exit status 128

    To Reproduce ghorg clone --scm gitlab --token *** --namespace *** --path F:\GHORG --base-url https://gitlab.***.com/api/v4 --clone-type org ***

    Desktop (please complete the following information):

    • OS: [e.g. iOS] - Windows 10
  • Only 50 repos get cloned - GitLab

    Only 50 repos get cloned - GitLab

    Describe the bug Only 50 repos get cloned

    To Reproduce Fresh install. Try to clone from GitLab, only 50 results clone successfully.

    Expected behavior All repos get cloned.

    /root/go/bin/ghorg clone $PROJECT --scm=gitlab --base-url=https://gitlab.com --protocol=ssh --token=$GITLAB_TOKEN --path=/opengrok/src/ --preserve-dir --concurrency=25
    
     |T|I|M|E| |T|O| |G|H|O|R|G|
     +-+-+-+-+ +-+-+ +-+-+-+-+-+
    
    *************************************
    * SCM           : gitlab
    * Type          : org
    * Protocol      : ssh
    * Location      : /opengrok/src/
    * Concurrency   : 25
    * Base URL      : https://gitlab.com
    * Config Used   : none
    *************************************
    
    50 repos found in acme-org
    

    This used to work fine, so might be an issue with a change or rate limiting on the Gitlab side?

    git --version
    git version 2.20.1
    
    # /root/go/bin/ghorg version
    v1.7.0
    

    Same if using https or ssh. I've tried a different PAT and setting Concurrency to 1 too.

  • Does not clone private repos with token and all repo scopes set

    Does not clone private repos with token and all repo scopes set

    Describe the bug ghorg does not clone private repos with token and all repo scopes set.

    To Reproduce Steps to reproduce the behavior:

    1. Add a token with all repo scopes
    2. Add the token to the config file and configure other filter options
    3. run ghorg clone
    4. Only public repos are cloned

    Expected behavior Public and private repos are cloned

    I like to write PRs, but I'm a JavaScript developer and my Go skills are non-existing 😄. This seems to be one of the rare projects that actually implement cloning all repos of a GitHub user/org.

  • Reclone not working inside container

    Reclone not working inside container

    Describe the bug I'm packaging this amazing tool in a docker container for Unraid. All is working fine except for reclone. The same command works with ghorg clone but not ghorg reclone. It is able to find the command and starts running it, but exits with ERROR: Running ghorg clone cmd: ghorg clone kubernetes, err: exit status 1. Here is the repository for all docker supporting scripts

    To Reproduce Steps to reproduce the behavior:

    1. Use the following reclone.yaml. I'll assume it is stored at $HOME/.config/ghorg/reclone.yaml
    kubernetes:
         cmd: "ghorg clone kubernetes"
    
    1. Run the following docker command, see that it works
    docker run --rm \
            -e GHORG_CONFIG="" `#Dont use config file` \
            -e GHORG_GITHUB_TOKEN=<API_TOKEN> \
            -v $HOME/.config/ghorg:/config \
            -v $HOME/repos:/data \
            afonsoc12/ghorg:latest \
            clone kubernetes
    
    1. Now use reclone. It will start running the command but will error:
    docker run --rm \
            -e GHORG_CONFIG="" `#Dont use config file` \
            -e GHORG_GITHUB_TOKEN=<API_TOKEN> \
            -v $HOME/.config/ghorg:/config \
            -v $HOME/repos:/data \
            afonsoc12/ghorg:latest \
            reclone
    

    Environment (please complete the following information): Tried in M1 Mac and Linux/Unraid

    Additional context Looking for a way to debug this, or get more information on the error.

    Thank you and keep up the great work!

  • exported GHORG_CONFIG environment variable is not picked up by ghorg

    exported GHORG_CONFIG environment variable is not picked up by ghorg

    Describe the bug I want to point ghorg to a configuration file via the exported environment variable GHORG_CONFIG. I am using a self-hosted GitLab configuration. My setup is as follows:

    $ env | grep GHORG_CONFIG
    GHORG_CONFIG=/Users/my_user/workspace/CUSTOMERS/my_customer/ghorg.yaml
    $ pwd
    /Users/my_user/workspace/CUSTOMERS/my_customer
    $ ls
    ghorg.yaml
    $ ghorg clone some-group
    Could not find a valid github token. GHORG_GITHUB_TOKEN or (--token, -t) flag must be set. Create a personal access token, then set it in your $HOME/.config/ghorg/conf.yaml or use the (--token, -t) flag, see 'GitHub Setup' in README.md
    

    My config in /Users/my_user/workspace/CUSTOMERS/my_customer/ghorg.yaml is as follows:

    ---
    GHORG_ABSOLUTE_PATH_TO_CLONE_TO: /Users/my_user/workspace/CUSTOMERS/my_customer/ghorg
    GHORG_BACKUP: false
    GHORG_BITBUCKET_APP_PASSWORD:
    GHORG_BITBUCKET_OAUTH_TOKEN:
    GHORG_BITBUCKET_USERNAME:
    GHORG_BRANCH:
    GHORG_CLONE_PROTOCOL: ssh
    GHORG_CLONE_TYPE: org
    GHORG_CLONE_WIKI: true
    GHORG_COLOR: enabled
    GHORG_CONCURRENCY: 5
    GHORG_DRY_RUN: false
    GHORG_EXCLUDE_MATCH_REGEX:
    GHORG_FETCH_ALL: true
    GHORG_GITEA_TOKEN:
    GHORG_GITHUB_TOKEN:
    GHORG_GITLAB_TOKEN: MY_GITLAB_TOKEN
    GHORG_INSECURE_GITLAB_CLIENT:
    GHORG_MATCH_PREFIX:
    GHORG_MATCH_PREFIX:
    GHORG_MATCH_REGEX:
    GHORG_NO_CLEAN: true
    GHORG_OUTPUT_DIR:
    GHORG_PRESERVE_DIRECTORY_STRUCTURE: true
    GHORG_SCM_BASE_URL: https://gitlab.my-tld.com/
    GHORG_SCM_TYPE: gitlab
    GHORG_SKIP_ARCHIVED: false
    GHORG_SKIP_FORKS: false
    GHORG_TOPICS:
    

    Expected behavior I want ghorg to use the configuration that I have configured in GHORG_CONFIG. This is not happening.

    Desktop (please complete the following information):

    • OS: macOS Big Sur 11.6.2 (20G314)
    • ghorg version: v1.7.9
    • zsh version: zsh 5.8 (x86_64-apple-darwin20.0)
  • Cannot clone subgroups

    Cannot clone subgroups

    refer to issue #88 i tried the latest version, this issue is still there

    i'm using this command : ghorg clone all-groups --base-url=http://code.xyz.com --scm=gitlab --token=abc123 --preserve-dir --insecure-gitlab-client --output-dir=/root/backup

    the error message saying : Encountered an error, aborting error fetching repos for group 'chopstick', error: group 'chopstick' does not exist

    note : chopstick is a subgroup and has 2 repositories

  • ghorg extremly slow to clone and errors out on many repos

    ghorg extremly slow to clone and errors out on many repos

    Describe the bug Extremely slow at pulling down repos and fails with many 128 or 1 error codes. I can manually clone the repos without issue.

    To Reproduce Steps to reproduce the behavior:

    1. ghorg clone org

    Expected behavior It should be fast to iterate through the repos and clone them and should do so without errors.

    Terminal output

    ============ Issues ============
    
    Problem trying to pull master Repo: [email protected]:ORG/repo1.git Error: exit status 1
    Problem trying to pull SCHOLAR-3.x Repo: [email protected]:ORG/repo2.git Error: exit status 1
    Problem trying to pull master Repo: [email protected]:ORG/repo3.git Error: exit status 1
    Problem trying to pull 1_1 Repo: [email protected]:ORG/repo4.git Error: exit status 1
    Problem trying to pull master Repo: [email protected]:ORG/repo5.git Error: exit status 1
    Problem trying to pull master Repo: [email protected]:ORG/repo6.git Error: exit status 1
    Problem trying to pull master Repo: [email protected]:ORG/repo7.git Error: exit status 1
    Problem trying to pull master Repo: [email protected]:ORG/repo8.git Error: exit status 1
    Problem trying to pull master Repo: [email protected]:ORG/repo9.git Error: exit status 1
    Problem trying to pull main Repo: [email protected]:ORG/repo10.git Error: exit status 1
    Problem trying to clone Repo: [email protected]:ORG/repo11.git Error: exit status 128
    Problem trying to clone Repo: [email protected]:ORG/repo12.git Error: exit status 128
    

    Desktop (please complete the following information):

    • OS: Fedora 34
    • Go Version: go version go1.16.5 linux/amd64
    • Git Version: git version 2.31.1
    • Ghorg Version: 1.6.0
    • Ulimit: DefaultLimitNOFILE=1024:524288

    Additional context I installed using the following command: go install github.com/gabrie30/ghorg@latest. I have this setup on Amazon Linux 2 as well and it works as expected, quick and efficient. It's using golang 1.15* however. It is oddly enough using ghorg 1.6.1, compared to the version getting pulled to the Fedora install, 1.6.0.

  • Running ghorg a second time to clone from gitlab asks for password

    Running ghorg a second time to clone from gitlab asks for password

    Describe the bug

    I'd like to backup all projects I can access from gitlab (gitlab.com).

    With ghorg I need to clone all groups seperately - it this correct? Or is there any way to clone really all groups that the token gives access to? (yes, this is somewhat unrelated question...)

    ghorg clone <group> works fine. Now when I want to update the backup it asks for user password a couple of times. I guess that's one for each concurrency access.

    On a further unrelated question: would this be the correct way to keep up-to-date backups? If "backup" is done via "--mirror" will it be kept up-to-date with git remote update?

    I tried with backup setting in config.yaml as well as without - same behaviour.

    I'm not sure what further information you need to reproduce the problem, so please ask.

    Expected behavior

    Should update cloned or mirrored repository.

    Desktop (please complete the following information):

    • OS: [e.g. iOS] Linux
  • Clone repos from a group recursively

    Clone repos from a group recursively

    Hi,

    Maybe I missed something, but cloning gitlab group only pulls repos in the group itself. Subgroups are not cloned, is it expected?

    ghorg cone --base-url https://gitlab.company.org --scm=gitlab -p /work --token=$token --preserve-dir group_name

    Thanks! Roman

  • Prompt for password when use api token

    Prompt for password when use api token

    Describe the bug When cloning from GitLab over https, I'm prompted to enter a password since the token is recognized as username.

    Screenshots The log is:

    +-+-+-+-+ +-+-+ +-+-+-+-+-+ |T|I|M|E| |T|O| |G|H|O|R|G| +-+-+-+-+ +-+-+ +-+-+-+-+-+


    • SCM : gitlab
    • Type : org
    • Protocol : https
    • Branch : master
    • Location : /home/osboxes/Desktop/
    • Concurrency : 25
    • Base URL : https://git.pl/api/v4
    • Backup : true

    118 repos found in 316


    7 repos found in my-org

    Password for 'https://[email protected]':

    Prompt for password multiple times.

    Desktop (please complete the following information):

    OS: ubuntu osboxes@mail:~/d00b$ brew install gabrie30/utils/ghorg Warning: gabrie30/utils/ghorg 1.2.0 is already installed and up-to-date To reinstall 1.2.0, run brew reinstall ghorg

    I don't know how to install the latest version of ghorg :(.

    Additional context The used GitLab account is configured with 2FA.

  • Support cloning repos of all users in an org

    Support cloning repos of all users in an org

    I didn't have the chance to try this tool with a github instance, and I'm not sure how github's api behaves.

    I did try it with gitlab, and when cloning an org, only the repositories contained in groups are cloned.

    The personal repositories of users are not cloned, even the publicly accessible ones.

    Is that intended, or is that something to fix?

  • Support cloning based on Language

    Support cloning based on Language

    Is your feature request related to a problem? Please describe. Sometime you want to clone only repos limited to your craft. e.g. if I'm a backend engineer I would like to clone only repos related to Go and PHP.

    Describe the solution you'd like Maybe we could parse a flag like GHORG_LANGUAGE which will actually be an enum containing all the supported languages of github/gitlab/.... Then based on this flag it will download only the repos that have as a base language this one.

    Describe alternatives you've considered

    Additional context Add any other context or screenshots about the feature request here.

  • Setup GitLab Enterprise integration tests to work with GitHub Actions

    Setup GitLab Enterprise integration tests to work with GitHub Actions

    Is your feature request related to a problem? Please describe. Currently no integration tests with Self Hosted GitLab community/enterprise

    Describe the solution you'd like Use the local-gitlab scripts https://github.com/gabrie30/ghorg/tree/master/scripts/local-gitlab to run as integration tests in a github actions workflow. It mostly works by running the command in the readme, but needs to be hooked into the GitHub action to run on pull request.

    Needs to run docker in docker inside GHA

  • Proofread/Review/Feedback for README.md

    Proofread/Review/Feedback for README.md

    Is your feature request related to a problem? Please describe. Ensure the README.md understandable for users of all experience levels and domain expertise.

    Describe the solution you'd like Would be great to get some feedback on the readme to flush out anything that is unclear/not obvious and or spelling/grammar mistakes. Please open a PR for review.

Clone of the old gasnow.org, now available at gasnow.dev

Gasnow 2 Clone of gasnow.org Quickstart The application connects to infura to get data from its ethereum full node. In order to do so the following en

Mar 30, 2022
Print lines matching a pattern in repositories using GitHub API
Print lines matching a pattern in repositories using GitHub API

gh-grep Print lines matching a pattern in repositories using GitHub API Usage $ gh grep func.*schema.Schema --include=**/*.go --owner k1LoW --repo tbl

Dec 1, 2022
Assemble multiple CODEOWNERS file into one

Codeowners Tool to generate a GitHub CODEOWNERS file from multiple CODEOWNERS files throughout the repo. This makes it easier to manage code ownership

Apr 11, 2022
Ghdl - A much more convenient way to download GitHub release binaries on the command line, works on Win & Unix-like systems

ghdl Memorize ghdl as github download ghdl is a fast and simple program (and als

Oct 12, 2022
An open source gitlab linting utility

gitlab-lint API and collector An open source gitlab linting utility Frontend https://github.com/globocom/gitlab-lint-react How to install Install depe

Oct 31, 2022
FreeDesktop.org (xdg) Specs implemented in Go

xdg Package xdg provides access to the FreeDesktop.org (XDG) specs. Documentation Documentation is available via godoc. Here are direct links to the d

Nov 11, 2022
A reverse-proxy cache for external images used on LinuxFr.org

External images on LinuxFr.org Our users can use images from external domains on LinuxFr.org. This component is a reverse-proxy / cache for these imag

May 14, 2021
OPG sirius supervision firm deputy hub: Managed by opg-org-infra & Terraform

OPG sirius supervision firm deputy hub: Managed by opg-org-infra & Terraform

Jan 10, 2022
Go types of schema.org ontology

schema.org for golang The library declares Go types of https://schema.org ontology. Inspiration Schema.org is a collaborative, community activity with

Jun 7, 2022
Go client library for Geonames Web Services (geonames.org)

geonames Go client library for Geonames Web Services (geonames.org) Usage Register your username at geonames.org Export ENV Var or read the username f

Nov 23, 2022
Run goplus org

Run goplus org

Jan 11, 2022
fccCoin Clone written in GoLang

fccCoin Description fccCoin Clone written in GoLang Actual Code for fccCoin written in Python

Oct 2, 2021
A go clone of johnnyopao/awsp
A go clone of johnnyopao/awsp

AWSP - AWS Profile Switcher a go clone of johnnyopao/awsp Easily switch between AWS Profiles Prereqs Setup your profiles using the aws cli aws configu

Jan 28, 2022
Purpose: dump slack messages, users and files using browser token and cookie.

Slack Dumper Purpose: dump slack messages, users and files using browser token and cookie. Typical usecase scenarios: You want to archive your private

Jan 2, 2023
Go implementation of the XDG Base Directory Specification and XDG user directories

xdg Provides an implementation of the XDG Base Directory Specification. The specification defines a set of standard paths for storing application file

Dec 23, 2022
Tool for printing a directory tree and indicating the space it occupies.

Tool for printing a directory tree and indicating the space it occupies.

Nov 6, 2021
Help to release a project which especially has multiple git repositories

This project aims to help to release a project which especially has multiple git repositories. Installation Install it to a Kubernetes cluster. You ca

Dec 15, 2022
Casbin-forum is the official forum for Casbin developers and users.

Casbin-forum is the official forum for Casbin developers and users. Link https://forum.casbin.com/ Architecture Casbin-forum contains 2 p

Jan 3, 2023
W3C WoT Thing Description Directory (TDD)

TinyIoT Thing Directory This is an implementation of the W3C WoT Thing Description Directory (TDD), a registry of Thing Descriptions. This project is

Jul 22, 2022