Skip to content

Commit

Permalink
Merge pull request #4684 from jedwards4b/refine_git_interface
Browse files Browse the repository at this point in the history
refine the git interface to handle no git and old git
  • Loading branch information
jedwards4b committed Sep 27, 2024
2 parents 2776043 + 9a57386 commit 9ac3e71
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 38 deletions.
44 changes: 17 additions & 27 deletions CIME/case/case_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,37 +527,27 @@ def case_setup(self, clean=False, test_mode=False, reset=False, keep=None):


def _create_case_repo(self, caseroot):
version = run_cmd_no_fail("git --version")
result = re.findall(r"([0-9]+)\.([0-9]+)\.?[0-9]*", version)
major = int(result[0][0])
minor = int(result[0][1])

# gitinterface needs git version 2.28 or newer
if major > 2 or (major == 2 and minor >= 28):
self._gitinterface = GitInterface(
caseroot, logger, branch=self.get_value("CASE")

self._gitinterface = GitInterface(caseroot, logger, branch=self.get_value("CASE"))
if self._gitinterface and not os.path.exists(os.path.join(caseroot, ".gitignore")):
safe_copy(
os.path.join(
self.get_value("CIMEROOT"),
"CIME",
"data",
"templates",
"gitignore.template",
),
os.path.join(caseroot, ".gitignore"),
)
append_case_status(
"", "", "local git repository created", gitinterface=self._gitinterface
)
if not os.path.exists(os.path.join(caseroot, ".gitignore")):
safe_copy(
os.path.join(
self.get_value("CIMEROOT"),
"CIME",
"data",
"templates",
"gitignore.template",
),
os.path.join(caseroot, ".gitignore"),
)
append_case_status(
"", "", "local git repository created", gitinterface=self._gitinterface
)
# add all files in caseroot to local repository
self._gitinterface._git_command("add", "*")
else:
logger.warning("git interface requires git version 2.28 or newer")

elif not self._gitinterface:
append_case_status(
"",
"",
f"local git version too old for cime git interface {major}.{minor}",
"Local git version too old for cime git interface, version 2.28 or newer required.",
)
33 changes: 30 additions & 3 deletions CIME/gitinterface.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
import sys
import sys, shutil, re
from CIME.utils import run_cmd_no_fail
from pathlib import Path


class GitInterface:
def __init__(self, repo_path, logger, branch=None):
major = 0
minor = 0
self.logger = logger
self._defined = False
if shutil.which("git"):
version = run_cmd_no_fail("git --version")
result = re.findall(r"([0-9]+)\.([0-9]+)\.?[0-9]*", version)
major = int(result[0][0])
minor = int(result[0][1])
if major < 2 or (major == 2 and minor < 28):
logger.warning(
"Git not found or git version too old for cesm git interface {} {}".format(
major, minor
)
)
return

logger.debug("Initialize GitInterface for {}".format(repo_path))
self._defined = True
if isinstance(repo_path, str):
self.repo_path = Path(repo_path).resolve()
elif isinstance(repo_path, Path):
self.repo_path = repo_path.resolve()
else:
raise TypeError("repo_path must be a str or Path object")
self.logger = logger
try:
import git

Expand All @@ -28,9 +45,11 @@ def __init__(self, repo_path, logger, branch=None):
if not (self.repo_path / ".git").exists():
self._init_git_repo(branch=branch)
msg = "Using shell interface to git"
self.logger.debug(msg)
logger.debug(msg)

def _git_command(self, operation, *args):
if not self._defined:
return
self.logger.debug(operation)
if self._use_module and operation != "submodule":
try:
Expand All @@ -41,6 +60,8 @@ def _git_command(self, operation, *args):
return ["git", "-C", str(self.repo_path), operation] + list(args)

def _init_git_repo(self, branch=None):
if not self._defined:
return
if self._use_module:
self.repo = self.git.Repo.init(str(self.repo_path))
if branch:
Expand All @@ -53,6 +74,8 @@ def _init_git_repo(self, branch=None):

# pylint: disable=unused-argument
def git_operation(self, operation, *args, **kwargs):
if not self._defined:
return
command = self._git_command(operation, *args)
if isinstance(command, list):
try:
Expand All @@ -63,6 +86,8 @@ def git_operation(self, operation, *args, **kwargs):
return command

def config_get_value(self, section, name):
if not self._defined:
return
if self._use_module:
config = self.repo.config_reader()
try:
Expand All @@ -83,6 +108,8 @@ def config_get_value(self, section, name):
return output.strip()

def config_set_value(self, section, name, value):
if not self._defined:
return
if self._use_module:
with self.repo.config_writer() as writer:
writer.set_value(section, name, value)
Expand Down
18 changes: 10 additions & 8 deletions CIME/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,20 @@ def append_case_status(phase, status, msg=None, caseroot=".", gitinterface=None)
if gitinterface:
filelist = gitinterface.git_operation(
"ls-files", "--deleted", "--exclude-standard"
).splitlines()
)
# First delete files that have been removed
for f in filelist:
logger.debug("removing file {}".format(f))
gitinterface.git_operation("rm", f)
if filelist:
for f in filelist.splitlines():
logger.debug("removing file {}".format(f))
gitinterface.git_operation("rm", f)
filelist = gitinterface.git_operation(
"ls-files", "--others", "--modified", "--exclude-standard"
).splitlines()
)
# Files that should not be added should have been excluded by the .gitignore file
for f in filelist:
logger.debug("adding file {}".format(f))
gitinterface.git_operation("add", f)
if filelist:
for f in filelist.splitlines():
logger.debug("adding file {}".format(f))
gitinterface.git_operation("add", f)
msg = msg if msg else " no message provided"
gitinterface.git_operation("commit", "-m", '"' + msg + '"')
remote = gitinterface.git_operation("remote")
Expand Down

0 comments on commit 9ac3e71

Please sign in to comment.