kryptorious-gitsweep 1.0.0__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.
- kryptorious_gitsweep-1.0.0/PKG-INFO +17 -0
- kryptorious_gitsweep-1.0.0/pyproject.toml +26 -0
- kryptorious_gitsweep-1.0.0/setup.cfg +4 -0
- kryptorious_gitsweep-1.0.0/src/gitsweep/__init__.py +2 -0
- kryptorious_gitsweep-1.0.0/src/gitsweep/cli.py +67 -0
- kryptorious_gitsweep-1.0.0/src/gitsweep/commands.py +283 -0
- kryptorious_gitsweep-1.0.0/src/kryptorious_gitsweep.egg-info/PKG-INFO +17 -0
- kryptorious_gitsweep-1.0.0/src/kryptorious_gitsweep.egg-info/SOURCES.txt +10 -0
- kryptorious_gitsweep-1.0.0/src/kryptorious_gitsweep.egg-info/dependency_links.txt +1 -0
- kryptorious_gitsweep-1.0.0/src/kryptorious_gitsweep.egg-info/entry_points.txt +2 -0
- kryptorious_gitsweep-1.0.0/src/kryptorious_gitsweep.egg-info/requires.txt +8 -0
- kryptorious_gitsweep-1.0.0/src/kryptorious_gitsweep.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kryptorious-gitsweep
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Git repository cleanup CLI — find stale branches, large files, and bloated history.
|
|
5
|
+
Author: Kryptorious Quantum Biosciences, Inc.
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://devflow.sh
|
|
8
|
+
Project-URL: Repository, https://github.com/kryptorious/gitsweep
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: gitpython>=3.1
|
|
12
|
+
Requires-Dist: rich>=13.0
|
|
13
|
+
Requires-Dist: click>=8.0
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
16
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
17
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "kryptorious-gitsweep"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Git repository cleanup CLI — find stale branches, large files, and bloated history."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [{name = "Kryptorious Quantum Biosciences, Inc."}]
|
|
13
|
+
dependencies = ["gitpython>=3.1", "rich>=13.0", "click>=8.0"]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
dev = ["pytest>=7.0", "black>=23.0", "ruff>=0.1"]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
gitsweep = "gitsweep.cli:main"
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://devflow.sh"
|
|
23
|
+
Repository = "https://github.com/kryptorious/gitsweep"
|
|
24
|
+
|
|
25
|
+
[tool.setuptools.packages.find]
|
|
26
|
+
where = ["src"]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""GitSweep CLI — main entry point."""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
|
|
6
|
+
console = Console()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.group()
|
|
10
|
+
@click.version_option(version="1.0.0", prog_name="gitsweep")
|
|
11
|
+
def main():
|
|
12
|
+
"""GitSweep — Clean up your git repositories.
|
|
13
|
+
|
|
14
|
+
Find stale branches, large files, and bloated history.
|
|
15
|
+
Sweep it clean.
|
|
16
|
+
"""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@main.command()
|
|
21
|
+
@click.option("--repo", "-r", default=".", help="Path to git repository")
|
|
22
|
+
@click.option("--merged/--all", default=True, help="Show only merged branches")
|
|
23
|
+
@click.option("--stale", "-s", default=90, help="Days since last commit to consider stale")
|
|
24
|
+
@click.option("--delete/--dry-run", default=False, help="Delete branches (premium feature)")
|
|
25
|
+
def branches(repo, merged, stale, delete):
|
|
26
|
+
"""Find stale and merged branches."""
|
|
27
|
+
from .commands import sweep_branches
|
|
28
|
+
sweep_branches(repo=repo, merged_only=merged, stale_days=stale, delete=delete)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@main.command()
|
|
32
|
+
@click.option("--repo", "-r", default=".", help="Path to git repository")
|
|
33
|
+
@click.option("--size", "-s", default=1.0, help="Minimum file size in MB")
|
|
34
|
+
@click.option("--count", "-n", default=20, help="Number of largest files to show")
|
|
35
|
+
def large(repo, size, count):
|
|
36
|
+
"""Find large files bloating your repository."""
|
|
37
|
+
from .commands import sweep_large
|
|
38
|
+
sweep_large(repo=repo, min_size_mb=size, top_n=count)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@main.command()
|
|
42
|
+
@click.option("--repo", "-r", default=".", help="Path to git repository")
|
|
43
|
+
@click.option("--days", "-d", default=365, help="Days of history to analyze")
|
|
44
|
+
@click.option("--author", "-a", default=None, help="Filter by author email")
|
|
45
|
+
def history(repo, days, author):
|
|
46
|
+
"""Analyze commit history for bloat and patterns."""
|
|
47
|
+
from .commands import sweep_history
|
|
48
|
+
sweep_history(repo=repo, days=days, author=author)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@main.command()
|
|
52
|
+
@click.option("--repo", "-r", default=".", help="Path to git repository")
|
|
53
|
+
@click.option("--aggressive/--safe", default=False, help="Aggressive cleanup (premium)")
|
|
54
|
+
def clean(repo, aggressive):
|
|
55
|
+
"""Run all sweeps and clean everything (premium)."""
|
|
56
|
+
console.print("[yellow]GitSweep clean is a premium feature.[/yellow]")
|
|
57
|
+
console.print("Upgrade at https://kryptorious.gumroad.com/l/jbvet")
|
|
58
|
+
console.print()
|
|
59
|
+
console.print("Running free sweeps instead...")
|
|
60
|
+
from .commands import sweep_branches, sweep_large, sweep_history
|
|
61
|
+
sweep_branches(repo=repo, merged_only=True, stale_days=90, delete=False)
|
|
62
|
+
sweep_large(repo=repo, min_size_mb=1, top_n=10)
|
|
63
|
+
sweep_history(repo=repo, days=90, author=None)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
main()
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
"""GitSweep commands."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
from datetime import datetime, timedelta, timezone
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import git
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.panel import Panel
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
from rich.text import Text
|
|
13
|
+
|
|
14
|
+
console = Console()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _get_repo(repo_path: str) -> git.Repo:
|
|
18
|
+
"""Get git repo object, searching upward if needed."""
|
|
19
|
+
path = Path(repo_path).resolve()
|
|
20
|
+
try:
|
|
21
|
+
return git.Repo(path, search_parent_directories=True)
|
|
22
|
+
except git.InvalidGitRepositoryError:
|
|
23
|
+
console.print(f"[red]Error:[/red] Not a git repository: {path}")
|
|
24
|
+
raise SystemExit(1)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def sweep_branches(repo: str = ".", merged_only: bool = True,
|
|
28
|
+
stale_days: int = 90, delete: bool = False):
|
|
29
|
+
"""Find stale and merged branches."""
|
|
30
|
+
r = _get_repo(repo)
|
|
31
|
+
console.print()
|
|
32
|
+
console.print(Panel(f"[bold]GitSweep — Branches[/bold] in [cyan]{Path(r.working_dir).name}[/cyan]",
|
|
33
|
+
border_style="blue"))
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
main_branch = r.active_branch.name
|
|
37
|
+
except (TypeError, ValueError):
|
|
38
|
+
# Detached HEAD — try to find main
|
|
39
|
+
for candidate in ["main", "master"]:
|
|
40
|
+
if candidate in r.heads:
|
|
41
|
+
main_branch = candidate
|
|
42
|
+
break
|
|
43
|
+
else:
|
|
44
|
+
main_branch = list(r.heads)[0].name if r.heads else "main"
|
|
45
|
+
|
|
46
|
+
console.print(f"Main branch: [bold]{main_branch}[/bold]")
|
|
47
|
+
|
|
48
|
+
stale_date = datetime.now(timezone.utc) - timedelta(days=stale_days)
|
|
49
|
+
candidates = []
|
|
50
|
+
|
|
51
|
+
for branch in r.heads:
|
|
52
|
+
if branch.name == main_branch:
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
commit = branch.commit
|
|
56
|
+
commit_date = commit.committed_datetime
|
|
57
|
+
|
|
58
|
+
# Check if merged
|
|
59
|
+
is_merged = False
|
|
60
|
+
try:
|
|
61
|
+
r.git.merge_base("--is-ancestor", branch.name, main_branch)
|
|
62
|
+
is_merged = True
|
|
63
|
+
except git.GitCommandError:
|
|
64
|
+
is_merged = False
|
|
65
|
+
|
|
66
|
+
# Check if stale
|
|
67
|
+
is_stale = commit_date.replace(tzinfo=timezone.utc) < stale_date
|
|
68
|
+
|
|
69
|
+
if merged_only and not is_merged:
|
|
70
|
+
continue
|
|
71
|
+
|
|
72
|
+
candidates.append({
|
|
73
|
+
"name": branch.name,
|
|
74
|
+
"last_commit": commit_date.strftime("%Y-%m-%d"),
|
|
75
|
+
"author": commit.author.name,
|
|
76
|
+
"message": commit.message.split("\n")[0][:60],
|
|
77
|
+
"merged": is_merged,
|
|
78
|
+
"stale": is_stale,
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
# Sort: merged first, then by date
|
|
82
|
+
candidates.sort(key=lambda b: (not b["merged"], b["last_commit"]))
|
|
83
|
+
|
|
84
|
+
if not candidates:
|
|
85
|
+
console.print("[green]No stale or merged branches found. Repo is clean![/green]")
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
table = Table(title=f"Found {len(candidates)} branches to sweep")
|
|
89
|
+
table.add_column("Branch", style="cyan")
|
|
90
|
+
table.add_column("Last Commit", style="dim")
|
|
91
|
+
table.add_column("Author")
|
|
92
|
+
table.add_column("Status")
|
|
93
|
+
table.add_column("Message")
|
|
94
|
+
|
|
95
|
+
for b in candidates:
|
|
96
|
+
status = []
|
|
97
|
+
if b["merged"]:
|
|
98
|
+
status.append("[green]merged[/green]")
|
|
99
|
+
if b["stale"]:
|
|
100
|
+
status.append("[yellow]stale[/yellow]")
|
|
101
|
+
table.add_row(
|
|
102
|
+
b["name"],
|
|
103
|
+
b["last_commit"],
|
|
104
|
+
b["author"],
|
|
105
|
+
" ".join(status),
|
|
106
|
+
b["message"][:50]
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
console.print(table)
|
|
110
|
+
console.print()
|
|
111
|
+
|
|
112
|
+
if delete:
|
|
113
|
+
console.print("[red]Branch deletion is a premium feature.[/red]")
|
|
114
|
+
console.print("Upgrade at https://kryptorious.gumroad.com/l/jbvet")
|
|
115
|
+
else:
|
|
116
|
+
console.print("[yellow]Run with --delete to remove these branches (premium feature)[/yellow]")
|
|
117
|
+
console.print("Free version: copy these commands to delete manually:")
|
|
118
|
+
console.print()
|
|
119
|
+
for b in candidates:
|
|
120
|
+
console.print(f" git branch -d {b['name']}")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def sweep_large(repo: str = ".", min_size_mb: float = 1.0, top_n: int = 20):
|
|
124
|
+
"""Find large files in git history."""
|
|
125
|
+
r = _get_repo(repo)
|
|
126
|
+
console.print()
|
|
127
|
+
console.print(Panel(f"[bold]GitSweep — Large Files[/bold] in [cyan]{Path(r.working_dir).name}[/cyan]",
|
|
128
|
+
border_style="blue"))
|
|
129
|
+
|
|
130
|
+
# Use git rev-list to find large objects
|
|
131
|
+
try:
|
|
132
|
+
# Find large files in HEAD
|
|
133
|
+
result = r.git.rev_list("--objects", "--all")
|
|
134
|
+
objects = {}
|
|
135
|
+
for line in result.split("\n"):
|
|
136
|
+
parts = line.split()
|
|
137
|
+
if len(parts) >= 2:
|
|
138
|
+
try:
|
|
139
|
+
size = r.git.cat_file("-s", parts[0])
|
|
140
|
+
size_bytes = int(size.strip())
|
|
141
|
+
if size_bytes >= min_size_mb * 1024 * 1024:
|
|
142
|
+
objects[parts[1] if len(parts) > 1 else parts[0]] = size_bytes
|
|
143
|
+
except (git.GitCommandError, ValueError):
|
|
144
|
+
pass
|
|
145
|
+
except git.GitCommandError:
|
|
146
|
+
console.print("[yellow]Could not analyze git objects. Trying alternative method...[/yellow]")
|
|
147
|
+
objects = {}
|
|
148
|
+
|
|
149
|
+
# Also find large tracked files in working tree
|
|
150
|
+
for root, dirs, files in os.walk(r.working_dir):
|
|
151
|
+
if ".git" in root:
|
|
152
|
+
continue
|
|
153
|
+
for f in files:
|
|
154
|
+
fp = os.path.join(root, f)
|
|
155
|
+
try:
|
|
156
|
+
size = os.path.getsize(fp)
|
|
157
|
+
if size >= min_size_mb * 1024 * 1024:
|
|
158
|
+
rel_path = os.path.relpath(fp, r.working_dir)
|
|
159
|
+
objects[rel_path] = size
|
|
160
|
+
except OSError:
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
if not objects:
|
|
164
|
+
console.print(f"[green]No files larger than {min_size_mb}MB found![/green]")
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
# Sort by size descending
|
|
168
|
+
sorted_files = sorted(objects.items(), key=lambda x: x[1], reverse=True)[:top_n]
|
|
169
|
+
|
|
170
|
+
table = Table(title=f"Largest Files (>{min_size_mb}MB)")
|
|
171
|
+
table.add_column("File", style="cyan")
|
|
172
|
+
table.add_column("Size", justify="right")
|
|
173
|
+
|
|
174
|
+
for path, size_bytes in sorted_files:
|
|
175
|
+
if size_bytes >= 1024 * 1024:
|
|
176
|
+
size_str = f"{size_bytes / (1024 * 1024):.1f} MB"
|
|
177
|
+
else:
|
|
178
|
+
size_str = f"{size_bytes / 1024:.1f} KB"
|
|
179
|
+
table.add_row(path, size_str)
|
|
180
|
+
|
|
181
|
+
console.print(table)
|
|
182
|
+
|
|
183
|
+
total_size = sum(s for _, s in sorted_files)
|
|
184
|
+
console.print(f"\nTotal: [bold]{total_size / (1024 * 1024):.1f} MB[/bold] in {len(sorted_files)} files")
|
|
185
|
+
|
|
186
|
+
# Show git-filter-repo command for cleanup
|
|
187
|
+
console.print()
|
|
188
|
+
console.print("[yellow]To clean large files from history (premium feature):[/yellow]")
|
|
189
|
+
console.print("Upgrade at https://kryptorious.gumroad.com/l/jbvet")
|
|
190
|
+
console.print()
|
|
191
|
+
console.print("Free tip: Use [bold]git-filter-repo[/bold] or [bold]BFG Repo-Cleaner[/bold]")
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def sweep_history(repo: str = ".", days: int = 365, author: str = None):
|
|
195
|
+
"""Analyze commit history."""
|
|
196
|
+
r = _get_repo(repo)
|
|
197
|
+
console.print()
|
|
198
|
+
console.print(Panel(f"[bold]GitSweep — History[/bold] in [cyan]{Path(r.working_dir).name}[/cyan]",
|
|
199
|
+
border_style="blue"))
|
|
200
|
+
|
|
201
|
+
since = datetime.now(timezone.utc) - timedelta(days=days)
|
|
202
|
+
|
|
203
|
+
# Collect stats
|
|
204
|
+
try:
|
|
205
|
+
commits = list(r.iter_commits(since=since.isoformat()))
|
|
206
|
+
except (ValueError, git.GitCommandError):
|
|
207
|
+
console.print("No commits found in this repository.")
|
|
208
|
+
return
|
|
209
|
+
if author:
|
|
210
|
+
commits = [c for c in commits if c.author.email == author]
|
|
211
|
+
|
|
212
|
+
if not commits:
|
|
213
|
+
console.print(f"No commits in the last {days} days.")
|
|
214
|
+
return
|
|
215
|
+
|
|
216
|
+
# Author stats
|
|
217
|
+
author_stats = {}
|
|
218
|
+
for c in commits:
|
|
219
|
+
email = c.author.email
|
|
220
|
+
if email not in author_stats:
|
|
221
|
+
author_stats[email] = {"name": c.author.name, "commits": 0, "insertions": 0, "deletions": 0}
|
|
222
|
+
author_stats[email]["commits"] += 1
|
|
223
|
+
try:
|
|
224
|
+
stats = c.stats
|
|
225
|
+
author_stats[email]["insertions"] += stats.total.get("insertions", 0)
|
|
226
|
+
author_stats[email]["deletions"] += stats.total.get("deletions", 0)
|
|
227
|
+
except Exception:
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
console.print(f"[bold]Last {days} days:[/bold] {len(commits)} commits by {len(author_stats)} authors")
|
|
231
|
+
console.print()
|
|
232
|
+
|
|
233
|
+
table = Table(title="Author Breakdown")
|
|
234
|
+
table.add_column("Author")
|
|
235
|
+
table.add_column("Commits", justify="right")
|
|
236
|
+
table.add_column("Insertions", justify="right")
|
|
237
|
+
table.add_column("Deletions", justify="right")
|
|
238
|
+
table.add_column("Net", justify="right")
|
|
239
|
+
|
|
240
|
+
for email, stats in sorted(author_stats.items(), key=lambda x: x[1]["commits"], reverse=True):
|
|
241
|
+
net = stats["insertions"] - stats["deletions"]
|
|
242
|
+
net_style = f"[green]+{net:,}[/green]" if net >= 0 else f"[red]{net:,}[/red]"
|
|
243
|
+
table.add_row(
|
|
244
|
+
stats["name"],
|
|
245
|
+
str(stats["commits"]),
|
|
246
|
+
f"[green]{stats['insertions']:,}[/green]",
|
|
247
|
+
f"[red]{stats['deletions']:,}[/red]",
|
|
248
|
+
net_style
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
console.print(table)
|
|
252
|
+
|
|
253
|
+
# Weekday patterns
|
|
254
|
+
weekday_counts = {i: 0 for i in range(7)}
|
|
255
|
+
for c in commits:
|
|
256
|
+
weekday_counts[c.committed_datetime.weekday()] += 1
|
|
257
|
+
|
|
258
|
+
days_names = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
|
259
|
+
console.print()
|
|
260
|
+
console.print("[bold]Commit activity by day:[/bold]")
|
|
261
|
+
max_count = max(weekday_counts.values()) if weekday_counts else 1
|
|
262
|
+
for i in range(7):
|
|
263
|
+
bar_len = int(weekday_counts[i] / max_count * 30) if max_count > 0 else 0
|
|
264
|
+
bar = "█" * bar_len
|
|
265
|
+
console.print(f" {days_names[i]}: {bar} {weekday_counts[i]}")
|
|
266
|
+
|
|
267
|
+
# File churn
|
|
268
|
+
file_changes = {}
|
|
269
|
+
for c in commits:
|
|
270
|
+
try:
|
|
271
|
+
for fpath, change in c.stats.files.items():
|
|
272
|
+
if fpath not in file_changes:
|
|
273
|
+
file_changes[fpath] = 0
|
|
274
|
+
file_changes[fpath] += change.get("lines", 0) or (change.get("insertions", 0) + change.get("deletions", 0))
|
|
275
|
+
except Exception:
|
|
276
|
+
pass
|
|
277
|
+
|
|
278
|
+
if file_changes:
|
|
279
|
+
top_files = sorted(file_changes.items(), key=lambda x: x[1], reverse=True)[:10]
|
|
280
|
+
console.print()
|
|
281
|
+
console.print("[bold]Most changed files:[/bold]")
|
|
282
|
+
for fpath, changes in top_files:
|
|
283
|
+
console.print(f" {changes:>6,} {fpath}")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kryptorious-gitsweep
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Git repository cleanup CLI — find stale branches, large files, and bloated history.
|
|
5
|
+
Author: Kryptorious Quantum Biosciences, Inc.
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://devflow.sh
|
|
8
|
+
Project-URL: Repository, https://github.com/kryptorious/gitsweep
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: gitpython>=3.1
|
|
12
|
+
Requires-Dist: rich>=13.0
|
|
13
|
+
Requires-Dist: click>=8.0
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
16
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
17
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
src/gitsweep/__init__.py
|
|
3
|
+
src/gitsweep/cli.py
|
|
4
|
+
src/gitsweep/commands.py
|
|
5
|
+
src/kryptorious_gitsweep.egg-info/PKG-INFO
|
|
6
|
+
src/kryptorious_gitsweep.egg-info/SOURCES.txt
|
|
7
|
+
src/kryptorious_gitsweep.egg-info/dependency_links.txt
|
|
8
|
+
src/kryptorious_gitsweep.egg-info/entry_points.txt
|
|
9
|
+
src/kryptorious_gitsweep.egg-info/requires.txt
|
|
10
|
+
src/kryptorious_gitsweep.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gitsweep
|