gitdirector 1.2.0__tar.gz → 1.2.2__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.
- {gitdirector-1.2.0 → gitdirector-1.2.2}/PKG-INFO +1 -1
- {gitdirector-1.2.0 → gitdirector-1.2.2}/pyproject.toml +1 -1
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/manager.py +2 -2
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/repo.py +65 -40
- {gitdirector-1.2.0 → gitdirector-1.2.2}/README.md +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/__init__.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/cli.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/__init__.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/autoclean.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/cd.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/help.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/link.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/listt.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/pull.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/status.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/tui/__init__.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/tui/app.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/tui/constants.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/tui/screens.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/commands/unlink.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/config.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/integrations/__init__.py +0 -0
- {gitdirector-1.2.0 → gitdirector-1.2.2}/src/gitdirector/integrations/tmux.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: gitdirector
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: A terminal based control plane for developers working across multiple repositories. Launch multiple AI coding agents, multiple tmux sessions and track changes across all your repos in one place.
|
|
5
5
|
Keywords: git,repository,manager,cli,synchronization,batch
|
|
6
6
|
Author: Anito Anto
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gitdirector"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.2"
|
|
8
8
|
description = "A terminal based control plane for developers working across multiple repositories. Launch multiple AI coding agents, multiple tmux sessions and track changes across all your repos in one place."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -131,11 +131,11 @@ class RepositoryManager:
|
|
|
131
131
|
except Exception as e:
|
|
132
132
|
return False, f"Error removing repositories: {str(e)}", []
|
|
133
133
|
|
|
134
|
-
def get_repository_status(self, path: Path) -> RepositoryInfo:
|
|
134
|
+
def get_repository_status(self, path: Path, *, fetch: bool = False) -> RepositoryInfo:
|
|
135
135
|
if path.exists() and (path / ".git").is_dir():
|
|
136
136
|
try:
|
|
137
137
|
repo = Repository(path)
|
|
138
|
-
return repo.get_status()
|
|
138
|
+
return repo.get_status(fetch=fetch)
|
|
139
139
|
except Exception as e:
|
|
140
140
|
return RepositoryInfo(path, path.name, RepoStatus.UNKNOWN, None, str(e))
|
|
141
141
|
return RepositoryInfo(
|
|
@@ -125,54 +125,79 @@ class Repository:
|
|
|
125
125
|
pass
|
|
126
126
|
return total
|
|
127
127
|
|
|
128
|
-
def get_status(self) -> RepositoryInfo:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
code,
|
|
136
|
-
|
|
128
|
+
def get_status(self, *, fetch: bool = False) -> RepositoryInfo:
|
|
129
|
+
if fetch:
|
|
130
|
+
code, _, err = self._run_git("fetch")
|
|
131
|
+
if code != 0:
|
|
132
|
+
branch = self.get_current_branch()
|
|
133
|
+
return RepositoryInfo(self.path, self.name, RepoStatus.UNKNOWN, branch, err)
|
|
134
|
+
|
|
135
|
+
code, out, _ = self._run_git("status", "--porcelain=v2", "--branch", _strip=False)
|
|
137
136
|
if code != 0:
|
|
138
137
|
return RepositoryInfo(
|
|
139
|
-
self.path, self.name, RepoStatus.UNKNOWN,
|
|
138
|
+
self.path, self.name, RepoStatus.UNKNOWN, None, "git status failed"
|
|
140
139
|
)
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
msg = f"ahead {ahead}, behind {behind}"
|
|
147
|
-
elif ahead > 0:
|
|
148
|
-
status = RepoStatus.AHEAD
|
|
149
|
-
msg = f"ahead {ahead}"
|
|
150
|
-
elif behind > 0:
|
|
151
|
-
status = RepoStatus.BEHIND
|
|
152
|
-
msg = f"behind {behind}"
|
|
153
|
-
else:
|
|
154
|
-
status = RepoStatus.UP_TO_DATE
|
|
155
|
-
msg = ""
|
|
156
|
-
except ValueError:
|
|
157
|
-
status = RepoStatus.UNKNOWN
|
|
158
|
-
msg = "Could not parse git status"
|
|
159
|
-
|
|
160
|
-
code, porcelain, _ = self._run_git("status", "--porcelain", _strip=False)
|
|
141
|
+
branch = None
|
|
142
|
+
has_upstream = False
|
|
143
|
+
ahead = 0
|
|
144
|
+
behind = 0
|
|
161
145
|
staged = False
|
|
162
146
|
unstaged = False
|
|
163
147
|
staged_files: list[str] = []
|
|
164
148
|
unstaged_files: list[str] = []
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
149
|
+
|
|
150
|
+
for line in out.splitlines():
|
|
151
|
+
if line.startswith("# branch.head "):
|
|
152
|
+
branch = line[14:]
|
|
153
|
+
if branch == "(detached)":
|
|
154
|
+
branch = None
|
|
155
|
+
elif line.startswith("# branch.ab "):
|
|
156
|
+
has_upstream = True
|
|
157
|
+
parts = line.split()
|
|
158
|
+
try:
|
|
159
|
+
ahead = int(parts[2].lstrip("+"))
|
|
160
|
+
behind = abs(int(parts[3]))
|
|
161
|
+
except (IndexError, ValueError):
|
|
162
|
+
pass
|
|
163
|
+
elif line.startswith("1 ") or line.startswith("2 "):
|
|
164
|
+
xy = line[2:4]
|
|
165
|
+
x, y = xy[0], xy[1]
|
|
166
|
+
if line.startswith("1 "):
|
|
167
|
+
parts = line.split(" ", 8)
|
|
168
|
+
filename = parts[8] if len(parts) > 8 else ""
|
|
169
|
+
else:
|
|
170
|
+
parts = line.split(" ", 9)
|
|
171
|
+
filename = parts[9].split("\t")[0] if len(parts) > 9 else ""
|
|
172
|
+
if x not in (".", "?"):
|
|
173
|
+
staged = True
|
|
174
|
+
staged_files.append(filename)
|
|
175
|
+
if y not in (".", "?"):
|
|
176
|
+
unstaged = True
|
|
177
|
+
unstaged_files.append(filename)
|
|
178
|
+
elif line.startswith("u "):
|
|
179
|
+
parts = line.split(" ", 10)
|
|
180
|
+
filename = parts[10] if len(parts) > 10 else ""
|
|
181
|
+
staged = True
|
|
182
|
+
unstaged = True
|
|
183
|
+
staged_files.append(filename)
|
|
184
|
+
unstaged_files.append(filename)
|
|
185
|
+
|
|
186
|
+
if not has_upstream:
|
|
187
|
+
status = RepoStatus.UNKNOWN
|
|
188
|
+
msg = "No tracking branch"
|
|
189
|
+
elif ahead > 0 and behind > 0:
|
|
190
|
+
status = RepoStatus.DIVERGED
|
|
191
|
+
msg = f"ahead {ahead}, behind {behind}"
|
|
192
|
+
elif ahead > 0:
|
|
193
|
+
status = RepoStatus.AHEAD
|
|
194
|
+
msg = f"ahead {ahead}"
|
|
195
|
+
elif behind > 0:
|
|
196
|
+
status = RepoStatus.BEHIND
|
|
197
|
+
msg = f"behind {behind}"
|
|
198
|
+
else:
|
|
199
|
+
status = RepoStatus.UP_TO_DATE
|
|
200
|
+
msg = ""
|
|
176
201
|
|
|
177
202
|
last_updated, last_commit_ts = self.get_last_commit_info()
|
|
178
203
|
size = self.get_tracked_size()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|