9 static FILE *info_ref_fp
;
10 static unsigned long info_ref_time
;
11 static int info_ref_is_stale
= 0;
13 static int stat_ref(const char *path
, const unsigned char *sha1
)
16 if (!stat(path
, &st
) && info_ref_time
< st
.st_mtime
)
17 info_ref_is_stale
= 1;
21 static int add_info_ref(const char *path
, const unsigned char *sha1
)
23 fprintf(info_ref_fp
, "%s %s\n", sha1_to_hex(sha1
), path
);
27 static int update_info_refs(int force
)
30 char *path0
= strdup(git_path("info/refs"));
31 int len
= strlen(path0
);
32 char *path1
= xmalloc(len
+ 2);
35 strcpy(path1
+ len
, "+");
38 if (stat(path0
, &st
)) {
40 info_ref_is_stale
= 1;
42 return error("cannot stat %s", path0
);
45 info_ref_time
= st
.st_mtime
;
46 for_each_ref(stat_ref
);
48 if (!info_ref_is_stale
)
52 safe_create_leading_directories(path0
);
53 info_ref_fp
= fopen(path1
, "w");
55 return error("unable to update %s", path0
);
56 for_each_ref(add_info_ref
);
65 static struct pack_info
{
72 unsigned char (*head
)[20];
73 char dep
[0]; /* more */
76 static const char *objdir
;
79 static struct object
*parse_object_cheap(const unsigned char *sha1
)
83 if ((o
= parse_object(sha1
)) == NULL
)
85 if (o
->type
== commit_type
) {
86 struct commit
*commit
= (struct commit
*)o
;
88 commit
->buffer
= NULL
;
93 static struct pack_info
*find_pack_by_name(const char *name
)
96 for (i
= 0; i
< num_pack
; i
++) {
97 struct packed_git
*p
= info
[i
]->p
;
98 /* skip "/pack/" after ".git/objects" */
99 if (!strcmp(p
->pack_name
+ objdirlen
+ 6, name
))
105 static struct pack_info
*find_pack_by_old_num(int old_num
)
108 for (i
= 0; i
< num_pack
; i
++)
109 if (info
[i
]->old_num
== old_num
)
114 static int add_head_def(struct pack_info
*this, unsigned char *sha1
)
116 if (this->nr_alloc
<= this->nr_heads
) {
117 this->nr_alloc
= alloc_nr(this->nr_alloc
);
118 this->head
= xrealloc(this->head
, this->nr_alloc
* 20);
120 memcpy(this->head
[this->nr_heads
++], sha1
, 20);
124 /* Returns non-zero when we detect that the info in the
125 * old file is useless.
127 static int parse_pack_def(const char *line
, int old_cnt
)
129 struct pack_info
*i
= find_pack_by_name(line
+ 2);
131 i
->old_num
= old_cnt
;
135 /* The file describes a pack that is no longer here;
136 * dependencies between packs needs to be recalculated.
142 /* Returns non-zero when we detect that the info in the
143 * old file is useless.
145 static int parse_depend_def(char *line
)
149 struct pack_info
*this, *that
;
152 num
= strtoul(cp
, &ep
, 10);
154 return error("invalid input %s", line
);
155 this = find_pack_by_old_num(num
);
158 while (ep
&& *(cp
= ep
)) {
159 num
= strtoul(cp
, &ep
, 10);
162 that
= find_pack_by_old_num(num
);
164 /* The pack this one depends on does not
165 * exist; this should not happen because
166 * we write out the list of packs first and
167 * then dependency information, but it means
168 * the file is useless anyway.
171 this->dep
[that
->new_num
] = 1;
176 /* Returns non-zero when we detect that the info in the
177 * old file is useless.
179 static int parse_head_def(char *line
)
181 unsigned char sha1
[20];
184 struct pack_info
*this;
188 num
= strtoul(cp
, &ep
, 10);
189 if (ep
== cp
|| *ep
++ != ' ')
190 return error("invalid input ix %s", line
);
191 this = find_pack_by_old_num(num
);
193 return 1; /* You know the drill. */
194 if (get_sha1_hex(ep
, sha1
) || ep
[40] != ' ')
195 return error("invalid input sha1 %s (%s)", line
, ep
);
196 if ((o
= parse_object_cheap(sha1
)) == NULL
)
197 return error("no such object: %s", line
);
198 return add_head_def(this, sha1
);
201 /* Returns non-zero when we detect that the info in the
202 * old file is useless.
204 static int read_pack_info_file(const char *infofile
)
210 fp
= fopen(infofile
, "r");
212 return 1; /* nonexisting is not an error. */
214 while (fgets(line
, sizeof(line
), fp
)) {
215 int len
= strlen(line
);
216 if (line
[len
-1] == '\n')
220 case 'P': /* P name */
221 if (parse_pack_def(line
, old_cnt
++))
224 case 'D': /* D ix dep-ix1 dep-ix2... */
225 if (parse_depend_def(line
))
228 case 'T': /* T ix sha1 type */
229 if (parse_head_def(line
))
233 error("unrecognized: %s", line
);
244 /* We sort the packs according to the date of the latest commit. That
245 * in turn indicates how young the pack is, and in general we would
246 * want to depend on younger packs.
248 static unsigned long get_latest_commit_date(struct packed_git
*p
)
250 unsigned char sha1
[20];
252 int num
= num_packed_objects(p
);
254 unsigned long latest
= 0;
256 for (i
= 0; i
< num
; i
++) {
257 if (nth_packed_object_sha1(p
, i
, sha1
))
258 die("corrupt pack file %s?", p
->pack_name
);
259 if ((o
= parse_object_cheap(sha1
)) == NULL
)
260 die("cannot parse %s", sha1_to_hex(sha1
));
261 if (o
->type
== commit_type
) {
262 struct commit
*commit
= (struct commit
*)o
;
263 if (latest
< commit
->date
)
264 latest
= commit
->date
;
270 static int compare_info(const void *a_
, const void *b_
)
272 struct pack_info
* const* a
= a_
;
273 struct pack_info
* const* b
= b_
;
275 if (0 <= (*a
)->old_num
&& 0 <= (*b
)->old_num
)
276 /* Keep the order in the original */
277 return (*a
)->old_num
- (*b
)->old_num
;
278 else if (0 <= (*a
)->old_num
)
279 /* Only A existed in the original so B is obviously newer */
281 else if (0 <= (*b
)->old_num
)
282 /* The other way around. */
285 if ((*a
)->latest
< (*b
)->latest
)
287 else if ((*a
)->latest
== (*b
)->latest
)
293 static void init_pack_info(const char *infofile
, int force
)
295 struct packed_git
*p
;
300 objdir
= get_object_directory();
301 objdirlen
= strlen(objdir
);
303 prepare_packed_git();
304 for (p
= packed_git
; p
; p
= p
->next
) {
305 /* we ignore things on alternate path since they are
306 * not available to the pullers in general.
308 if (strncmp(p
->pack_name
, objdir
, objdirlen
) ||
309 strncmp(p
->pack_name
+ objdirlen
, "/pack/", 6))
314 info
= xcalloc(num_pack
, sizeof(struct pack_info
*));
315 for (i
= 0, p
= packed_git
; p
; p
= p
->next
) {
316 if (strncmp(p
->pack_name
, objdir
, objdirlen
) ||
317 p
->pack_name
[objdirlen
] != '/')
319 info
[i
] = xcalloc(1, sizeof(struct pack_info
) + num_pack
);
321 info
[i
]->old_num
= -1;
325 if (infofile
&& !force
)
326 stale
= read_pack_info_file(infofile
);
330 for (i
= 0; i
< num_pack
; i
++) {
332 info
[i
]->old_num
= -1;
333 memset(info
[i
]->dep
, 0, num_pack
);
334 info
[i
]->nr_heads
= 0;
336 if (info
[i
]->old_num
< 0)
337 info
[i
]->latest
= get_latest_commit_date(info
[i
]->p
);
340 qsort(info
, num_pack
, sizeof(info
[0]), compare_info
);
341 for (i
= 0; i
< num_pack
; i
++)
342 info
[i
]->new_num
= i
;
344 /* we need to fix up the dependency information
348 for (i
= 0; i
< num_pack
; i
++) {
351 if (info
[i
]->old_num
< 0)
354 dep_temp
= xmalloc(num_pack
);
355 memset(dep_temp
, 0, num_pack
);
356 for (old
= 0; old
< num_pack
; old
++) {
357 struct pack_info
*base
;
358 if (!info
[i
]->dep
[old
])
360 base
= find_pack_by_old_num(old
);
362 die("internal error renumbering");
363 dep_temp
[base
->new_num
] = 1;
365 memcpy(info
[i
]->dep
, dep_temp
, num_pack
);
370 static void write_pack_info_file(FILE *fp
)
373 for (i
= 0; i
< num_pack
; i
++)
374 fprintf(fp
, "P %s\n", info
[i
]->p
->pack_name
+ objdirlen
+ 6);
376 for (i
= 0; i
< num_pack
; i
++) {
377 fprintf(fp
, "D %1d", i
);
378 for (j
= 0; j
< num_pack
; j
++) {
379 if ((i
== j
) || !(info
[i
]->dep
[j
]))
381 fprintf(fp
, " %1d", j
);
386 for (i
= 0; i
< num_pack
; i
++) {
387 struct pack_info
*this = info
[i
];
388 for (j
= 0; j
< this->nr_heads
; j
++) {
389 struct object
*o
= lookup_object(this->head
[j
]);
390 fprintf(fp
, "T %1d %s %s\n",
391 i
, sha1_to_hex(this->head
[j
]), o
->type
);
397 #define REFERENCED 01
401 static void show(struct object
*o
, int pack_ix
)
404 * We are interested in objects that are not referenced,
405 * and objects that are referenced but not internal.
407 if (o
->flags
& EMITTED
)
410 if (!(o
->flags
& REFERENCED
))
411 add_head_def(info
[pack_ix
], o
->sha1
);
412 else if ((o
->flags
& REFERENCED
) && !(o
->flags
& INTERNAL
)) {
415 /* Which pack contains this object? That is what
416 * pack_ix can depend on. We earlier sorted info
417 * array from youngest to oldest, so try newer packs
418 * first to favor them here.
420 for (i
= num_pack
- 1; 0 <= i
; i
--) {
421 struct packed_git
*p
= info
[i
]->p
;
422 struct pack_entry ent
;
423 if (find_pack_entry_one(o
->sha1
, &ent
, p
)) {
424 info
[pack_ix
]->dep
[i
] = 1;
432 static void find_pack_info_one(int pack_ix
)
434 unsigned char sha1
[20];
436 struct object_list
*ref
;
438 struct packed_git
*p
= info
[pack_ix
]->p
;
439 int num
= num_packed_objects(p
);
441 /* Scan objects, clear flags from all the edge ones and
442 * internal ones, possibly marked in the previous round.
444 for (i
= 0; i
< num
; i
++) {
445 if (nth_packed_object_sha1(p
, i
, sha1
))
446 die("corrupt pack file %s?", p
->pack_name
);
447 if ((o
= lookup_object(sha1
)) == NULL
)
448 die("cannot parse %s", sha1_to_hex(sha1
));
449 for (ref
= o
->refs
; ref
; ref
= ref
->next
)
450 ref
->item
->flags
= 0;
454 /* Mark all the internal ones */
455 for (i
= 0; i
< num
; i
++) {
456 if (nth_packed_object_sha1(p
, i
, sha1
))
457 die("corrupt pack file %s?", p
->pack_name
);
458 if ((o
= lookup_object(sha1
)) == NULL
)
459 die("cannot find %s", sha1_to_hex(sha1
));
460 for (ref
= o
->refs
; ref
; ref
= ref
->next
)
461 ref
->item
->flags
|= REFERENCED
;
462 o
->flags
|= INTERNAL
;
465 for (i
= 0; i
< num
; i
++) {
466 if (nth_packed_object_sha1(p
, i
, sha1
))
467 die("corrupt pack file %s?", p
->pack_name
);
468 if ((o
= lookup_object(sha1
)) == NULL
)
469 die("cannot find %s", sha1_to_hex(sha1
));
472 for (ref
= o
->refs
; ref
; ref
= ref
->next
)
473 show(ref
->item
, pack_ix
);
478 static void find_pack_info(void)
481 for (i
= 0; i
< num_pack
; i
++) {
482 /* The packed objects are cast in stone, and a head
483 * in a pack will stay as head, so is the set of missing
484 * objects. If the repo has been reorganized and we
485 * are missing some packs available back then, we have
486 * already discarded the info read from the file, so
487 * we will find (old_num < 0) in that case.
489 if (0 <= info
[i
]->old_num
)
491 find_pack_info_one(i
);
495 static int update_info_packs(int force
)
497 char infofile
[PATH_MAX
];
502 namelen
= sprintf(infofile
, "%s/info/packs", get_object_directory());
503 strcpy(name
, infofile
);
504 strcpy(name
+ namelen
, "+");
506 init_pack_info(infofile
, force
);
509 safe_create_leading_directories(name
);
510 fp
= fopen(name
, "w");
512 return error("cannot open %s", name
);
513 write_pack_info_file(fp
);
515 rename(name
, infofile
);
520 static int record_rev_cache_ref(const char *path
, const unsigned char *sha1
)
522 struct object
*obj
= parse_object(sha1
);
525 return error("ref %s has bad sha %s", path
, sha1_to_hex(sha1
));
526 while (obj
&& obj
->type
== tag_type
)
527 obj
= parse_object(((struct tag
*)obj
)->tagged
->sha1
);
528 if (!obj
|| obj
->type
!= commit_type
)
529 /* tag pointing at a non-commit */
531 return record_rev_cache(obj
->sha1
, NULL
);
534 static int update_info_revs(int force
)
536 char *path0
= strdup(git_path("info/rev-cache"));
537 int len
= strlen(path0
);
538 char *path1
= xmalloc(len
+ 2);
540 strcpy(path1
, path0
);
541 strcpy(path1
+ len
, "+");
543 /* read existing rev-cache */
545 read_rev_cache(path0
, NULL
, 0);
546 safe_create_leading_directories(path0
);
548 for_each_ref(record_rev_cache_ref
);
550 /* update the rev-cache database */
551 write_rev_cache(path1
, force
? "/dev/null" : path0
);
552 rename(path1
, path0
);
559 int update_server_info(int force
)
561 /* We would add more dumb-server support files later,
562 * including index of available pack files and their
563 * intended audiences.
567 errs
= errs
| update_info_refs(force
);
568 errs
= errs
| update_info_packs(force
);
569 errs
= errs
| update_info_revs(force
);