• Stars
    star
    281
  • Rank 147,023 (Top 3 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 5 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Sync personal and work git repositories from multiple providers 🚀

git-workspace 🚀

Crates.io Actions Status

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:

  • Easily synchronizing your projects directory with Github, Gitlab.com or Gitlab self-hosted 🔧
  • Keep projects consistently named and under the correct path 📁
  • Automatically set upstreams for forks
  • Move deleted repositories to an archive directory 💾
  • Allowing you to access any repository instantly :shipit:
  • Execute 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.

Table of Contents

Install 💿

Homebrew (MacOS + Linux)

brew install git-workspace

Nix (MacOS + Linux)

nix-shell

nix-shell -p git-workspace

nix shell (Flakes)

nix shell nixpkgs#git-workspace

home-manager (home.nix)

{
  home.packages = with pkgs; [
    git-workspace
  ];
}

NixOS (configuration.nix)

{
  environment.systemPackages = with pkgs; [
    git-workspace
  ];
}

AUR (ArchLinux)

paru -S git-workspace

Binaries (Windows)

Download the latest release from the github releases page. Extract it and move it to a directory on your PATH.

Cargo

Don't do this, it's pretty slow: cargo install git-workspace

Usage 🎷

Git is really annoying and hijacks the --help flag for subcommands. So to get help use git-workspace --help, not git workspace --help.

$ git-workspace --help
git-workspace 1.1.0
Tom Forbes <[email protected]>
Manage and update personal and work git repos from multiple providers

USAGE:
    git-workspace --workspace <workspace> <SUBCOMMAND>

FLAGS:
    -h, --help
            Prints help information

    -V, --version
            Prints version information


OPTIONS:
    -w, --workspace <workspace>
             [env: GIT_WORKSPACE=/Users/tom/PycharmProjects/]


SUBCOMMANDS:
    add                Add a provider to the configuration
    archive            Archive repositories that don't exist in the workspace anymore
    fetch              Fetch new commits for all repositories in the workspace
    help               Prints this message or the help of the given subcommand(s)
    list               List all repositories in the workspace
    lock               Fetch all repositories from configured providers and write the lockfile
    run                Run a git command in all repositories
    switch-and-pull    Pull new commits on the primary branch for all repositories in the workspace
    update             Update the workspace, removing and adding any repositories as needed

Define your workspace

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

Provider credentials

Both Github and Gitlab require personal access tokens to access their GraphQL endpoints. Create an access token here:

Export these tokens as GITHUB_TOKEN and GITLAB_TOKEN in your shell.

Adding providers

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]
  • Exclude specific repositories:

    • git workspace add github [USER OR ORG NAME] --exclude="foo.*bar$" --exclude="(abc|def)"
  • Clone a namespace or user from Gitlab:

    • git workspace add gitlab gitlab-ce/gitlab-services
  • Clone from a self-hosted gitlab/github instance:

    • git workspace add gitlab my-company-group --url=https://internal-gitlab.company.com
    • git workspace add github user-or-org-name --url=https://internal-github.company.com/api/graphql

Multiple configs

Git workspace will read from any workspace*.toml file under your $GIT_WORKSPACE directory.

Updating your workspace

Running git workspace update will:

  1. Fetch all repositories from your providers
  2. Clone any new repositories that are not present locally
  3. Move any deleted repositories to $GIT_WORKSPACE/.archived/ for posterity

Fetching all changes

git workspace fetch will run git fetch on all projects.

Switch 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.

Fish, with fzf

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
end

Zsh, with fzf

function project {
	local filter="$@"
	local chosen_project=$(git workspace list | fzf -q "$filter")
	if [[ -n $chosen_project ]]; then
		pushd "$GIT_WORKSPACE/$chosen_project"
	fi
}

Bash, with fzf

Contributed by a user (@kreyren:github.com):

#!/bin/sh
# shellcheck shell=sh # Written to comply with IEEE Std 1003.1-2017 for standard POSIX environment

###! # WorkSPace (wsp)
###! Switches to specified git-workspace project directory
###! - Requires git and fzf
wsp() {
    # Check for required non-standard commands
    for command in ${FZF:-"fzf"} ${GIT:-"git"}; do
        ${COMMAND:-"command"} -v "$command" || { ${PRINTF:-"printf"} "FATAL: %s\\n" "Command '$command' is not executable"; ${EXIT:-"exit"} 127 ;}
    done
    
    # shellcheck disable=SC2086 # Harmless warning about missing double-quotes that are not expected to allow parsing multiple arguments
    wsp_path="${1:-"${GTT_WORKSPACE:-"$PWD"}/$(${GIT:-"git"} workspace list | ${FZF:-"fzf"} ${fzf_arg:-"-q"} "$@")"}" # Path to the git workspace directory
    
    # Change directory
    ${CD:-"cd"} "$wsp_path" || { printf "FATAL: %s\\n" "Unable to change directory to '$wsp_path'";}
}

