Manage multiple git repos
_______________________________ ( ____ \__ __|__ __( ___ ) | ( \/ ) ( ) ( | ( ) | | | | | | | | (___) | | | ____ | | | | | ___ | | | \_ ) | | | | | ( ) | | (___) |__) (___ | | | ) ( | (_______)_______/ )_( |/ \| v0.8
Gita: a command-line tool to manage multiple git repos
This tool does two things
- display the status of multiple git repos such as branch, modification, commit message side by side
- delegate git commands/aliases from any working directory
If several repos compile together, it helps to see their status together too. I also hate to change directories to execute git commands.
Here the branch color distinguishes 5 situations between local and remote branches:
- white: local has no remote
- green: local is the same as remote
- red: local has diverged from remote
- purple: local is ahead of remote (good for push)
- yellow: local is behind remote (good for merge)
The additional status symbols denote
+: staged changes
*: unstaged changes
_: untracked files/folders
The bookkeeping sub-commands are
gita add <repo-path(s)>: add repo(s) to
gita rm <repo-name(s)>: remove repo(s) from
gita(won't remove files from disk)
gita ll: display the status of all repos
gita ls: display the names of all repos
gita ls <repo-name>: display the absolute path of one repo
gita -v: display gita version
Repo paths are saved in
$XDG_CONFIG_HOME/gita/repo_path (most likely
The delegating sub-commands are of two formats
gita <sub-command> [repo-name(s)]: optional repo input, and no input means all repos.
gita <sub-command> <repo-name(s)>: required repo name(s) input
By default, only
pull take optional input.
Sub-commands with required input are
If more than one repos are specified, the git command will run asynchronously,
with the exception of
mergetool, which require non-trivial user input.
Custom delegating sub-commands can be defined in
And they shadow the default ones if name collisions exist.
Default delegating sub-commands are defined in
gita stat <repo-name(s)> is registered as
stat: cmd: diff --stat help: show edit statistics
git diff --stat.
If the delegated git command is a single word, the
cmd tag can be omitted.
push for an example.
To disable asynchronous execution, set the
disable_async tag to be
difftool for an example.
If you want a custom command to behave like
gita fetch, i.e., to apply
command to all repos if nothing is specified,
allow_all option to be
For example, the following snippet creates a new command
gita comaster [repo-name(s)] with optional repo name input.
comaster: cmd: checkout master allow_all: true help: checkout the master branch
The superman mode delegates any git command/alias. Usage:
gita super [repo-name(s)] <any-git-command-with-or-without-options>
repo-name(s) is optional, and absence means all repos.
gita super checkout masterputs all repos on the master branch
gita super frontend-repo backend-repo commit -am 'implement a new feature'executes
git commit -am 'implement a new feature'for
Under the hood, gita uses subprocess to run git commands/aliases.
Thus the installed git version may matter.
I have git
2.20.1 on my machines, and
their results agree.
To install the latest version, run
pip3 install -U gita
If development mode is preferred, download the source code and run
pip3 install -e <gita-source-folder> ``` In either case, calling `gita` in terminal may not work, then you can put the following line in the `.bashrc` file. ``` alias gita="python3 -m gita" ``` ## Auto-completion For auto completion, download [.gita-completion.bash](https://github.com/nosarthur/gita/blob/master/.gita-completion.bash) and source it in `.bashrc`. ## Contributing To contribute, you can - report/fix bugs - request/implement features - star/recommend this project To run tests locally, simply `pytest`. More implementation details are in [design.md](https://github.com/nosarthur/gita/blob/master/design.md). ## Other multi-repo tools I haven't tried them but I heard good things about them. - [myrepos](https://myrepos.branchable.com/) - [repo](https://source.android.com/setup/develop/repo)