1
1
#include "builtin.h"
2
+ #include "git-compat-util.h"
2
3
#include "config.h"
3
4
#include "parse-options.h"
4
5
#include "repository.h"
6
+ #include "commit.h"
7
+ #include "hex.h"
8
+ #include "tree.h"
9
+ #include "tree-walk.h"
5
10
#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"
6
22
7
23
static const char * const builtin_backfill_usage [] = {
8
24
N_ ("git backfill [<options>]" ),
9
25
NULL
10
26
};
11
27
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
+
12
108
int cmd_backfill (int argc , const char * * argv , const char * prefix , struct repository * repo )
13
109
{
110
+ struct backfill_context ctx = {
111
+ .repo = repo ,
112
+ .current_batch = OID_ARRAY_INIT ,
113
+ .batch_size = 50000 ,
114
+ };
14
115
struct option options [] = {
15
116
OPT_END (),
16
117
};
@@ -23,7 +124,5 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit
23
124
24
125
repo_config (repo , git_default_config , NULL );
25
126
26
- die (_ ("not implemented" ));
27
-
28
- return 0 ;
127
+ return do_backfill (& ctx );
29
128
}
0 commit comments