Consider using shfmt to optimize the file size.

Contributing 🐛

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 💣. I run integration tests with Github Actions, but that's about it. It's on my to-do list, I promise ™️.

More Repositories

1

gping

Ping, but with a graph
Rust
10,623
star
2

html-query

jq, but for HTML
HTML
622
star
3

simple

Simple is a clone of Obtvse written in Python running on Flask.
CSS
505
star
4

xcat

XPath injection tool
Python
355
star
5

cyborg

Python web scraping framework
Python
315
star
6

django-debug-toolbar-template-timings

A django-debug-toolbar panel that displays template rendering times for your Django application
Python
296
star
7

dirscan

A high performance tool for summarizing large directories or drives
Rust
141
star
8

inliner

Automagically inline python methods
Python
102
star
9

cargo-bloat-action

Track rust binary sizes across builds using Github Actions
TypeScript
96
star
10

wordinserter

Insert HTML or Markdown into a Word document
Python
82
star
11

bare-hugo-theme

A Hugo theme based on Bulma.io
HTML
72
star
12

datatables

SQLAlchemy->Datatables
Python
52
star
13

ptail

Stream and display a fixed number of lines from a processes output.
Rust
49
star
14

human_id

Human readable IDs, in Python
Python
44
star
15

MovieFinder

A basic movie recommendation site built using Python, Flask, SQLAlchemy and Backbone.js
JavaScript
31
star
16

ripgrep-structured

Ripgrep over structured data
Rust
24
star
17

crontabula

Parse crontab expressions with Python
Python
23
star
18

websocket_stdout_example

Use websockets with twisteds ProcessProtocol
Python
21
star
19

django-docker-box

See https://github.com/django/django-docker-box
Python
21
star
20

xcat_app

A XPath injection demonstration application
Java
20
star
21

django-choice-object

A choice object for Django
Python
17
star
22

spam

A tool to graph who has sent you the most emails
Python
17
star
23

HtmlToWord

Render HTML to a specific portion of a word document using Python and PyWin32
Python
16
star
24

dotfiles

My dotfiles.
Nushell
14
star
25

cel-rust-original

Rust
13
star
26

pytest-scrutinize

Find bottlenecks in your test suites
Python
12
star
27

xpath-expressions

Treat XPath expressions as Python objects
Python
11
star
28

petal

🌺 Petal - Flask, for gRPC services.
Python
11
star
29

TinyLink

Small link-shortening service written in Django
JavaScript
10
star
30

CTF

Simple capture the flag web application
JavaScript
9
star
31

django-github-actions

Github actions PoC for Django
Python
7
star
32

pinger

Archived: Now part of https://github.com/orf/gping
Rust
7
star
33

uni_timetables

A quick timetabling application written in Python using Flask
JavaScript
6
star
34

cvsslib

A library implementing CVSS v2 and v3 scores
Python
6
star
35

aio-pipes

Asynchronous pipes in Python
Python
6
star
36

hnewssimulator

Hacker news simulator using Markov chains. Very messy at the moment.
Python
6
star
37

alfred-quip-workflow

Fulltext, local Quip document search
Python
6
star
38

deterministic-zip

Deterministic zipfiles, with Rust
Rust
5
star
39

pyvector

https://vector.dev/ embedded inside Python
Rust
5
star
40

django-performance-metrics

Python
5
star
41

alfred-pycharm

Quickly open Pycharm projects via Alfred
Python
4
star
42

s3-deletion-visualizer

Rust
4
star
43

howslow_django

4
star
44

hncat

Grab all Hacker News stores + comments, quickly.
Rust
3
star
45

redis-parser

Rust
3
star
46

watchman-client

Python
3
star
47

apple-music-importer

Import your Library.xml file into Apple Music
TypeScript
3
star
48

digest

Simple RSS digester
2
star
49

pypaper

A windows desktop background manager written in Python
Python
2
star
50

Gmail-dumper

Dump Gmail inboxes
Python
2
star
51

cargo-bloat-backend

Python
2
star
52

blog-hugo

My blog!
CSS
2
star
53

logbot

Logbot tails local log files to an IRC channel.
Python
2
star
54

homebrew-brew

Personal homebrew things
Ruby
1
star
55

workaround

Python
1
star
56

Facebook-link-stats

Half finished facebook application that would track links shared on facebook.
Python
1
star
57

vulnerable_website

A vulnerable website I made for a presentation
CSS
1
star
58

wow_economy

Word of Warcraft auction price average thing.
Python
1
star
59

FindMeChicken-mono

C#
1
star
60

trend

Simple terminal graphs
Rust
1
star
61

proximity-db

euclidean distance calculations, fast.
Rust
1
star
62

circleci-inspector

Python
1
star
63

Wikipedia-XML-Processor

Wikipedia XML Processor
C#
1
star
64

presentations

Presentations I've given since 2019
Shell
1
star
65

ripgrep-stream

Rust
1
star