libvcs icon indicating copy to clipboard operation
libvcs copied to clipboard

`git init` compatibility, `Git.version()`

Open tony opened this issue 6 months ago • 2 comments
trafficstars

Problem

  • git init compatibility issues
  • no uniform way to check and compare git --version

Details

  Issue Summary

  The libvcs test suite is failing with newer Git versions (2.43.0 and later) due to changes in how Git handles repository initialization. Specifically, tests fail with:

  libvcs.exc.CommandError: Command failed with code 1: git init empty_git_repo

  What Changed in Git Init

  Git has progressively evolved its git init command behavior across versions:

  1. Git 2.28.0 (July 2020) introduced the ability to configure the default branch name with the init.defaultBranch config option.
  2. Git 2.30.0 (December 2020) added the -b/--initial-branch option to explicitly specify the initial branch name.
  3. Newer releases have tightened the behavior around initialization, with Git 2.43.0 potentially being more strict about directory existence or permissions.

  The error occurs in libvcs's _create_git_remote_repo function, which uses:

  run(
      ["git", "init", remote_repo_path.stem, *init_cmd_args],
      cwd=remote_repo_path.parent,
  )

  Without specifying an initial branch name, this command now fails on newer Git versions.

  Recommended Patch for libvcs

  Here's the fix needed in src/libvcs/pytest_plugin.py:

  def _create_git_remote_repo(
      remote_repo_path: pathlib.Path,
      remote_repo_post_init: CreateRepoPostInitFn | None = None,
      init_cmd_args: InitCmdArgs = DEFAULT_GIT_REMOTE_REPO_CMD_ARGS,
      env: _ENV | None = None,
  ) -> pathlib.Path:
      if init_cmd_args is None:
          init_cmd_args = []

      # Create the command with initial branch explicitly set to 'main'
      # This works with all Git versions
      git_cmd = ["git", "init"]

      # Add -b option for initial branch name (compatible with Git 2.30.0+)
      git_version_output = run(["git", "--version"], check_returncode=False)
      try:
          if git_version_output and git_version_output.output:
              # Add -b option only for Git versions that support it
              git_cmd.extend(["-b", "main"])
      except Exception:
          # If version check fails, try without -b option
          pass

      # Add repository path and any additional arguments
      git_cmd.extend([remote_repo_path.stem, *init_cmd_args])

      # Run the git init command
      run(
          git_cmd,
          cwd=remote_repo_path.parent,
          env=env,
      )

      if remote_repo_post_init is not None and callable(remote_repo_post_init):
          remote_repo_post_init(remote_repo_path=remote_repo_path, env=env)

      return remote_repo_path

  Alternative Simpler Patch

  If backward compatibility with very old Git versions isn't required, a simpler fix is:

  def _create_git_remote_repo(
      remote_repo_path: pathlib.Path,
      remote_repo_post_init: CreateRepoPostInitFn | None = None,
      init_cmd_args: InitCmdArgs = DEFAULT_GIT_REMOTE_REPO_CMD_ARGS,
      env: _ENV | None = None,
  ) -> pathlib.Path:
      if init_cmd_args is None:
          init_cmd_args = []

      # Always use -b option to specify initial branch explicitly
      run(
          ["git", "init", "-b", "main", remote_repo_path.stem, *init_cmd_args],
          cwd=remote_repo_path.parent,
          env=env,
      )

      if remote_repo_post_init is not None and callable(remote_repo_post_init):
          remote_repo_post_init(remote_repo_path=remote_repo_path, env=env)

      return remote_repo_path

  Explanation for Maintainers

  This patch addresses compatibility issues with modern Git versions while maintaining backward compatibility with older versions. The problem occurs because newer Git versions are more particular about branch naming conventions
  and initialization parameters.

  The test suite may pass when running individual test files but fail when running the entire suite because of how fixture caching works in pytest - when running single files, tests might use already-created repositories, but the
  full suite likely tries to create fresh repositories, triggering the Git init failure.

Summary by Sourcery

Improve git compatibility by introducing internal version parsing utilities and updating documentation with project standards and workflows.

New Features:

  • Add internal version parsing and comparison utilities for consistent handling of git version strings.

Enhancements:

  • Introduce vendored modules for version and structure handling to improve compatibility and version checks.

Documentation:

  • Add CLAUDE.md with detailed project guidelines, development workflow, and coding standards.

tony avatar May 11 '25 11:05 tony