From ecd8c6abe61bc2b7c27faf9aaf9e69677e74f5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Lipski?= Date: Wed, 1 Dec 2021 18:32:47 +0100 Subject: [PATCH] Make sure that machete file for worktrees is sought for in the top-level git dir (#361) * Make sure that machete file for worktrees is sought for in the top-level git dir * Make sure that machete file for worktrees is sought for in the top-level git dir - 1st round of fixes * Make sure that machete file for worktrees is sought for in the top-level git dir - 2nd round of fixes * Make sure that machete file for worktrees is sought for in the top-level git dir - 3rd round of fixes --- RELEASE_NOTES.md | 4 ++++ docs/source/cli_help/file.rst | 9 +++++++-- docs/source/completion.rst | 2 +- git_machete/client.py | 2 +- git_machete/docs.py | 9 +++++++-- git_machete/git_operations.py | 10 +++++++++- git_machete/tests/functional/test_machete.py | 5 +++-- tox.ini | 8 ++++---- 8 files changed, 36 insertions(+), 13 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index d31eff919..f2f044e40 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,9 @@ # Release notes +## New in git-machete 3.6.1 + +- fixed: support for worktrees (reported by @kgadek) + ## New in git-machete 3.6.0 - added: `t` alias for `traverse` command diff --git a/docs/source/cli_help/file.rst b/docs/source/cli_help/file.rst index 06dad9c1e..1b1dfb33f 100644 --- a/docs/source/cli_help/file.rst +++ b/docs/source/cli_help/file.rst @@ -8,5 +8,10 @@ file git machete file -Outputs the absolute path of the machete definition file. Currently fixed to ``/machete``. -Note: this won't always be just ``/.git/machete`` since e.g. submodules and worktrees have their git directories in different location. +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**, this file is located under ``.git/machete`` as well (**not** in the git folder of the worktree 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/completion.rst b/docs/source/completion.rst index 2c01e6ac6..68108a9cf 100644 --- a/docs/source/completion.rst +++ b/docs/source/completion.rst @@ -101,7 +101,7 @@ Fish: Please look at the section about [installation via Homebrew](https://github.com/VirtusLab/git-machete#using-homebrew-macos). ``brew install git-machete`` automatically installs fish completion files for ``git machete``. * Linux - #. Place the completion script in ``/path/to/fish/completions/`` (typically ``~/.config/fish/completions/git-machete.fish``). + Place the completion script in ``/path/to/fish/completions/`` (typically ``~/.config/fish/completions/git-machete.fish``). .. code-block:: shell diff --git a/git_machete/client.py b/git_machete/client.py index 3bb64b90f..dff9bae4a 100644 --- a/git_machete/client.py +++ b/git_machete/client.py @@ -851,7 +851,7 @@ def traverse( if not any_action_suggested and initial_branch not in self.__roots: print(fmt("Tip: `traverse` by default starts from the current branch, " "use flags (`--starts-from=`, `--whole` or `-w`, `-W`) to change this behavior.\n" - "Further info under `git machete traverse --help`."), file=sys.stdout) + "Further info under `git machete traverse --help`.")) if opt_return_to == "here" or ( opt_return_to == "nearest-remaining" and nearest_remaining_branch == initial_branch): print(f"Returned to the initial branch {bold(initial_branch)}") diff --git a/git_machete/docs.py b/git_machete/docs.py index 803bb3dc6..ce926f521 100644 --- a/git_machete/docs.py +++ b/git_machete/docs.py @@ -208,8 +208,13 @@ "file": """ Usage: git machete file - Outputs the absolute path of the machete definition file. Currently fixed to `/machete`. - Note: this won't always be just `/.git/machete` since e.g. submodules and worktrees have their git directories in different location. + 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, this file is located under `.git/machete` as well (not in the git folder of the worktree 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`. """, "fork-point": """ Usage: diff --git a/git_machete/git_operations.py b/git_machete/git_operations.py index 4e1173856..fc5b1a981 100644 --- a/git_machete/git_operations.py +++ b/git_machete/git_operations.py @@ -1,3 +1,4 @@ +from pathlib import Path from typing import Callable, Dict, Generator, Iterator, List, Match, Optional, Set, Tuple import os @@ -254,7 +255,14 @@ def get_root_dir(self) -> str: def __get_git_dir(self) -> str: if not self._git_dir: try: - self._git_dir = self._popen_git("rev-parse", "--git-dir").strip() + git_dir: str = self._popen_git("rev-parse", "--git-dir").strip() + git_dir_parts = Path(git_dir).parts + if len(git_dir_parts) >= 3 and git_dir_parts[-3] == '.git' and git_dir_parts[-2] == 'worktrees': + self._git_dir = os.path.join(*git_dir_parts[:-2]) + debug('__get_git_dir', f'git dir pointing to {git_dir} - we are in a worktree; ' + f'using {self._git_dir} as the effective git dir instead') + else: + self._git_dir = git_dir except MacheteException: raise MacheteException("Not a git repository") return self._git_dir diff --git a/git_machete/tests/functional/test_machete.py b/git_machete/tests/functional/test_machete.py index c89b031d9..121ae942f 100644 --- a/git_machete/tests/functional/test_machete.py +++ b/git_machete/tests/functional/test_machete.py @@ -456,14 +456,15 @@ def setup_discover_standard_tree(self) -> None: ) @mock.patch('git_machete.utils.run_cmd', mock_run_cmd) # to hide git outputs in tests - def test_branch_reappers_in_definition(self) -> None: + def test_branch_reappears_in_definition(self) -> None: body: str = \ """master \tdevelop \t\n develop """ - expected_error_msg: str = fmt('.git/machete, line 5: branch `develop` re-appears in the tree definition. Edit the definition file manually with `git machete edit`') + expected_error_msg: str = fmt('.git/machete, line 5: branch `develop` re-appears in the tree definition. ' + 'Edit the definition file manually with `git machete edit`') self.repo_sandbox.new_branch("root") self.rewrite_definition_file(body) diff --git a/tox.ini b/tox.ini index 74f388a87..16b836151 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = pep8,mypy-py{36,37,38,39},py{36,37,38,39},coverage,docs +envlist = pep8,mypy-py{36,37,38,39,310},py{36,37,38,39,310},coverage,docs minversion = 2.3.2 skipsdist = True @@ -32,7 +32,7 @@ exclude = ./.*,build,dist,*egg,venv import-order-style = pep8 [testenv:coverage] -description = "Checking the test coverage of the code." +description = "Check the test coverage of the code" deps = coverage commands = coverage erase @@ -51,9 +51,9 @@ commands = [testenv:mypy] whitelist_externals = tox -commands = tox -e "mypy-py{36,37,38,39}" +commands = tox -e "mypy-py{36,37,38,39,310}" -[testenv:mypy-py{36,37,38,39}] +[testenv:mypy-py{36,37,38,39,310}] deps = mypy commands = mypy --config-file mypy.ini git_machete