initial commit [141.14.129.234,mike]
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
# mgsh — git shell
|
||||
|
||||
A small interactive shell / command-line wrapper around a self-hosted bare git
|
||||
server reachable over ssh. It manages a flat set of projects living under a base
|
||||
directory (default `$HOME/src`, or `/db/src` on Linux). Go port of the original
|
||||
Perl `mgsh` (`mgsh.perl`).
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
./build.sh # builds ./mgsh and bumps the patch version by 0.0.1
|
||||
go build -o mgsh . # plain build, keeps the default version
|
||||
```
|
||||
|
||||
`build.sh` reads `version.txt`, increments the patch component, injects it via
|
||||
`-ldflags -X main.VERSION`, and writes it back — so `version.txt` always holds
|
||||
the version of the binary just built. Dependencies are fetched via Go modules
|
||||
(`go.mod` / `go.sum`) on first build.
|
||||
|
||||
Run the tests with `go test ./...`.
|
||||
|
||||
## Usage
|
||||
|
||||
Launch `mgsh` for the interactive shell, or run a single command directly from a
|
||||
project directory, e.g. `mgsh push "message"`, `mgsh status`, `mgsh log`.
|
||||
|
||||
The interactive prompt is colored (Catppuccin Mocha) and shows the active
|
||||
project, its git branch and a `*` dirty marker:
|
||||
|
||||
```
|
||||
< src/myproject (master*) >
|
||||
```
|
||||
|
||||
Features: command history (`~/.mgsh_history`), Tab completion (commands, local
|
||||
projects for `cd`/`open`, server repos for `clone`/`show`, branches/tags for
|
||||
`checkout`/`tag`, filesystem paths for `dist`), and colored `list`/`log`/error
|
||||
output.
|
||||
|
||||
Exit with `quit`, `exit`, `Ctrl-D`, or `Ctrl-C` on an empty line.
|
||||
|
||||
### Shell escape
|
||||
|
||||
Unknown commands are **not** forwarded to a shell. To run a shell command,
|
||||
prefix it with `!`:
|
||||
|
||||
```
|
||||
< src/myproject > !ls -la
|
||||
```
|
||||
|
||||
### Commands
|
||||
|
||||
Run `help` for the full list. Highlights:
|
||||
|
||||
| command | description |
|
||||
|---------------------------|------------------------------------------------|
|
||||
| `cd [project]` | change project |
|
||||
| `push [comment]` | commit everything and push to the server |
|
||||
| `pushremote [desc]` | mirror the repo to a public server (gitea/github/gitlab) |
|
||||
| `pull` / `fetch` | pull / fetch from the server |
|
||||
| `status [-a]` / `diff` | short git status (`-a`: overview of all projects) |
|
||||
| `overview` | dirty / ahead-behind summary of all projects |
|
||||
| `log` | show the project log |
|
||||
| `edit [n]` | interactive rebase of the last n commits |
|
||||
| `clone [-a] <repo>` | clone a repository (or archive) from the server |
|
||||
| `list [-a] [pattern]` | list repositories on the server |
|
||||
| `show <repo>` | show a repository log directly on the server |
|
||||
| `archive [comment]` | snapshot the server-side repo into `./archive` |
|
||||
| `init` | make a new repository from the current directory |
|
||||
| `tag [add/checkout/delete]` | manage tags |
|
||||
| `alias [name [cmd]]` | list, show or define a command alias |
|
||||
| `unalias <name>` | remove a command alias |
|
||||
| `rescan` | refresh the cached server repository list |
|
||||
| `!<command>` | run `<command>` in the shell |
|
||||
|
||||
### Aliases
|
||||
|
||||
`alias <name> '<command>'` defines a reusable shortcut, persisted to
|
||||
`~/.mgshrc` and reloaded on every start. The expansion is itself a mgsh
|
||||
command line and may reference the alias arguments:
|
||||
|
||||
| placeholder | meaning |
|
||||
|-------------|----------------------------------|
|
||||
| `$1` … `$N` | the Nth argument (empty if unset)|
|
||||
| `$*` / `$@` | all arguments, space-joined |
|
||||
|
||||
When the expansion contains no placeholder, the arguments are appended (classic
|
||||
shell-alias behaviour). Because unknown commands are **not** forwarded to a
|
||||
shell, a shell command inside an alias needs the `!` prefix:
|
||||
|
||||
```
|
||||
alias co 'checkout $1' # co v2 -> checkout v2 (builtin)
|
||||
alias p 'push $*' # p fixed bug -> push fixed bug (builtin)
|
||||
alias ec '!echo $1' # ec hello -> echo hello (shell)
|
||||
```
|
||||
|
||||
`alias` with no arguments lists all aliases, `alias <name>` shows one, and
|
||||
`unalias <name>` removes it. Aliases cannot shadow builtin commands.
|
||||
|
||||
### Public mirror (`pushremote`)
|
||||
|
||||
Besides the internal ssh git server, `pushremote` mirrors the active project to
|
||||
a public hosting server (Gitea, GitHub or GitLab) over its REST API. It reads
|
||||
two settings from `~/.mgshrc`:
|
||||
|
||||
```ini
|
||||
remoteurl = https://git.example.com # base URL of the server
|
||||
remotekey = <personal-access-token> # API token
|
||||
# remotetype = gitea # optional; auto-detected from remoteurl
|
||||
# remotevisibility = private # visibility of created repos (default private)
|
||||
# mirror = true # `push` also mirrors via pushremote
|
||||
```
|
||||
|
||||
`pushremote` authenticates with the token, creates the repository (named after
|
||||
the current project) if it does not exist yet, adds a credential-free remote
|
||||
named `public`, and pushes all branches and tags. New repositories are
|
||||
**private** unless `remotevisibility = public`; any words after the command
|
||||
(`pushremote <description>`) are set as the repository description on creation.
|
||||
The token is sent as a one-shot HTTP auth header, never written into the repo's
|
||||
git config. The provider is auto-detected from `remoteurl` (`github.com` →
|
||||
GitHub, `gitlab*` → GitLab, otherwise Gitea) and can be forced with
|
||||
`remotetype`. Set `mirror = true` to have every `push` mirror automatically.
|
||||
|
||||
## Configuration
|
||||
|
||||
mgsh has **no built-in defaults**. Configuration comes entirely from `~/.mgshrc`
|
||||
(overlaid with `MGSH_*` environment variables). On first run mgsh writes a blank,
|
||||
annotated `~/.mgshrc` template (migrating any aliases from a pre-4.x
|
||||
`~/.mgsh_aliases`) and then exits with an error until the required settings —
|
||||
`base`, `githost`, `gitport`, `gituser`, `gitpath` — are filled in.
|
||||
|
||||
It uses simple `key = value` (or `key: value`) lines (`#` comments allowed);
|
||||
alias definitions live in the same file:
|
||||
|
||||
```ini
|
||||
# --- required ---
|
||||
base = /Users/me/src
|
||||
githost = git.example.com
|
||||
gitport = 22
|
||||
gituser = git
|
||||
gitpath = /home/git
|
||||
|
||||
# --- optional ---
|
||||
gitname = Your Name
|
||||
gitemail = you@example.com
|
||||
pushdefault = matching
|
||||
editor = code # fallback opener for `open`
|
||||
|
||||
alias co 'checkout $1'
|
||||
```
|
||||
|
||||
Environment overrides: `MGSH_BASE`, `MGSH_GITHOST`, `MGSH_GITPORT`,
|
||||
`MGSH_GITUSER`, `MGSH_GITPATH`, `MGSH_GITKEY`, `MGSH_GITNAME`, `MGSH_GITEMAIL`,
|
||||
`MGSH_PUSHDEFAULT`, `MGSH_EDITOR`, `MGSH_REMOTEURL`, `MGSH_REMOTEKEY`,
|
||||
`MGSH_REMOTETYPE`, `MGSH_REMOTEVISIBILITY`, `MGSH_MIRROR`.
|
||||
|
||||
See `mgshrc.example` for an annotated template.
|
||||
Reference in New Issue
Block a user