1+ // Package git provides a wrapper around common git commands.
12package git
23
34import (
@@ -6,41 +7,83 @@ import (
67 "unicode"
78)
89
9- // CommitLog represents a single line in the commit history, which could be a
10- // commit or just part of the graph.
10+ // CommitLog represents a single entry in the git log graph.
11+ // It can be a commit or a line representing the graph structure .
1112type CommitLog struct {
12- Graph string
13- SHA string
14- AuthorInitials string
15- Subject string
13+ Graph string // The graph structure string.
14+ SHA string // The abbreviated commit hash.
15+ AuthorInitials string // The initials of the commit author.
16+ Subject string // The subject line of the commit message.
1617}
1718
18- // GetCommitLogsGraph fetches the git log with a graph and returns a slice of CommitLog structs.
19+ // LogOptions specifies the options for the git log command.
20+ type LogOptions struct {
21+ Oneline bool
22+ Graph bool
23+ All bool
24+ MaxCount int
25+ Format string
26+ Color string
27+ }
28+
29+ // GetCommitLogsGraph fetches the git log with a graph format and returns it as a
30+ // slice of CommitLog structs.
1931func (g * GitCommands ) GetCommitLogsGraph () ([]CommitLog , error ) {
20- // We use a custom format with a unique delimiter "<COMMIT>" to reliably parse the output.
32+ // A custom format with a unique delimiter is used to reliably parse the output.
2133 format := "<COMMIT>%h|%an|%s"
2234 options := LogOptions {
2335 Graph : true ,
2436 Format : format ,
2537 Color : "never" ,
38+ All : true ,
2639 }
2740
2841 output , err := g .ShowLog (options )
2942 if err != nil {
3043 return nil , err
3144 }
32-
3345 return parseCommitLogs (strings .TrimSpace (output )), nil
3446}
3547
48+ // ShowLog executes the `git log` command with the given options and returns the raw output.
49+ func (g * GitCommands ) ShowLog (options LogOptions ) (string , error ) {
50+ args := []string {"log" }
51+
52+ if options .Format != "" {
53+ args = append (args , fmt .Sprintf ("--pretty=format:%s" , options .Format ))
54+ } else if options .Oneline {
55+ args = append (args , "--oneline" )
56+ }
57+
58+ if options .Graph {
59+ args = append (args , "--graph" )
60+ }
61+ if options .All {
62+ args = append (args , "--all" )
63+ }
64+ if options .MaxCount > 0 {
65+ args = append (args , fmt .Sprintf ("-%d" , options .MaxCount ))
66+ }
67+ if options .Color != "" {
68+ args = append (args , fmt .Sprintf ("--color=%s" , options .Color ))
69+ }
70+
71+ cmd := ExecCommand ("git" , args ... )
72+ output , err := cmd .CombinedOutput ()
73+ if err != nil {
74+ return string (output ), fmt .Errorf ("failed to get log: %w" , err )
75+ }
76+
77+ return string (output ), nil
78+ }
79+
3680// parseCommitLogs processes the raw git log string into a slice of CommitLog structs.
3781func parseCommitLogs (output string ) []CommitLog {
3882 var logs []CommitLog
3983 lines := strings .Split (output , "\n " )
4084
4185 for _ , line := range lines {
4286 if strings .Contains (line , "<COMMIT>" ) {
43- // This line represents a commit.
4487 parts := strings .SplitN (line , "<COMMIT>" , 2 )
4588 graph := parts [0 ]
4689 commitData := strings .SplitN (parts [1 ], "|" , 3 )
@@ -58,12 +101,10 @@ func parseCommitLogs(output string) []CommitLog {
58101 logs = append (logs , CommitLog {Graph : line })
59102 }
60103 }
61-
62104 return logs
63105}
64106
65- // getInitials extracts the first two letters from a name for display.
66- // It handles single names, multiple names, and empty strings.
107+ // getInitials extracts up to two initials from a name string for concise display.
67108func getInitials (name string ) string {
68109 name = strings .TrimSpace (name )
69110 if len (name ) == 0 {
@@ -72,11 +113,11 @@ func getInitials(name string) string {
72113
73114 parts := strings .Fields (name )
74115 if len (parts ) > 1 {
75- // For "John Doe", return "JD"
116+ // For "John Doe", return "JD".
76117 return strings .ToUpper (string (parts [0 ][0 ]) + string (parts [len (parts )- 1 ][0 ]))
77118 }
78119
79- // For "John", return "JO"
120+ // For a single name like "John", return "JO".
80121 var initials []rune
81122 for _ , r := range name {
82123 if unicode .IsLetter (r ) {
@@ -94,47 +135,5 @@ func getInitials(name string) string {
94135 return string (initials [0 :2 ])
95136 }
96137
97- return "" // Should not happen if name is not empty
98- }
99-
100- // LogOptions specifies the options for the git log command.
101- type LogOptions struct {
102- Oneline bool
103- Graph bool
104- Decorate bool
105- MaxCount int
106- Format string
107- Color string
108- }
109-
110- // ShowLog returns the commit logs.
111- func (g * GitCommands ) ShowLog (options LogOptions ) (string , error ) {
112- args := []string {"log" }
113-
114- if options .Format != "" {
115- args = append (args , fmt .Sprintf ("--pretty=format:%s" , options .Format ))
116- } else if options .Oneline {
117- args = append (args , "--oneline" )
118- }
119-
120- if options .Graph {
121- args = append (args , "--graph" )
122- }
123- if options .Decorate {
124- args = append (args , "--decorate" )
125- }
126- if options .MaxCount > 0 {
127- args = append (args , fmt .Sprintf ("-%d" , options .MaxCount ))
128- }
129- if options .Color != "" {
130- args = append (args , fmt .Sprintf ("--color=%s" , options .Color ))
131- }
132-
133- cmd := ExecCommand ("git" , args ... )
134- output , err := cmd .CombinedOutput ()
135- if err != nil {
136- return string (output ), fmt .Errorf ("failed to get log: %v" , err )
137- }
138-
139- return string (output ), nil
138+ return ""
140139}
0 commit comments