fetch-pack: prepare updated shallow file before fetching the pack

index-pack --strict looks up and follows parent commits. If shallow
information is not ready by the time index-pack is run, index-pack may
be led to non-existent objects. Make fetch-pack save shallow file to
disk before invoking index-pack.

git learns new global option --shallow-file to pass on the alternate
shallow file path. Undocumented (and not even support --shallow-file=
syntax) because it's unlikely to be used again elsewhere.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy
2013-05-26 08:16:15 +07:00
committed by Junio C Hamano
parent 0781aa4766
commit 6035d6aad8
5 changed files with 93 additions and 38 deletions

View File

@ -3,6 +3,16 @@
#include "tag.h"
static int is_shallow = -1;
static struct stat shallow_stat;
static char *alternate_shallow_file;
void set_alternate_shallow_file(const char *path)
{
if (is_shallow != -1)
die("BUG: is_repository_shallow must not be called before set_alternate_shallow_file");
free(alternate_shallow_file);
alternate_shallow_file = path ? xstrdup(path) : NULL;
}
int register_shallow(const unsigned char *sha1)
{
@ -21,12 +31,21 @@ int is_repository_shallow(void)
{
FILE *fp;
char buf[1024];
const char *path = alternate_shallow_file;
if (is_shallow >= 0)
return is_shallow;
fp = fopen(git_path("shallow"), "r");
if (!fp) {
if (!path)
path = git_path("shallow");
/*
* fetch-pack sets '--shallow-file ""' as an indicator that no
* shallow file should be used. We could just open it and it
* will likely fail. But let's do an explicit check instead.
*/
if (!*path ||
stat(path, &shallow_stat) ||
(fp = fopen(path, "r")) == NULL) {
is_shallow = 0;
return is_shallow;
}
@ -108,3 +127,22 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
return result;
}
void check_shallow_file_for_update(void)
{
struct stat st;
if (!is_shallow)
return;
else if (is_shallow == -1)
die("BUG: shallow must be initialized by now");
if (stat(git_path("shallow"), &st))
die("shallow file was removed during fetch");
else if (st.st_mtime != shallow_stat.st_mtime
#ifdef USE_NSEC
|| ST_MTIME_NSEC(st) != ST_MTIME_NSEC(shallow_stat)
#endif
)
die("shallow file was changed during fetch");
}