@@ -78,8 +78,13 @@ local function get_detailed_commits(from_ref, to_ref)
7878 local escaped_range = vim .fn .shellescape (range )
7979
8080 -- Get commits with more details
81- local commit_cmd =
82- string.format (" git log --pretty=format:'%%H|%%s|%%b|%%an|%%ae|%%ad' --date=short %s" , escaped_range )
81+ -- Use git log with a separator to handle multi-line bodies correctly
82+ local separator = " ---COMMIT_SEPARATOR---"
83+ local commit_cmd = string.format (
84+ " git log --pretty=format:'%%H||%%s||%%an||%%ae||%%ad||%%b%s' --date=short %s" ,
85+ separator ,
86+ escaped_range
87+ )
8388
8489 local success , output = pcall (vim .fn .system , commit_cmd )
8590 if not success or vim .v .shell_error ~= 0 then
@@ -92,38 +97,83 @@ local function get_detailed_commits(from_ref, to_ref)
9297 end
9398
9499 local commits = {}
95- for line in output :gmatch (" [^\r\n ]+" ) do
96- local parts = vim .split (line , " |" )
97- if # parts >= 6 then
98- local hash = parts [1 ]
99- local subject = parts [2 ]
100- local body = parts [3 ] ~= " " and parts [3 ] or nil
101-
102- -- Get diff stats for this commit (safely handle first commit)
103- local diff_stats = nil
104- local diff_cmd = string.format (" git diff-tree --stat --root %s" , hash )
105- local diff_success , stats_output = pcall (vim .fn .system , diff_cmd )
106- if diff_success and vim .v .shell_error == 0 then
107- diff_stats = stats_output
100+ -- Split by separator to get individual commits
101+ local commit_entries = vim .split (output , separator , { plain = true })
102+
103+ for _ , entry in ipairs (commit_entries ) do
104+ if entry and vim .trim (entry ) ~= " " then
105+ -- Find the first non-empty line with commit info
106+ local lines = vim .split (entry , " \n " )
107+ local commit_line = nil
108+ local body_start_idx = 1
109+
110+ -- Find the line with the commit info (has || separators)
111+ for i , line in ipairs (lines ) do
112+ if line :match (" ||" ) then
113+ commit_line = line
114+ body_start_idx = i + 1
115+ break
116+ end
108117 end
109118
110- -- Parse conventional commit type
111- local commit_type , scope = subject :match (" ^(%w+)%((.-)%):" )
112- if not commit_type then
113- commit_type = subject :match (" ^(%w+):" )
114- end
119+ if commit_line then
120+ local parts = vim .split (commit_line , " ||" , { plain = true })
121+
122+ if # parts >= 5 then
123+ local hash = vim .trim (parts [1 ] or " " )
124+ local subject = vim .trim (parts [2 ] or " " )
125+ local author = vim .trim (parts [3 ] or " " )
126+ local email = vim .trim (parts [4 ] or " " )
127+ local date = vim .trim (parts [5 ] or " " )
128+
129+ -- Handle body (can be in part 6 or in following lines)
130+ local body = nil
131+ local body_lines = {}
132+
133+ -- Check if body is in the 6th part
134+ if # parts > 5 and vim .trim (parts [6 ]) ~= " " then
135+ table.insert (body_lines , vim .trim (parts [6 ]))
136+ end
137+
138+ -- Add any additional lines as body
139+ for i = body_start_idx , # lines do
140+ local line = vim .trim (lines [i ])
141+ if line ~= " " then
142+ table.insert (body_lines , line )
143+ end
144+ end
145+
146+ if # body_lines > 0 then
147+ body = table.concat (body_lines , " \n " )
148+ end
149+
150+ -- Get diff stats for this commit (safely handle first commit)
151+ local diff_stats = nil
152+ local diff_cmd = string.format (" git diff-tree --stat --root %s" , hash )
153+ local diff_success , stats_output = pcall (vim .fn .system , diff_cmd )
154+ if diff_success and vim .v .shell_error == 0 then
155+ diff_stats = stats_output
156+ end
115157
116- table.insert (commits , {
117- hash = hash ,
118- subject = subject ,
119- body = body ,
120- author = parts [4 ],
121- email = parts [5 ],
122- date = parts [6 ],
123- type = commit_type ,
124- scope = scope ,
125- diff_stats = diff_stats ,
126- })
158+ -- Parse conventional commit type
159+ local commit_type , scope = subject :match (" ^(%w+)%((.-)%):" )
160+ if not commit_type then
161+ commit_type = subject :match (" ^(%w+):" )
162+ end
163+
164+ table.insert (commits , {
165+ hash = hash ,
166+ subject = subject ,
167+ body = body ,
168+ author = author ,
169+ email = email ,
170+ date = date ,
171+ type = commit_type ,
172+ scope = scope ,
173+ diff_stats = diff_stats ,
174+ })
175+ end
176+ end
127177 end
128178 end
129179
0 commit comments