git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] upload-pack: allow shallow fetching from a read-only repository
@ 2014-02-27  7:13 Nguyễn Thái Ngọc Duy
  2014-02-27  9:04 ` Jeff King
  2014-03-04 12:30 ` [PATCH v2] upload-pack: allow shallow fetching from a read-only repository Nguyễn Thái Ngọc Duy
  0 siblings, 2 replies; 22+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2014-02-27  7:13 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

Before cdab485 (upload-pack: delegate rev walking in shallow fetch to
pack-objects - 2013-08-16) upload-pack does not write to the source
repository. cdab485 starts to write $GIT_DIR/shallow_XXXXXX if it's a
shallow fetch, so the source repo must be writable.

Fall back to $TMPDIR if $GIT_DIR/shallow_XXXXXX cannot be created in
this case. Note that in other cases that write $GIT_DIR/shallow_XXXXXX
and eventually rename it to $GIT_DIR/shallow, there is no fallback to
$TMPDIR.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/receive-pack.c   |  2 +-
 commit.h                 |  2 +-
 fetch-pack.c             |  2 +-
 shallow.c                | 13 +++++++++++--
 t/t5537-fetch-shallow.sh | 13 +++++++++++++
 upload-pack.c            |  2 +-
 6 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 85bba35..9d96f2c 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -936,7 +936,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
 			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
 
 	if (si->nr_ours || si->nr_theirs) {
-		alt_shallow_file = setup_temporary_shallow(si->shallow);
+		alt_shallow_file = setup_temporary_shallow(si->shallow, 0);
 		argv_array_pushl(&av, "--shallow-file", alt_shallow_file, NULL);
 	}
 
diff --git a/commit.h b/commit.h
index 16d9c43..44a40ad 100644
--- a/commit.h
+++ b/commit.h
@@ -209,7 +209,7 @@ extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
 extern void setup_alternate_shallow(struct lock_file *shallow_lock,
 				    const char **alternate_shallow_file,
 				    const struct sha1_array *extra);
-extern char *setup_temporary_shallow(const struct sha1_array *extra);
+extern char *setup_temporary_shallow(const struct sha1_array *extra, int read_only);
 extern void advertise_shallow_grafts(int);
 
 struct shallow_info {
diff --git a/fetch-pack.c b/fetch-pack.c
index 90fdd49..382b825 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -853,7 +853,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 		setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
 					NULL);
 	else if (si->nr_ours || si->nr_theirs)
-		alternate_shallow_file = setup_temporary_shallow(si->shallow);
+		alternate_shallow_file = setup_temporary_shallow(si->shallow, 0);
 	else
 		alternate_shallow_file = NULL;
 	if (get_pack(args, fd, pack_lockfile))
diff --git a/shallow.c b/shallow.c
index bbc98b5..3adfbd5 100644
--- a/shallow.c
+++ b/shallow.c
@@ -216,7 +216,7 @@ int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
 	return write_shallow_commits_1(out, use_pack_protocol, extra, 0);
 }
 
