From bddee63922e227c73fd1b4e5b50bbef56bb9a61f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 18 Aug 2020 22:21:46 +0200 Subject: Adding upstream version 0.10.9. Signed-off-by: Daniel Baumann --- doc/design.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 doc/design.md (limited to 'doc/design.md') diff --git a/doc/design.md b/doc/design.md new file mode 100644 index 0000000..6edf84e --- /dev/null +++ b/doc/design.md @@ -0,0 +1,81 @@ +# design + +This document explains the inner workings of this 200 LOC (excluding tests) project. + +The main idea of `gita` is to run git command/alias in subprocess or +asynchronous subprocess, which enables the following features + +- execute git commands/aliases from any working directory +- execute the same command for multiple repos in batch mode + +In addition, the `gita ll` command runs various `git` commands to collect +information for each repo, and displays the result of all repos side by side. + +## user interface + +There are three types of `gita` sub-commands + +- **bookkeeping**: add/remove repos from `gita`, display repo information +- **delegating**: delegate pre-configured `git` commands or aliases +- **`super`**: delegate arbitrary `git` commands or aliases + +And there are only two `gita` options, i.e., the `-h` for help and `-v` for version. + +The bookkeeping and delegating sub-commands all share the formats + +```shell +gita +gita [repo-name(s)] +``` + +The exceptions are `add`, `ll`, and `super` + +```shell +gita ll +gita add +gita super [repo-name(s)] +``` + +The argument choices are determined by two utility functions + +- ``: `utils.get_repos() -> Dict[str, str]` +- `[repo-name(s)]`: `utils.get_choices() -> List[Union[str, None]]` which allows null input + +## sub-command actions + +The actions of the `gita` sub-commands are defined +in [`__main__.py`](https://github.com/nosarthur/gita/gita/__main__.py). + +All delegating sub-commands call + +```python +f_git_cmd(args: argparse.Namespace) +``` + +to run either `subprocess` or `asyncio` APIs. +`subprocess` is used if there is only one repo input or the sub-command is +not allowed to run asynchronously. Otherwise `asyncio` is used for efficiency. + +The bookkeeping and `super` sub-commands have their own action functions + +```python +f_(args: argparse.Namespace) +``` + +Not surprisingly, the `f_super` function calls `f_git_cmd` in the end. + +## repo status information + +Utility functions to extract repo status information are defined in [utils.py](https://github.com/nosarthur/gita/gita/utils.py). +For example, + +| information | API | note | +| ------------------------------------------------------------------------------ | ------------------------------------------- | --------------------------------------- | +| repo name and path | `get_repos() -> Dict[str, str]` | parse `$XDG_CONFIG_HOME/gita/repo_path` | +| branch name | `get_head(path: str) -> str` | parse `.git/HEAD` | +| commit message | `get_commit_msg() -> str` | run `subprocess` | +| loca/remote relation | `_get_repo_status(path: str) -> Tuple[str]` | run `subprocess` | +| edit status, i.e., unstaged change `*`, staged change `+`, untracked files `_` | `_get_repo_status(path: str) -> Tuple[str]` | run `subprocess` | + +I notice that parsing file is faster than running `subprocess`. +One future improvement could be replacing the `subprocess` calls. -- cgit v1.2.3