Repository: VirtusLab/git-machete
Pull request #638 (2022-08-19 15:00:43)

Issue #211: Generate command line documentation based on .rst files.

codecov-commenter: # [Codecov](https://codecov.io/gh/VirtusLab/git-machete/pull/638?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab) Report
> Merging [#638](https://codecov.io/gh/VirtusLab/git-machete/pull/638?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab) (164e788) into [develop](https://codecov.io/gh/VirtusLab/git-machete/commit/bf0d7c317de6d3a767d23800a53e22c32aabed63?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab) (bf0d7c3) will **decrease** coverage by `0.02%`.
> The diff coverage is `100.00%`.

```diff
@@             Coverage Diff             @@
##           develop     #638      +/-   ##
===========================================
- Coverage    69.54%   69.52%   -0.03%     
===========================================
  Files           10       11       +1     
  Lines         2932     2930       -2     
  Branches       709      709              
===========================================
- Hits          2039     2037       -2     
  Misses         623      623              
  Partials       270      270              
```


| [Impacted Files](https://codecov.io/gh/VirtusLab/git-machete/pull/638?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab) | Coverage Δ | |
|---|---|---|
| [git\_machete/docs.py](https://codecov.io/gh/VirtusLab/git-machete/pull/638/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab#diff-Z2l0X21hY2hldGUvZG9jcy5weQ==) | `100.00% <ø> (ø)` | |
| [git\_machete/cli.py](https://codecov.io/gh/VirtusLab/git-machete/pull/638/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab#diff-Z2l0X21hY2hldGUvY2xpLnB5) | `75.53% <100.00%> (+0.05%)` | :arrow_up: |
| [git\_machete/short\_docs.py](https://codecov.io/gh/VirtusLab/git-machete/pull/638/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab#diff-Z2l0X21hY2hldGUvc2hvcnRfZG9jcy5weQ==) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VirtusLab)


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index c67fc73..10c4b23 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -85,13 +85,13 @@ jobs:
       - codecov/upload:
           file: coverage.xml
 
-  "sphinx docs and python 3_10 git 2_33_1":
+  "docs and python 3_10 git 2_33_1":
     executor: ubuntu_executor
     steps:
       - checkout
       - run:
           name: Run tests against Python 3.10 and git 2.33.1 (with building docs)
-          command: PYTHON_VERSION=3.10 GIT_VERSION=2.33.1 BUILD_DOCS=true  bash ci/tox/ci-run.sh
+          command: PYTHON_VERSION=3.10 GIT_VERSION=2.33.1 BUILD_SPHINX_DOCS=true CHECK_PY_DOCS_UP_TO_DATE=true bash ci/tox/ci-run.sh
       - store_test_results:
           path: test-results/
       - store_artifacts:
@@ -191,7 +191,7 @@ mandatory_jobs: &mandatory_jobs
   - python 3_7 git 2_7_6
   - pep8 and python 3_8 git 2_25_0
   - coverage and python 3_9 git 2_30_1
-  - sphinx docs and python 3_10 git 2_33_1
+  - docs and python 3_10 git 2_33_1
 
 workflows:
   version: 2
@@ -202,7 +202,7 @@ workflows:
       - python 3_7 git 2_7_6
       - pep8 and python 3_8 git 2_25_0
       - coverage and python 3_9 git 2_30_1
-      - sphinx docs and python 3_10 git 2_33_1
+      - docs and python 3_10 git 2_33_1
       - dry run deploy:
           filters:
             branches:
diff --git a/ci/tox/.env-sample b/ci/tox/.env-sample
index 03f569a..ddbf2a2 100644
--- a/ci/tox/.env-sample
+++ b/ci/tox/.env-sample
@@ -3,6 +3,7 @@ GIT_VERSION=2.25.0  # note that generally the older the git version, the faster
 PYTHON_VERSION=3.8
 
 # Vars for `docker-compose run`
-BUILD_DOCS=false
+BUILD_SPHINX_DOCS=false
+CHECK_PY_DOCS_UP_TO_DATE=false
 CHECK_COVERAGE=false
 CHECK_PEP8=false
diff --git a/ci/tox/build-context/run.sh b/ci/tox/build-context/run.sh
index f28b6f8..0bcc609 100644
--- a/ci/tox/build-context/run.sh
+++ b/ci/tox/build-context/run.sh
@@ -17,8 +17,12 @@ else
   TOX_ENV_LIST="mypy-py${PYTHON_VERSION/./},py${PYTHON_VERSION/./}"
 fi
 
-if [[ $BUILD_DOCS = true ]]; then
-  TOX_ENV_LIST="$TOX_ENV_LIST,docs"
+if [[ $BUILD_SPHINX_DOCS = true ]]; then
+  TOX_ENV_LIST="$TOX_ENV_LIST,sphinx-docs"
+fi
+
+if [[ $CHECK_PY_DOCS_UP_TO_DATE = true ]]; then
+  TOX_ENV_LIST="$TOX_ENV_LIST,check-py-docs"
 fi
 
 if [[ $CHECK_PEP8 = true ]]; then
diff --git a/ci/tox/docker-compose.yml b/ci/tox/docker-compose.yml
index 8161577..4def728 100644
--- a/ci/tox/docker-compose.yml
+++ b/ci/tox/docker-compose.yml
@@ -9,7 +9,8 @@ services:
         - git_version=${GIT_VERSION:-0.0.0}
         - python_version=${PYTHON_VERSION:-0.0.0}
     environment:
-      - BUILD_DOCS=${BUILD_DOCS:-false}
+      - BUILD_SPHINX_DOCS=${BUILD_SPHINX_DOCS:-false}
+      - CHECK_PY_DOCS_UP_TO_DATE=${CHECK_PY_DOCS_UP_TO_DATE:-false}
       - CHECK_COVERAGE=${CHECK_COVERAGE:-false}
       - CHECK_PEP8=${CHECK_PEP8:-false}
     volumes:
diff --git a/docs/enforce-docs-up-to-date.sh b/docs/enforce-docs-up-to-date.sh
new file mode 100755
index 0000000..4869016
--- /dev/null
+++ b/docs/enforce-docs-up-to-date.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+set -e -o pipefail -u
+
+current_docs=$(<git_machete/generated_long_docs.py)
+generated_docs=$(python docs/generate_py_docs.py)
+
+if [[ "$current_docs" != "$generated_docs" ]]; then
+  echo "Command line docs are not up-to-date. Please regenerate docs via tox -e py-docs"
+  exit 1
+fi
diff --git a/docs/generate_py_docs.py b/docs/generate_py_docs.py
new file mode 100644
index 0000000..fd18ac6
--- /dev/null
+++ b/docs/generate_py_docs.py
@@ -0,0 +1,178 @@
+from bs4 import BeautifulSoup
+from docutils import core
+import os
+from os.path import isfile, join
+import re
+from textwrap import dedent, indent
+
+
+def rst2html(input_string: str, source_path: str = None, destination_path: str = None,
+             input_encoding: str = 'unicode', doctitle: bool = True,
+             initial_header_level: int = 1):
+    overrides = {'input_encoding': input_encoding,
+                 'doctitle_xform': doctitle,
+                 'initial_header_level': initial_header_level}
+    parts = core.publish_parts(
+        source=input_string, source_path=source_path,
+        destination_path=destination_path,
+        writer_name='html', settings_overrides=overrides)
+    return parts['body']
+
+
+def html2txt(html: str):
+    html_elements = BeautifulSoup(html, features="html.parser")
+    INDENT = '   '
+
+    # remove style tags
+    for tag in html_elements.select('style'):
+        tag.decompose()
+
+    for tag in html_elements.select('td'):
+        # remove non-breaking spaces
+        if tag.text == u'\xa0':
+            tag.decompose()
+        else:
+            # add new line and indent for the cells inside a table
+            if 'class' not in tag.attrs:
+                tag.insert_before(f'\n{2 * INDENT}')
+
+    # substitute double backticks with a single backtick
+    for tag in html_elements.select('tt'):
+        tag.insert_before('`')
+        tag.insert_after('`')
+
+    # format cite's tag text with single backticks
+    for tag in html_elements.select('cite'):
+        tag.insert_before('`')
+        tag.insert_after('`')
+
+    # format colors
+    for tag in html_elements.select('span'):
+        if 'class' in tag.attrs:
+            color = ' '.join(tag.attrs['class']).replace('gray', 'dim')
+            if color in ['green', 'yellow', 'red', 'dim']:
+                tag.insert_before(f'<{color}>')
+                tag.insert_after(f'</{color}>')
+
+    # make the option's text inside the option list bold
+    for tag in html_elements.select('span'):
+        if 'class' in tag.attrs:
+            if ' '.join(tag.attrs['class']) == 'option':
+                tag.insert_before('<b>')
+                tag.insert_after('</b>')
+
+    # keep bold text bold
+    for tag in html_elements.select('strong'):
+        tag.insert_before('<b>')
+        tag.insert_after('</b>')
+
+    # add new lines after the paragraph tag
+    for tag in html_elements.select('p'):
+        if 'class' in tag.attrs:
+            if ' '.join(tag.attrs['class']) == 'first':
+                tag.insert_before(' ')
+            if 'admonition-title' in ' '.join(tag.attrs['class']):
+                tag.decompose()
+            else:
+                tag.insert_before('\n')
+        else:
+            tag.insert_before('\n\n')
+
+    # add indent and bullet points to the nested bulleted list
+    for tag in html_elements.select('li'):
+        if tag.parent.parent is not None:
+            if tag.parent.parent.name == 'li':
+                tag.string = indent('- ' + tag.text, INDENT + '  ')
+
+    # add indent and bullet points to the bulleted list
+    for tag in html_elements.select('li'):
+        if tag.parent.parent is not None:
+            if tag.parent.parent.name != 'li':
+                tag.insert_before(f'\n{INDENT}*')
+                tag.string = indent(tag.text, ' ')
+
+    # format elements in the `Option:` section by adding new line and indent
+    for tag in html_elements.select('kbd'):
+        tag.insert_before(f'\n{INDENT}')
+
+    # add indent to the description list
+    for tag in html_elements.select('dt'):
+        tag.string = '\n' + indent(tag.text.strip(), INDENT)
+
+    # add indent to the nested description list
+    for tag in html_elements.select('dd'):
+        tag.string = '\n' + indent(tag.text, 2 * INDENT) + '\n'
+
+    # format code examples
+    for tag in html_elements.select('pre'):
+        if 'class' in tag.attrs:
+            if ' '.join(tag.attrs['class']).replace('first', '').replace('last', '').replace('  ', ' ') == 'code literal-block':
+                tag.string = '\n<dim>' + indent(tag.text, '  ') + '</dim>'
+            elif 'literal-block' in ' '.join(tag.attrs['class']):
+                tag.string = '<b>' + indent(tag.text.rstrip('\n'), INDENT) + '</b>'
+
+    # build python docs string out of the previously formatted html tags
+    text: str = ''
+    for html_element in html_elements.descendants:
+        if isinstance(html_element, str):
+            if html_element != '\n':
+                new_text = html_element
+            else:
+                new_text = html_element.replace('\n', '')
+            text += new_text
+    return text
+
+
+def skip_or_replace_unparseable_directives(rst: str) -> str:
+    rst = rst.replace(':ref:', '')
+    return rst
+
+
+def resolve_includes(rst: str, docs_source_path: str) -> str:
+    matches = re.findall(r'(.*)\.\. include:: (.*)', rst)
+    for indent_, match in matches:
+        with open(f'{docs_source_path}/{match}', 'r') as handle:
+            include_text = handle.read()
+        rst = rst.replace(f'{indent_}.. include:: {match}', indent(dedent(include_text), indent_))
+    return rst
+
+
+def skip_prefix_new_lines(txt: str) -> str:
+    txt = re.sub(r'\A[\n]+', '', txt)
+    return txt
+
+
+def replace_3_newlines_and_more_with_2_newlines(txt: str) -> str:
+    for i in range(10, 2, -1):
+        txt = txt.replace(i * '\n', '\n\n')
+    return txt
+
+
+if __name__ == '__main__':
+    docs_source_path = 'docs/source'
+    warning_text = '# ---------------------------------------------------------------------------------------------------------\n' \
+                   '# Warning: This file is NOT supposed to be edited directly, ' \
+                   'but instead regenerated via tox -e docs\n' \
+                   '# ---------------------------------------------------------------------------------------------------------\n'
+    output_text = 'from typing import Dict\n\n' + warning_text + '\nlong_docs: Dict[str, str] = {\n'
+    path = docs_source_path + '/cli_help'
+    commands_and_file_paths = {f.split('.')[0]: join(path, f) for f in sorted(os.listdir(path)) if isfile(join(path, f))}
+
+    for command, file in commands_and_file_paths.items():
+        with open(file, 'r') as f:
+            rst = f.read()
+
+        rst = skip_or_replace_unparseable_directives(rst)
+        rst = resolve_includes(rst=rst, docs_source_path=docs_source_path)
+
+        html = rst2html(rst)
+
+        plain_text = html2txt(html)
+        plain_text = skip_prefix_new_lines(plain_text)
+        plain_text = plain_text.replace('---', '—')
+
+        output_text += f'    "{command}": """\n' + indent(plain_text, '        ') + '\n   """,\n'
+        output_text = replace_3_newlines_and_more_with_2_newlines(output_text)
+
+    output_text += '}'
+    print(output_text)
diff --git a/docs/source/cli_help/advance.rst b/docs/source/cli_help/advance.rst
index ce519be..731c895 100644
--- a/docs/source/cli_help/advance.rst
+++ b/docs/source/cli_help/advance.rst
@@ -19,7 +19,7 @@ and subsequently slides out ``D``. All three steps require manual confirmation u
 
 The downstream ``D`` is selected according to the following criteria:
 
-    * if ``C`` has exactly one downstream (child) branch ``d`` connected with a :green:`green edge` (see :ref:`status` for definition) to ``C`` or is overridden, then ``d`` is selected as ``D``,
+    * if ``C`` has exactly one downstream (child) branch ``d`` connected with a :green:`green edge` (see help for :ref:`status`) to ``C`` or is overridden, then ``d`` is selected as ``D``,
     * if ``C`` has no downstream branches connected with a :green:`green edge` to ``C``, then ``advance`` fails,
     * if ``C`` has more than one downstream branch connected with a :green:`green edge` to ``C``,
       then user is asked to pick the branch to fast-forward merge into (similarly to what happens in ``git machete go down``). If ``--yes`` is specified, then ``advance`` fails.
@@ -34,16 +34,9 @@ As an example, if ``git machete status --color=never --list-commits`` is as foll
       |
       | Enable adding remote branch in the manner similar to git checkout
       o-feature/add-from-remote
-      | |
-      | | Add support and sample for machete-post-slide-out hook
-      | o-feature/post-slide-out-hook
-      |
-      | Remove support for Python 2
-      | Remove support for Python 2 --- 1st round of fixes
-      ?-chore/v3
-      |
-      | Apply Python2-compatible static typing
-      x-feature/types
+        |
+        | Add support and sample for machete-post-slide-out hook
+        o-feature/post-slide-out-hook
 
 then running ``git machete advance`` will fast-forward the current branch ``develop`` to match ``feature/add-from-remote``, and subsequently slide out the latter.
 After ``advance`` completes, ``status`` will show:
@@ -57,13 +50,6 @@ After ``advance`` completes, ``status`` will show:
       |
       | Add support and sample for machete-post-slide-out hook
       o-feature/post-slide-out-hook
-      |
-      | Remove support for Python 2
-      | Remove support for Python 2 --- 1st round of fixes
-      ?-chore/v3
-      |
-      | Apply Python2-compatible static typing
-      x-feature/types
 
 Note that the current branch after the operation is still ``develop``, just pointing to ``feature/add-from-remote``'s tip now.
 
diff --git a/docs/source/cli_help/clean.rst b/docs/source/cli_help/clean.rst
index 063df51..cbaa6a7 100644
--- a/docs/source/cli_help/clean.rst
+++ b/docs/source/cli_help/clean.rst
@@ -9,6 +9,7 @@ clean
     git machete clean [-c|--checkout-my-github-prs] [-y|--yes]
 
 Synchronizes with the remote repository:
+
     1. if invoked with ``-H`` or ``--checkout-my-github-prs``, checks out open PRs for the current user associated with the GitHub token and also traverses the chain of pull requests upwards, adding branches one by one to git-machete and checks them out locally as well,
     2. deletes unmanaged branches,
     3. deletes untracked managed branches that have no downstream branch.
diff --git a/docs/source/cli_help/config.rst b/docs/source/cli_help/config.rst
index 4e99d05..da3d8fc 100644
--- a/docs/source/cli_help/config.rst
+++ b/docs/source/cli_help/config.rst
@@ -8,78 +8,32 @@ Note: ``config`` is not a command as such, just a help topic (there is no ``git
 
 **Config keys:**
 
-    * ``machete.github.{remote,organization,repository}``:
+``machete.github.{remote,organization,repository}``:
+    When executing ``git machete github <subcommand>`` command, the following will happen:
 
-        When executing ``git machete github <subcommand>`` command, GitHub API server URL will be inferred from ``git remote``.
-        You can override this by setting the following local git config keys:
+    .. include:: github_config_keys.rst
 
-            Remote name
-                E.g. ``machete.github.remote`` = ``origin``
+``machete.overrideForkPoint.<branch>.{to,whileDescendantOf}``:
+    Executing ``git machete fork-point --override-to=<revision> [<branch>]`` sets up a fork point override for <branch>.
+    The override data is stored under ``machete.overrideForkPoint.<branch>.to`` and ``machete.overrideForkPoint.<branch>.whileDescendantOf`` git config keys.
 
-            Organization name
-                E.g. ``machete.github.organization`` = ``VirtusLab``
+``machete.status.extraSpaceBeforeBranchName``:
+    .. include:: status_config_key.rst
 
-            Repository name
-                E.g. ``machete.github.repository`` = ``git-machete``
-
-        To do this, run ``git config --local --edit`` and add the following section:
-
-        .. code-block:: ini
-
-            [machete "github"]
-                organization = <organization_name>
-                repository = <repo_name>
-                remote = <remote_name>
-
-    * ``machete.overrideForkPoint.<branch>.{to,whileDescendantOf}``
-
-        Executing ``git machete fork-point --override-to=<revision> [<branch>]`` sets up a fork point override for <branch>.
-        The override data is stored under ``machete.overrideForkPoint.<branch>.to`` and ``machete.overrideForkPoint.<branch>.whileDescendantOf`` git config keys.
-
-    * ``machete.status.extraSpaceBeforeBranchName``
-
-        To make it easier to select branch name from the ``status`` output on certain terminals
-        (e.g. `Alacritty <https://github.com/alacritty/alacritty>`_), you can add an extra
-        space between ``└─`` and ``branch name`` by setting ``git config machete.status.extraSpaceBeforeBranchName true``.
-
-        For example, by default it's:
-
-        .. code-block::
-
-          develop
-          │
-          ├─feature_branch1
-          │
-          └─feature_branch2
-
-        With ``machete.status.extraSpaceBeforeBranchName`` config set to ``true``:
-
-        .. code-block::
-
-           develop
-           │
-           ├─ feature_branch1
-           │
-           └─ feature_branch2
-
-    * ``machete.worktree.useTopLevelMacheteFile``
-
-        The default value of this key is ``true``, which means that the path to machete definition file will be ``.git/machete``
-        for both regular directory and worktree. If you want the worktree to have its own machete definition file (located under
-        ``.git/worktrees/.../machete``), set ``git config machete.worktree.useTopLevelMacheteFile false``.
+``machete.worktree.useTopLevelMacheteFile``:
+    The default value of this key is ``true``, which means that the path to machete definition file will be ``.git/machete``
+    for both regular directory and worktree. If you want the worktree to have its own machete definition file (located under
+    ``.git/worktrees/.../machete``), set ``git config machete.worktree.useTopLevelMacheteFile false``.
 
 
 **Environment variables:**
 
-    * ``GIT_MACHETE_EDITOR``
-
-        Name of the editor used by ``git machete e[dit]``, example: ``vim`` or ``nano``.
-
-    * ``GIT_MACHETE_REBASE_OPTS``
-
-        Used to pass extra options to the underlying ``git rebase`` invocation (called by the executed command, such as: ``reapply``, ``slide-out``, ``traverse``, ``update``)
-        Example: ``GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete update``.
+``GIT_MACHETE_EDITOR``
+    Name of the editor used by ``git machete e[dit]``, example: ``vim`` or ``nano``.
 
-    * ``GITHUB_TOKEN``
+``GIT_MACHETE_REBASE_OPTS``
+    Used to pass extra options to the underlying ``git rebase`` invocation (called by the executed command, such as: ``reapply``, ``slide-out``, ``traverse``, ``update``)
+    Example: ``GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete update``.
 
-        Used to store GitHub API token. Used by commands such as: ``anno``, ``clean``, ``github``.
+``GITHUB_TOKEN``
+    Used to store GitHub API token. Used by commands such as: ``anno``, ``clean``, ``github``.
diff --git a/docs/source/cli_help/delete-unmanaged.rst b/docs/source/cli_help/delete-unmanaged.rst
index 802b411..ae26db1 100644
--- a/docs/source/cli_help/delete-unmanaged.rst
+++ b/docs/source/cli_help/delete-unmanaged.rst
@@ -13,7 +13,7 @@ and ask to delete each of them (with ``git branch -d`` or ``git branch -D``) if
 No branch will be deleted unless explicitly confirmed by the user (or unless ``-y/--yes`` option is passed).
 
 Note: this should be used with care since deleting local branches can sometimes make it impossible for ``git machete`` to properly figure out fork points.
-See :ref:`fork-point` for more details.
+See help for :ref:`fork-point` for more details.
 
 **Options:**
 
diff --git a/docs/source/cli_help/diff.rst b/docs/source/cli_help/diff.rst
index c225bfc..4fe7efb 100644
--- a/docs/source/cli_help/diff.rst
+++ b/docs/source/cli_help/diff.rst
@@ -9,7 +9,7 @@ diff
     git machete d[iff] [-s|--stat] [<branch>]
 
 Runs ``git diff`` of the given branch tip against its fork point or, if none specified, of the current working tree against the fork point of the currently checked out branch.
-See :ref:`fork-point` for more details on meaning of the *fork point*.
+See help for :ref:`fork-point` for more details on the meaning of *fork point*.
 
 Note: the branch in question does not need to occur in the definition file.
 
diff --git a/docs/source/cli_help/discover.rst b/docs/source/cli_help/discover.rst
index 79cec4f..ca260e9 100644
--- a/docs/source/cli_help/discover.rst
+++ b/docs/source/cli_help/discover.rst
@@ -10,7 +10,7 @@ discover
 
 Discovers and displays tree of branch dependencies using a heuristic based on reflogs and asks whether to overwrite the existing definition :ref:`file` with the new discovered tree.
 If confirmed with a ``y[es]`` or ``e[dit]`` reply, backs up the current definition file (if it exists) as ``$GIT_DIR/machete~`` and saves the new tree under the usual ``$GIT_DIR/machete`` path.
-If the reply was ``e[dit]``, additionally an editor is opened (as in :ref:`git machete edit<edit>`) after saving the new definition file.
+If the reply was ``e[dit]``, additionally an editor is opened (as in: ``git machete`` :ref:`edit`) after saving the new definition file.
 
 **Options:**
 
diff --git a/docs/source/cli_help/file.rst b/docs/source/cli_help/file.rst
index 76b369d..fc14908 100644
--- a/docs/source/cli_help/file.rst
+++ b/docs/source/cli_help/file.rst
@@ -12,9 +12,11 @@ Outputs the absolute path of machete definition file.
 The file is always called ``machete`` and is located in the git directory of the project.
 
 Three cases are possible:
+
     * if ``git machete`` is executed from a regular working directory (not a worktree or submodule), the file is located under ``.git/machete``,
     * if ``git machete`` is executed from a **worktree**, the file path depends on the ``machete.worktree.useTopLevelMacheteFile`` config key value:
 
-        * if ``machete.worktree.useTopLevelMacheteFile`` is true (default), the file is located under ``.git/machete``
-        * if ``machete.worktree.useTopLevelMacheteFile`` is false, the file is located under ``.git/worktrees/.../machete``,
+      - if ``machete.worktree.useTopLevelMacheteFile`` is true (default), the file is located under ``.git/machete``
+      - if ``machete.worktree.useTopLevelMacheteFile`` is false, the file is located under ``.git/worktrees/.../machete``,
+
     * if ``git machete`` is executed from a **submodule**, this file is located in the git folder of the submodule itself under ``.git/modules/.../machete``.
diff --git a/docs/source/cli_help/format.rst b/docs/source/cli_help/format.rst
index 8139bd4..72e718b 100644
--- a/docs/source/cli_help/format.rst
+++ b/docs/source/cli_help/format.rst
@@ -25,7 +25,7 @@ Branches ``adjust-reads-prec``, ``edit-margin-not-allowed`` and ``grep-errors-sc
 
 Every branch name can be followed (after a single space as a delimiter) by a custom annotation --- a PR number in the above example.
 The annotations don't influence the way ``git machete`` operates other than that they are displayed in the output of the ``status`` command.
-Also see :ref:`anno` command.
+Also see help for :ref:`anno` command.
 
 Tabs or any number of spaces can be used as indentation.
 It's only important to be consistent wrt. the sequence of characters used for indentation between all lines.
diff --git a/docs/source/cli_help/github.rst b/docs/source/cli_help/github.rst
index 31fafa3..378a8dc 100644
--- a/docs/source/cli_help/github.rst
+++ b/docs/source/cli_help/github.rst
@@ -15,62 +15,55 @@ Creates, checks out and manages GitHub PRs while keeping them reflected in branc
 .. include:: github_api_access.rst
 .. include:: github_config_keys.rst
 
-``anno-prs``:
+**Subcommands:**
 
-  Annotates the branches based on their corresponding GitHub PR numbers and authors.
-  Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched.
-  Equivalent to ``git machete anno --sync-github-prs``.
+``anno-prs``:
+    Annotates the branches based on their corresponding GitHub PR numbers and authors.
+    Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched.
+    Equivalent to ``git machete anno --sync-github-prs``.
 
 
 ``checkout-prs [--all | --by=<github-login> | --mine | <PR-number-1> ... <PR-number-N>]``:
+    Check out the head branch of the given pull requests (specified by numbers or by a flag),
+    also traverse chain of pull requests upwards, adding branches one by one to git-machete and check them out locally.
+    Once the specified pull requests are checked out locally, annotate local branches with corresponding pull request numbers.
+    If only one PR has been checked out, then switch the local repository's HEAD to its head branch.
 
-  Check out the head branch of the given pull requests (specified by numbers or by a flag),
-  also traverse chain of pull requests upwards, adding branches one by one to git-machete and check them out locally.
-  Once the specified pull requests are checked out locally, annotate local branches with corresponding pull request numbers.
-  If only one PR has been checked out, then switch the local repository's HEAD to its head branch.
-
-  **Options:**
+    **Options:**
 
-    ``--all``    Checkout all open PRs.
+    --all    Checkout all open PRs.
 
-    ``--by``    Checkout open PRs authored by the given GitHub user.
+    --by=<github-login>     Checkout open PRs authored by the given GitHub user. ``<github-login>`` is the GitHub account name.
 
-      **Parameters:**
-        ``<github-login>`` GitHub account name.
+    --mine    Checkout open PRs for the current user associated with the GitHub token.
 
-    ``--mine``    Checkout open PRs for the current user associated with the GitHub token.
+    **Parameters:**
 
-  **Parameters:**
-    ``<PR-number-1> ... <PR-number-N>``
-      Pull request numbers to checkout.
+    ``<PR-number-1> ... <PR-number-N>``    Pull request numbers to checkout.
 
 ``create-pr [--draft]``:
+    Creates a PR for the current branch, using the upstream (parent) branch as the PR base.
+    Once the PR is successfully created, annotates the current branch with the new PR's number.
 
-  Creates a PR for the current branch, using the upstream (parent) branch as the PR base.
-  Once the PR is successfully created, annotates the current branch with the new PR's number.
+    If ``.git/info/description`` file is present, its contents are used as PR description.
+    If ``.git/info/milestone`` file is present, its contents (a single number --- milestone id) are used as milestone.
+    If ``.git/info/reviewers`` file is present, its contents (one GitHub login per line) are used to set reviewers.
 
-  If ``.git/info/description`` file is present, its contents are used as PR description.
-  If ``.git/info/milestone`` file is present, its contents (a single number --- milestone id) are used as milestone.
-  If ``.git/info/reviewers`` file is present, its contents (one GitHub login per line) are used to set reviewers.
+    **Options:**
 
-  **Options:**
-
-    ``--draft``
-      Creates the new PR as a draft.
+    --draft    Creates the new PR as a draft.
 
 ``retarget-pr``:
-
-  Sets the base of the current branch's PR to upstream (parent) branch, as seen by git machete (see ``git machete show up``).
+    Sets the base of the current branch's PR to upstream (parent) branch, as seen by git machete (see ``git machete show up``).
 
 ``sync``:
+    Synchronizes with the remote repository:
 
-  Synchronizes with the remote repository:
-
-    1. checks out open PRs for the current user associated with the GitHub token and also traverses the chain of pull requests upwards, adding branches one by one to git-machete and checks them out locally as well,
-    2. deletes unmanaged branches,
-    3. deletes untracked managed branches that have no downstream branch.
+      1. checks out open PRs for the current user associated with the GitHub token and also traverses the chain of pull requests upwards, adding branches one by one to git-machete and checks them out locally as well,
+      2. deletes unmanaged branches,
+      3. deletes untracked managed branches that have no downstream branch.
 
-  Equivalent of ``git machete clean --checkout-my-github-prs``.
+    Equivalent of ``git machete clean --checkout-my-github-prs``.
 
 **Environment variables (all subcommands):**
 
diff --git a/docs/source/cli_help/hooks.rst b/docs/source/cli_help/hooks.rst
index ed99c23..168b52f 100644
--- a/docs/source/cli_help/hooks.rst
+++ b/docs/source/cli_help/hooks.rst
@@ -7,8 +7,9 @@ All hooks are executed from the top-level folder of the repository (or top-level
 
 Note: ``hooks`` is not a command as such, just a help topic (there is no ``git machete hooks`` command).
 
-* ``machete-post-slide-out <new-upstream> <lowest-slid-out-branch> [<new-downstreams>...]``
+**Hooks:**
 
+``machete-post-slide-out <new-upstream> <lowest-slid-out-branch> [<new-downstreams>...]``
     The hook that is executed after a branch (or possibly multiple branches, in case of ``slide-out``)
     is slid out by ``advance``, ``slide-out`` or ``traverse``.
 
@@ -34,8 +35,7 @@ Note: ``hooks`` is not a command as such, just a help topic (there is no ``git m
     Note that non-zero exit code of the hook doesn't cancel the effects of slide-out itself, only the subsequent operations.
     The hook is executed only once the slide-out is complete and can in fact rely on .git/machete file being updated to the new branch layout.
 
-* ``machete-pre-rebase <new-base> <fork-point-hash> <branch-being-rebased>``
-
+``machete-pre-rebase <new-base> <fork-point-hash> <branch-being-rebased>``
     The hook that is executed before rebase is run during ``reapply``, ``slide-out``, ``traverse`` and ``update``.
     Note that it is NOT executed by ``squash`` (despite its similarity to ``reapply``), since no rebase is involved in ``squash``.
 
@@ -51,8 +51,7 @@ Note: ``hooks`` is not a command as such, just a help topic (there is no ``git m
     If machete-pre-rebase returns zero, the execution flow continues to ``git rebase``, which may also run ``pre-rebase hook`` if present.
     ``machete-pre-rebase`` is thus always launched before ``pre-rebase``.
 
-* ``machete-status-branch <branch-name>``
-
+``machete-status-branch <branch-name>``
     The hook that is executed for each branch displayed during ``discover``, ``status`` and ``traverse``.
 
     The standard output of this hook is displayed at the end of the line, after branch name, (optionally) custom annotation and (optionally) remote sync-ness status.
@@ -61,5 +60,5 @@ Note: ``hooks`` is not a command as such, just a help topic (there is no ``git m
     Note: the hook is always invoked with ``ASCII_ONLY`` variable passed into the environment.
     If ``status`` runs in ASCII-only mode (i.e. if ``--color=auto`` and stdout is not a terminal, or if ``--color=never``), then ``ASCII_ONLY=true``, otherwise ``ASCII_ONLY=false``.
 
-Please see `hook_samples <https://github.com/VirtusLab/git-machete/tree/master/hook_samples>`_ for examples.
+Please see `hook_samples <https://github.com/VirtusLab/git-machete/tree/master/hook_samples>`_ directory in git-machete project for examples.
 An example of using the standard git ``post-commit hook`` to ``git machete add`` branches automatically is also included.
diff --git a/docs/source/cli_help/log.rst b/docs/source/cli_help/log.rst
index 489e4ea..cdcc0b3 100644
--- a/docs/source/cli_help/log.rst
+++ b/docs/source/cli_help/log.rst
@@ -9,6 +9,6 @@ log
     git machete l[og] [<branch>]
 
 Runs ``git log`` for the range of commits from tip of the given branch (or current branch, if none specified) back to its fork point.
-See :ref:`fork-point` for more details on meaning of the *fork point*.
+See help for :ref:`fork-point` for more details on meaning of the *fork point*.
 
 Note: the branch in question does not need to occur in the definition file.
diff --git a/docs/source/cli_help/reapply.rst b/docs/source/cli_help/reapply.rst
index ff42262..47b5d1c 100644
--- a/docs/source/cli_help/reapply.rst
+++ b/docs/source/cli_help/reapply.rst
@@ -10,7 +10,7 @@ reapply
 
 Interactively rebase the current branch on the top of its computed fork point.
 The chunk of the history to be rebased starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by ``--fork-point``.
-See :ref:`fork-point` for more details on meaning of the *fork point*.
+See help for :ref:`fork-point` for more details on meaning of the *fork point*.
 
 Note: the current reapplied branch does not need to occur in the definition file.
 
@@ -25,5 +25,4 @@ but there is also dedicated ``squash`` command that achieves the same goal witho
 
 ``GIT_MACHETE_REBASE_OPTS``
     Extra options to pass to the underlying ``git rebase`` invocation, space-separated.
-
     Example: ``GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete reapply``.
diff --git a/docs/source/cli_help/slide-out.rst b/docs/source/cli_help/slide-out.rst
index 6931df6..15d71d7 100644
--- a/docs/source/cli_help/slide-out.rst
+++ b/docs/source/cli_help/slide-out.rst
@@ -62,5 +62,4 @@ Note: This command doesn't delete any branches from git, just removes them from
 
 ``GIT_MACHETE_REBASE_OPTS``
     Extra options to pass to the underlying ``git rebase`` invocations, space-separated.
-
     Example: ``GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete slide-out``.
diff --git a/docs/source/cli_help/squash.rst b/docs/source/cli_help/squash.rst
index 597e939..5508fd8 100644
--- a/docs/source/cli_help/squash.rst
+++ b/docs/source/cli_help/squash.rst
@@ -10,7 +10,7 @@ squash
 
 Squashes the commits belonging uniquely to the current branch into a single commit.
 The chunk of the history to be squashed starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by ``--fork-point``.
-See :ref:`fork-point` for more details on meaning of the *fork point*.
+See help for :ref:`fork-point` for more details on meaning of the *fork point*.
 The message for the squashed is taken from the earliest squashed commit, i.e. the commit directly following the fork point.
 
 Note: the current squashed branch does not need to occur in the definition file.
diff --git a/docs/source/cli_help/status.rst b/docs/source/cli_help/status.rst
index f8286f0..0649818 100644
--- a/docs/source/cli_help/status.rst
+++ b/docs/source/cli_help/status.rst
@@ -40,9 +40,9 @@ Apart from simply ASCII-formatting the definition file, this also:
 
     * prints (``untracked``/``ahead of <remote>``/``behind <remote>``/``diverged from [& older than] <remote>``) message if the branch is not in sync with its remote counterpart;
 
-    * displays the custom annotations (see :ref:`format` and :ref:`anno`) next to each branch, if present;
+    * displays the custom annotations (see help for :ref:`format` and :ref:`anno`) next to each branch, if present;
 
-    * displays the output of ``machete-status-branch hook`` (see :ref:`hooks`), if present;
+    * displays the output of ``machete-status-branch hook`` (see help for :ref:`hooks`), if present;
 
     * optionally lists commits introduced on each branch if ``-l/--list-commits`` or ``-L/--list-commits-with-hashes`` is supplied.
 
@@ -50,9 +50,9 @@ Name of the currently checked-out branch is underlined (or shown in blue on term
 
 In case of :yellow:`yellow edge`, use ``-l`` or ``-L`` flag to show the exact location of the inferred fork point
 (which indicates e.g. what range of commits is going to be rebased when the branch is updated).
-The inferred fork point can be always overridden manually, see :ref:`fork-point`.
+The inferred fork point can be always overridden manually, see help for :ref:`fork-point`.
 
-:grey:`Grey/dimmed edge` suggests that the downstream branch can be slid out (see :ref:`slide-out` and :ref:`traverse`).
+:grey:`Grey/dimmed edge` suggests that the downstream branch can be slid out (see help for :ref:`slide-out` and :ref:`traverse`).
 
 Using colors can be disabled with a ``--color`` flag set to ``never``.
 With ``--color=always``, git machete always emits colors and with ``--color=auto``, it emits colors only when standard output is connected to a terminal.
@@ -70,6 +70,7 @@ With ``--color=always``, git machete always emits colors and with ``--color=auto
     |
     m-<branch4>     # grey (merged to parent)
 
+
 **Options:**
 
 --color=WHEN                      Colorize the output; WHEN can be ``always``, ``auto`` (default; i.e. only if stdout is a terminal), or ``never``.
@@ -80,28 +81,7 @@ With ``--color=always``, git machete always emits colors and with ``--color=auto
 
 --no-detect-squash-merges         Only consider *strict* (fast-forward or 2-parent) merges, rather than rebase/squash merges, when detecting if a branch is merged into its upstream (parent).
 
- .. note::
-
-    To make it easier to select branch name from the ``status`` output on certain terminals
-    (e.g. `Alacritty <https://github.com/alacritty/alacritty>`_), you can add an extra
-    space between ``└─`` and ``branch name`` by setting ``git config machete.status.extraSpaceBeforeBranchName true``.
-
-    For example, by default the status is displayed as:
-
-    .. code-block::
-
-      develop
-      │
-      ├─feature_branch1
-      │
-      └─feature_branch2
-
-    With ``machete.status.extraSpaceBeforeBranchName`` config set to ``true``:
-
-    .. code-block::
+**Config keys:**
 
-       develop
-       │
-       ├─ feature_branch1
-       │
-       └─ feature_branch2
+``machete.status.extraSpaceBeforeBranchName``
+    .. include:: status_config_key.rst
diff --git a/docs/source/cli_help/traverse.rst b/docs/source/cli_help/traverse.rst
index f87355c..5f37152 100644
--- a/docs/source/cli_help/traverse.rst
+++ b/docs/source/cli_help/traverse.rst
@@ -34,7 +34,7 @@ For each branch, the command:
       - by commit equivalency (default), or by strict detection of merge commits (if ``--no-detect-squash-merges`` passed),
       - if so, asks the user whether to slide out the branch from the dependency tree (typically branches are no longer needed after they're merged);
 
-    * otherwise, if the branch has a :red:`red` or :yellow:`yellow` edge to its parent/upstream (see :ref:`status`):
+    * otherwise, if the branch has a :red:`red` or :yellow:`yellow` edge to its parent/upstream (see help for :ref:`status`):
 
       - asks the user whether to rebase (default) or merge (if ``--merge`` passed) the branch onto into its upstream branch
         --- equivalent to ``git machete update`` with no ``--fork-point`` option passed;
@@ -98,5 +98,4 @@ Unlike with e.g. ``git rebase``, there is no special ``--continue`` flag, as ``t
 
 ``GIT_MACHETE_REBASE_OPTS``
     Extra options to pass to the underlying ``git rebase`` invocations, space-separated.
-
     Example: ``GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete traverse``.
diff --git a/docs/source/cli_help/update.rst b/docs/source/cli_help/update.rst
index 8260a7e..018477e 100644
--- a/docs/source/cli_help/update.rst
+++ b/docs/source/cli_help/update.rst
@@ -12,7 +12,7 @@ Synchronizes the current branch with its upstream (parent) branch either by reba
 
 If updating by rebase, interactively rebases the current branch on the top of its upstream (parent) branch.
 The chunk of the history to be rebased starts at the fork point of the current branch, which by default is inferred automatically, but can also be set explicitly by ``--fork-point``.
-See :ref:`fork-point` for more details on meaning of the *fork point*.
+See help for :ref:`fork-point` for more details on the meaning of *fork point*.
 
 If updating by merge, merges the upstream (parent) branch into the current branch.
 
@@ -32,5 +32,4 @@ If updating by merge, merges the upstream (parent) branch into the current branc
 
 ``GIT_MACHETE_REBASE_OPTS``
     Extra options to pass to the underlying ``git rebase`` invocation, space-separated.
-
     Example: ``GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete update``.
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 340151c..5fc2014 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -48,7 +48,8 @@ exclude_patterns = [
     'description.rst',
     'learning_materials.rst',
     'github_api_access.rst',
-    'github_config_keys.rst'
+    'github_config_keys.rst',
+    'status_config_key.rst'
 ]
 
 
diff --git a/docs/source/github_config_keys.rst b/docs/source/github_config_keys.rst
index cd9771c..da228e1 100644
--- a/docs/source/github_config_keys.rst
+++ b/docs/source/github_config_keys.rst
@@ -14,7 +14,7 @@
 
     To do this, run ``git config --local --edit`` and add the following section:
 
-    .. code-block:: ini
+    .. code-block::
 
         [machete "github"]
             organization = <organization_name>
diff --git a/docs/source/status_config_key.rst b/docs/source/status_config_key.rst
new file mode 100644
index 0000000..c5459f9
--- /dev/null
+++ b/docs/source/status_config_key.rst
@@ -0,0 +1,25 @@
+ .. note::
+
+    To make it easier to select branch name from the ``status`` output on certain terminals
+    (e.g. `Alacritty <https://github.com/alacritty/alacritty>`_), you can add an extra
+    space between └─ and ``branch name`` by setting ``git config machete.status.extraSpaceBeforeBranchName true``.
+
+    For example, by default the status is displayed as:
+
+    .. code-block::
+
+      develop
+      │
+      ├─feature_branch1
+      │
+      └─feature_branch2
+
+    With ``machete.status.extraSpaceBeforeBranchName`` config set to ``true``:
+
+    .. code-block::
+
+       develop
+       │
+       ├─ feature_branch1
+       │
+       └─ feature_branch2
diff --git a/git_machete/cli.py b/git_machete/cli.py
index d037907..a241a7a 100644
--- a/git_machete/cli.py
+++ b/git_machete/cli.py
@@ -11,7 +11,8 @@ import git_machete.options
 from git_machete import __version__
 from git_machete import utils
 from git_machete.client import MacheteClient
-from git_machete.docs import short_docs, long_docs
+from git_machete.generated_long_docs import long_docs
+from git_machete.handmade_short_docs import short_docs
 from git_machete.exceptions import MacheteException, StopInteraction
 from git_machete.git_operations import AnyBranchName, AnyRevision, GitContext, LocalBranchShortName, RemoteBranchShortName
 from git_machete.utils import bold, fmt, underline, excluding, warn
diff --git a/git_machete/docs.py b/git_machete/docs.py
deleted file mode 100644
index fa30f7e..0000000
--- a/git_machete/docs.py
+++ /dev/null
@@ -1,855 +0,0 @@
-import textwrap
-from typing import Dict
-from git_machete.constants import DISCOVER_DEFAULT_FRESH_BRANCH_COUNT
-
-short_docs: Dict[str, str] = {
-    "add": "Add a branch to the tree of branch dependencies",
-    "advance": "Fast-forward merge one of children to the current branch, push it and then slide out the child",
-    "anno": "Manage custom annotations",
-    "clean": "Delete untracked and unmanaged branches and also optionally check out user's open GitHub PRs",
-    "config": "Display docs for the git machete configuration keys and environment variables",
-    "delete-unmanaged": "Delete local branches that are not present in the definition file",
-    "diff": "Diff current working directory or a given branch against its computed fork point",
-    "discover": "Automatically discover tree of branch dependencies",
-    "edit": "Edit the definition file",
-    "file": "Display the location of the definition file",
-    "fork-point": "Display or override fork point for a branch",
-    "format": "Display docs for the format of the definition file",
-    "github": "Create, check out and manage GitHub PRs while keeping them reflected in git machete",
-    "go": "Check out the branch relative to the position of the current branch, accepts down/first/last/next/root/prev/up argument",
-    "help": "Display this overview, or detailed help for a specified command",
-    "hooks": "Display docs for the extra hooks added by git machete",
-    "is-managed": "Check if the current branch is managed by git machete (mostly for scripts)",
-    "list": "List all branches that fall into one of pre-defined categories (mostly for internal use)",
-    "log": "Log the part of history specific to the given branch",
-    "reapply": "Rebase the current branch onto its computed fork point",
-    "show": "Show name(s) of the branch(es) relative to the position of a branch, accepts down/first/last/next/root/prev/up argument",
-    "slide-out": "Slide out the current branch and sync its downstream (child) branches with its upstream (parent) branch via rebase or merge",
-    "squash": "Squash the unique history of the current branch into a single commit",
-    "status": "Display formatted tree of branch dependencies, including info on their sync with upstream branch and with remote",
-    "traverse": "Walk through the tree of branch dependencies and rebase, merge, slide out, push and/or pull each branch one by one. By default starts from current branch",
-    "update": "Sync the current branch with its upstream (parent) branch via rebase or merge",
-    "version": "Display the version and exit"
-}
-
-github_api_access = '''To allow GitHub API access for private repositories (and also to perform side-effecting actions like opening a PR,
-even in case of public repositories), a GitHub API token with `repo` scope is required, see https://github.com/settings/tokens.
-This will be resolved from the first of:
-    1. `GITHUB_TOKEN` env var,
-    2. content of the `.github-token` file in the home directory (`~`),
-    3. current auth token from the `gh` GitHub CLI,
-    4. current auth token from the `hub` GitHub CLI.'''
-
-github_config_keys = '''GitHub API server URL will be inferred from `git remote`.
-You can override this by setting the following local git config keys:
-    Remote name
-        E.g. `machete.github.remote` = `origin`
-    Organization name
-        E.g. `machete.github.organization` = `VirtusLab`
-    Repository name
-        E.g. `machete.github.repository` = `git-machete`
-
-To do this, run `git config --local --edit` and add the following section:
-    [machete "github"]
-        organization = <organization_name>
-        repository = <repo_name>
-        remote = <remote_name>'''
-
-status_extraSpaceBeforeBranchName_config_key = '''The default value of this key is `false` but in order to make it easier to select branch
-name from the `git machete status` output on certain terminals (e.g. Alacritty), you can add an extra
-space between └─ and branch name by setting `git config machete.status.extraSpaceBeforeBranchName true`.
-
-For example, by default the status is displayed as:
-    develop
-    │
-    ├─feature_branch1
-    │
-    └─feature_branch2
-
-With `machete.status.extraSpaceBeforeBranchName` config set to `true`:
-    develop
-    │
-    ├─ feature_branch1
-    │
-    └─ feature_branch2'''
-
-long_docs: Dict[str, str] = {
-    "add": """
-        <b>Usage: git machete add [-o|--onto=<target-upstream-branch>] [-R|--as-root] [-y|--yes] [<branch>]</b>
-
-        Adds the provided <branch> (or the current branch, if none specified) to the definition file.
-        If <branch> is provided but no local branch with the given name exists:
-        * if a remote branch of the same name exists in exactly one remote, then user is asked whether to check out this branch locally (as in `git checkout`),
-        * otherwise, user is asked whether it should be created as a new local branch.
-
-        If the definition file is empty or `-R`/`--as-root` is provided, the branch will be added as a root of the tree of branch dependencies.
-        Otherwise, the desired upstream (parent) branch can be specified with `-o`/`--onto`.
-        Neither of these options is mandatory, however; if both are skipped, git machete will try to automatically infer the target upstream.
-        If the upstream branch can be inferred, the user will be presented with inferred branch and asked to confirm.
-
-        Note: all the effects of `add` (except git branch creation) can as well be achieved by manually editing the definition file.
-
-        <b>Options:</b>
-          <b>-o, --onto=<target-upstream-branch></b>    Specifies the target parent branch to add the given branch onto.
-                                                 Cannot be specified together with `-R`/`--as-root`.
-
-          <b>-R, --as-root</b>                          Add the given branch as a new root (and not onto any other branch).
-                                                 Cannot be specified together with `-o`/`--onto`.
-
-          <b>-y, --yes</b>                              Don't ask for confirmation whether to create the branch or whether to add onto the inferred upstream.
-    """,
-    "advance": """
-        <b>Usage: git machete advance [-y|--yes]</b>
-
-        Fast forwards (as in `git merge --ff-only`) the current branch `C` to match its downstream `D`, pushes `C`
-        and subsequently slides out `D`. All three steps require manual confirmation unless `-y`/`--yes` is provided.
-
-        The downstream `D` is selected according to the following criteria:
-        * if `C` has exactly one downstream branch `d` whose tip is a descendant of `C`, and whose fork point is equal to `C` or is overridden
-          (basically: there's a <b><green>green edge</green></b> between `C` and `d`), then `d` is selected as `D`,
-        * if `C` has no downstream branches connected with a <b><green>green edge</green></b> to `C`, then `advance` fails,
-        * if `C` has more than one downstream branch connected with a <b><green>green edge</green></b> to `C`,
-          then user is asked to pick the branch to fast-forward merge into (similarly to what happens in `git machete go down`).
-          If `--yes` is specified, then `advance` fails.
-
-        As an example, if `git machete status --color=never --list-commits` is as follows:
-        <dim>
-          master
-          |
-          m-develop *
-            |
-            | Enable adding remote branch in the manner similar to git checkout
-            o-feature/add-from-remote
-            | |
-            | | Add support and sample for machete-post-slide-out hook
-            | o-feature/post-slide-out-hook
-            |
-            | Remove support for Python 2
-            | Remove support for Python 2 - 1st round of fixes
-            ?-chore/v3
-            |
-            | Apply Python2-compatible static typing
-            x-feature/types
-        </dim>
-        then running `git machete advance` will fast-forward the current branch `develop` to match `feature/add-from-remote`, and subsequently slide out the latter.
-        After `advance` completes, `status` will show:
-        <dim>
-          master
-          |
-          | Enable adding remote branch in the manner similar to git checkout
-          o-develop *
-            |
-            | Add support and sample for machete-post-slide-out hook
-            o-feature/post-slide-out-hook
-            |
-            | Remove support for Python 2
-            | Remove support for Python 2 - 1st round of fixes
-            ?-chore/v3
-            |
-            | Apply Python2-compatible static typing
-            x-feature/types
-        </dim>
-        Note that the current branch after the operation is still `develop`, just pointing to `feature/add-from-remote`'s tip now.
-
-        <b>Options:</b>
-          <b>-y, --yes</b>         Don't ask for confirmation whether to fast-forward the current branch or whether to slide-out the downstream.
-                            Fails if the current branch has more than one green-edge downstream branch.
-    """,
-    "anno": f"""
-        <b>Usage:
-          git machete anno [-b|--branch=<branch>] [<annotation text>]
-          git machete anno -H|--sync-github-prs</b>
-
-        If invoked without any argument, prints out the custom annotation for the given branch (or current branch, if none specified with `-b/--branch`).
-
-        If invoked with a single empty string argument, like:
-        <dim>$ git machete anno ''</dim>
-        then clears the annotation for the current branch (or a branch specified with `-b/--branch`).
-
-        If invoked with `-H` or `--sync-github-prs`, annotates the branches based on their corresponding GitHub PR numbers and authors.
-        Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched.
-
-{textwrap.indent(github_api_access, "          ")}
-
-{textwrap.indent(github_config_keys, "          ")}
-
-        In any other case, sets the annotation for the given/current branch to the given argument.
-        If multiple arguments are passed to the command, they are concatenated with a single space.
-
-        Note: all the effects of `anno` can be always achieved by manually editing the definition file.
-
-        <b>Options:</b>
-          <b>-b, --branch=<branch></b>      Branch to set the annotation for.
-          <b>-H, --sync-github-prs</b>      Annotate with GitHub PR numbers and authors where applicable.
-    """,
-    "clean": f"""
-        <b>Usage: git machete clean [-c|--checkout-my-github-prs] [-y|--yes]</b>
-
-        Synchronizes with the remote repository:
-            1. if invoked with `-H` or `--checkout-my-github-prs`, checks out open PRs for the current user associated with the GitHub token and also traverses the chain of pull requests upwards, adding branches one by one to git-machete and checks them out locally as well,
-            2. deletes unmanaged branches,
-            3. deletes untracked managed branches that have no downstream branch.
-
-        No branch will be deleted unless explicitly confirmed by the user (or unless `-y/--yes` option is passed).
-        Equivalent of `git machete github sync` if invoked with `-H` or `--checkout-my-github-prs`.
-
-{textwrap.indent(github_api_access, "          ")}
-
-{textwrap.indent(github_config_keys, "          ")}
-
-        **Options:**
-          <b>--c, --checkout-my-github-prs</b>     Checkout your open PRs into local branches.
-          <b>-y, --yes</b>                         Don't ask for confirmation when deleting branches from git.
-    """,
-    "config": f"""
-        <b>Config keys: </b>
-
-        - `machete.github.{{remote,organization,repository}}`:
-
-          When executing `git machete github <subcommand>` command, {textwrap.indent(github_config_keys, "          ").strip()}
-
-        - `machete.overrideForkPoint.<branch>.{{to,whileDescendantOf}}`
-
-          Executing `git machete fork-point --override-to=<revision> [<branch>]` sets up a fork point override for <branch>.
-          The override data is stored under `machete.overrideForkPoint.<branch>.to` and `machete.overrideForkPoint.<branch>.whileDescendantOf` git config keys.
-
-        - `machete.status.extraSpaceBeforeBranchName`
-
-          {textwrap.indent(status_extraSpaceBeforeBranchName_config_key, "          ").strip()}
-
-        - `machete.worktree.useTopLevelMacheteFile`
-
-          The default value of this key is `true`, which means that the path to machete definition file will be `.git/machete`
-          for both regular directory and worktree. If you want the worktree to have its own machete definition file (located under
-          `.git/worktrees/.../machete`), set `git config machete.worktree.useTopLevelMacheteFile false`.
-
-
-        <b>Environment variables: </b>
-
-        - `GIT_MACHETE_EDITOR`
-
-          Name of the editor used by `git machete e[dit]`, example: `vim` or `nano`.
-
-        - `GIT_MACHETE_REBASE_OPTS`
-
-          Used to pass extra options to the underlying `git rebase` invocation (called by the executed command, such as: `reapply`, `slide-out`, `traverse`, `update`)
-          Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete update`.
-
-        - `GITHUB_TOKEN`
-
-          Used to store GitHub API token. Used by commands such as: `anno`, `clean`, `github`.
-    """,
-    "delete-unmanaged": """
-        <b>Usage: git machete delete-unmanaged [-y|--yes]</b>
-
-        Goes one-by-one through all the local git branches that don't exist in the definition file,
-        and ask to delete each of them (with `git branch -d` or `git branch -D`) if confirmed by user.
-        No branch will be deleted unless explicitly confirmed by the user (or unless `-y/--yes` option is passed).
-
-        Note: this should be used with care since deleting local branches can sometimes make it impossible for `git machete` to properly figure out fork points.
-        See `git machete help fork-point` for more details.
-
-        <b>Options:</b>
-          <b>-y, --yes</b>          Don't ask for confirmation.
-    """,
-    "diff": """
-        <b>Usage: git machete d[iff] [-s|--stat] [<branch>]</b>
-
-        Runs `git diff` of the given branch tip against its fork point or, if none specified, of the current working tree against the fork point of the currently checked out branch.
-        See `git machete help fork-point` for more details on meaning of the "fork point".
-
-        Note: the branch in question does not need to occur in the definition file.
-
-        Options:
-          <b>-s, --stat</b>    Makes `git machete diff` pass `--stat` option to `git diff`, so that only summary (diffstat) is printed.
-    """,
-    "discover": f"""
-        <b>Usage: git machete discover [-C|--checked-out-since=<date>] [-l|--list-commits] [-r|--roots=<branch1>,<branch2>,...] [-y|--yes]</b>
-
-        Discovers and displays tree of branch dependencies using a heuristic based on reflogs and asks whether to overwrite the existing definition file with the new discovered tree.
-        If confirmed with a `y[es]` or `e[dit]` reply, backs up the current definition file (if it exists) as `$GIT_DIR/machete~` and saves the new tree under the usual `$GIT_DIR/machete` path.
-        If the reply was `e[dit]`, additionally an editor is opened (as in `git machete edit`) after saving the new definition file.
-
-        Options:
-          <b>-C, --checked-out-since=<date></b>   Only consider branches checked out at least once since the given date. <date> can be e.g. `2 weeks ago` or `2020-06-01`, as in `git log --since=<date>`.
-                                           If not present, the date is selected automatically so that around {str(DISCOVER_DEFAULT_FRESH_BRANCH_COUNT)} branches are included.
-
-          <b>-l, --list-commits</b>               When printing the discovered tree, additionally lists the messages of commits introduced on each branch (as for `git machete status`).
-
-          <b>-r, --roots=<branch1,...></b>        Comma-separated list of branches that should be considered roots of trees of branch dependencies.
-                                           If not present, `master` is assumed to be a root.
-                                           Note that in the process of discovery, certain other branches can also be additionally deemed to be roots as well.
-
-          <b>-y, --yes</b>                        Don't ask for confirmation before saving the newly-discovered tree.
-                                           Mostly useful in scripts; not recommended for manual use.
-    """,
-    "edit": """
-        <b>Usage: git machete e[dit]</b>
-
-        Opens an editor and lets you edit the definition file manually.
-
-        The editor is determined by checking up the following locations:
-        * `$GIT_MACHETE_EDITOR`
-        * `$GIT_EDITOR`
-        * `$(git config core.editor)`
-        * `$VISUAL`
-        * `$EDITOR`
-        * `editor`
-        * `nano`
-        * `vi`
-        and selecting the first one that is defined and points to an executable file accessible on `PATH`.
-
-        Note that the above editor selection only applies for editing the definition file,
-        but not for any other actions that may be indirectly triggered by git-machete, including editing of rebase TODO list, commit messages etc.
-
-        The definition file can be always accessed and edited directly under the path returned by `git machete file`
-        (usually `.git/machete`, unless worktrees or submodules are involved).
-    """,
-    "file": """
-        <b>Usage: git machete file</b>
-
-        Outputs the absolute path of machete definition file.
-        The file is always called `machete` and is located in the git directory of the project.
-
-        Three cases are possible:
-        * if `git machete` is executed from a regular working directory (not a worktree or submodule), the file is located under `.git/machete`,
-        * if `git machete` is executed from a <b>worktree</b>, the file path depends on the `machete.worktree.useTopLevelMacheteFile` config key value:
-          * if `machete.worktree.useTopLevelMacheteFile` is true (default), the file is located under `.git/machete`
-          * if `machete.worktree.useTopLevelMacheteFile` is false, the file is located under `.git/worktrees/.../machete`,
-        * if `git machete` is executed from a <b>submodule</b>, this file is located in the git folder of the submodule itself under `.git/modules/.../machete`.
-    """,
-    "fork-point": """
-        <b>Usage:
-          git machete fork-point [--inferred] [<branch>]
-          git machete fork-point --override-to=<revision>|--override-to-inferred|--override-to-parent [<branch>]
-          git machete fork-point --unset-override [<branch>]</b>
-
-        Note: in all three forms, if no <branch> is specified, the currently checked out branch is assumed.
-        The branch in question does not need to occur in the definition file.
-
-
-        Without any option, displays full hash of the fork point commit for the <branch>.
-        Fork point of the given <branch> is the commit at which the history of the <branch> diverges from history of any other branch.
-
-        Fork point is assumed by many `git machete` commands as the place where the unique history of the <branch> starts.
-        The range of commits between the fork point and the tip of the given branch is, for instance:
-        * listed for each branch by `git machete status --list-commits`
-        * passed to `git rebase` by `git machete reapply`/`slide-out`/`traverse`/`update`
-        * provided to `git diff`/`log` by `git machete diff`/`log`.
-
-        `git machete` assumes fork point of <branch> is the most recent commit in the log of <branch> that has NOT been introduced on that very branch,
-        but instead occurs on a reflog (see help for `git reflog`) of some other, usually chronologically earlier, branch.
-        This yields a correct result in typical cases, but there are some situations
-        (esp. when some local branches have been deleted) where the fork point might not be determined correctly.
-        Thus, all rebase-involving operations (`reapply`, `slide-out`, `traverse` and `update`) run `git rebase` in the interactive mode by default,
-        unless told explicitly not to do so by `--no-interactive-rebase` flag, so that the suggested commit range can be inspected before the rebase commences.
-        Also, `reapply`, `slide-out`, `squash`, and `update` allow to specify the fork point explicitly by a command-line option.
-
-        `git machete fork-point` is different (and more powerful) than `git merge-base --fork-point`,
-        since the latter takes into account only the reflog of the one provided upstream branch,
-        while the former scans reflogs of all local branches and their remote tracking branches.
-        This makes git-machete's `fork-point` more resilient to modifications of .git/machete file where certain branches are re-attached under new parents (upstreams).
-
-
-        With `--override-to=<revision>`, sets up a fork point override for <branch>.
-        Fork point for <branch> will be overridden to the provided <revision> (commit) as long as the <branch> still points to (or is descendant of) the commit X
-        that <branch> pointed to at the moment the override is set up.
-        Even if revision is a symbolic name (e.g. other branch name or `HEAD~3`) and not explicit commit hash (like `a1b2c3ff`),
-        it's still resolved to a specific commit hash at the moment the override is set up (and not later when the override is actually used).
-        The override data is stored under `machete.overrideForkPoint.<branch>.to` and `machete.overrideForkPoint.<branch>.whileDescendantOf` git config keys.
-        Note: the provided fork point <revision> must be an ancestor of the current <branch> commit X.
-
-        With `--override-to-parent`, overrides fork point of the <branch> to the commit currently pointed by <branch>'s parent in the branch dependency tree.
-        Note: this will only work if <branch> has a parent at all (i.e. is not a root) and parent of <branch> is an ancestor of current <branch> commit X.
-
-        With `--inferred`, displays the commit that `git machete fork-point` infers to be the fork point of <branch>.
-        If there is NO fork point override for <branch>, this is identical to the output of `git machete fork-point`.
-        If there is a fork point override for <branch>, this is identical to the what the output of `git machete fork-point` would be if the override was NOT present.
-
-        With `--override-to-inferred` option, overrides fork point of the <branch> to the commit that `git machete fork-point` infers to be the fork point of <branch>.
-        Note: this piece of information is also displayed by `git machete status --list-commits` in case a <b><yellow>yellow edge</yellow></b> occurs.
-
-        With `--unset-override`, the fork point override for <branch> is unset.
-        This is simply done by removing the corresponding `machete.overrideForkPoint.<branch>.*` config entries.
-
-
-        <b>Note:</b> if an overridden fork point applies to a branch `B`, then it's considered to be connected with a <b><green>green edge</green></b> to its upstream (parent) `U`,
-        even if the overridden fork point of `B` is NOT equal to the commit pointed by `U`.
-    """,
-    "format": """
-        Note: there is no 'git machete format' command as such; 'format' is just a topic of 'git machete help'.
-
-        The format of the definition file should be as follows:
-        <dim>
-          develop
-              adjust-reads-prec PR #234
-                  block-cancel-order PR #235
-                      change-table
-                          drop-location-type
-              edit-margin-not-allowed
-                  full-load-gatling
-              grep-errors-script
-          master
-              hotfix/receipt-trigger PR #236
-        </dim>
-        In the above example `develop` and `master` are roots of the tree of branch dependencies.
-        Branches `adjust-reads-prec`, `edit-margin-not-allowed` and `grep-errors-script` are direct downstream branches for `develop`.
-        `block-cancel-order` is a downstream branch of `adjust-reads-prec`, `change-table` is a downstream branch of `block-cancel-order` and so on.
-
-        Every branch name can be followed (after a single space as a delimiter) by a custom annotation - a PR number in the above example.
-        The annotations don't influence the way `git machete` operates other than that they are displayed in the output of the `status` command.
-        Also see help for the `anno` command.
-
-        Tabs or any number of spaces can be used as indentation.
-        It's only important to be consistent wrt. the sequence of characters used for indentation between all lines.
-    """,
-    "github": f"""
-        <b>Usage: git machete github <subcommand></b>
-        where <subcommand> is one of: `anno-prs`, `checkout-prs`, `create-pr`, `retarget-pr`, `sync`.
-
-        Creates, checks out and manages GitHub PRs while keeping them reflected in branch definition file.
-
-{textwrap.indent(github_api_access, "          ")}
-
-{textwrap.indent(github_config_keys, "          ")}
-
-
-        <b>`anno-prs`:</b>
-
-          Annotates the branches based on their corresponding GitHub PR numbers and authors.
-          Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched.
-          Equivalent to `git machete anno --sync-github-prs`.
-
-        <b>`checkout-prs [--all | --by=<github-login> | --mine | <PR-number-1> ... <PR-number-N>]`:</b>
-
-          Check out the head branch of the given pull requests (specified by numbers or by a flag),
-          also traverse chain of pull requests upwards, adding branches one by one to git-machete and check them out locally.
-          Once the specified pull requests are checked out locally, annotate local branches with corresponding pull request numbers.
-          If only one PR has been checked out, then switch the local repository's HEAD to its head branch.
-
-          <b>Options:</b>
-            <b>--all</b>     Checkout all open PRs.
-            <b>--by</b>      Checkout open PRs authored by the given GitHub user.
-              <b>Parameters:</b>
-                <b><github-login></b> GitHub account name.
-            <b>--mine</b>    Checkout open PRs for the current user associated with the GitHub token.
-
-          <b>Parameters:</b>
-            <b><PR-number-1> ... <PR-number-N></b>    Pull request numbers to checkout.
-
-        <b>`create-pr [--draft]`:</b>
-
-          Creates a PR for the current branch, using the upstream (parent) branch as the PR base.
-          Once the PR is successfully created, annotates the current branch with the new PR's number.
-
-          If `.git/info/description` file is present, its contents is used as PR description.
-          If `.git/info/milestone` file is present, its contents (a single number - milestone id) is used as milestone.
-          If `.git/info/reviewers` file is present, its contents (one GitHub login per line) are used to set reviewers.
-
-          <b>Options:</b>
-            <b>--draft</b>    Creates the new PR as a draft.
-
-        <b>`retarget-pr`:</b>
-
-          Sets the base of the current branch's PR to upstream (parent) branch, as seen by git machete (see `git machete show up`).
-
-        <b>`sync`:</b>
-
-            Synchronizes with the remote repository:
-                1. checks out open PRs for the current user associated with the GitHub token and also traverses the chain of pull requests upwards, adding branches one by one to git-machete and checks them out locally as well,
-                2. deletes unmanaged branches,
-                3. deletes untracked managed branches that have no downstream branch.
-          Equivalent of `git machete clean --checkout-my-github-prs`.
-    """,
-    "go": """
-        <b>Usage: git machete g[o] <direction></b>
-        where <direction> is one of: `d[own]`, `f[irst]`, `l[ast]`, `n[ext]`, `p[rev]`, `r[oot]`, `u[p]`
-
-        Checks out the branch specified by the given direction relative to the current branch:
-        * `down`:    the direct children/downstream branch of the current branch.
-        * `first`:   the first downstream of the root branch of the current branch (like `root` followed by `next`), or the root branch itself if the root has no downstream branches.
-        * `last`:    the last branch in the definition file that has the same root as the current branch; can be the root branch itself if the root has no downstream branches.
-        * `next`:    the direct successor of the current branch in the definition file.
-        * `prev`:    the direct predecessor of the current branch in the definition file.
-        * `root`:    the root of the tree where the current branch is located. Note: this will typically be something like `develop` or `master`, since all branches are usually meant to be ultimately merged to one of those.
-        * `up`:      the direct parent/upstream branch of the current branch.
-
-        Roughly equivalent to `git checkout $(git machete show <direction>)`.
-    """,
-    "help": """
-        <b>Usage: git machete help [<command>]</b>
-
-        Prints a summary of this tool, or a detailed info on a command if provided.
-    """,
-    "hooks": """
-        As with the standard git hooks, git-machete looks for its own specific hooks in `$GIT_DIR/hooks/*` (or `$(git config core.hooksPath)/*`, if set).
-        All hooks are executed from the top-level folder of the repository (or top-level folder of worktree/submodule, if applicable).
-
-        Note: `hooks` is not a command as such, just a help topic (there is no `git machete hooks` command).
-
-        * <b>machete-post-slide-out <new-upstream> <lowest-slid-out-branch> [<new-downstreams>...]</b>
-            The hook that is executed after a branch (or possibly multiple branches, in case of `slide-out`)
-            is slid out by `advance`, `slide-out` or `traverse`.
-
-            At least two parameters (branch names) are passed to the hook:
-            * <b><new-upstream></b> is the upstream of the branch that has been slid out,
-              or in case of multiple branches being slid out - the upstream of the highest slid out branch;
-            * <b><lowest-slid-out-branch></b> is the branch that has been slid out,
-              or in case of multiple branches being slid out - the lowest slid out branch;
-            * <b><new-downstreams></b> are all the following (possibly zero) parameters,
-              which correspond to all original downstreams of <lowest-slid-out-branch>, now reattached as the downstreams of <new-upstream>.
-              Note that this may be zero, one, or multiple branches.
-
-            Note: the hook, if present, is executed:
-            * zero or once during a `advance` execution (depending on whether the slide-out has been confirmed or not),
-            * exactly once during a `slide-out` execution (even if multiple branches are slid out),
-            * zero or more times during `traverse` (every time a slide-out operation is confirmed).
-
-            If the hook returns a non-zero exit code, then an error is raised and the execution of the command is aborted,
-            i.e. `slide-out` won't attempt rebase of the new downstream branches and `traverse` won't continue the traversal.
-            In case of `advance` there is no difference (other than exit code of the entire `advance` command being non-zero),
-            since slide-out is the last operation that happens within `advance`.
-            Note that non-zero exit code of the hook doesn't cancel the effects of slide-out itself, only the subsequent operations.
-            The hook is executed only once the slide-out is complete and can in fact rely on .git/machete file being updated to the new branch layout.
-
-        * <b>machete-pre-rebase <new-base> <fork-point-hash> <branch-being-rebased></b>
-            The hook that is executed before rebase is run during `reapply`, `slide-out`, `traverse` and `update`.
-            Note that it is NOT executed by `squash` (despite its similarity to `reapply`), since no rebase is involved in `squash`.
-
-            The parameters are exactly the three revisions that are passed to `git rebase --onto`:
-            1. what is going to be the new base for the rebased commits,
-            2. what is the fork point - the place where the rebased history diverges from the upstream history,
-            3. what branch is rebased.
-            If the hook returns a non-zero exit code, an error is raised and the entire rebase is aborted.
-
-            Note: this hook is independent from git's standard `pre-rebase` hook.
-            If machete-pre-rebase returns zero, the execution flow continues to `git rebase`, which may also run `pre-rebase` hook if present.
-            `machete-pre-rebase` is thus always launched before `pre-rebase`.
-
-        * <b>machete-status-branch <branch-name></b>
-            The hook that is executed for each branch displayed during `discover`, `status` and `traverse`.
-
-            The standard output of this hook is displayed at the end of the line, after branch name, (optionally) custom annotation and (optionally) remote sync-ness status.
-            Standard error is ignored. If the hook returns a non-zero exit code, both stdout and stderr are ignored, and printing the status continues as usual.
-
-            Note: the hook is always invoked with `ASCII_ONLY` variable passed into the environment.
-            If `status` runs in ASCII-only mode (i.e. if `--color=auto` and stdout is not a terminal, or if `--color=never`), then `ASCII_ONLY=true`, otherwise `ASCII_ONLY=false`.
-
-        Please see hook_samples/ directory of git-machete project for examples.
-        An example of using the standard git `post-commit` hook to `git machete add` branches automatically is also included.
-    """,
-    "is-managed": """
-        <b>Usage: git machete is-managed [<branch>]</b>
-
-        Returns with zero exit code if the given branch (or current branch, if none specified) is managed by git-machete (i.e. listed in .git/machete).
-
-        Returns with a non-zero exit code in case:
-        * the <branch> is provided but isn't managed (or doesn't exist), or
-        * the <branch> isn't provided and the current branch isn't managed, or
-        * the <branch> isn't provided and there's no current branch (detached HEAD).
-    """,
-    "list": """
-        <b>Usage: git machete list <category></b>
-        where <category> is one of: `addable`, `managed`, `slidable`, `slidable-after <branch>`, `unmanaged`, `with-overridden-fork-point`.
-
-        Lists all branches that fall into one of the specified categories:
-        * `addable`: all branches (local or remote) than can be added to the definition file,
-        * `childless`: all branches that do not possess child branches,
-        * `managed`: all branches that appear in the definition file,
-        * `slidable`: all managed branches that have an upstream and can be slid out with `slide-out` command
-        * `slidable-after <branch>`: the downstream branch of the <branch>, if it exists and is the only downstream of <branch> (i.e. the one that can be slid out immediately following <branch>),
-        * `unmanaged`: all local branches that don't appear in the definition file,
-        * `with-overridden-fork-point`: all local branches that have a fork point override set up (even if this override does not affect the location of their fork point anymore).
-
-        This command is generally not meant for a day-to-day use, it's mostly needed for the sake of branch name completion in shell.
-    """,
-    "log": """
-        <b>Usage: git machete l[og] [<branch>]</b>
-
-        Runs `git log` for the range of commits from tip of the given branch (or current branch, if none specified) back to its fork point.
-        See `git machete help fork-point` for more details on meaning of the "fork point".
-
-        Note: the branch in question does not need to occur in the definition file.
-    """,
-    "reapply": """
-        <b>Usage: git machete reapply [-f|--fork-point=<fork-point-commit>]</b>
-
-        Interactively rebase the current branch on the top of its computed fork point.
-        The chunk of the history to be rebased starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by `--fork-point`.
-        See `git machete help fork-point` for more details on meaning of the "fork point".
-
-        Note: the current reapplied branch does not need to occur in the definition file.
-
-        Tip: `reapply` can be used for squashing the commits on the current branch to make history more condensed before push to the remote,
-        but there is also dedicated `squash` command that achieves the same goal without running `git rebase`.
-
-        <b>Options:</b>
-          <b>-f, --fork-point=<fork-point-commit></b>    Specifies the alternative fork point commit after which the rebased part of history is meant to start.
-
-        <b>Environment variables:</b>
-          <b>GIT_MACHETE_REBASE_OPTS</b>                 Extra options to pass to the underlying `git rebase` invocation, space-separated.
-                                                  Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete reapply`.
-    """,
-    "show": """
-        <b>Usage: git machete show <direction> [<branch>]</b>
-        where <direction> is one of: `c[urrent]`, `d[own]`, `f[irst]`, `l[ast]`, `n[ext]`, `p[rev]`, `r[oot]`, `u[p]`
-        displayed relative to given <branch>, or the current checked out branch if <branch> is unspecified.
-
-        Outputs name of the branch (or possibly multiple branches, in case of `down`) that is:
-
-        * `current`: the current branch; exits with a non-zero status if none (detached HEAD)
-        * `down`:    the direct children/downstream branch of the given branch.
-        * `first`:   the first downstream of the root branch of the given branch (like `root` followed by `next`), or the root branch itself if the root has no downstream branches.
-        * `last`:    the last branch in the definition file that has the same root as the given branch; can be the root branch itself if the root has no downstream branches.
-        * `next`:    the direct successor of the given branch in the definition file.
-        * `prev`:    the direct predecessor of the given branch in the definition file.
-        * `root`:    the root of the tree where the given branch is located. Note: this will typically be something like `develop` or `master`, since all branches are usually meant to be ultimately merged to one of those.
-        * `up`:      the direct parent/upstream branch of the given branch.
-    """,
-    "slide-out": """
-        <b>Usage: git machete slide-out [-d|--down-fork-point=<down-fork-point-commit>] [--delete] [-M|--merge] [-n|--no-edit-merge|--no-interactive-rebase] [<branch> [<branch> [<branch> ...]]]</b>
-
-        Removes the given branch (or multiple branches) from the branch tree definition. If no branch has been specified current branch is assumed as the only branch.
-        Then synchronizes the downstream (child) branches of the last specified branch on the top of the upstream (parent) branch of the first specified branch.
-        Sync is performed either by rebase (default) or by merge (if `--merge` option passed).
-
-        The most common use is to slide out a single branch whose upstream was a `develop`/`master` branch and that has been recently merged.
-
-        Since this tool is designed to perform only one single rebase/merge at the end, provided branches must form a chain, i.e. all of the following conditions must be met:
-        * for i=1..N-1, (i+1)-th branch must be the only downstream (child) branch of the i-th branch,
-        * all provided branches must have an upstream branch (so, in other words, roots of branch dependency tree cannot be slid out).
-
-        For example, let's assume the following dependency tree:
-        <dim>
-          develop
-              adjust-reads-prec
-                  block-cancel-order
-                      change-table
-                          drop-location-type
-                      add-notification
-        </dim>
-        And now let's assume that `adjust-reads-prec` and later `block-cancel-order` were merged to develop.
-        After running `git machete slide-out adjust-reads-prec block-cancel-order` the tree will be reduced to:
-        <dim>
-          develop
-              change-table
-                  drop-location-type
-              add-notification
-        </dim>
-        and `change-table` and `add-notification` will be rebased onto develop (fork point for this rebase is configurable, see `-d` option below).
-
-        Note: This command doesn't delete any branches from git, just removes them from the tree of branch dependencies.
-
-        <b>Options:</b>
-          <b>-d, --down-fork-point=<down-fork-point-commit></b>    If updating by rebase, specifies the alternative fork point for downstream branches for the operation.
-                                                            `git machete fork-point` overrides for downstream branches are recommended over use of this option.
-                                                            See also doc for `--fork-point` option in `git machete help reapply` and `git machete help update`.
-                                                            Not allowed if updating by merge.
-
-          <b>--delete</b>                                          Delete slid-out branches from git.
-
-          <b>-M, --merge</b>                                       Update the downstream branch by merge rather than by rebase.
-
-          <b>-n</b>                                                If updating by rebase, equivalent to `--no-interactive-rebase`. If updating by merge, equivalent to `--no-edit-merge`.
-
-          <b>--no-edit-merge</b>                                   If updating by merge, skip opening the editor for merge commit message while doing `git merge` (i.e. pass `--no-edit` flag to underlying `git merge`).
-                                                            Not allowed if updating by rebase.
-
-          <b>--no-interactive-rebase</b>                           If updating by rebase, run `git rebase` in non-interactive mode (without `-i/--interactive` flag).
-                                                            Not allowed if updating by merge.
-
-        <b>Environment variables:</b>
-          <b>GIT_MACHETE_REBASE_OPTS</b>                           Extra options to pass to the underlying `git rebase` invocations, space-separated.
-                                                            Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete slide-out`.
-    """,
-    "squash": """
-        <b>Usage: git machete squash [-f|--fork-point=<fork-point-commit>]</b>
-
-        Squashes the commits belonging uniquely to the current branch into a single commit.
-        The chunk of the history to be squashed starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by `--fork-point`.
-        See `git machete help fork-point` for more details on meaning of the "fork point".
-        The message for the squashed is taken from the earliest squashed commit, i.e. the commit directly following the fork point.
-
-        Note: the current squashed branch does not need to occur in the definition file.
-
-        Tip: `squash` does NOT run `git rebase` under the hood. For more complex scenarios that require rewriting the history of current branch, see `reapply` and `update`.
-
-        <b>Options:</b>
-          <b>-f, --fork-point=<fork-point-commit></b>    Specifies the alternative fork point commit after which the squashed part of history is meant to start.
-    """,
-    "status": f"""
-        <b>Usage: git machete s[tatus] [--color=WHEN] [-l|--list-commits] [-L|--list-commits-with-hashes] [--no-detect-squash-merges]</b>
-
-        Displays a tree-shaped status of the branches listed in the definition file.
-
-        Apart from simply ASCII-formatting the definition file, this also:
-
-        * colors the edges between upstream (parent) and downstream (children) branches:
-
-          - <b><red>red edge</red></b> means that the downstream branch tip is <b>not a direct descendant</b> of the upstream branch tip,
-
-          - <b><yellow>yellow edge</yellow></b> means that the downstream branch tip is a <b>direct descendant</b> of the upstream branch tip,
-            but the fork point (see help on `fork-point`) of the downstream branch is <b>not equal</b> to the upstream branch tip,
-
-          - <b><green>green edge</green></b> means that the downstream branch tip is a <b>direct descendant</b> of the upstream branch tip
-            and the fork point of the downstream branch is <b>equal</b> to the upstream branch tip,
-
-          - <b><dim>grey/dimmed edge</dim></b> means that the downstream branch has been <b>merged</b> to the upstream branch,
-            detected by commit equivalency (default), or by strict detection of merge commits (if `--no-detect-squash-merges` passed).
-
-
-        * prints `(untracked/ahead of <remote>/behind <remote>/diverged from [& older than] <remote>)` message if the branch is not in sync with its remote counterpart;
-
-        * displays the custom annotations (see help on `format` and `anno`) next to each branch, if present;
-
-        * displays the output of `machete-status-branch` hook (see help on `hooks`), if present;
-
-        * optionally lists commits introduced on each branch if `-l`/`--list-commits` or `-L`/`--list-commits-with-hashes` is supplied.
-
-        Name of the currently checked-out branch is underlined (or shown in blue on terminals that don't support underline).
-
-        In case of yellow edge, use `-l` flag to show the exact location of the inferred fork point
-        (which indicates e.g. what range of commits is going to be rebased when the branch is updated).
-        The inferred fork point can be always overridden manually, see help on `fork-point`.
-
-        Grey/dimmed edge suggests that the downstream branch can be slid out (see help on `slide-out` and `traverse`).
-
-        Using colors can be disabled with a `--color` flag set to `never`.
-        With `--color=always`, git machete always emits colors and with `--color=auto`, it emits colors only when standard output is connected to a terminal.
-        `--color=auto` is the default. When colors are disabled, relation between branches is represented in the following way (not including the hash-comments):
-        <dim>
-          <branch0>
-          |
-          o-<branch1> *   # green (in sync with parent; asterisk for the current branch)
-          | |
-          | x-<branch2>   # red (not in sync with parent)
-          |   |
-          |   ?-<branch3> # yellow (in sync with parent, but parent is not the fork point)
-          |
-          m-<branch4>     # grey (merged to parent)
-        </dim>
-        <b>Options:</b>
-          <b>--color=WHEN</b>                      Colorize the output; WHEN can be `always`, `auto` (default; i.e. only if stdout is a terminal), or `never`.
-
-          <b>-l, --list-commits</b>                Additionally list the commits introduced on each branch.
-
-          <b>-L, --list-commits-with-hashes</b>    Additionally list the short hashes and messages of commits introduced on each branch.
-
-          <b>--no-detect-squash-merges</b>         Only consider "strict" (fast-forward or 2-parent) merges, rather than rebase/squash merges,
-                                            when detecting if a branch is merged into its upstream (parent).
-
-        <b>Config keys:</b>
-{textwrap.indent(status_extraSpaceBeforeBranchName_config_key, "          ")}
-    """,
-    "traverse": """
-        <b>Usage: git machete t[raverse] [-F|--fetch] [-l|--list-commits] [-M|--merge]
-                                         [-n|--no-edit-merge|--no-interactive-rebase] [--no-detect-squash-merges]
-                                         [--[no-]push] [--[no-]push-untracked]
-                                         [--return-to=WHERE] [--start-from=WHERE] [-w|--whole] [-W] [-y|--yes]</b>
-
-        Traverses the branch tree in pre-order (i.e. simply in the order as they occur in the definition file).
-        By default `traverse` starts from the current branch.
-        This behaviour can, however, be customized using options: `--start-from=`, `--whole` or `-w`, `-W`.
-
-        For each branch, the command:
-        * detects if the branch is merged (<b><dim>grey</dim></b> edge) to its parent (aka upstream)
-          - by commit equivalency (default), or by strict detection of merge commits (if `--no-detect-squash-merges` passed),
-          - if so, asks the user whether to slide out the branch from the dependency tree (typically branches are no longer needed after they're merged);
-        * otherwise, if the branch has a <b><red>red</red></b> or <b><yellow>yellow</yellow></b> edge to its parent/upstream (see `status`):
-          - asks the user whether to rebase (default) or merge (if `--merge` passed) the branch onto into its upstream branch - equivalent to `git machete update` with no `--fork-point` option passed;
-
-        * if the branch is not tracked on a remote, is ahead of its remote counterpart, or diverged from the counterpart & has newer head commit than the counterpart:
-          - asks the user whether to push the branch (possibly with `--force-with-lease` if the branches diverged);
-        * otherwise, if the branch diverged from the remote counterpart & has older head commit than the counterpart:
-          - asks the user whether to `git reset --keep` the branch to its remote counterpart
-        * otherwise, if the branch is behind its remote counterpart:
-          - asks the user whether to pull the branch;
-
-        * and finally, if any of the above operations has been successfully completed:
-          - prints the updated `status`.
-
-        If the traverse flow is stopped (typically due to merge/rebase conflicts), just run `git machete traverse` after the merge/rebase is finished.
-        It will pick up the walk from the current branch (unless `--start-from=` or `-w` etc. is passed).
-        Unlike with e.g. `git rebase`, there is no special `--continue` flag, as `traverse` is stateless
-        (doesn't keep a state of its own like `git rebase` does in `.git/rebase-apply/`).
-
-        <b>Options:</b>
-          <b>-F, --fetch</b>                  Fetch the remotes of all managed branches at the beginning of traversal (no `git pull` involved, only `git fetch`).
-
-          <b>-l, --list-commits</b>           When printing the status, additionally list the messages of commits introduced on each branch.
-
-          <b>-M, --merge</b>                  Update by merge rather than by rebase.
-
-          <b>-n</b>                           If updating by rebase, equivalent to `--no-interactive-rebase`. If updating by merge, equivalent to `--no-edit-merge`.
-
-          <b>--no-detect-squash-merges</b>    Only consider "strict" (fast-forward or 2-parent) merges, rather than rebase/squash merges,
-                                       when detecting if a branch is merged into its upstream (parent).
-
-          <b>--no-edit-merge</b>              If updating by merge, skip opening the editor for merge commit message while doing `git merge` (i.e. pass `--no-edit` flag to underlying `git merge`).
-                                       Not allowed if updating by rebase.
-
-          <b>--no-interactive-rebase</b>      If updating by rebase, run `git rebase` in non-interactive mode (without `-i/--interactive` flag).
-                                       Not allowed if updating by merge.
-
-          <b>--no-push</b>                    Do not push any (neither tracked nor untracked) branches to remote, re-enable via `--push`.
-
-          <b>--no-push-untracked</b>          Do not push untracked branches to remote, re-enable via `--push-untracked`.
-
-          <b>--push</b>                       Push all (both tracked and untracked) branches to remote - default behavior.
-
-          <b>--push-untracked</b>             Push untracked branches to remote - default behavior.
-
-          <b>--return-to=WHERE</b>            Specifies the branch to return after traversal is successfully completed; WHERE can be `here` (the current branch at the moment when traversal starts),
-                                       `nearest-remaining` (nearest remaining branch in case the `here` branch has been slid out by the traversal)
-                                       or `stay` (the default - just stay wherever the traversal stops).
-                                       Note: when user quits by `q/yq` or when traversal is stopped because one of git actions fails, the behavior is always `stay`.
-
-          <b>--start-from=WHERE</b>           Specifies the branch to start the traversal from; WHERE can be `here` (the default - current branch, must be managed by git-machete),
-                                       `root` (root branch of the current branch, as in `git machete show root`) or `first-root` (first listed managed branch).
-
-          <b>-w, --whole</b>                  Equivalent to `-n --start-from=first-root --return-to=nearest-remaining`;
-                                       useful for quickly traversing & syncing all branches (rather than doing more fine-grained operations on the local section of the branch tree).
-
-          <b>-W</b>                           Equivalent to `--fetch --whole`; useful for even more automated traversal of all branches.
-
-          <b>-y, --yes</b>                    Don't ask for any interactive input, including confirmation of rebase/push/pull. Implies `-n`.
-
-        <b>Environment variables:</b>
-          <b>GIT_MACHETE_REBASE_OPTS</b>      Extra options to pass to the underlying `git rebase` invocations, space-separated.
-                                       Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete traverse`.
-    """,
-    "update": """
-        <b>Usage: git machete update [-f|--fork-point=<fork-point-commit>] [-M|--merge] [-n|--no-edit-merge|--no-interactive-rebase]</b>
-
-        Synchronizes the current branch with its upstream (parent) branch either by rebase (default) or by merge (if `--merge` option passed).
-
-        If updating by rebase, interactively rebases the current branch on the top of its upstream (parent) branch.
-        The chunk of the history to be rebased starts at the fork point of the current branch, which by default is inferred automatically, but can also be set explicitly by `--fork-point`.
-        See `git machete help fork-point` for more details on meaning of the "fork point".
-
-        If updating by merge, merges the upstream (parent) branch into the current branch.
-
-        <b>Options:</b>
-          <b>-f, --fork-point=<fork-point-commit></b>    If updating by rebase, specifies the alternative fork point commit after which the rebased part of history is meant to start.
-                                                  Not allowed if updating by merge.
-
-          <b>-M, --merge</b>                             Update by merge rather than by rebase.
-
-          <b>-n</b>                                      If updating by rebase, equivalent to `--no-interactive-rebase`. If updating by merge, equivalent to `--no-edit-merge`.
-
-          <b>--no-edit-merge</b>                         If updating by merge, skip opening the editor for merge commit message while doing `git merge` (i.e. pass `--no-edit` flag to underlying `git merge`).
-                                                  Not allowed if updating by rebase.
-
-          <b>--no-interactive-rebase</b>                 If updating by rebase, run `git rebase` in non-interactive mode (without `-i/--interactive` flag).
-                                                  Not allowed if updating by merge.
-
-        <b>Environment variables:</b>
-          <b>GIT_MACHETE_REBASE_OPTS</b>                 Extra options to pass to the underlying `git rebase` invocation, space-separated.
-                                                  Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete update`.
-    """,
-    "version": """
-        <b>Usage: git machete version</b>
-
-        Prints the version and exits.
-    """
-}
diff --git a/git_machete/generated_long_docs.py b/git_machete/generated_long_docs.py
new file mode 100644
index 0000000..629c647
--- /dev/null
+++ b/git_machete/generated_long_docs.py
@@ -0,0 +1,962 @@
+from typing import Dict
+
+# ---------------------------------------------------------------------------------------------------------
+# Warning: This file is NOT supposed to be edited directly, but instead regenerated via tox -e docs
+# ---------------------------------------------------------------------------------------------------------
+
+long_docs: Dict[str, str] = {
+    "add": """
+        <b>Usage:</b><b>
+           git machete add [-o|--onto=<target-upstream-branch>] [-R|--as-root] [-y|--yes] [<branch>]</b>
+
+        Adds the provided <branch> (or the current branch, if none specified) to the definition file.
+        If <branch> is provided but no local branch with the given name exists:
+           * if a remote branch of the same name exists in exactly one remote, then user is asked whether to check out this branch locally (as in `git checkout`),
+           * otherwise, user is asked whether it should be created as a new local branch.
+
+        If the definition file is empty or `-R/--as-root` is provided, the branch will be added as a root of the tree of branch dependencies.
+        Otherwise, the desired upstream (parent) branch can be specified with `-o/--onto`.
+        Neither of these options is mandatory, however; if both are skipped, git machete will try to automatically infer the target upstream.
+        If the upstream branch can be inferred, the user will be presented with inferred branch and asked to confirm.
+
+        Note: all the effects of `add` (except git branch creation) can as well be achieved by manually editing the definition file.
+
+        <b>Options:</b>
+           <b>-o</b>, <b>--onto=<target-upstream-branch></b>
+              Specifies the target parent branch to add the given branch onto. Cannot be specified together with `-R/--as-root`.
+           <b>-R</b>, <b>--as-root</b>
+              Add the given branch as a new root (and not onto any other branch). Cannot be specified together with `-o/--onto`.
+           <b>-y</b>, <b>--yes</b>
+              Don't ask for confirmation whether to create the branch or whether to add onto the inferred upstream.
+   """,
+    "advance": """
+        <b>Usage:</b><b>
+           git machete advance [-y|--yes]</b>
+
+        Fast forwards (as in `git merge --ff-only`) the current branch `C` to match its downstream `D`, pushes `C`
+        and subsequently slides out `D`. All three steps require manual confirmation unless `-y/--yes` is provided.
+
+        The downstream `D` is selected according to the following criteria:
+           * if `C` has exactly one downstream (child) branch `d` connected with a <green>green edge</green> (see help for `status`) to `C` or is overridden, then `d` is selected as `D`,
+           * if `C` has no downstream branches connected with a <green>green edge</green> to `C`, then `advance` fails,
+           * if `C` has more than one downstream branch connected with a <green>green edge</green> to `C`,
+         then user is asked to pick the branch to fast-forward merge into (similarly to what happens in `git machete go down`). If `--yes` is specified, then `advance` fails.
+
+        As an example, if `git machete status --color=never --list-commits` is as follows:
+        <dim>
+          master
+          |
+          m-develop *
+            |
+            | Enable adding remote branch in the manner similar to git checkout
+            o-feature/add-from-remote
+              |
+              | Add support and sample for machete-post-slide-out hook
+              o-feature/post-slide-out-hook
+        </dim>
+
+        then running `git machete advance` will fast-forward the current branch `develop` to match `feature/add-from-remote`, and subsequently slide out the latter.
+        After `advance` completes, `status` will show:
+        <dim>
+          master
+          |
+          | Enable adding remote branch in the manner similar to git checkout
+          o-develop *
+            |
+            | Add support and sample for machete-post-slide-out hook
+            o-feature/post-slide-out-hook
+        </dim>
+
+        Note that the current branch after the operation is still `develop`, just pointing to `feature/add-from-remote`'s tip now.
+
+        <b>Options:</b>
+           <b>-y</b>, <b>--yes</b>
+              Don't ask for confirmation whether to fast-forward the current branch or whether to slide-out the downstream. Fails if the current branch has more than one <green>green-edge</green> downstream branch.
+   """,
+    "anno": """
+        <b>Usage:</b><b>
+           git machete anno [-b|--branch=<branch>] [<annotation text>]
+           git machete anno -H|--sync-github-prs</b>
+
+        If invoked without any <annotation text>, prints out the custom annotation for the given branch (or current branch, if none specified with `-b/--branch`).
+
+        If invoked with a single empty string <annotation text>, like:<b>
+           $ git machete anno ''</b>
+
+        then clears the annotation for the current branch (or a branch specified with `-b/--branch`).
+
+        If invoked with `-H` or `--sync-github-prs`, annotates the branches based on their corresponding GitHub PR numbers and authors.
+        Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched.
+
+        To allow GitHub API access for private repositories (and also to perform side-effecting actions like opening a PR, even in case of public repositories),
+        a GitHub API token with `repo` scope is required, see https://github.com/settings/tokens. This will be resolved from the first of:
+           * `GITHUB_TOKEN` env var,
+           * content of the `.github-token` file in the home directory (`~`),
+           * current auth token from the `gh` GitHub CLI,
+           * current auth token from the `hub` GitHub CLI.
+
+        GitHub API server URL will be inferred from `git remote`.
+        You can override this by setting the following git config keys:
+           Remote name
+              E.g. `machete.github.remote` = `origin`
+
+           Organization name
+              E.g. `machete.github.organization` = `VirtusLab`
+
+           Repository name
+              E.g. `machete.github.repository` = `git-machete`
+
+        To do this, run `git config --local --edit` and add the following section:
+        <dim>
+          [machete "github"]
+              organization = <organization_name>
+              repository = <repo_name>
+              remote = <remote_name>
+        </dim>
+
+        In any other case, sets the annotation for the given/current branch to the given <annotation text>.
+        If multiple <annotation text>'s are passed to the command, they are concatenated with a single space.
+
+        Note: all the effects of `anno` can be always achieved by manually editing the definition file.
+
+        <b>Options:</b>
+           <b>-b</b>, <b>--branch=<branch></b>
+              Branch to set the annotation for.
+           <b>-H</b>, <b>--sync-github-prs</b>
+              Annotate with GitHub PR numbers and authors where applicable.
+
+        <b>Environment variables:</b>
+           `GITHUB_TOKEN`
+              GitHub API token.
+
+   """,
+    "clean": """
+        <b>Usage:</b><b>
+           git machete clean [-c|--checkout-my-github-prs] [-y|--yes]</b>
+
+        Synchronizes with the remote repository:
+           * if invoked with `-H` or `--checkout-my-github-prs`, checks out open PRs for the current user associated with the GitHub token and also traverses the chain of pull requests upwards, adding branches one by one to git-machete and checks them out locally as well,
+           * deletes unmanaged branches,
+           * deletes untracked managed branches that have no downstream branch.
+
+        No branch will be deleted unless explicitly confirmed by the user (or unless `-y/--yes` option is passed).
+        Equivalent of `git machete github sync` if invoked with `-H` or `--checkout-my-github-prs`.
+
+        To allow GitHub API access for private repositories (and also to perform side-effecting actions like opening a PR, even in case of public repositories),
+        a GitHub API token with `repo` scope is required, see https://github.com/settings/tokens. This will be resolved from the first of:
+           * `GITHUB_TOKEN` env var,
+           * content of the `.github-token` file in the home directory (`~`),
+           * current auth token from the `gh` GitHub CLI,
+           * current auth token from the `hub` GitHub CLI.
+
+        GitHub API server URL will be inferred from `git remote`.
+        You can override this by setting the following git config keys:
+           Remote name
+              E.g. `machete.github.remote` = `origin`
+
+           Organization name
+              E.g. `machete.github.organization` = `VirtusLab`
+
+           Repository name
+              E.g. `machete.github.repository` = `git-machete`
+
+        To do this, run `git config --local --edit` and add the following section:
+        <dim>
+          [machete "github"]
+              organization = <organization_name>
+              repository = <repo_name>
+              remote = <remote_name>
+        </dim>
+
+        <b>Options:</b>
+           <b>-c</b>, <b>--checkout-my-github-prs</b>
+              Checkout your open PRs into local branches.
+           <b>-y</b>, <b>--yes</b>
+              Don't ask for confirmation when deleting branches from git.
+
+        <b>Environment variables:</b>
+           `GITHUB_TOKEN`
+              GitHub API token.
+
+   """,
+    "config": """
+        Documentation about available `git machete` config keys and environment variables that change the command's default behavior.
+
+        Note: `config` is not a command as such, just a help topic (there is no `git machete config` command).
+
+        <b>Config keys:</b>
+           `machete.github.{remote,organization,repository}`:
+ 
+              When executing `git machete github <subcommand>` command, the following will happen:
+
+              GitHub API server URL will be inferred from `git remote`.
+              You can override this by setting the following git config keys:
+
+                 Remote name
+              E.g. `machete.github.remote` = `origin`
+
+                 Organization name
+              E.g. `machete.github.organization` = `VirtusLab`
+
+                 Repository name
+              E.g. `machete.github.repository` = `git-machete`
+
+              To do this, run `git config --local --edit` and add the following section:
+
+              [machete "github"]
+                  organization = <organization_name>
+                  repository = <repo_name>
+                  remote = <remote_name>
+
+           `machete.overrideForkPoint.<branch>.{to,whileDescendantOf}`:
+              Executing `git machete fork-point --override-to=<revision> [<branch>]` sets up a fork point override for <branch>.
+              The override data is stored under `machete.overrideForkPoint.<branch>.to` and `machete.overrideForkPoint.<branch>.whileDescendantOf` git config keys.
+
+           `machete.status.extraSpaceBeforeBranchName`:
+
+              To make it easier to select branch name from the `status` output on certain terminals
+              (e.g. Alacritty), you can add an extra
+              space between └─ and `branch name` by setting `git config machete.status.extraSpaceBeforeBranchName true`.
+
+              For example, by default the status is displayed as:
+
+              develop
+              │
+              ├─feature_branch1
+              │
+              └─feature_branch2
+
+              With `machete.status.extraSpaceBeforeBranchName` config set to `true`:
+
+              develop
+              │
+              ├─ feature_branch1
+              │
+              └─ feature_branch2
+
+           `machete.worktree.useTopLevelMacheteFile`:
+              The default value of this key is `true`, which means that the path to machete definition file will be `.git/machete`
+              for both regular directory and worktree. If you want the worktree to have its own machete definition file (located under
+              `.git/worktrees/.../machete`), set `git config machete.worktree.useTopLevelMacheteFile false`.
+
+        <b>Environment variables:</b>
+           `GIT_MACHETE_EDITOR`
+              Name of the editor used by `git machete e[dit]`, example: `vim` or `nano`.
+
+           `GIT_MACHETE_REBASE_OPTS`
+              Used to pass extra options to the underlying `git rebase` invocation (called by the executed command, such as: `reapply`, `slide-out`, `traverse`, `update`)
+              Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete update`.
+
+           `GITHUB_TOKEN`
+              Used to store GitHub API token. Used by commands such as: `anno`, `clean`, `github`.
+
+   """,
+    "delete-unmanaged": """
+        <b>Usage:</b><b>
+           git machete delete-unmanaged [-y|--yes]</b>
+
+        Goes one-by-one through all the local git branches that don't exist in the definition file,
+        and ask to delete each of them (with `git branch -d` or `git branch -D`) if confirmed by user.
+        No branch will be deleted unless explicitly confirmed by the user (or unless `-y/--yes` option is passed).
+
+        Note: this should be used with care since deleting local branches can sometimes make it impossible for `git machete` to properly figure out fork points.
+        See help for `fork-point` for more details.
+
+        <b>Options:</b>
+           <b>-y</b>, <b>--yes</b>
+              Don't ask for confirmation.
+   """,
+    "diff": """
+        <b>Usage:</b><b>
+           git machete d[iff] [-s|--stat] [<branch>]</b>
+
+        Runs `git diff` of the given branch tip against its fork point or, if none specified, of the current working tree against the fork point of the currently checked out branch.
+        See help for `fork-point` for more details on the meaning of fork point.
+
+        Note: the branch in question does not need to occur in the definition file.
+
+        <b>Options:</b>
+           <b>-s</b>, <b>--stat</b>
+              Makes `git machete diff` pass `--stat` option to `git diff`, so that only summary (diffstat) is printed.
+   """,
+    "discover": """
+        <b>Usage:</b><b>
+           git machete discover [-C|--checked-out-since=<date>] [-l|--list-commits] [-r|--roots=<branch1>,<branch2>,...] [-y|--yes]</b>
+
+        Discovers and displays tree of branch dependencies using a heuristic based on reflogs and asks whether to overwrite the existing definition `file` with the new discovered tree.
+        If confirmed with a `y[es]` or `e[dit]` reply, backs up the current definition file (if it exists) as `$GIT_DIR/machete~` and saves the new tree under the usual `$GIT_DIR/machete` path.
+        If the reply was `e[dit]`, additionally an editor is opened (as in: `git machete` `edit`) after saving the new definition file.
+
+        <b>Options:</b>
+           <b>-C</b>, <b>--checked-out-since=<date></b>
+              Only consider branches checked out at least once since the given date. <date> can be e.g. `2 weeks ago` or `2020-06-01`, as in `git log --since=<date>`. If not present, the date is selected automatically so that around 10 branches are included.
+           <b>-l</b>, <b>--list-commits</b>
+              When printing the discovered tree, additionally lists the messages of commits introduced on each branch (as for `git machete status`).
+           <b>-r</b>, <b>--roots=<branch1,...></b>
+              Comma-separated list of branches that should be considered roots of trees of branch dependencies. If not present, `master` is assumed to be a root. Note that in the process of discovery, certain other branches can also be additionally deemed to be roots as well.
+           <b>-y</b>, <b>--yes</b>
+              Don't ask for confirmation before saving the newly-discovered tree. Mostly useful in scripts; not recommended for manual use.
+   """,
+    "edit": """
+        <b>Usage:</b><b>
+           git machete e[dit]</b>
+
+        Opens an editor and lets you edit the definition file manually.
+
+        The editor is determined by checking up the following locations:
+           * `$GIT_MACHETE_EDITOR`
+           * `$GIT_EDITOR`
+           * `$(git config core.editor)`
+           * `$VISUAL`
+           * `$EDITOR`
+           * `editor`
+           * `nano`
+           * `vi`
+
+        and selecting the first one that is defined and points to an executable file accessible on `PATH`.
+
+        Note that the above editor selection only applies for editing the definition file,
+        but not for any other actions that may be indirectly triggered by git machete, including editing of rebase TODO list, commit messages etc.
+
+        The definition file can be always accessed and edited directly under the path returned by `git machete file`
+        (usually `.git/machete`, unless worktrees or submodules are involved).
+
+        <b>Environment variables:</b>
+           `GIT_MACHETE_EDITOR`
+              Name of the editor executable.
+
+   """,
+    "file": """
+        <b>Usage:</b><b>
+           git machete file</b>
+
+        Outputs the absolute path of machete definition file.
+        The file is always called `machete` and is located in the git directory of the project.
+
+        Three cases are possible:
+           * if `git machete` is executed from a regular working directory (not a worktree or submodule), the file is located under `.git/machete`,
+           * if `git machete` is executed from a <b>worktree</b>, the file path depends on the `machete.worktree.useTopLevelMacheteFile` config key value:
+              - if `machete.worktree.useTopLevelMacheteFile` is true (default), the file is located under `.git/machete`
+              - if `machete.worktree.useTopLevelMacheteFile` is false, the file is located under `.git/worktrees/.../machete`,
+
+           * if `git machete` is executed from a <b>submodule</b>, this file is located in the git folder of the submodule itself under `.git/modules/.../machete`.
+   """,
+    "fork-point": """
+        <b>Usage:</b><b>
+           git machete fork-point [--inferred] [<branch>]
+           git machete fork-point --override-to=<revision>|--override-to-inferred|--override-to-parent [<branch>]
+           git machete fork-point --unset-override [<branch>]</b>
+
+        Note: in all three forms, if no <branch> is specified, the currently checked out branch is assumed.
+        The branch in question does not need to occur in the definition file.
+
+        Without any option, displays full hash of the fork point commit for the <branch>.
+        Fork point of the given <branch> is the commit at which the history of the <branch> diverges from history of any other branch.
+
+        Fork point is assumed by many `git machete` commands as the place where the unique history of the <branch> starts.
+        The range of commits between the fork point and the tip of the given branch is, for instance:
+           * listed for each branch by `git machete status --list-commits`
+           * passed to `git rebase` by `git machete` `reapply`/`slide-out`/`traverse`/`update`
+           * provided to `git diff`/`log` by `git machete` `diff`/`log`.
+
+        `git machete` assumes fork point of <branch> is the most recent commit in the log of <branch> that has NOT been introduced on that very branch,
+        but instead occurs on a reflog (see help for `git reflog`) of some other, usually chronologically earlier, branch.
+        This yields a correct result in typical cases, but there are some situations
+        (esp. when some local branches have been deleted) where the fork point might not be determined correctly.
+        Thus, all rebase-involving operations (`reapply`, `slide-out`, `traverse` and `update`) run `git rebase` in the interactive mode by default,
+        unless told explicitly not to do so by `--no-interactive-rebase` flag, so that the suggested commit range can be inspected before the rebase commences.
+        Also, `reapply`, `slide-out`, `squash`, and `update` allow to specify the fork point explicitly by a command-line option.
+
+        `git machete fork-point` is different (and more powerful) than `git merge-base --fork-point`,
+        since the latter takes into account only the reflog of the one provided upstream branch,
+        while the former scans reflogs of all local branches and their remote tracking branches.
+        This makes git machete's `fork-point` more resilient to modifications of `.git/machete` `file` where certain branches are re-attached under new parents (upstreams).
+
+        With `--override-to=<revision>`, sets up a fork point override for <branch>.
+        Fork point for <branch> will be overridden to the provided <revision> (commit) as long as the <branch> still points to (or is descendant of) the commit X
+        that <branch> pointed to at the moment the override is set up.
+        Even if revision is a symbolic name (e.g. other branch name or `HEAD~3)` and not explicit commit hash (like `a1b2c3ff`),
+        it's still resolved to a specific commit hash at the moment the override is set up (and not later when the override is actually used).
+        The override data is stored under `machete.overrideForkPoint.<branch>.to` and `machete.overrideForkPoint.<branch>.whileDescendantOf` git config keys.
+        Note: the provided fork point <revision> must be an ancestor of the current <branch> commit X.
+
+        With `--override-to-parent`, overrides fork point of the <branch> to the commit currently pointed by <branch>'s parent in the branch dependency tree.
+        Note: this will only work if <branch> has a parent at all (i.e. is not a root) and parent of <branch> is an ancestor of current <branch> commit X.
+
+        With `--inferred`, displays the commit that `git machete fork-point` infers to be the fork point of <branch>.
+        If there is NO fork point override for <branch>, this is identical to the output of `git machete fork-point`.
+        If there is a fork point override for <branch>, this is identical to the what the output of `git machete fork-point` would be if the override was NOT present.
+
+        With `--override-to-inferred` option, overrides fork point of the <branch> to the commit that `git machete fork-point` infers to be the fork point of <branch>.
+        Note: this piece of information is also displayed by `git machete status --list-commits` in case a <yellow>yellow</yellow> edge occurs.
+
+        With `--unset-override`, the fork point override for <branch> is unset.
+        This is simply done by removing the corresponding `machete.overrideForkPoint.<branch>.*` config entries.
+
+        Note: if an overridden fork point applies to a branch `B`, then it's considered to be connected with a <green>green</green> edge to its upstream (parent) `U`,
+        even if the overridden fork point of `B` is NOT equal to the commit pointed by `U`.
+   """,
+    "format": """
+        Note: there is no `git machete format` command as such; `format` is just a topic of `git machete help`.
+
+        The format of the definition file should be as follows:
+        <dim>
+          develop
+              adjust-reads-prec PR #234
+                  block-cancel-order PR #235
+                      change-table
+                          drop-location-type
+              edit-margin-not-allowed
+                  full-load-gatling
+              grep-errors-script
+          master
+              hotfix/receipt-trigger PR #236
+        </dim>
+
+        In the above example `develop` and `master` are roots of the tree of branch dependencies.
+        Branches `adjust-reads-prec`, `edit-margin-not-allowed` and `grep-errors-script` are direct downstream branches for `develop`.
+        `block-cancel-order` is a downstream branch of `adjust-reads-prec`, `change-table` is a downstream branch of `block-cancel-order` and so on.
+
+        Every branch name can be followed (after a single space as a delimiter) by a custom annotation — a PR number in the above example.
+        The annotations don't influence the way `git machete` operates other than that they are displayed in the output of the `status` command.
+        Also see help for `anno` command.
+
+        Tabs or any number of spaces can be used as indentation.
+        It's only important to be consistent wrt. the sequence of characters used for indentation between all lines.
+   """,
+    "github": """
+        <b>Usage:</b><b>
+           git machete github <subcommand></b>
+
+        where `<subcommand>` is one of: `anno-prs`, `checkout-prs`, `create-pr`, `retarget-pr`.
+
+        Creates, checks out and manages GitHub PRs while keeping them reflected in branch definition file.
+
+        To allow GitHub API access for private repositories (and also to perform side-effecting actions like opening a PR, even in case of public repositories),
+        a GitHub API token with `repo` scope is required, see https://github.com/settings/tokens. This will be resolved from the first of:
+           * `GITHUB_TOKEN` env var,
+           * content of the `.github-token` file in the home directory (`~`),
+           * current auth token from the `gh` GitHub CLI,
+           * current auth token from the `hub` GitHub CLI.
+
+        GitHub API server URL will be inferred from `git remote`.
+        You can override this by setting the following git config keys:
+           Remote name
+              E.g. `machete.github.remote` = `origin`
+
+           Organization name
+              E.g. `machete.github.organization` = `VirtusLab`
+
+           Repository name
+              E.g. `machete.github.repository` = `git-machete`
+
+        To do this, run `git config --local --edit` and add the following section:
+        <dim>
+          [machete "github"]
+              organization = <organization_name>
+              repository = <repo_name>
+              remote = <remote_name>
+        </dim>
+
+        <b>Subcommands:</b>
+           `anno-prs`:
+              Annotates the branches based on their corresponding GitHub PR numbers and authors.
+              Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched.
+              Equivalent to `git machete anno --sync-github-prs`.
+
+           `checkout-prs [--all | --by=<github-login> | --mine | <PR-number-1> ... <PR-number-N>]`:
+ 
+              Check out the head branch of the given pull requests (specified by numbers or by a flag),
+              also traverse chain of pull requests upwards, adding branches one by one to git-machete and check them out locally.
+              Once the specified pull requests are checked out locally, annotate local branches with corresponding pull request numbers.
+              If only one PR has been checked out, then switch the local repository's HEAD to its head branch.
+
+              <b>Options:</b>
+
+                 <b>--all</b>
+
+                    Checkout all open PRs.
+
+                 <b>--by=<github-login></b>
+
+                    Checkout open PRs authored by the given GitHub user. `<github-login>` is the GitHub account name.
+
+                 <b>--mine</b>
+
+                    Checkout open PRs for the current user associated with the GitHub token.
+
+              <b>Parameters:</b>
+
+              `<PR-number-1> ... <PR-number-N>`    Pull request numbers to checkout.
+
+           `create-pr [--draft]`:
+ 
+              Creates a PR for the current branch, using the upstream (parent) branch as the PR base.
+              Once the PR is successfully created, annotates the current branch with the new PR's number.
+
+              If `.git/info/description` file is present, its contents are used as PR description.
+              If `.git/info/milestone` file is present, its contents (a single number — milestone id) are used as milestone.
+              If `.git/info/reviewers` file is present, its contents (one GitHub login per line) are used to set reviewers.
+
+              <b>Options:</b>
+
+                 <b>--draft</b>
+
+                    Creates the new PR as a draft.
+
+           `retarget-pr`:
+              Sets the base of the current branch's PR to upstream (parent) branch, as seen by git machete (see `git machete show up`).
+
+           `sync`:
+ 
+              Synchronizes with the remote repository:
+
+                 * checks out open PRs for the current user associated with the GitHub token and also traverses the chain of pull requests upwards, adding branches one by one to git-machete and checks them out locally as well,
+
+                 * deletes unmanaged branches,
+
+                 * deletes untracked managed branches that have no downstream branch.
+
+              Equivalent of `git machete clean --checkout-my-github-prs`.
+
+        <b>Environment variables (all subcommands):</b>
+           `GITHUB_TOKEN`
+              GitHub API token.
+
+   """,
+    "go": """
+        <b>Usage:</b><b>
+           git machete g[o] <direction></b>
+
+        where <direction> is one of: `d[own]`, `f[irst]`, `l[ast]`, `n[ext]`, `p[rev]`, `r[oot]`, `u[p]`
+
+        Checks out the branch specified by the given direction relative to the current branch:
+           * `down`:    the direct children/downstream branch of the current branch.
+           * `first`:   the first downstream of the root branch of the current branch (like `root` followed by `next`), or the root branch itself if the root has no downstream branches.
+           * `last`:    the last branch in the definition file that has the same root as the current branch; can be the root branch itself if the root has no downstream branches.
+           * `next`:    the direct successor of the current branch in the definition file.
+           * `prev`:    the direct predecessor of the current branch in the definition file.
+           * `root`:    the root of the tree where the current branch is located. Note: this will typically be something like `develop` or `master`, since all branches are usually meant to be ultimately merged to one of those.
+           * `up`:      the direct parent/upstream branch of the current branch.
+
+        Roughly equivalent to `git checkout $(git machete show <direction>)`.
+   """,
+    "help": """
+        <b>Usage:</b><b>
+           git machete help [<command>]</b>
+
+        Prints a summary of this tool, or a detailed info on a command if provided.
+   """,
+    "hooks": """
+        As with the standard git hooks, git machete looks for its own specific hooks in `$GIT_DIR/hooks/*` (or `$(git config core.hooksPath)/*`, if set).
+        All hooks are executed from the top-level folder of the repository (or top-level folder of worktree/submodule, if applicable).
+
+        Note: `hooks` is not a command as such, just a help topic (there is no `git machete hooks` command).
+
+        <b>Hooks:</b>
+           `machete-post-slide-out <new-upstream> <lowest-slid-out-branch> [<new-downstreams>...]`
+ 
+              The hook that is executed after a branch (or possibly multiple branches, in case of `slide-out`)
+              is slid out by `advance`, `slide-out` or `traverse`.
+
+              At least two parameters (branch names) are passed to the hook:
+
+                 * <new-upstream> is the upstream of the branch that has been slid out, or in case of multiple branches being slid out — the upstream of the highest slid out branch;
+
+                 * <lowest-slid-out-branch> is the branch that has been slid out, or in case of multiple branches being slid out — the lowest slid out branch;
+
+                 * <new-downstreams> are all the following (possibly zero) parameters, which correspond to all original downstreams of <lowest-slid-out-branch>, now reattached as the downstreams of <new-upstream>.
+
+              Note that this may be zero, one, or multiple branches.
+
+              Note: the hook, if present, is executed:
+
+                 * zero or once during a `advance` execution (depending on whether the slide-out has been confirmed or not),
+
+                 * exactly once during a `slide-out` execution (even if multiple branches are slid out),
+
+                 * zero or more times during `traverse` (every time a slide-out operation is confirmed).
+
+              If the hook returns a non-zero exit code, then an error is raised and the execution of the command is aborted,
+              i.e. `slide-out` won't attempt rebase of the new downstream branches and `traverse` won't continue the traversal.
+              In case of `advance` there is no difference (other than exit code of the entire `advance` command being non-zero),
+              since slide-out is the last operation that happens within `advance`.
+
+              Note that non-zero exit code of the hook doesn't cancel the effects of slide-out itself, only the subsequent operations.
+              The hook is executed only once the slide-out is complete and can in fact rely on .git/machete file being updated to the new branch layout.
+
+           `machete-pre-rebase <new-base> <fork-point-hash> <branch-being-rebased>`
+ 
+              The hook that is executed before rebase is run during `reapply`, `slide-out`, `traverse` and `update`.
+              Note that it is NOT executed by `squash` (despite its similarity to `reapply`), since no rebase is involved in `squash`.
+
+              The parameters are exactly the three revisions that are passed to `git rebase --onto`:
+
+                 * what is going to be the new base for the rebased commits,
+
+                 * what is the fork point — the place where the rebased history diverges from the upstream history,
+
+                 * what branch is rebased.
+
+              If the hook returns a non-zero exit code, an error is raised and the entire rebase is aborted.
+
+              Note: this hook is independent from git's standard `pre-rebase hook`.
+              If machete-pre-rebase returns zero, the execution flow continues to `git rebase`, which may also run `pre-rebase hook` if present.
+              `machete-pre-rebase` is thus always launched before `pre-rebase`.
+
+           `machete-status-branch <branch-name>`
+ 
+              The hook that is executed for each branch displayed during `discover`, `status` and `traverse`.
+
+              The standard output of this hook is displayed at the end of the line, after branch name, (optionally) custom annotation and (optionally) remote sync-ness status.
+              Standard error is ignored. If the hook returns a non-zero exit code, both stdout and stderr are ignored, and printing the status continues as usual.
+
+              Note: the hook is always invoked with `ASCII_ONLY` variable passed into the environment.
+              If `status` runs in ASCII-only mode (i.e. if `--color=auto` and stdout is not a terminal, or if `--color=never`), then `ASCII_ONLY=true`, otherwise `ASCII_ONLY=false`.
+
+        Please see hook_samples directory in git-machete project for examples.
+        An example of using the standard git `post-commit hook` to `git machete add` branches automatically is also included.
+   """,
+    "is-managed": """
+        <b>Usage:</b><b>
+           git machete is-managed [<branch>]</b>
+
+        Returns with zero exit code if the given branch (or current branch, if none specified) is managed by git machete (i.e. listed in .git/machete).
+
+        Returns with a non-zero exit code in case:
+           * the <branch> is provided but isn't managed (or doesn't exist), or
+           * the <branch> isn't provided and the current branch isn't managed, or
+           * the <branch> isn't provided and there's no current branch (detached HEAD).
+   """,
+    "list": """
+        <b>Usage:</b><b>
+           git machete list <category></b>
+
+        where <category> is one of: `addable`, `childless`, `managed`, `slidable`, `slidable-after <branch>`, `unmanaged`, `with-overridden-fork-point`.
+
+        Lists all branches that fall into one of the specified categories:
+           * `addable`: all branches (local or remote) than can be added to the definition file,
+           * `childless`: all branches that do not possess child branches,
+           * `managed`: all branches that appear in the definition file,
+           * `slidable`: all managed branches that have an upstream and can be slid out with `slide-out` command
+           * `slidable-after <branch>`: the downstream branch of the <branch>, if it exists and is the only downstream of <branch> (i.e. the one that can be slid out immediately following <branch>),
+           * `unmanaged`: all local branches that don't appear in the definition file,
+           * `with-overridden-fork-point`: all local branches that have a `fork point<fork-point>` override set up (even if this override does not affect the location of their fork point anymore).
+
+        This command is generally not meant for a day-to-day use, it's mostly needed for the sake of branch name completion in shell.
+   """,
+    "log": """
+        <b>Usage:</b><b>
+           git machete l[og] [<branch>]</b>
+
+        Runs `git log` for the range of commits from tip of the given branch (or current branch, if none specified) back to its fork point.
+        See help for `fork-point` for more details on meaning of the fork point.
+
+        Note: the branch in question does not need to occur in the definition file.
+   """,
+    "reapply": """
+        <b>Usage:</b><b>
+           git machete reapply [-f|--fork-point=<fork-point-commit>]</b>
+
+        Interactively rebase the current branch on the top of its computed fork point.
+        The chunk of the history to be rebased starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by `--fork-point`.
+        See help for `fork-point` for more details on meaning of the fork point.
+
+        Note: the current reapplied branch does not need to occur in the definition file.
+
+        Tip: `reapply` can be used for squashing the commits on the current branch to make history more condensed before push to the remote,
+        but there is also dedicated `squash` command that achieves the same goal without running `git rebase`.
+
+        <b>Options:</b>
+           <b>-f</b>, <b>--fork-point=<fork-point-commit></b>
+              Specifies the alternative fork point commit after which the rebased part of history is meant to start.
+
+        <b>Environment variables:</b>
+           `GIT_MACHETE_REBASE_OPTS`
+              Extra options to pass to the underlying `git rebase` invocation, space-separated.
+              Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete reapply`.
+
+   """,
+    "show": """
+        <b>Usage:</b><b>
+           git machete show <direction> [<branch>]</b>
+
+        where <direction> is one of: `c[urrent]`, `d[own]`, `f[irst]`, `l[ast]`, `n[ext]`, `p[rev]`, `r[oot]`, `u[p]`
+        displayed relative to given <branch>, or the current checked out branch if <branch> is unspecified.
+
+        Outputs name of the branch (or possibly multiple branches, in case of `down`) that is:
+           * `current`: the current branch; exits with a non-zero status if none (detached HEAD)
+           * `down`:    the direct children/downstream branch of the given branch.
+           * `first`:   the first downstream of the root branch of the given branch (like `root` followed by `next`), or the root branch itself if the root has no downstream branches.
+           * `last`:    the last branch in the definition file that has the same root as the given branch; can be the root branch itself if the root has no downstream branches.
+           * `next`:    the direct successor of the given branch in the definition file.
+           * `prev`:    the direct predecessor of the given branch in the definition file.
+           * `root`:    the root of the tree where the given branch is located. Note: this will typically be something like `develop` or `master`, since all branches are usually meant to be ultimately merged to one of those.
+           * `up`:      the direct parent/upstream branch of the given branch.
+   """,
+    "slide-out": """
+        <b>Usage:</b><b>
+           git machete slide-out [-d|--down-fork-point=<down-fork-point-commit>] [--delete] [-M|--merge] [-n|--no-edit-merge|--no-interactive-rebase] [<branch> [<branch> [<branch> ...]]]</b>
+
+        Removes the given branch (or multiple branches) from the branch tree definition.  If no branch has been specified current branch is assumed as the only branch.
+        Then synchronizes the downstream (child) branches of the last specified branch on the top of the upstream (parent) branch of the first specified branch.
+        Sync is performed either by rebase (default) or by merge (if `--merge` option passed).
+
+        The most common use is to slide out a single branch whose upstream was a `develop`/`master` branch and that has been recently merged.
+
+        Since this tool is designed to perform only one single rebase/merge at the end, provided branches must form a chain, i.e. all of the following conditions must be met:
+           * for i=1..N-1, (i+1)-th branch must be the only downstream (child) branch of the i-th branch,
+           * all provided branches must have an upstream branch (so, in other words, roots of branch dependency tree cannot be slid out).
+
+        For example, let's assume the following dependency tree:
+        <dim>
+          develop
+              adjust-reads-prec
+                  block-cancel-order
+                      change-table
+                          drop-location-type
+                      add-notification
+        </dim>
+
+        And now let's assume that `adjust-reads-prec` and later `block-cancel-order` were merged to develop.
+        After running `git machete slide-out adjust-reads-prec block-cancel-order` the tree will be reduced to:
+        <dim>
+          develop
+              change-table
+                  drop-location-type
+              add-notification
+        </dim>
+
+        and `change-table` and `add-notification` will be rebased onto develop (fork point for this rebase is configurable, see `-d` option below).
+
+        Note: This command doesn't delete any branches from git, just removes them from the tree of branch dependencies.
+
+        <b>Options:</b>
+           <b>-d</b>, <b>--down-fork-point=<down-fork-point-commit></b>
+              If updating by rebase, specifies the alternative fork point for downstream branches for the operation. `git machete fork-point` overrides for downstream branches are recommended over use of this option. See also doc for `--fork-point` option in `git machete help reapply` and `git machete help update`. Not allowed if updating by merge.
+           <b>--delete</b>
+              Delete the slid-out branches.
+           <b>-M</b>, <b>--merge</b>
+              Update the downstream branch by merge rather than by rebase.
+           <b>-n</b>
+              If updating by rebase, equivalent to `--no-interactive-rebase`. If updating by merge, equivalent to `--no-edit-merge`.
+           <b>--no-edit-merge</b>
+              If updating by merge, skip opening the editor for merge commit message while doing `git merge` (i.e. pass `--no-edit` flag to underlying `git merge`). Not allowed if updating by rebase.
+           <b>--no-interactive-rebase</b>
+              If updating by rebase, run `git rebase` in non-interactive mode (without `-i/--interactive` flag). Not allowed if updating by merge.
+
+        <b>Environment variables:</b>
+           `GIT_MACHETE_REBASE_OPTS`
+              Extra options to pass to the underlying `git rebase` invocations, space-separated.
+              Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete slide-out`.
+
+   """,
+    "squash": """
+        <b>Usage:</b><b>
+           git machete squash [-f|--fork-point=<fork-point-commit>]</b>
+
+        Squashes the commits belonging uniquely to the current branch into a single commit.
+        The chunk of the history to be squashed starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by `--fork-point`.
+        See help for `fork-point` for more details on meaning of the fork point.
+        The message for the squashed is taken from the earliest squashed commit, i.e. the commit directly following the fork point.
+
+        Note: the current squashed branch does not need to occur in the definition file.
+
+        Tip: `squash` does NOT run `git rebase` under the hood. For more complex scenarios that require rewriting the history of current branch, see `reapply` and `update`.
+
+        <b>Options:</b>
+           <b>-f</b>, <b>--fork-point=<fork-point-commit></b>
+              Specifies the alternative fork point commit after which the squashed part of history is meant to start.
+   """,
+    "status": """
+        <b>Usage:</b><b>
+           git machete s[tatus] [--color=WHEN] [-l|--list-commits] [-L|--list-commits-with-hashes] [--no-detect-squash-merges]</b>
+
+        Displays a tree-shaped status of the branches listed in the definition file.
+
+        Apart from simply ASCII-formatting the definition file, this also:
+           * colors the edges between upstream (parent) and downstream (children) branches:
+              - <red>red edge</red> means that the downstream branch tip is not a direct descendant of the upstream branch tip,
+              - <yellow>yellow edge</yellow> means that the downstream branch tip is a direct descendant of the upstream branch tip,
+              but the `fork point<fork-point>` of the downstream branch is not equal to the upstream branch tip,
+              - <green>green edge</green> means that the downstream branch tip is a direct descendant of the upstream branch tip
+              and the fork point of the downstream branch is equal to the upstream branch tip,
+              - grey/dimmed edge means that the downstream branch has been merged to the upstream branch,
+              detected by commit equivalency (default), or by strict detection of merge commits (if `--no-detect-squash-merges` passed).
+
+           * prints (`untracked`/`ahead of <remote>`/`behind <remote>`/`diverged from [& older than] <remote>`) message if the branch is not in sync with its remote counterpart;
+           * displays the custom annotations (see help for `format` and `anno`) next to each branch, if present;
+           * displays the output of `machete-status-branch hook` (see help for `hooks`), if present;
+           * optionally lists commits introduced on each branch if `-l/--list-commits` or `-L/--list-commits-with-hashes` is supplied.
+
+        Name of the currently checked-out branch is underlined (or shown in blue on terminals that don't support underline).
+
+        In case of <yellow>yellow edge</yellow>, use `-l` or `-L` flag to show the exact location of the inferred fork point
+        (which indicates e.g. what range of commits is going to be rebased when the branch is updated).
+        The inferred fork point can be always overridden manually, see help for `fork-point`.
+
+        Grey/dimmed edge suggests that the downstream branch can be slid out (see help for `slide-out` and `traverse`).
+
+        Using colors can be disabled with a `--color` flag set to `never`.
+        With `--color=always`, git machete always emits colors and with `--color=auto`, it emits colors only when standard output is connected to a terminal.
+        `--color=auto` is the default. When colors are disabled, relation between branches is represented in the following way (not including the hash-comments):
+        <dim>
+          <branch0>
+          |
+          o-<branch1> *   # green (in sync with parent; asterisk for the current branch)
+          | |
+          | x-<branch2>   # red (not in sync with parent)
+          |   |
+          |   ?-<branch3> # yellow (in sync with parent, but parent is not the fork point)
+          |
+          m-<branch4>     # grey (merged to parent)
+        </dim>
+
+        <b>Options:</b>
+           <b>--color=WHEN</b>
+              Colorize the output; WHEN can be `always`, `auto` (default; i.e. only if stdout is a terminal), or `never`.
+           <b>-l</b>, <b>--list-commits</b>
+              Additionally list the commits introduced on each branch.
+           <b>-L</b>, <b>--list-commits-with-hashes</b>
+              Additionally list the short hashes and messages of commits introduced on each branch.
+           <b>--no-detect-squash-merges</b>
+              Only consider strict (fast-forward or 2-parent) merges, rather than rebase/squash merges, when detecting if a branch is merged into its upstream (parent).
+
+        <b>Config keys:</b>
+           `machete.status.extraSpaceBeforeBranchName`
+
+              To make it easier to select branch name from the `status` output on certain terminals
+              (e.g. Alacritty), you can add an extra
+              space between └─ and `branch name` by setting `git config machete.status.extraSpaceBeforeBranchName true`.
+
+              For example, by default the status is displayed as:
+
+              develop
+              │
+              ├─feature_branch1
+              │
+              └─feature_branch2
+
+              With `machete.status.extraSpaceBeforeBranchName` config set to `true`:
+
+              develop
+              │
+              ├─ feature_branch1
+              │
+              └─ feature_branch2
+
+   """,
+    "traverse": """
+        <b>Usage:</b><b>
+           git machete t[raverse] [-F|--fetch] [-l|--list-commits] [-M|--merge]
+                                  [-n|--no-edit-merge|--no-interactive-rebase] [--no-detect-squash-merges]
+                                  [--[no-]push] [--[no-]push-untracked]
+                                  [--return-to=WHERE] [--start-from=WHERE] [-w|--whole] [-W] [-y|--yes]</b>
+
+        Traverses the branch tree in pre-order (i.e. simply in the order as they occur in the definition file).
+        By default `traverse` starts from the current branch.
+        This behaviour can, however, be customized using options: `--start-from=`, `--whole` or `-w`, `-W`.
+
+        For each branch, the command:
+           * detects if the branch is merged (grey edge) to its parent (aka upstream):
+              - by commit equivalency (default), or by strict detection of merge commits (if `--no-detect-squash-merges` passed),
+              - if so, asks the user whether to slide out the branch from the dependency tree (typically branches are no longer needed after they're merged);
+
+           * otherwise, if the branch has a <red>red</red> or <yellow>yellow</yellow> edge to its parent/upstream (see help for `status`):
+              - asks the user whether to rebase (default) or merge (if `--merge` passed) the branch onto into its upstream branch
+              — equivalent to `git machete update` with no `--fork-point` option passed;
+
+           * if the branch is not tracked on a remote, is ahead of its remote counterpart, or diverged from the counterpart & has newer head commit than the counterpart:
+              - asks the user whether to push the branch (possibly with `--force-with-lease` if the branches diverged);
+
+           * otherwise, if the branch diverged from the remote counterpart & has older head commit than the counterpart:
+              - asks the user whether to `git reset --keep` the branch to its remote counterpart
+
+           * otherwise, if the branch is behind its remote counterpart:
+              - asks the user whether to pull the branch;
+
+           * and finally, if any of the above operations has been successfully completed:
+              - prints the updated `status`.
+
+        If the traverse flow is stopped (typically due to merge/rebase conflicts), just run `git machete traverse` after the merge/rebase is finished.
+        It will pick up the walk from the current branch (unless `--start-from=` or `-w` etc. is passed).
+        Unlike with e.g. `git rebase`, there is no special `--continue` flag, as `traverse` is stateless
+        (doesn't keep a state of its own like `git rebase` does in `.git/rebase-apply/`).
+
+        <b>Options:</b>
+           <b>-F</b>, <b>--fetch</b>
+              Fetch the remotes of all managed branches at the beginning of traversal (no `git pull` involved, only `git fetch`).
+           <b>-l</b>, <b>--list-commits</b>
+              When printing the status, additionally list the messages of commits introduced on each branch.
+           <b>-M</b>, <b>--merge</b>
+              Update by merge rather than by rebase.
+           <b>-n</b>
+              If updating by rebase, equivalent to `--no-interactive-rebase`. If updating by merge, equivalent to `--no-edit-merge`.
+           <b>--no-detect-squash-merges</b>
+              Only consider strict (fast-forward or 2-parent) merges, rather than rebase/squash merges, when detecting if a branch is merged into its upstream (parent).
+           <b>--no-edit-merge</b>
+              If updating by merge, skip opening the editor for merge commit message while doing `git merge` (i.e. pass `--no-edit` flag to the underlying `git merge`). Not allowed if updating by rebase.
+           <b>--no-interactive-rebase</b>
+              If updating by rebase, run `git rebase` in non-interactive mode (without `-i/--interactive` flag). Not allowed if updating by merge.
+           <b>--no-push</b>
+              Do not push any (neither tracked nor untracked) branches to remote, re-enable via `--push`.
+           <b>--no-push-untracked</b>
+              Do not push untracked branches to remote, re-enable via `--push-untracked`.
+           <b>--push</b>
+              Push all (both tracked and untracked) branches to remote — default behavior.
+           <b>--push-untracked</b>
+              Push untracked branches to remote — default behavior.
+           <b>--return-to=WHERE</b>
+              Specifies the branch to return after traversal is successfully completed; WHERE can be `here` (the current branch at the moment when traversal starts), `nearest-remaining` (nearest remaining branch in case the `here` branch has been slid out by the traversal) or `stay` (the default — just stay wherever the traversal stops). Note: when user quits by `q`/`yq` or when traversal is stopped because one of git actions fails, the behavior is always `stay`.
+           <b>--start-from=WHERE</b>
+              Specifies the branch to start the traversal from; WHERE can be `here` (the default — current branch, must be managed by git machete), `root` (root branch of the current branch, as in `git machete show root`) or `first-root` (first listed managed branch).
+           <b>-w</b>, <b>--whole</b>
+              Equivalent to `-n --start-from=first-root --return-to=nearest-remaining`; useful for quickly traversing & syncing all branches (rather than doing more fine-grained operations on the local section of the branch tree).
+           <b>-W</b>
+              Equivalent to `--fetch --whole`; useful for even more automated traversal of all branches.
+           <b>-y</b>, <b>--yes</b>
+              Don't ask for any interactive input, including confirmation of rebase/push/pull. Implies `-n`.
+
+        <b>Environment variables:</b>
+           `GIT_MACHETE_REBASE_OPTS`
+              Extra options to pass to the underlying `git rebase` invocations, space-separated.
+              Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete traverse`.
+
+   """,
+    "update": """
+        <b>Usage:</b><b>
+           git machete update [-f|--fork-point=] [-M|--merge] [-n|--no-edit-merge|--no-interactive-rebase]</b>
+
+        Synchronizes the current branch with its upstream (parent) branch either by rebase (default) or by merge (if `--merge` option passed).
+
+        If updating by rebase, interactively rebases the current branch on the top of its upstream (parent) branch.
+        The chunk of the history to be rebased starts at the fork point of the current branch, which by default is inferred automatically, but can also be set explicitly by `--fork-point`.
+        See help for `fork-point` for more details on the meaning of fork point.
+
+        If updating by merge, merges the upstream (parent) branch into the current branch.
+
+        <b>Options:</b>
+           <b>-f</b>, <b>--fork-point=<fork-point-commit></b>
+              If updating by rebase, specifies the alternative fork point commit after which the rebased part of history is meant to start. Not allowed if updating by merge.
+           <b>-M</b>, <b>--merge</b>
+              Update by merge rather than by rebase.
+           <b>-n</b>
+              If updating by rebase, equivalent to `--no-interactive-rebase`. If updating by merge, equivalent to `--no-edit-merge`.
+           <b>--no-edit-merge</b>
+              If updating by merge, skip opening the editor for merge commit message while doing `git merge` (i.e. pass `--no-edit` flag to underlying `git merge`). Not allowed if updating by rebase.
+           <b>--no-interactive-rebase</b>
+              If updating by rebase, run `git rebase` in non-interactive mode (without `-i/--interactive` flag). Not allowed if updating by merge.
+
+        <b>Environment variables:</b>
+           `GIT_MACHETE_REBASE_OPTS`
+              Extra options to pass to the underlying `git rebase` invocation, space-separated.
+              Example: `GIT_MACHETE_REBASE_OPTS="--keep-empty --rebase-merges" git machete update`.
+
+   """,
+    "version": """
+        <b>Usage:</b><b>
+           git machete version</b>
+
+        Prints the version and exits.
+   """,
+}
diff --git a/git_machete/handmade_short_docs.py b/git_machete/handmade_short_docs.py
new file mode 100644
index 0000000..828cfa7
--- /dev/null
+++ b/git_machete/handmade_short_docs.py
@@ -0,0 +1,35 @@
+from typing import Dict
+
+# ---------------------------------------------------------------------------------------------------------
+# This file is supposed to be modified manually
+# ---------------------------------------------------------------------------------------------------------
+
+short_docs: Dict[str, str] = {
+    "add": "Add a branch to the tree of branch dependencies",
+    "advance": "Fast-forward merge one of children to the current branch, push it and then slide out the child",
+    "anno": "Manage custom annotations",
+    "clean": "Delete untracked and unmanaged branches and also optionally check out user's open GitHub PRs",
+    "config": "Display docs for the git machete configuration keys and environment variables",
+    "delete-unmanaged": "Delete local branches that are not present in the definition file",
+    "diff": "Diff current working directory or a given branch against its computed fork point",
+    "discover": "Automatically discover tree of branch dependencies",
+    "edit": "Edit the definition file",
+    "file": "Display the location of the definition file",
+    "fork-point": "Display or override fork point for a branch",
+    "format": "Display docs for the format of the definition file",
+    "github": "Create, check out and manage GitHub PRs while keeping them reflected in git machete",
+    "go": "Check out the branch relative to the position of the current branch, accepts down/first/last/next/root/prev/up argument",
+    "help": "Display this overview, or detailed help for a specified command",
+    "hooks": "Display docs for the extra hooks added by git machete",
+    "is-managed": "Check if the current branch is managed by git machete (mostly for scripts)",
+    "list": "List all branches that fall into one of pre-defined categories (mostly for internal use)",
+    "log": "Log the part of history specific to the given branch",
+    "reapply": "Rebase the current branch onto its computed fork point",
+    "show": "Show name(s) of the branch(es) relative to the position of a branch, accepts down/first/last/next/root/prev/up argument",
+    "slide-out": "Slide out the current branch and sync its downstream (child) branches with its upstream (parent) branch via rebase or merge",
+    "squash": "Squash the unique history of the current branch into a single commit",
+    "status": "Display formatted tree of branch dependencies, including info on their sync with upstream branch and with remote",
+    "traverse": "Walk through the tree of branch dependencies and rebase, merge, slide out, push and/or pull each branch one by one. By default starts from current branch",
+    "update": "Sync the current branch with its upstream (parent) branch via rebase or merge",
+    "version": "Display the version and exit"
+}
diff --git a/requirements.py-docs.txt b/requirements.py-docs.txt
new file mode 100644
index 0000000..f7269b4
--- /dev/null
+++ b/requirements.py-docs.txt
@@ -0,0 +1,3 @@
+docutils==0.17.1
+pygments==2.13
+beautifulsoup4==4.9
diff --git a/tox.ini b/tox.ini
index f222d67..1ca63d9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = pep8,mypy-py{36,37,38,39,310},py{36,37,38,39,310},coverage,docs
+envlist = pep8,mypy-py{36,37,38,39,310},py{36,37,38,39,310},coverage,sphinx-docs,py-docs
 minversion = 2.3.2
 skipsdist = True
 
@@ -32,7 +32,7 @@ commands = flake8
 ignore = W504
 show-source = True
 max-line-length = 140
-exclude = ./.*,build,dist,*egg,venv, git_machete/docs.py
+exclude = ./.*,build,dist,*egg,venv, git_machete/handmade_short_docs.py, git_machete/generated_long_docs.py
 import-order-style = pep8
 
 [testenv:venv]
@@ -53,14 +53,34 @@ commands =
   # Saves a report to coverage.xml (uploaded to Codecov from CI, as Codecov apparently does not accept .coverage binary files)
   coverage xml
 
-[testenv:docs]
-description = "Build documentation"
+[testenv:sphinx-docs]
+description = "Build Sphinx documentation"
 usedevelop=true
 deps =
-  -r{toxinidir}/requirements.docs.txt
+  -r{toxinidir}/requirements.sphinx-docs.txt
 commands =
   sphinx-build -W --keep-going -b html docs/source docs/html
 
+[testenv:py-docs]
+description = "Build Python documentation"
+# The generation of the python docs uses git_machete package
+usedevelop=true
+allowlist_externals = bash
+deps =
+  -r{toxinidir}/requirements.py-docs.txt
+commands =
+  bash -c "python docs/generate_py_docs.py > git_machete/generated_long_docs.py"
+
+[testenv:check-py-docs]
+description = "Check if Python documentation is up to date with Sphinx documentation"
+# The generation of the python docs uses git_machete package
+usedevelop=true
+allowlist_externals = bash
+deps =
+  -r{toxinidir}/requirements.py-docs.txt
+commands =
+  bash docs/enforce-docs-up-to-date.sh
+
 [testenv:mypy]
 allowlist_externals = tox
 commands = tox -e "mypy-py{36,37,38,39,310}"


Test patch:
diff --git a/requirements.docs.txt b/requirements.sphinx-docs.txt
similarity index 100%
rename from requirements.docs.txt
rename to requirements.sphinx-docs.txt
diff --git a/tests/mockers.py b/tests/mockers.py
index e4c843d..55bf541 100644
--- a/tests/mockers.py
+++ b/tests/mockers.py
@@ -410,3 +410,7 @@ def mock_exit_script(status_code: Optional[int] = None, error: Optional[BaseExce
         raise error
     else:
         sys.exit(status_code)
+
+
+def mock_exit_script_no_exit(status_code: Optional[int] = None, error: Optional[BaseException] = None) -> None:
+    return
diff --git a/tests/test_help.py b/tests/test_help.py
index 79be711..acce166 100644
--- a/tests/test_help.py
+++ b/tests/test_help.py
@@ -2,9 +2,11 @@ from typing import Any, List
 
 import pytest
 
-from git_machete.docs import long_docs
+from git_machete.generated_long_docs import long_docs
 
-from .mockers import GitRepositorySandbox, launch_command, mock_run_cmd
+from unittest import mock
+
+from .mockers import GitRepositorySandbox, launch_command, mock_exit_script_no_exit, mock_run_cmd
 
 
 class TestHelp:
@@ -56,3 +58,9 @@ class TestHelp:
                 assert expected_exit_code_when_failed == e.value.code, \
                     f"Verify that `git machete {command} --help` causes " \
                     f"SystemExit with {expected_exit_code} exit code."
+
+    @mock.patch('git_machete.cli.exit_script', mock_exit_script_no_exit)
+    def test_help_output_has_no_ansi_codes(self) -> None:
+        for command in long_docs.keys():
+            help_output = launch_command('help', command)
+            assert '\033' not in help_output