Subject: [PATCH] Push to create

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This teaches receive-pack to create a new directory as a bare repository
when a user tries to push into a directory that does not exist.

Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
---
 "Shawn O. Pearce" <spearce@xxxxxxxxxxx> writes:

 > But I think that's only true for situations where you are likely the
 > owner of the repository in your own home directory, such as ~you
 > on kernel.org.  For "hosted repositories" like any of the systems
 > you described above, there is a lot more to the creation than just
 > executing "git init" somewhere.
 > .
 > For the usage of
 > creating a new repository in your own home directory on some remote
 > server, why isn't this just an option to git push?

 I am not at all convinced that the use case people would for whatever
 reason do not want to "ssh-in, create and then push from here" is limited
 to "your own playpen in your $HOME", but it certainly limits the
 complexity and the scope of the damage.

 builtin-receive-pack.c |   29 ++++++++++++++++++++++++++++-
 t/t5541-push-create.sh |   20 ++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletions(-)
 create mode 100755 t/t5541-push-create.sh

diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c
index 849f1fe..2f2831c 100644
--- a/builtin-receive-pack.c
+++ b/builtin-receive-pack.c
@@ -652,6 +652,33 @@ static void add_alternate_refs(void)
 	foreach_alt_odb(add_refs_from_alternate, NULL);
 }
 
+static char *create_new_repo(char *dir)
+{
+	struct child_process child;
+	const char *argv[20];
+	int argc;
+
+	if (mkdir(dir, 0777)) {
+		error("cannot mkdir '%s': %s", dir, strerror(errno));
+		return NULL;
+	}
+	argc = 0;
+	argv[argc++] = "init";
+	argv[argc++] = "--bare";
+	argv[argc++] = NULL;
+	child.argv = argv;
+	if (run_command_v_opt_cd_env(argv,
+				     RUN_COMMAND_NO_STDIN |
+				     RUN_COMMAND_STDOUT_TO_STDERR |
+				     RUN_GIT_CMD,
+				     dir,
+				     NULL)) {
+		error("cannot run git init");
+		return NULL;
+	}
+	return enter_repo(dir, 0);
+}
+
 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 {
 	int i;
@@ -674,7 +701,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 
 	setup_path();
 
-	if (!enter_repo(dir, 0))
+	if (!enter_repo(dir, 0) && !create_new_repo(dir))
 		die("'%s': unable to chdir or not a git archive", dir);
 
 	if (is_repository_shallow())
diff --git a/t/t5541-push-create.sh b/t/t5541-push-create.sh
new file mode 100755
index 0000000..52558a5
--- /dev/null
+++ b/t/t5541-push-create.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+test_description='push into nonexisting repository'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	test_commit A &&
+	test_commit B &&
+	test_commit C
+'
+
+test_expect_success 'push into nonexisting repository' '
+	this=$(git rev-parse B) &&
+	git push "file://$(pwd)/not-here.git" B:refs/heads/master &&
+	that=$(GIT_DIR=not-here.git git rev-parse HEAD) &&
+	test "$this" = "$that"
+'
+
+test_done
-- 
1.6.2.rc2.123.gab4478

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux