Skip to content

Commit 69361c8

Browse files
Merge pull request #115 from Undertone0809/v1.4.0/add-git-info
feat: add 'git info' command to display repository details
2 parents 1b93b94 + 24393b6 commit 69361c8

File tree

5 files changed

+302
-3
lines changed

5 files changed

+302
-3
lines changed

docs/guide/commands.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Show the help message with a list of available GCOP commands.
3232

3333
Open the GCOP configuration file in the default editor.
3434

35+
### `git info`
36+
37+
Display basic information about the current git repository.
38+
3539
## Usage Examples
3640

3741
1. Generate and apply an AI commit message:
@@ -54,4 +58,30 @@ Open the GCOP configuration file in the default editor.
5458
git p
5559
```
5660

57-
For more detailed information on each command, refer to the [Quick Start](/guide/quick-start.md) section in the guide.
61+
5. View repository information:
62+
```
63+
git info
64+
```
65+
This command provides a summary of your repository, including:
66+
67+
- Project name
68+
- Current branch
69+
- Latest commit
70+
- Number of uncommitted changes
71+
- Remote URL
72+
- Total number of commits
73+
- Number of contributors
74+
- Repository creation time
75+
- Last modified time
76+
- Repository size
77+
- Most active contributor
78+
- Most changed file
79+
- Line count by language (if cloc is installed)
80+
- Latest tag
81+
- Branch count
82+
- Untracked files count
83+
- Submodule information
84+
- Latest merge commit
85+
- File type statistics
86+
87+
For more detailed information on each command, refer to the [Quick Start](/guide/quick-start.md) section in the guide.

docs/guide/quick-start.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,44 @@ These changes improve the clarity and accuracy of the documentation, ensuring th
100100
3 files changed, 5 insertions(+), 2 deletions(-)
101101
```
102102

103+
### Viewing Repository Information
104+
105+
To get a detailed overview of your repository, use:
106+
107+
```
108+
git info
109+
```
110+
111+
This command now displays comprehensive information about your repository, including:
112+
113+
- Project name
114+
- Current branch
115+
- Latest commit
116+
- Number of uncommitted changes
117+
- Remote URL
118+
- Total number of commits
119+
- Number of contributors
120+
- Repository creation time
121+
- Last modified time
122+
- Repository size
123+
- Most active contributor
124+
- Most changed file
125+
- Line count by language (if cloc is installed)
126+
- Latest tag
127+
- Branch count
128+
- Untracked files count
129+
- Submodule information
130+
- Latest merge commit
131+
- File type statistics
132+
133+
This detailed information provides a thorough understanding of your project's state, history, and composition. It's particularly useful for quickly assessing the repository's overall structure and recent activities.
134+
135+
For example:
136+
137+
![repository information](../images/git-info.png)
138+
139+
> Note: Some features like line count by language require additional tools (e.g., cloc) to be installed.
140+
103141
### Other Useful Commands
104142

105143
- `git ac`: Add all changes and commit with an AI-generated message

docs/images/git-info.png

100 KB
Loading

gcop/__main__.py

