blob: a0c9d439bd259a6d676e30400d52b8e5c416f763 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import annotations
from pathlib import Path
from unittest import mock
import pytest
from airflow_breeze.utils.path_utils import get_main_git_dir_for_worktree
class TestGetMainGitDirForWorktree:
"""Tests for get_main_git_dir_for_worktree detection."""
def test_returns_none_when_dot_git_is_directory(self, tmp_path):
"""Standard clone: .git is a directory, not a worktree."""
git_dir = tmp_path / ".git"
git_dir.mkdir()
with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path):
assert get_main_git_dir_for_worktree() is None
def test_returns_none_when_dot_git_missing(self, tmp_path):
"""No .git at all — not a git repo."""
with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path):
assert get_main_git_dir_for_worktree() is None
def test_returns_none_when_dot_git_file_without_gitdir_prefix(self, tmp_path):
""".git file exists but does not start with 'gitdir: '."""
git_file = tmp_path / ".git"
git_file.write_text("something unexpected\n")
with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path):
assert get_main_git_dir_for_worktree() is None
def test_absolute_gitdir_path(self, tmp_path):
"""Worktree with an absolute gitdir path resolves to the main .git directory."""
# Simulate: /main-repo/.git/worktrees/my-worktree
main_repo = tmp_path / "main-repo"
main_git = main_repo / ".git"
worktree_gitdir = main_git / "worktrees" / "my-worktree"
worktree_gitdir.mkdir(parents=True)
worktree_dir = tmp_path / "my-worktree"
worktree_dir.mkdir()
(worktree_dir / ".git").write_text(f"gitdir: {worktree_gitdir}\n")
with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", worktree_dir):
result = get_main_git_dir_for_worktree()
assert result is not None
assert result == main_git
def test_relative_gitdir_path(self, tmp_path):
"""Worktree with a relative gitdir path is resolved correctly."""
# Simulate: main-repo/.git/worktrees/my-worktree
main_repo = tmp_path / "main-repo"
main_git = main_repo / ".git"
worktree_gitdir = main_git / "worktrees" / "my-worktree"
worktree_gitdir.mkdir(parents=True)
worktree_dir = tmp_path / "my-worktree"
worktree_dir.mkdir()
# Write a relative path from worktree_dir to worktree_gitdir
relative_gitdir = Path("../main-repo/.git/worktrees/my-worktree")
(worktree_dir / ".git").write_text(f"gitdir: {relative_gitdir}\n")
with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", worktree_dir):
result = get_main_git_dir_for_worktree()
assert result is not None
assert result.resolve() == main_git.resolve()
@pytest.mark.parametrize(
"gitdir_content",
[
"gitdir: {path}/worktrees/wt\n",
"gitdir: {path}/worktrees/wt",
"gitdir: {path}/worktrees/wt \n",
],
ids=["trailing-newline", "no-trailing-newline", "extra-whitespace"],
)
def test_strips_whitespace_from_gitdir(self, tmp_path, gitdir_content):
"""Whitespace and trailing newlines are stripped from the gitdir content."""
main_repo = tmp_path / "main-repo"
main_git = main_repo / ".git"
(main_git / "worktrees" / "wt").mkdir(parents=True)
content = gitdir_content.format(path=main_git)
(tmp_path / ".git").write_text(content)
with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path):
result = get_main_git_dir_for_worktree()
assert result is not None
assert result == main_git