From 1b75050668b5ac9d1f698b9a1e2aebd4d1e2c884 Mon Sep 17 00:00:00 2001 From: sherwinski Date: Wed, 28 Jan 2026 21:38:42 -0800 Subject: [PATCH] feat: support shallow cloning Skip missing commits/parents when walking history or looking up parents so shallow clones can open cleanly. --- GitUpKit/Core/GCCommit.m | 7 ++++++- GitUpKit/Core/GCHistory.m | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/GitUpKit/Core/GCCommit.m b/GitUpKit/Core/GCCommit.m index f31b5916..3f94a5da 100644 --- a/GitUpKit/Core/GCCommit.m +++ b/GitUpKit/Core/GCCommit.m @@ -195,7 +195,12 @@ - (NSArray*)lookupParentsForCommit:(GCCommit*)commit error:(NSError**)error { NSMutableArray* array = [[NSMutableArray alloc] init]; for (unsigned int i = 0, count = git_commit_parentcount(commit.private); i < count; ++i) { git_commit* gitCommit; - CALL_LIBGIT2_FUNCTION_RETURN(nil, git_commit_parent, &gitCommit, commit.private, i); + int status = git_commit_parent(&gitCommit, commit.private, i); + if (status == GIT_ENOTFOUND) { + XLOG_WARNING(@"Missing parent commit for %s in repository \"%@\"", git_oid_tostr_s(git_commit_id(commit.private)), self.repositoryPath); + continue; + } + CHECK_LIBGIT2_FUNCTION_CALL(return nil, status, == GIT_OK); GCCommit* parentCommit = [[GCCommit alloc] initWithRepository:self commit:gitCommit]; [array addObject:parentCommit]; } diff --git a/GitUpKit/Core/GCHistory.m b/GitUpKit/Core/GCHistory.m index e67c67c5..9039c857 100644 --- a/GitUpKit/Core/GCHistory.m +++ b/GitUpKit/Core/GCHistory.m @@ -924,9 +924,18 @@ - (BOOL)_reloadHistory:(GCHistory*)history if (status == GIT_ITEROVER) { break; } + if (status == GIT_ENOTFOUND) { + XLOG_WARNING(@"Missing commit encountered while walking history in \"%@\"", self.repositoryPath); + continue; + } CHECK_LIBGIT2_FUNCTION_CALL(goto cleanup, status, == GIT_OK); git_commit* walkCommit; - CALL_LIBGIT2_FUNCTION_GOTO(cleanup, git_commit_lookup, &walkCommit, self.private, &oid); + status = git_commit_lookup(&walkCommit, self.private, &oid); + if (status == GIT_ENOTFOUND) { + XLOG_WARNING(@"Missing commit %s from repository \"%@\"", git_oid_tostr_s(&oid), self.repositoryPath); + continue; + } + CHECK_LIBGIT2_FUNCTION_CALL(goto cleanup, status, == GIT_OK); GCHistoryCommit* commit = [[GCHistoryCommit alloc] initWithRepository:self commit:walkCommit autoIncrementID:nextAutoIncrementID++]; [commits addObject:commit]; [commit release]; @@ -1224,6 +1233,11 @@ - (NSArray*)lookupCommitsForFile:(NSString*)path followRenames:(BOOL)follow erro for (unsigned int i = 0, count = git_commit_parentcount(commit); i < count; ++i) { git_commit* parentCommit; status = git_commit_parent(&parentCommit, commit, i); + if (status == GIT_ENOTFOUND) { + XLOG_WARNING(@"Missing parent commit for %s in repository \"%@\"", git_oid_tostr_s(&oid), self.repositoryPath); + status = GIT_ITEROVER; + break; + } if (status == GIT_OK) { git_tree* parentTree; status = git_commit_tree(&parentTree, parentCommit); @@ -1265,7 +1279,13 @@ - (NSArray*)lookupCommitsForFile:(NSString*)path followRenames:(BOOL)follow erro git_tree_free(tree); } git_commit_free(commit); + } else if (status == GIT_ENOTFOUND) { + XLOG_WARNING(@"Missing commit %s from repository \"%@\"", git_oid_tostr_s(&oid), self.repositoryPath); + status = GIT_OK; } + } else if (status == GIT_ENOTFOUND) { + XLOG_WARNING(@"Missing commit encountered while walking file history in \"%@\"", self.repositoryPath); + status = GIT_OK; } if (status == GIT_ITEROVER) { break;