1
0
Fork 0

Merging upstream version 0.15.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-11 18:42:23 +01:00
parent 86d5d7fe9f
commit 9cbf6c15e9
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
22 changed files with 1805 additions and 372 deletions

210
README.md
View file

@ -14,7 +14,7 @@
| | ____ | | | | | ___ |
| | \_ ) | | | | | ( ) |
| (___) |__) (___ | | | ) ( |
(_______)_______/ )_( |/ \| v0.12
(_______)_______/ )_( |/ \| v0.15
```
# Gita: a command-line tool to manage multiple git repos
@ -29,11 +29,13 @@ I also hate to change directories to execute git commands.
![gita screenshot](https://github.com/nosarthur/gita/raw/master/doc/screenshot.png)
In the screenshot, the `gita remote nowhub` command translates to `git remote -v`
for the `nowhub` repo, even though we are at the `blog` repo.
To see the pre-defined sub-commands, run `gita -h` or take a look at
[cmds.yml](https://github.com/nosarthur/gita/blob/master/gita/cmds.yml).
To add your own sub-commands, see the [customization section](#custom).
In this screenshot, the `gita ll` command displays the status of all repos.
The `gita remote dotfiles` command translates to `git remote -v`
for the `dotfiles` repo, even though we are not in the repo.
The `gita fetch` command fetches from all repos and two of them have updates.
To see the pre-defined commands, run `gita -h` or take a look at
[cmds.json](https://github.com/nosarthur/gita/blob/master/gita/cmds.json).
To add your own commands, see the [customization section](#custom).
To run arbitrary `git` command, see the [superman mode section](#superman).
To run arbitrary shell command, see the [shell mode section](#shell).
@ -48,7 +50,7 @@ The branch color distinguishes 5 situations between local and remote branches:
The choice of purple for ahead and yellow for behind is motivated by
[blueshift](https://en.wikipedia.org/wiki/Blueshift) and [redshift](https://en.wikipedia.org/wiki/Redshift),
using green as baseline.
You can change the color scheme using the `gita color` sub-command.
You can change the color scheme using the `gita color` command.
See the [customization section](#custom).
The additional status symbols denote
@ -60,7 +62,13 @@ The additional status symbols denote
The bookkeeping sub-commands are
- `gita add <repo-path(s)>`: add repo(s) to `gita`
- `gita add -a <repo-parent-path(s)>`: add repo(s) in <repo-parent-path(s)> recursively
and automatically generate hierarchical groups. See the [customization section](#custom) for more details.
- `gita add -b <bare-repo-path(s)>`: add bare repo(s) to `gita`. See the [customization section](#custom) for more details on setting custom worktree.
- `gita add -m <main-repo-path(s)>`: add main repo(s) to `gita`. See the [customization section](#custom) for more details.
- `gita add -r <repo-parent-path(s)>`: add repo(s) in <repo-parent-path(s)> recursively
- `gita clone <config-file>`: clone repos in `config-file` (generated by `gita freeze`) to current directory.
- `gita clone -p <config-file>`: clone repos in `config-file` to prescribed paths.
- `gita context`: context sub-command
- `gita context`: show current context
- `gita context none`: remove context
@ -68,9 +76,12 @@ The bookkeeping sub-commands are
- `gita color`: color sub-command
- `gita color [ll]`: Show available colors and the current coloring scheme
- `gita color set <situation> <color>`: Use the specified color for the local-remote situation
- `gita flags`: flags sub-command
- `gita flags set <repo-name> <flags>`: add custom `flags` to repo
- `gita flags [ll]`: display repos with custom flags
- `gita freeze`: print information of all repos such as URL, name, and path.
- `gita group`: group sub-command
- `gita group add <repo-name(s)> -n <group-name>`: add repo(s) to a new group or existing group
- `gita group add <repo-name(s)> -n <group-name>`: add repo(s) to a new or existing group
- `gita group [ll]`: display existing groups with repos
- `gita group ls`: display existing group names
- `gita group rename <group-name> <new-name>`: change group name
@ -85,7 +96,7 @@ The bookkeeping sub-commands are
- `gita ls`: display the names of all repos
- `gita ls <repo-name>`: display the absolute path of one repo
- `gita rename <repo-name> <new-name>`: rename a repo
- `gita rm <repo-name(s)>`: remove repo(s) from `gita` (won't remove files from disk)
- `gita rm <repo-name(s)>`: remove repo(s) from `gita` (won't remove files on disk)
- `gita -v`: display gita version
The `git` delegating sub-commands are of two formats
@ -99,7 +110,7 @@ They translate to `git <sub-command>` for the corresponding repos.
By default, only `fetch` and `pull` take optional input. In other words,
`gita fetch` and `gita pull` apply to all repos.
To see the pre-defined sub-commands, run `gita -h` or take a look at
[cmds.yml](https://github.com/nosarthur/gita/blob/master/gita/cmds.yml).
[cmds.json](https://github.com/nosarthur/gita/blob/master/gita/cmds.json).
To add your own sub-commands or override the default behaviors, see the [customization section](#custom).
To run arbitrary `git` command, see the [superman mode section](#superman).
@ -107,7 +118,8 @@ If more than one repos are specified, the `git` command runs asynchronously,
with the exception of `log`, `difftool` and `mergetool`,
which require non-trivial user input.
Repo paths are saved in `$XDG_CONFIG_HOME/gita/repo_path` (most likely `~/.config/gita/repo_path`).
Repo configuration is saved in `$XDG_CONFIG_HOME/gita/repos.csv`
(most likely `~/.config/gita/repos.csv`).
## Installation
@ -124,7 +136,7 @@ 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.
then put the following line in the `.bashrc` file.
```
alias gita="python3 -m gita"
@ -140,7 +152,7 @@ Download
[.gita-completion.bash](https://github.com/nosarthur/gita/blob/master/.gita-completion.bash)
or
[.gita-completion.zsh](https://github.com/nosarthur/gita/blob/master/.gita-completion.zsh)
and source it in the corresponding rc file.
and source it in shell.
## <a name='superman'></a> Superman mode
@ -171,65 +183,178 @@ Here `repo-name(s)` or `group-name(s)` are optional, and their absence means all
For example,
- `gita shell ll` lists contents for all repos
- `gita shell repo1 mkdir docs` create a new directory `docs` in repo1
- `gita shell repo1 repo2 mkdir docs` create a new directory `docs` in `repo1` and `repo2`
- `gita shell "git describe --abbrev=0 --tags | xargs git checkout"`: check out the latest tag for all repos
## <a name='custom'></a> Customization
### user-defined sub-command using yaml file
### define repo group and context
Custom delegating sub-commands can be defined in `$XDG_CONFIG_HOME/gita/cmds.yml`
(most likely `~/.config/gita/cmds.yml`).
When the project contains several independent but related repos,
we can define a group and execute `gita` command on this group.
For example,
```
gita group add repo1 repo2 -n my-group
gita ll my-group
gita pull my-group
```
To save more typing, one can set a group as context, then any `gita` command
is scoped to the group
```
gita context my-group
gita ll
gita pull
```
It is also possible to recursively add repos within a directory and
generate hierarchical groups automatically. For example, running
```
gita add -a src
```
on the following folder structure
```
src
├── project1
│   ├── repo1
│   └── repo2
├── repo3
├── project2
│   ├── repo4
│   └── repo5
└── repo6
```
gives rise to
```
src:repo1,repo2,repo3,repo4,repo5,repo6
src-project1:repo1,repo2
src-project2:repo4,repo5
```
### define main repos and shadow the global configuration setting with local setting
The so-called main repos contain `.gita` folder for local configurations.
It works best for the repos-within-repo project structure, for example,
```
main-repo
├── sub-repo1
│   └── sub-sub-repo
├── sub-repo2
└── sub-repo3
```
When executing `gita` commands within/relative to a main repo, local configurations
are used. And only repos within the current main repos are in the scope.
To add a main repo, run
```
gita add -m main-repo-path
```
Subordinate repos are added recursively to the local configuration.
Only the main repo is saved to the global configuration.
In the `gita ll` display, the main repos are underlined.
### add user-defined sub-command using json file
Custom delegating sub-commands can be defined in `$XDG_CONFIG_HOME/gita/cmds.json`
(most likely `~/.config/gita/cmds.json`)
And they shadow the default ones if name collisions exist.
Default delegating sub-commands are defined in
[cmds.yml](https://github.com/nosarthur/gita/blob/master/gita/cmds.yml).
[cmds.json](https://github.com/nosarthur/gita/blob/master/gita/cmds.json).
For example, `gita stat <repo-name(s)>` is registered as
```yaml
stat:
cmd: diff --stat
help: show edit statistics
```json
"stat":{
"cmd": "git diff --stat",
"help": "show edit statistics"
}
```
which executes `git diff --stat` for the specified repo(s).
If the delegated `git` command is a single word, the `cmd` tag can be omitted.
See `push` for an example.
To disable asynchronous execution, set the `disable_async` tag to be `true`.
See `difftool` for an example.
To disable asynchronous execution, set `disable_async` to be `true`.
See the `difftool` example:
If you want a custom command to behave like `gita fetch`, i.e., to apply the
command to all repos when no repo is specified,
set the `allow_all` option to be `true`.
```json
"difftool":{
"cmd": "git difftool",
"disable_async": true,
"help": "show differences using a tool"
}
```
If you want a custom command to behave like `gita fetch`, i.e., to apply to all
repos when no repo is specified, set `allow_all` to be `true`.
For example, the following snippet creates a new command
`gita comaster [repo-name(s)]` with optional repo name input.
```yaml
comaster:
cmd: checkout master
allow_all: true
help: checkout the master branch
```json
"comaster":{
"cmd": "checkout master",
"allow_all": true,
"help": "checkout the master branch"
}
```
Any command that runs in the [superman mode](#superman) mode or the
[shell mode](#shell) can be defined in this json format.
For example, the following command runs in shell mode and fetches only the
current branch from upstream.
```json
"fetchcrt":{
"cmd": "git rev-parse --abbrev-ref HEAD | xargs git fetch --prune upstream",
"allow_all": true,
"shell": true,
"help": "fetch current branch only"
}
```
### customize the local/remote relationship coloring displayed by the `gita ll` command
You can see the default color scheme and the available colors via `gita color`.
To change the color coding, use `gita color set <situation> <color>`.
The configuration is saved in `$XDG_CONFIG_HOME/gita/color.yml`.
The configuration is saved in `$XDG_CONFIG_HOME/gita/color.csv`.
### customize information displayed by the `gita ll` command
You can customize the information displayed by `gita ll`.
The used and unused information items are shown with `gita info`, and the
configuration is saved in `$XDG_CONFIG_HOME/gita/info.yml`.
configuration is saved in `$XDG_CONFIG_HOME/gita/info.csv`.
For example, the default information items setting corresponds to
For example, the default setting corresponds to
```yaml
- branch
- commit_msg
```csv
branch,commit_msg,commit_time
```
### customize git command flags
One can set custom flags to run `git` commands. For example
```
gita flags set my-repo --git-dir=$HOME/somefolder --work-tree=$HOME
```
Then any `git` command/alias triggered from `gita` on `my-repo` will use these flags.
Note that the flags are applied immediately after `git`. For example,
`gita st my-repo` translates to
```
git --git-dir=$HOME/somefolder --work-tree=$HOME status
```
running from the `my-repo` directory.
## Requirements
Gita requires Python 3.6 or higher, due to the use of
@ -249,9 +374,12 @@ To contribute, you can
- request/implement features
- star/recommend this project
Read [this article](https://www.dataschool.io/how-to-contribute-on-github/) if you have never contribute code to open source project before.
Chat room is available on [![Join the chat at https://gitter.im/nosarthur/gita](https://badges.gitter.im/nosarthur/gita.svg)](https://gitter.im/nosarthur/gita?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
To run tests locally, simply `pytest`.
To run tests locally, simply `pytest` in the source code folder.
Note that context should be set as `none`.
More implementation details are in
[design.md](https://github.com/nosarthur/gita/blob/master/doc/design.md).
A step-by-step guide to reproduce this project is [here](https://nosarthur.github.io/side%20project/2019/05/27/gita-breakdown.html).