-char *setup_temporary_shallow(const struct sha1_array *extra)
+char *setup_temporary_shallow(const struct sha1_array *extra, int read_only)
 {
 	struct strbuf sb = STRBUF_INIT;
 	int fd;
@@ -224,7 +224,16 @@ char *setup_temporary_shallow(const struct sha1_array *extra)
 	if (write_shallow_commits(&sb, 0, extra)) {
 		struct strbuf path = STRBUF_INIT;
 		strbuf_addstr(&path, git_path("shallow_XXXXXX"));
-		fd = xmkstemp(path.buf);
+		if (read_only) {
+			fd = mkstemp(path.buf);
+			if (fd < 0) {
+				char buf[PATH_MAX];
+				fd = git_mkstemp(buf, sizeof(buf), "shallow_XXXXXX");
+			}
+			if (fd < 0)
+				die_errno("Unable to create temporary shallow file");
+		} else
+			fd = xmkstemp(path.buf);
 		if (write_in_full(fd, sb.buf, sb.len) != sb.len)
 			die_errno("failed to write to %s",
 				  path.buf);
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index b0fa738..171db88 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -173,6 +173,19 @@ EOF
 	)
 '
 
+test_expect_success POSIXPERM 'shallow fetch from a read-only repo' '
+	cp -R .git read-only.git &&
+	find read-only.git -print | xargs chmod -w &&
+	test_when_finished "find read-only.git -type d -print | xargs chmod +w" &&
+	git clone --no-local --depth=2 read-only.git from-read-only &&
+	git --git-dir=from-read-only/.git log --format=%s >actual &&
+	cat >expect <<EOF &&
+add-1-back
+4
+EOF
+	test_cmp expect actual
+'
+
 if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
 	say 'skipping remaining tests, git built without http support'
 	test_done
diff --git a/upload-pack.c b/upload-pack.c
index 0c44f6b..11404b4 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -84,7 +84,7 @@ static void create_pack_file(void)
 	char *shallow_file = NULL;
 
 	if (shallow_nr) {
-		shallow_file = setup_temporary_shallow(NULL);
+		shallow_file = setup_temporary_shallow(NULL, 1);
 		argv[arg++] = "--shallow-file";
 		argv[arg++] = shallow_file;
 	}
-- 
1.9.0.66.g14f785a

^ permalink raw reply related	[flat|nested] 22+ messages in thread
* [PATCH] shallow: verify shallow file after taking lock
@ 2014-03-15  3:47 Jeff King
  0 siblings, 0 replies; 22+ messages in thread
From: Jeff King @ 2014-03-15  3:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

Before writing the shallow file, we stat() the existing file
to make sure it has not been updated since our operation
began. However, we do not do so under a lock, so there is a
possible race:

  1. Process A takes the lock.

  2. Process B calls check_shallow_file_for_update and finds
     no update.

  3. Process A commits the lockfile.

  4. Process B takes the lock, then overwrite's process A's
     changes.

We can fix this by doing our check while we hold the lock.

Signed-off-by: Jeff King <peff@peff.net>
---
This is a repost of:

  http://article.gmane.org/gmane.comp.version-control.git/242795

You picked up the other two related patches as jk/shallow-update-fix,
but I suspect this one just got lost in the noise because I didn't
format it as a proper series.

 shallow.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/shallow.c b/shallow.c
index bbc98b5..75da07a 100644
--- a/shallow.c
+++ b/shallow.c
@@ -246,9 +246,9 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
 	struct strbuf sb = STRBUF_INIT;
 	int fd;
 
-	check_shallow_file_for_update();
 	fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
 				       LOCK_DIE_ON_ERROR);
+	check_shallow_file_for_update();
 	if (write_shallow_commits(&sb, 0, extra)) {
 		if (write_in_full(fd, sb.buf, sb.len) != sb.len)
 			die_errno("failed to write to %s",
@@ -293,9 +293,9 @@ void prune_shallow(int show_only)
 		strbuf_release(&sb);
 		return;
 	}
-	check_shallow_file_for_update();
 	fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
 				       LOCK_DIE_ON_ERROR);
+	check_shallow_file_for_update();
 	if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
 		if (write_in_full(fd, sb.buf, sb.len) != sb.len)
 			die_errno("failed to write to %s",
-- 
1.9.0.532.g9ab8f58

^ permalink raw reply related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-03-15  3:47 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-27  7:13 [PATCH] upload-pack: allow shallow fetching from a read-only repository Nguyễn Thái Ngọc Duy
2014-02-27  9:04 ` Jeff King
2014-02-27  9:10   ` [PATCH] shallow: verify shallow file after taking lock Jeff King
2014-02-27  9:22     ` Jeff King
2014-02-27 10:18       ` Duy Nguyen
2014-02-27 10:56         ` [PATCH] shallow: use stat_validity to check for up-to-date file Jeff King
2014-02-27 10:11   ` [PATCH] upload-pack: allow shallow fetching from a read-only repository Duy Nguyen
2014-02-27 11:25     ` [PATCH] shallow: automatically clean up shallow tempfiles Jeff King
2014-03-04 12:30 ` [PATCH v2] upload-pack: allow shallow fetching from a read-only repository Nguyễn Thái Ngọc Duy
2014-03-04 18:10   ` Junio C Hamano
2014-03-05 12:43     ` Duy Nguyen
2014-03-05 19:50       ` Junio C Hamano
2014-03-06  8:49   ` [PATCH v3] upload-pack: send shallow info over stdin to pack-objects Nguyễn Thái Ngọc Duy
2014-03-06 18:37     ` Junio C Hamano
2014-03-06 23:13       ` Duy Nguyen
2014-03-07 18:27         ` Junio C Hamano
2014-03-08  0:08           ` Duy Nguyen
2014-03-10 15:23             ` Junio C Hamano
2014-03-07  1:24     ` Duy Nguyen
2014-03-07 18:33       ` Junio C Hamano
2014-03-11 12:59     ` [PATCH v4] " Nguyễn Thái Ngọc Duy
  -- strict thread matches above, loose matches on Subject: below --
2014-03-15  3:47 [PATCH] shallow: verify shallow file after taking lock Jeff King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).