summaryrefslogtreecommitdiff
path: root/shallow.c
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2013-05-26 08:16:15 +0700
committerJunio C Hamano <gitster@pobox.com>2013-05-28 08:06:08 -0700
commit6035d6aad8ca11954c0d7821f6f3e7c047039c8f (patch)
treea24924b1323fe52278be3f912b36bc78eed7be22 /shallow.c
parent0781aa4766ed88d620ea060c7d775ca806ebfa93 (diff)
downloadgit-6035d6aad8ca11954c0d7821f6f3e7c047039c8f.tar.gz
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>
Diffstat (limited to 'shallow.c')
-rw-r--r--shallow.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/shallow.c b/shallow.c
index 6be915f38f..cbe2526d8c 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;
}
@@ -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");
+}