Skip to content

Commit 0fe1094

Browse files
committed
feat: Implement getCommitHistory method to retrieve commit history from GitLab
1 parent 1910526 commit 0fe1094

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

  • java-ecosystem/libs/vcs-client/src/main/java/org/rostilos/codecrow/vcsclient/gitlab

java-ecosystem/libs/vcs-client/src/main/java/org/rostilos/codecrow/vcsclient/gitlab/GitLabClient.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import java.net.URLEncoder;
1515
import java.nio.charset.StandardCharsets;
1616
import java.nio.file.Path;
17+
import java.time.OffsetDateTime;
18+
import java.time.format.DateTimeFormatter;
1719
import java.util.ArrayList;
1820
import java.util.List;
1921

@@ -498,6 +500,78 @@ public String getLatestCommitHash(String workspaceId, String repoIdOrSlug, Strin
498500
}
499501
}
500502

503+
@Override
504+
public List<VcsCommit> getCommitHistory(String workspaceId, String repoIdOrSlug, String branchOrCommit, int limit) throws IOException {
505+
String projectPath = workspaceId + "/" + repoIdOrSlug;
506+
String encodedPath = URLEncoder.encode(projectPath, StandardCharsets.UTF_8);
507+
String encodedRef = URLEncoder.encode(branchOrCommit, StandardCharsets.UTF_8);
508+
int perPage = Math.min(limit, 100); // GitLab max per_page is 100
509+
510+
String url = baseUrl + "/projects/" + encodedPath + "/repository/commits?ref_name=" + encodedRef + "&per_page=" + perPage;
511+
512+
List<VcsCommit> commits = new ArrayList<>();
513+
514+
while (url != null && commits.size() < limit) {
515+
Request request = createGetRequest(url);
516+
try (Response response = httpClient.newCall(request).execute()) {
517+
if (!response.isSuccessful()) {
518+
throw createException("get commit history", response);
519+
}
520+
521+
JsonNode root = objectMapper.readTree(response.body().string());
522+
if (root == null || !root.isArray()) break;
523+
524+
for (JsonNode commitNode : root) {
525+
if (commits.size() >= limit) break;
526+
527+
String hash = getTextOrNull(commitNode, "id");
528+
if (hash == null) continue;
529+
530+
String message = getTextOrNull(commitNode, "message");
531+
String authorName = getTextOrNull(commitNode, "author_name");
532+
String authorEmail = getTextOrNull(commitNode, "author_email");
533+
OffsetDateTime timestamp = null;
534+
535+
String dateStr = getTextOrNull(commitNode, "authored_date");
536+
if (dateStr != null) {
537+
try {
538+
timestamp = OffsetDateTime.parse(dateStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
539+
} catch (Exception e) {
540+
log.debug("Could not parse commit date '{}': {}", dateStr, e.getMessage());
541+
}
542+
}
543+
544+
List<String> parentHashes = new ArrayList<>();
545+
JsonNode parentsArray = commitNode.get("parent_ids");
546+
if (parentsArray != null && parentsArray.isArray()) {
547+
for (JsonNode parentId : parentsArray) {
548+
if (!parentId.isNull()) {
549+
parentHashes.add(parentId.asText());
550+
}
551+
}
552+
}
553+
554+
commits.add(new VcsCommit(hash, message, authorName, authorEmail, timestamp, parentHashes));
555+
}
556+
557+
// Follow pagination via Link header or X-Next-Page
558+
if (commits.size() < limit) {
559+
String nextPage = response.header("X-Next-Page");
560+
if (nextPage != null && !nextPage.isEmpty()) {
561+
url = baseUrl + "/projects/" + encodedPath + "/repository/commits?ref_name=" + encodedRef
562+
+ "&per_page=" + perPage + "&page=" + nextPage;
563+
} else {
564+
url = null;
565+
}
566+
} else {
567+
url = null;
568+
}
569+
}
570+
}
571+
572+
return commits;
573+
}
574+
501575
@Override
502576
public String getBranchDiff(String workspaceId, String repoIdOrSlug, String baseBranch, String compareBranch) throws IOException {
503577
// GitLab: GET /projects/:id/repository/compare

0 commit comments

Comments
 (0)