11#include "builtin.h"
2+ #include "git-compat-util.h"
23#include "config.h"
34#include "parse-options.h"
45#include "repository.h"
6+ #include "commit.h"
7+ #include "hex.h"
8+ #include "tree.h"
9+ #include "tree-walk.h"
510#include "object.h"
11+ #include "object-store-ll.h"
12+ #include "oid-array.h"
13+ #include "oidset.h"
14+ #include "promisor-remote.h"
15+ #include "strmap.h"
16+ #include "string-list.h"
17+ #include "revision.h"
18+ #include "trace2.h"
19+ #include "progress.h"
20+ #include "packfile.h"
21+ #include "path-walk.h"
622
723static const char * const builtin_backfill_usage [] = {
824 N_ ("git backfill [<options>]" ),
925 NULL
1026};
1127
28+ struct backfill_context {
29+ struct repository * repo ;
30+ struct oid_array current_batch ;
31+ size_t batch_size ;
32+ };
33+
34+ static void clear_backfill_context (struct backfill_context * ctx )
35+ {
36+ oid_array_clear (& ctx -> current_batch );
37+ }
38+
39+ static void download_batch (struct backfill_context * ctx )
40+ {
41+ promisor_remote_get_direct (ctx -> repo ,
42+ ctx -> current_batch .oid ,
43+ ctx -> current_batch .nr );
44+ oid_array_clear (& ctx -> current_batch );
45+
46+ /*
47+ * We likely have a new packfile. Add it to the packed list to
48+ * avoid possible duplicate downloads of the same objects.
49+ */
50+ reprepare_packed_git (ctx -> repo );
51+ }
52+
53+ static int fill_missing_blobs (const char * path UNUSED ,
54+ struct oid_array * list ,
55+ enum object_type type ,
56+ void * data )
57+ {
58+ struct backfill_context * ctx = data ;
59+
60+ if (type != OBJ_BLOB )
61+ return 0 ;
62+
63+ for (size_t i = 0 ; i < list -> nr ; i ++ ) {
64+ off_t size = 0 ;
65+ struct object_info info = OBJECT_INFO_INIT ;
66+ info .disk_sizep = & size ;
67+ if (oid_object_info_extended (ctx -> repo ,
68+ & list -> oid [i ],
69+ & info ,
70+ OBJECT_INFO_FOR_PREFETCH ) ||
71+ !size )
72+ oid_array_append (& ctx -> current_batch , & list -> oid [i ]);
73+ }
74+
75+ if (ctx -> current_batch .nr >= ctx -> batch_size )
76+ download_batch (ctx );
77+
78+ return 0 ;
79+ }
80+
81+ static int do_backfill (struct backfill_context * ctx )
82+ {
83+ struct rev_info revs ;
84+ struct path_walk_info info = PATH_WALK_INFO_INIT ;
85+ int ret ;
86+
87+ repo_init_revisions (ctx -> repo , & revs , "" );
88+ handle_revision_arg ("HEAD" , & revs , 0 , 0 );
89+
90+ info .blobs = 1 ;
91+ info .tags = info .commits = info .trees = 0 ;
92+
93+ info .revs = & revs ;
94+ info .path_fn = fill_missing_blobs ;
95+ info .path_fn_data = ctx ;
96+
97+ ret = walk_objects_by_path (& info );
98+
99+ /* Download the objects that did not fill a batch. */
100+ if (!ret )
101+ download_batch (ctx );
102+
103+ clear_backfill_context (ctx );
104+ release_revisions (& revs );
105+ return ret ;
106+ }
107+
12108int cmd_backfill (int argc , const char * * argv , const char * prefix , struct repository * repo )
13109{
110+ struct backfill_context ctx = {
111+ .repo = repo ,
112+ .current_batch = OID_ARRAY_INIT ,
113+ .batch_size = 50000 ,
114+ };
14115 struct option options [] = {
15116 OPT_END (),
16117 };
@@ -23,7 +124,5 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit
23124
24125 repo_config (repo , git_default_config , NULL );
25126
26- die (_ ("not implemented" ));
27-
28- return 0 ;
127+ return do_backfill (& ctx );
29128}
0 commit comments