smart-commit-tool 2.0.2__tar.gz → 2.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smart-commit-tool
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Automated pre-push workflow manager with built-in code quality enforcement and smart branch protection.
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "smart-commit-tool"
7
- version = "2.0.2"
7
+ version = "2.0.3"
8
8
  description = "Automated pre-push workflow manager with built-in code quality enforcement and smart branch protection."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -7,21 +7,32 @@ from ..logger import Console, logger
7
7
  class GitService:
8
8
  @classmethod
9
9
  def _run(cls, cmd: list[str], silent: bool = True) -> subprocess.CompletedProcess:
10
- """Internal helper for executing Git commands."""
10
+ """Internal helper for executing Git commands with combined output."""
11
11
  logger.debug(f"Git CMD: {' '.join(cmd)}")
12
- return subprocess.run(cmd, capture_output=silent, text=True)
12
+ return subprocess.run(cmd, capture_output=True, text=True)
13
13
 
14
14
  @classmethod
15
15
  def ensure_repo(cls):
16
- """Checks for repository initialization and Detached HEAD state."""
17
- if not Path(".git").exists():
16
+ """Checks for repository initialization, Detached HEAD, and ongoing merges/rebases."""
17
+ git_dir = Path(".git")
18
+ if not git_dir.exists():
18
19
  Console.warning("Git not initialized. Initializing now...")
19
20
  cls._run(["git", "init"])
21
+ is_rebase = (git_dir / "rebase-apply").exists() or (
22
+ git_dir / "rebase-merge"
23
+ ).exists()
24
+ is_merge = (git_dir / "MERGE_HEAD").exists()
25
+
26
+ if is_rebase or is_merge:
27
+ raise GitOperationError(
28
+ "🛑 Git is currently in the middle of a REBASE or MERGE.\n"
29
+ "Please resolve conflicts manually or run 'git rebase --abort', then try again."
30
+ )
20
31
 
21
32
  res = cls._run(["git", "branch", "--show-current"])
22
33
  if not res.stdout.strip():
23
34
  raise GitOperationError(
24
- "You are in a DETACHED HEAD state. Process stopped for safety."
35
+ "You are in a DETACHED HEAD state. Please switch to a branch (e.g., 'git checkout main')."
25
36
  )
26
37
 
27
38
  @classmethod
@@ -76,33 +87,41 @@ class GitService:
76
87
 
77
88
  @classmethod
78
89
  def commit(cls, message: str):
79
- """Commits changes and extracts Git output if it fails."""
90
+ """Commits changes. Ignores 'nothing to commit' errors to allow push-only flows."""
80
91
  res = cls._run(["git", "commit", "-m", message])
92
+
81
93
  if res.returncode != 0:
82
- error_msg = res.stderr.strip() or res.stdout.strip()
83
- raise GitOperationError(f"Commit failed. Git says:\n{error_msg}")
94
+ output = (res.stdout + res.stderr).lower()
95
+ if "nothing to commit" in output or "working tree clean" in output:
96
+ return
97
+
98
+ raise GitOperationError(
99
+ f"Commit failed. Git says:\n{res.stderr or res.stdout}"
100
+ )
84
101
 
85
102
  @classmethod
86
103
  def push_with_retry(cls, branch: str):
87
- """Pushes to remote, attempting a pull --rebase if rejected."""
104
+ """Pushes to remote, attempting a pull --rebase if rejected or diverged."""
88
105
  Console.info(f"Pushing to branch: {branch}...")
89
106
  res = cls._run(["git", "push", "-u", "origin", branch])
90
107
 
91
108
  if res.returncode == 0:
92
109
  Console.success(f"Code successfully pushed to origin/{branch}!")
93
110
  return
111
+ Console.warning("Push rejected or branches diverged. Remote changes detected.")
112
+ Console.info("Synchronizing via pull --rebase...")
94
113
 
95
- Console.warning("Push rejected. Remote changes detected.")
96
- Console.info("Synchronizing (pull --rebase)...")
97
114
  pull_res = cls._run(["git", "pull", "origin", branch, "--rebase"])
98
115
 
99
116
  if pull_res.returncode != 0:
100
117
  error_msg = pull_res.stderr.strip() or pull_res.stdout.strip()
118
+ cls._run(["git", "rebase", "--abort"])
101
119
  raise GitOperationError(
102
- f"🛑 Rebase conflict detected!\nGit says: {error_msg}"
120
+ f"🛑 Rebase conflict! Conflicts were detected with remote files.\n"
121
+ f"Sync aborted. Please resolve manually. Git says:\n{error_msg}"
103
122
  )
104
123
 
105
- Console.success("Sync successful. Retrying push...")
124
+ Console.success("Sync successful. Retrying final push...")
106
125
  push_retry = cls._run(["git", "push", "-u", "origin", branch])
107
126
 
108
127
  if push_retry.returncode != 0: