UNPKG

git-oneflow

Version:

CLI tooling implementing GIT OneFlow branching model

282 lines (193 loc) 14.9 kB
# ![git-OneFlow](g1-logo.png) [![CodeFactor](https://www.codefactor.io/repository/github/msanguineti/git-oneflow/badge/main)](https://www.codefactor.io/repository/github/msanguineti/git-oneflow/overview/main) [![npm](https://badgen.net/npm/v/git-oneflow)](https://www.npmjs.com/package/git-oneflow) [![code style: prettier](https://badgen.net/badge/code%20style/prettier/ff69b4)](https://prettier.io/) [![Conventional Commits](https://badgen.net/badge/Conventional%20Commits/1.0.0/d4ac20)](https://conventionalcommits.org) ![Dependabot Status](https://badgen.net/github/dependabot/msanguineti/git-oneflow?icon=dependabot) ![CodeQL](https://github.com/msanguineti/git-oneflow/workflows/CodeQL/badge.svg) > CLI tools implementing the _OneFlow_ git branching model. OneFlow is a git branching model proposed by [Adam Ruka](https://github.com/skinny85) as an [alternative to GitFlow](https://www.endoflineblog.com/gitflow-considered-harmful). In [this article](https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow#develop-feature-branches), Adam describes how it works and when it should be employed. **_This workflow is not for the uninitiated:_** 1. Heavy use of `rebase` 2. By default, work is off of `main` 3. ??? 4. No Profit :( and surefire way to mess things up quickly and embarrassingly. For a good overview of why you should _and_ when you shouldn't use rebase read [this](https://git-scm.com/book/en/v2/Git-Branching-Rebasing#_rebase_peril) I have simply put together some CLI commands to leverage the OneFlow model. I have remained strictly faithful to how Adam defines the workflow without adding anything fancy (yet). This means that, by default, **_git-OneFlow_** works with one main branch only (`main`) and new features are rebased. Check the [customisation](#customisation) section. Of course, one-size-fits-all does not always work, therefore, I have implemented all the feature integration options described in the article and both the _one main branch_ and _main and development branches_ models. Fun facts: 1. _Two branches_ model + integration option #2 gives... :drumroll: GitFlow :) 2. Adam Ruka doesn't really like the idea of 'tools' like this one ## Node Compatibility Supported version are LTS and above. ## Install ```sh npm install -g git-oneflow ``` ## Usage ```sh git-oneflow --help ``` or ```sh gof --help ``` `gof` is a convenient alias for the overly verbose and long to type `git-oneflow`. ### Node Package Execute - npx It is possible to run `git-oneflow` directly (i.e. no local installation) from the `npm` registry with Node Package Execute: ```sh npx git-oneflow --help ``` ## Configuration **_git-OneFlow_** comes with some defaults which faithfully mirror Adam Ruka recommendations. ### Defaults #### One main branch `main` #### Feature branches Feature branches stem from `feature`: ```sh gof start feature my-feature # equivalent to... git checkout -b feature/my-feature ``` Finishing a feature is done by rebasing: ```sh gof finish feature my-feature # equivalent to... git checkout feature/my-feature git rebase -i main git checkout main git merge --ff-only feature/my-feature git push origin main git branch -d feature/my-feature ``` #### Release/Hotfix branches Releases and hotfixes share the same workflow: (just substitute `hotfix` for `release` in the following examples) ```sh gof start release 2.3.0 # equivalent to... git checkout -b release/2.3.0 ``` ...then ```sh gof finish release 2.3.0 -t 2.3.0 # equivalent to... git checkout release/2.3.0 git tag -a -m '2.3.0' 2.3.0 git checkout main git merge release/2.3.0 git push --follow-tags origin main git branch -d release/2.3.0 ``` ##### Tags Tags creation when releasing or hot-fixing might not be needed. One case would be if something like [`standard-version`](https://www.npmjs.com/package/standard-version) is used, which tags releases based on some commit conventions. Therefore, a `--no-tag` option is used to avoid tagging the commit. A commit is either tagged on the command line by passing `-t|--tag <tagName>` or the program will ask to specify a tag name. If both `-t` and `--no-tag` are specified, `--no-tag` takes the precedence. This is true for any other `off` switch. ### Configuration file ```sh gof init ``` `init` starts an interactive session that allows for customising the configuration of **_git-OneFlow_** This creates a `.git-oneflowrc` file with the chosen configuration [options](#options). **_git-OneFlow_** uses [`cosmiconfig`](https://www.npmjs.com/package/cosmiconfig) under the hood. To specify a configuration file on the command line use `-c|--configuration` with the name of the file (and it's path). ```sh gof start feature -c config/my-gof-config.json ``` #### Configuration options | Option | Description | Default | Details | | -------------------- | ------------------------------------------------------------------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `main` | name of the main (production) branch | `main` | must be set to an existing branch name | | `development` | name of the development branch | `undefined` | not set or an existing branch name | | `features` | name of the features branch (prefixed to the feature name) | `feature` | empty string or a valid branch name. This strings works as a branch prefix, e.g. if the chosen feature name is `my-super-feature` the resulting (using the default) branch name for this feature will be `feature/my-super-feature`. An empty string will result in `my-super-feature`. This applies to releases and hotfixes as well. | | `releases` | name of the releases branch (prefixed to the release name) | `release` | empty string or a valid branch name | | `hotfixes` | name of the hotfixes branch (prefixed to the hotfix name) | `hotfix` | empty string or a valid branch name | | `strategy` | which feature integration merge strategy to use | `rebase` | Valid options are: `rebase`, `rebase-no-ff` and `no-ff` | | `interactive` | whether to rebase interactively `rebase -i` | `true` | the values `true` or `false`, not the strings 'true' or 'false'. See [example](#generate-default-file). If set to `false` this, and other boolean options, act as a permanent `off` switch for the given option. In this case, it is like `--no-interactive` is always specified on the command line. | | `pushAfterMerge` | whether to push to `origin` after finishing | `true` | `true`, `false` | | `deleteAfterMerge` | whether to delete the working branch after merging with main/development | `true` | `true`, `false` | | `tagCommit` | whether to ask to tag releases and hotfixes | `true` | `true`, `false`. This option is used to decide whether to prompt the user or not in case a tag hasn't been specified, for example with `--tag 2.3.4`. | | `askOnFeatureStart` | whether to ask which branch to start a feature from | `false` | `true`, `false`. This option is used to decide whether to prompt the user or not in case they start a feature. | | `askOnFeatureFinish` | whether to ask which branch to merge a feature onto | `false` | `true`, `false`. This option is used to decide whether to prompt the user or not in case they finish a feature. | #### Generate default file To create a configuration file with default values: ```sh gof init -y ``` this will create `.gitonelfowrc` in the current directory with the following content: ```json { "main": "main", "features": "feature", "releases": "release", "hotfixes": "hotfix", "strategy": "rebase", "interactive": true, "deleteAfterMerge": true, "pushAfterMerge": true, "tagCommit": true } ``` ## Commands Under the hood, **_git-OneFlow_** uses [`commander`](https://www.npmjs.com/package/commander). Essentially, it is possible to `start` or `finish` either a `feature`, a `release` or an `hotfix`. Each command can be passed options that modify the default behaviour. ### Common options to **all** commands | Option flag | Description | | --------------------- | ------------------------------------- | | -c, --config \<file\> | configuration file to use | | -b, --base \<name\> | override the current base branch name | | --no-base | do not use a base branch name | ### The `start` command ```sh gof start <feature|release|hotfix> [options] [name] ``` Commands can be shortened using the initial letter: ```sh gof s f -h # => gof start feature --help ``` #### `start` options Options are common to every sub-command (`start feature`, `start release`, `start hotfix`) | Option flag | Description | | ----------------- | --------------------------------------------------------------- | | -r, --ref \<ref\> | new branch will be created from the given branch, commit or tag | | --no-ref | create the new branch from the current branch | ### The `finish` command The `finish` command syntax is exactly the same as the `start` command. What changes are the options that can be passed to the sub-commands. #### Common `finish` options | Option flag | Description | | ------------------ | ------------------------------ | | -o,--onto \<onto\> | branch to merge or rebase onto | | -p,--push | push to origin after merge | | --no-push | do not push | | -d,--delete | delete branch after merge | | --no-delete | do not delete branch | #### `finish feature` options | Option flag | Description | | -------------------------- | --------------------------- | | -i,--interactive | interactive rebase | | --no-interactive | do not rebase interactively | | -s,--strategy \<strategy\> | merge strategy | #### `finish release` and `finish hotfix` options | Option flag | Description | | -------------------- | ----------------------------------------------------- | | -t,--tag \<tagName\> | tag the commit with the given tag | | --no-tag | do not tag the commit | | -m,--message \<msg\> | annotate tag with a message (default to the tag name) | ### `--help` and `--dry-run` options A help menu is available with every command. Just append `-h` or `--help` to access help. ```sh gof finish release --help ``` Another interesting way to experiment with **_git-OneFlow_** is to use the `--dry-run` option. This will show the commands that would be invoked without actually doing anything. It is possible to activate the `dry-run` mode also by setting the environment variable `GOF_DRY_RUN` ```sh GOF_DRY_RUN=1 gof start release ``` or for Windows ```sh set GOF_DRY_RUN=1 & gof start release ``` ## Changelog The changelog can be found on the [Releases page](https://github.com/msanguineti/git-oneflow/releases). ## Contributing PRs welcome! ## License **_git-OneFlow_** is released under the MIT License. See [LICENSE](./LICENSE) for more details.