Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b3bf58f

Browse files
committed
commit-graph: Use the commit-graph in revwalks
This change makes revwalks a bit faster by using the `commit-graph` file (if present). This is thanks to the `commit-graph` allow much faster parsing of the commit information by requiring near-zero I/O (aside from reading a few dozen bytes off of a `mmap(2)`-ed file) for each commit, instead of having to read the ODB, inflate the commit, and parse it. Part of: #5757
1 parent adaaffc commit b3bf58f

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

src/commit_list.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ static int commit_quick_parse(
124124
return -1;
125125
}
126126

127+
node->generation = 0;
127128
node->time = commit->committer->when.time;
128129
node->out_degree = (uint16_t) git_array_size(commit->parent_ids);
129130
node->parents = alloc_parents(walk, node, node->out_degree);
@@ -148,6 +149,31 @@ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
148149
if (commit->parsed)
149150
return 0;
150151

152+
/* Let's try to use the commit graph first. */
153+
if (walk->cgraph) {
154+
git_commit_graph_entry e;
155+
156+
error = git_commit_graph_entry_find(&e, walk->cgraph, &commit->oid, GIT_OID_RAWSZ);
157+
if (error == 0 && git__is_uint16(e.parent_count)) {
158+
size_t i;
159+
commit->generation = (uint32_t)e.generation;
160+
commit->time = e.commit_time;
161+
commit->out_degree = (uint16_t)e.parent_count;
162+
commit->parents = alloc_parents(walk, commit, commit->out_degree);
163+
GIT_ERROR_CHECK_ALLOC(commit->parents);
164+
165+
for (i = 0; i < commit->out_degree; ++i) {
166+
git_commit_graph_entry parent;
167+
error = git_commit_graph_entry_parent(&parent, walk->cgraph, &e, i);
168+
if (error < 0)
169+
return error;
170+
commit->parents[i] = git_revwalk__commit_lookup(walk, &parent.sha1);
171+
}
172+
commit->parsed = 1;
173+
return 0;
174+
}
175+
}
176+
151177
if ((error = git_odb_read(&obj, walk->odb, &commit->oid)) < 0)
152178
return error;
153179

src/commit_list.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
typedef struct git_commit_list_node {
2727
git_oid oid;
2828
int64_t time;
29+
uint32_t generation;
2930
unsigned int seen:1,
3031
uninteresting:1,
3132
topo_delay:1,

src/revwalk.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,9 @@ static int prepare_walk(git_revwalk *walk)
672672
int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo)
673673
{
674674
git_revwalk *walk = git__calloc(1, sizeof(git_revwalk));
675+
git_buf commit_graph_path = GIT_BUF_INIT;
676+
int error = 0;
677+
675678
GIT_ERROR_CHECK_ALLOC(walk);
676679

677680
if (git_oidmap_new(&walk->commits) < 0 ||
@@ -689,6 +692,23 @@ int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo)
689692
return -1;
690693
}
691694

695+
if ((error = git_repository_item_path(&commit_graph_path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0) {
696+
git_revwalk_free(walk);
697+
return error;
698+
}
699+
if ((error = git_buf_joinpath(
700+
&commit_graph_path,
701+
git_buf_cstr(&commit_graph_path),
702+
"info/commit-graph"))
703+
< 0) {
704+
git_buf_dispose(&commit_graph_path);
705+
git_revwalk_free(walk);
706+
return error;
707+
}
708+
/* Best effort */
709+
(void)git_commit_graph_open(&walk->cgraph, git_buf_cstr(&commit_graph_path));
710+
git_buf_dispose(&commit_graph_path);
711+
692712
*revwalk_out = walk;
693713
return 0;
694714
}
@@ -698,6 +718,7 @@ void git_revwalk_free(git_revwalk *walk)
698718
if (walk == NULL)
699719
return;
700720

721+
git_commit_graph_free(walk->cgraph);
701722
git_revwalk_reset(walk);
702723
git_odb_free(walk->odb);
703724

@@ -817,4 +838,3 @@ int git_revwalk_add_hide_cb(
817838

818839
return 0;
819840
}
820-

src/revwalk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "git2/revwalk.h"
1313
#include "oidmap.h"
14+
#include "commit_graph.h"
1415
#include "commit_list.h"
1516
#include "pqueue.h"
1617
#include "pool.h"
@@ -21,6 +22,7 @@
2122
struct git_revwalk {
2223
git_repository *repo;
2324
git_odb *odb;
25+
git_commit_graph_file *cgraph;
2426

2527
git_oidmap *commits;
2628
git_pool commit_pool;

0 commit comments

Comments
 (0)