Lines changed: 232 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ def init_command():
210210
check=True,
211211
encoding="utf-8", # noqa
212212
)
213+
subprocess.run(
214+
["git", "config", "--global", "alias.info", "!gcop info"],
215+
check=True,
216+
encoding="utf-8", # noqa
217+
)
213218
subprocess.run(
214219
["git", "config", "--global", "alias.gconfig", "!gcop config"],
215220
check=True,
@@ -228,6 +233,231 @@ def init_command():
228233
print(f"Error adding git aliases: {error}")
229234

230235

236+
@app.command(name="info")
237+
def info_command():
238+
"""Display detailed information about the current git repository."""
239+
try:
240+
# Get project name (usually the directory name)
241+
project_name = os.path.basename(os.getcwd())
242+
243+
# Get current branch
244+
current_branch = subprocess.check_output(
245+
["git", "rev-parse", "--abbrev-ref", "HEAD"], text=True
246+
).strip()
247+
248+
# Get latest commit info
249+
latest_commit = subprocess.check_output(
250+
["git", "log", "-1", "--oneline"], text=True
251+
).strip()
252+
253+
# Get number of uncommitted changes
254+
uncommitted_changes = len(
255+
subprocess.check_output(
256+
["git", "status", "--porcelain"], text=True
257+
).splitlines()
258+
)
259+
260+
# Get remote URL
261+
remote_url = subprocess.check_output(
262+
["git", "config", "--get", "remote.origin.url"], text=True
263+
).strip()
264+
265+
# Get total number of commits
266+
total_commits = subprocess.check_output(
267+
["git", "rev-list", "--count", "HEAD"], text=True
268+
).strip()
269+
270+
# Get number of contributors
271+
contributors = len(
272+
set(
273+
subprocess.check_output(
274+
["git", "log", "--format='%ae'"], text=True
275+
).splitlines()
276+
)
277+
)
278+
279+
# Get repository creation time
280+
creation_time = subprocess.check_output(
281+
[
282+
"git",
283+
"log",
284+
"--reverse",
285+
"--date=iso",
286+
"--format=%ad",
287+
"|",
288+
"head",
289+
"-1",
290+
],
291+
text=True,
292+
shell=True,
293+
).strip()
294+
295+
# Get last modified time
296+
last_modified = subprocess.check_output(
297+
["git", "log", "-1", "--date=iso", "--format=%ad"], text=True
298+
).strip()
299+
300+
# Get repository size
301+
repo_size = (
302+
subprocess.check_output(["git", "count-objects", "-vH"], text=True)
303+
.split("\n")[2]
304+
.split(":")[1]
305+
.strip()
306+
)
307+
308+
# Get most active contributor
309+
most_active = (
310+
subprocess.check_output(
311+
["git", "shortlog", "-sn", "--no-merges", "|", "head", "-n", "1"],
312+
text=True,
313+
shell=True,
314+
)
315+
.strip()
316+
.split("\t")[1]
317+
)
318+
319+
# Get most changed file
320+
most_changed = (
321+
subprocess.check_output(
322+
[
323+
"git",
324+
"log",
325+
"--pretty=format:",
326+
"--name-only",
327+
"|",
328+
"sort",
329+
"|",
330+
"uniq",
331+
"-c",
332+
"|",
333+
"sort",
334+
"-rg",
335+
"|",
336+
"head",
337+
"-n",
338+
"1",
339+
],
340+
text=True,
341+
shell=True,
342+
)
343+
.strip()
344+
.split()[-1]
345+
)
346+
347+
# Get line count by language (requires cloc to be installed)
348+
try:
349+
line_count = subprocess.check_output(
350+
["cloc", ".", "--quiet", "--json"], text=True
351+
)
352+
# Parse JSON output and format it
353+
import json
354+
355+
line_count_data = json.loads(line_count)
356+
formatted_line_count = "\n".join(
357+
[
358+
f"{lang}: {data['code']} lines"
359+
for lang, data in line_count_data.items()
360+
if lang != "header" and lang != "SUM"
361+
]
362+
)
363+
line_count = formatted_line_count
364+
except FileNotFoundError:
365+
line_count = (
366+
"cloc not found. Please ensure it's installed and in your system PATH."
367+
)
368+
except json.JSONDecodeError:
369+
line_count = (
370+
"Error parsing cloc output. Please check if cloc is working correctly."
371+
)
372+
except subprocess.CalledProcessError:
373+
line_count = "Error running cloc. Please check if it's installed correctly."
374+
375+
# Get latest tag
376+
try:
377+
latest_tag = subprocess.check_output(
378+
["git", "describe", "--tags", "--abbrev=0"], text=True
379+
).strip()
380+
except subprocess.CalledProcessError:
381+
latest_tag = "No tags found"
382+
383+
# Get branch count
384+
branch_count = len(
385+
subprocess.check_output(["git", "branch", "-a"], text=True).splitlines()
386+
)
387+
388+
# Get untracked files count
389+
untracked_count = len(
390+
subprocess.check_output(
391+
["git", "ls-files", "--others", "--exclude-standard"], text=True
392+
).splitlines()
393+
)
394+
395+
# Get submodule info
396+
try:
397+
submodules = subprocess.check_output(
398+
["git", "submodule", "status"], text=True
399+
).strip()
400+
if not submodules:
401+
submodules = "No submodules"
402+
except subprocess.CalledProcessError:
403+
submodules = "No submodules"
404+
405+
# Get latest merge commit
406+
try:
407+
latest_merge = subprocess.check_output(
408+
["git", "log", "--merges", "-n", "1", "--pretty=format:%h - %s"],
409+
text=True,
410+
).strip()
411+
if not latest_merge:
412+
latest_merge = "No merge commits found"
413+
except subprocess.CalledProcessError:
414+
latest_merge = "No merge commits found"
415+
416+
# Get file type statistics
417+
file_types = subprocess.check_output(
418+
[
419+
"git",
420+
"ls-files",
421+
"|",
422+
"sed",
423+
"s/.*\\.//",
424+
"|",
425+
"sort",
426+
"|",
427+
"uniq",
428+
"-c",
429+
"|",
430+
"sort",
431+
"-rn",
432+
],
433+
text=True,
434+
shell=True,
435+
).strip()
436+
437+
console.print(f"[bold]Project Name:[/] {project_name}")
438+
console.print(f"[bold]Current Branch:[/] {current_branch}")
439+
console.print(f"[bold]Latest Commit:[/] {latest_commit}")
440+
console.print(f"[bold]Uncommitted Changes:[/] {uncommitted_changes}")
441+
console.print(f"[bold]Remote URL:[/] {remote_url}")
442+
console.print(f"[bold]Total Commits:[/] {total_commits}")
443+
console.print(f"[bold]Contributors:[/] {contributors}")
444+
console.print(f"[bold]Repository Created:[/] {creation_time}")
445+
console.print(f"[bold]Last Modified:[/] {last_modified}")
446+
console.print(f"[bold]Repository Size:[/] {repo_size}")
447+
console.print(f"[bold]Most Active Contributor:[/] {most_active}")
448+
console.print(f"[bold]Most Changed File:[/] {most_changed}")
449+
console.print(f"[bold]Line Count by Language:[/]\n{line_count}")
450+
console.print(f"[bold]Latest Tag:[/] {latest_tag}")
451+
console.print(f"[bold]Branch Count:[/] {branch_count}")
452+
console.print(f"[bold]Untracked Files:[/] {untracked_count}")
453+
console.print(f"[bold]Submodules:[/]{submodules}")
454+
console.print(f"[bold]Latest Merge Commit:[/] {latest_merge}")
455+
console.print(f"[bold]File Type Statistics:[/]\n{file_types}")
456+
457+
except subprocess.CalledProcessError as e:
458+
console.print(f"[red]Error getting repository information: {e}[/]")
459+
460+
231461
@app.command(name="commit")
232462
def commit_command(feedback: Optional[str] = None):
233463
"""Generate a git commit message based on the staged changes and commit the
@@ -296,8 +526,9 @@ def help_command():
296526
git ghelp Add command into git config
297527
git gconfig Open the config file in the default editor
298528
git gcommit Generate a git commit message based on the staged changes and commit the changes
299-
git ac The same as `git add . && git gcommit` command
300529
git c The same as `git gcommit` command
530+
git ac The same as `git add . && git gcommit` command
531+
git info Display basic information about the current git repository
301532
""" # noqa
302533

303534
console.print(help_message)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ requires = ["poetry-core"]
55

66
[tool.poetry]
77
name = "gcop"
8-
version = "1.3.2"
8+
version = "1.4.0"
99
description = "gcop is your git AI copilot."
1010
readme = "README.md"
1111
authors = ["gcop <zeeland4work@gmail.com>"]

0 commit comments

Comments
 (0)