Sync personal and work git repositories from multiple providers :rocket:
Sync personal and work git repositories from multiple providers :rocket:
If your company has a large number of repositories and your work involves jumping between a lot of them then git-workspace can save you some time by:
git fetch on all projects in parallel :godmode:This may sound useless, but the "log into your git provider, browse to the project, copy the clone URL, devise a suitable path to clone it" dance can be a big slowdown. The only obvious solution here is to spend more time than you'll ever spend doing this in your whole life on writing a tool in Rust to do it for you.
brew install git-workspace
nix-shell -p git-workspacenix shell nixpkgs#git-workspace{
home.packages = with pkgs; [
git-workspace
];
}{
environment.systemPackages = with pkgs; [
git-workspace
];
}paru -S git-workspace
Download the latest release from the github releases page. Extract it
and move it to a directory on your PATH.
Don't do this, it's pretty slow: cargo install git-workspace
Git is really annoying and hijacks the --help flag for subcommands. So to get help use git-workspace --help, not git workspace --help.
…A workspace is the directory that git-workspace will manage for you, filling it with projects cloned from your providers. To configure this just set a GIT_WORKSPACE environment variable that points to an empty directory. For example:
export GIT_WORKSPACE=~/projects
Both Github and Gitlab require personal access tokens to access their GraphQL endpoints. Create an access token here:
GitHub: https://github.com/settings/tokens (Just the repo scope)
GitHub fine-grained tokens: https://github.com/settings/personal-access-tokens/new (Just the Contents and Metadata scopes, with read-only permissions)
Gitlab: https://gitlab.com/profile/personal_access_tokens (Just the api scope)
Export these tokens as GITHUB_TOKEN and GITLAB_TOKEN in your shell.
If you already use the Github CLI, git-workspace can ask it
for a token instead of reading one from the environment:
git workspace add github [USER OR ORG NAME] --auth-type gh-cliThis runs gh auth token whenever repositories are fetched, so you only need to have run
gh auth login once. Self-hosted instances work too: the hostname is taken from --url
and passed to gh --hostname.
In workspace.toml this is the auth_type key, which defaults to env-var:
[[provider]]
provider = "github"
name = "my-org"
auth_type = "gh-cli"You can use git workspace add to quickly add entries to your workspace.toml:
Clone all github repositories for a user or org
git workspace add github [USER OR ORG NAME]Include and exclude specific repositories:
git workspace add github [USER OR ORG NAME] --include="a.*$" --include="b.*$" --exclude="aa.*$" --exclude="bb.*$"
Both --include and --exclude can be specified multiple times.
By default all repositories are included.
All include filters are evaluated before the exclude filters.
Clone a namespace or user from Gitlab:
git workspace add gitlab gitlab-ce/gitlab-servicesClone from a self-hosted gitlab/github instance:
git workspace add gitlab my-company-group --url=https://internal-gitlab.company.comgit workspace add github user-or-org-name --url=https://internal-github.company.com/api/graphqlGit workspace will read from any workspace*.toml file under your $GIT_WORKSPACE directory.
Running git workspace update will:
$GIT_WORKSPACE/.archived/ for posteritygit workspace fetch will run git fetch on all projects.
git workspace list will output the names of all your projects. You can integrate this with whatever tool you wish to provide a way to quickly search for and select repositories.
The following fish shell snippet gives you a open-project [search-string] command you can use to search for and open projects. It combines the git workspace list command with fzf, and opens the project path with your $EDITOR:
# ~/.config/fish/functions/open-project.fish
function open-project -d "Open a project"
set filter "$argv"
set chosen_project (git workspace list | fzf -q "$filter")
if string length -q -- $chosen_project
$EDITOR $GIT_WORKSPACE/$chosen_project
pushd $GIT_WORKSPACE/$chosen_project
end
endfunction project {
local filter="$@"
local chosen_project=$(git workspace list | fzf -q "$filter")
if [[ -n $chosen_project ]]; then
pushd "$GIT_WORKSPACE/$chosen_project"
fi
}Contributed by a user (@kreyren:github.com):
…Consider using shfmt to optimize the file size.
This is my first 'proper' Rust project. If you're experienced with Rust you might puke at the code, but any feedback to help me improve would be greatly appreciated!
If you want to contribute then just go for it. cargo install should get you ready to go. Be warned: there are currently no tests :bomb:. I run integration tests with Github Actions, but that's about it. It's on my to-do list, I promise :tm:.
No open issues yet, or sync has not completed.