summaryrefslogtreecommitdiff
path: root/shallow.c
diff options
context:
space:
mode:
Diffstat (limited to 'shallow.c')
-rw-r--r--shallow.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/shallow.c b/shallow.c
index a0363dea20..8a9c96d019 100644
--- a/shallow.c
+++ b/shallow.c
@@ -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;
}
@@ -72,8 +91,14 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
}
if (parse_commit(commit))
die("invalid commit");
- commit->object.flags |= not_shallow_flag;
cur_depth++;
+ if (cur_depth >= depth) {
+ commit_list_insert(commit, &result);
+ commit->object.flags |= shallow_flag;
+ commit = NULL;
+ continue;
+ }
+ commit->object.flags |= not_shallow_flag;
for (p = commit->parents, commit = NULL; p; p = p->next) {
if (!p->item->util) {
int *pointer = xmalloc(sizeof(int));
@@ -85,20 +110,34 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
continue;
*pointer = cur_depth;
}
- if (cur_depth < depth) {
- if (p->next)
- add_object_array(&p->item->object,
- NULL, &stack);
- else {
- commit = p->item;
- cur_depth = *(int *)commit->util;
- }
- } else {
- commit_list_insert(p->item, &result);
- p->item->object.flags |= shallow_flag;
+ if (p->next)
+ add_object_array(&p->item->object,
+ NULL, &stack);
+ else {
+ commit = p->item;
+ cur_depth = *(int *)commit->util;
}
}
}
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");
+}