Git development
 help / color / mirror / Atom feed
* Re: [PATCH] Correct handling of upload-pack in builtin-fetch-pack
From: Shawn O. Pearce @ 2007-10-30  2:41 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0710292232330.7357@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> wrote:
> The field in the args was being ignored in favor of a static constant
> 
> Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
> ---
> Found this while trying to figure out how builtin-fetch-pack was 
> initializing the string in the args struct, and why it generally worked 
> even though it wasn't.

Gahhh.  Yes, obviously correct fix.  Thanks!  :-)
 
> -static struct fetch_pack_args args;
> +static struct fetch_pack_args args = {
> +	/* .uploadpack = */ "git-upload-pack",
> +};
>  
>  static const char fetch_pack_usage[] =
>  "git-fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
> -static const char *uploadpack = "git-upload-pack";
>  
>  #define COMPLETE	(1U << 0)
>  #define COMMON		(1U << 1)
> @@ -773,7 +774,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
>  			st.st_mtime = 0;
>  	}
>  
> -	pid = git_connect(fd, (char *)dest, uploadpack,
> +	pid = git_connect(fd, (char *)dest, args.uploadpack,
>                            args.verbose ? CONNECT_VERBOSE : 0);
>  	if (pid < 0)
>  		return NULL;

-- 
Shawn.

^ permalink raw reply

* [PATCH] Correct handling of upload-pack in builtin-fetch-pack
From: Daniel Barkalow @ 2007-10-30  2:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Shawn O. Pearce

The field in the args was being ignored in favor of a static constant

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
Found this while trying to figure out how builtin-fetch-pack was 
initializing the string in the args struct, and why it generally worked 
even though it wasn't.

 builtin-fetch-pack.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 8f25d50..8753840 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -11,11 +11,12 @@
 static int transfer_unpack_limit = -1;
 static int fetch_unpack_limit = -1;
 static int unpack_limit = 100;
-static struct fetch_pack_args args;
+static struct fetch_pack_args args = {
+	/* .uploadpack = */ "git-upload-pack",
+};
 
 static const char fetch_pack_usage[] =
 "git-fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
-static const char *uploadpack = "git-upload-pack";
 
 #define COMPLETE	(1U << 0)
 #define COMMON		(1U << 1)
@@ -773,7 +774,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
 			st.st_mtime = 0;
 	}
 
-	pid = git_connect(fd, (char *)dest, uploadpack,
+	pid = git_connect(fd, (char *)dest, args.uploadpack,
                           args.verbose ? CONNECT_VERBOSE : 0);
 	if (pid < 0)
 		return NULL;
-- 
1.5.3.4.1206.g5f96

^ permalink raw reply related

* Re: How to merge git://repo.or.cz/git-gui into git.git
From: Yin Ping @ 2007-10-30  2:12 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Peter Baumann, git
In-Reply-To: <20071030005217.GT14735@spearce.org>

> You are merging in the wrong direction.  You want to merge git-gui
> into git.git:
>
>         git clone git://repo.or.cz/alt-git.git mygit
>         cd mygit
>         git pull -s subtree git://repo.or.cz/git-gui.git master
>
> So you are pulling git-gui into git, not the reverse.  But yes,
> when this happens the entire history of the pulled project (in the
> above case git-gui) suddenly appears in the history of the parent
> project (in this case git).  If you don't want this to happen then
> you need to make git-gui into a submodule.  That has been talked
> about being done, but hasn't happened yet in the main git repository.
> git-gui is currently still being subtree merged in.
>
> --
> Shawn.
>
Ok, I see. I'm just be interested in the subtree strategy and try a
few ways and different directions to merge. And also i'm trying to
figure out which one of subtree merge and submodule is more suitable
for my project. However, the conclusion havn't come.

-- 
franky

^ permalink raw reply

* [PATCH 4/4 v2] Use built-in send-pack.
From: Daniel Barkalow @ 2007-10-30  2:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 transport.c |   51 ++++++++++-----------------------------------------
 1 files changed, 10 insertions(+), 41 deletions(-)

diff --git a/transport.c b/transport.c
index 89b73dc..6b1f419 100644
--- a/transport.c
+++ b/transport.c
@@ -6,6 +6,7 @@
 #endif
 #include "pkt-line.h"
 #include "fetch-pack.h"
+#include "send-pack.h"
 #include "walker.h"
 #include "bundle.h"
 #include "dir.h"
@@ -653,48 +654,16 @@ static int fetch_refs_via_pack(struct transport *transport,
 
 static int git_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags) {
 	struct git_transport_data *data = transport->data;
-	const char **argv;
-	char *rem;
-	int argc;
-	int err;
+	struct send_pack_args args;
 
-	argv = xmalloc((refspec_nr + 11) * sizeof(char *));
-	argv[0] = "send-pack";
-	argc = 1;
-	if (flags & TRANSPORT_PUSH_ALL)
-		argv[argc++] = "--all";
-	if (flags & TRANSPORT_PUSH_FORCE)
-		argv[argc++] = "--force";
-	if (flags & TRANSPORT_PUSH_DRY_RUN)
-		argv[argc++] = "--dry-run";
-	if (data->receivepack) {
-		char *rp = xmalloc(strlen(data->receivepack) + 16);
-		sprintf(rp, "--receive-pack=%s", data->receivepack);
-		argv[argc++] = rp;
-	}
-	if (data->thin)
-		argv[argc++] = "--thin";
-	rem = xmalloc(strlen(transport->remote->name) + 10);
-	sprintf(rem, "--remote=%s", transport->remote->name);
-	argv[argc++] = rem;
-	argv[argc++] = transport->url;
-	while (refspec_nr--)
-		argv[argc++] = *refspec++;
-	argv[argc] = NULL;
-	err = run_command_v_opt(argv, RUN_GIT_CMD);
-	switch (err) {
-	case -ERR_RUN_COMMAND_FORK:
-		error("unable to fork for %s", argv[0]);
-	case -ERR_RUN_COMMAND_EXEC:
-		error("unable to exec %s", argv[0]);
-		break;
-	case -ERR_RUN_COMMAND_WAITPID:
-	case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
-	case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
-	case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
-		error("%s died with strange error", argv[0]);
-	}
-	return !!err;
+	args.receivepack = data->receivepack;
+	args.send_all = !!(flags & TRANSPORT_PUSH_ALL);
+	args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
+	args.use_thin_pack = data->thin;
+	args.verbose = transport->verbose;
+	args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
+
+	return send_pack(&args, transport->url, transport->remote, refspec_nr, refspec);
 }
 
 static int disconnect_git(struct transport *transport)
-- 
1.5.3.4.1206.g5f96

^ permalink raw reply related

* [PATCH 3/4 v2] Build-in send-pack, with an API for other programs to call.
From: Daniel Barkalow @ 2007-10-30  2:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Also marks some more things as const, as needed.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 Makefile                           |    1 +
 send-pack.c => builtin-send-pack.c |   81 +++++++++++++++++++----------------
 builtin.h                          |    1 +
 git.c                              |    1 +
 send-pack.h                        |   17 ++++++++
 5 files changed, 64 insertions(+), 37 deletions(-)
 rename send-pack.c => builtin-send-pack.c (88%)
 create mode 100644 send-pack.h

diff --git a/Makefile b/Makefile
index 64ad297..8b0c8cd 100644
--- a/Makefile
+++ b/Makefile
@@ -359,6 +359,7 @@ BUILTIN_OBJS = \
 	builtin-push.o \
 	builtin-read-tree.o \
 	builtin-reflog.o \
+	builtin-send-pack.o \
 	builtin-config.o \
 	builtin-rerere.o \
 	builtin-reset.o \
diff --git a/send-pack.c b/builtin-send-pack.c
similarity index 88%
rename from send-pack.c
rename to builtin-send-pack.c
index fe56617..60a12f7 100644
--- a/send-pack.c
+++ b/builtin-send-pack.c
@@ -5,16 +5,15 @@
 #include "pkt-line.h"
 #include "run-command.h"
 #include "remote.h"
+#include "send-pack.h"
 
 static const char send_pack_usage[] =
 "git-send-pack [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
 "  --all and explicit <ref> specification are mutually exclusive.";
-static const char *receivepack = "git-receive-pack";
-static int verbose;
-static int send_all;
-static int force_update;
-static int use_thin_pack;
-static int dry_run;
+
+static struct send_pack_args args = {
+	/* .receivepack = */ "git-receive-pack",
+};
 
 /*
  * Make a pack stream and spit it out into file descriptor fd
@@ -26,7 +25,7 @@ static int pack_objects(int fd, struct ref *refs)
 	 * the revision parameters to it via its stdin and
 	 * let its stdout go back to the other end.
 	 */
-	const char *args[] = {
+	const char *argv[] = {
 		"pack-objects",
 		"--all-progress",
 		"--revs",
@@ -36,10 +35,10 @@ static int pack_objects(int fd, struct ref *refs)
 	};
 	struct child_process po;
 
-	if (use_thin_pack)
-		args[4] = "--thin";
+	if (args.use_thin_pack)
+		argv[4] = "--thin";
 	memset(&po, 0, sizeof(po));
-	po.argv = args;
+	po.argv = argv;
 	po.in = -1;
 	po.out = fd;
 	po.git_cmd = 1;
@@ -178,7 +177,7 @@ static int receive_status(int in)
 	return ret;
 }
 
-static int send_pack(int in, int out, struct remote *remote, int nr_refspec, const char **refspec)
+static int do_send_pack(int in, int out, struct remote *remote, int nr_refspec, const char **refspec)
 {
 	struct ref *ref;
 	int new_refs;
@@ -201,7 +200,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, con
 	if (!remote_tail)
 		remote_tail = &remote_refs;
 	if (match_refs(local_refs, remote_refs, &remote_tail,
-		       nr_refspec, refspec, send_all))
+		       nr_refspec, refspec, args.send_all))
 		return -1;
 
 	if (!remote_refs) {
@@ -230,7 +229,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, con
 		}
 		if (!will_delete_ref &&
 		    !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
-			if (verbose)
+			if (args.verbose)
 				fprintf(stderr, "'%s': up-to-date\n", ref->name);
 			continue;
 		}
@@ -254,7 +253,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, con
 		 *     always allowed.
 		 */
 
-		if (!force_update &&
+		if (!args.force_update &&
 		    !will_delete_ref &&
 		    !is_null_sha1(ref->old_sha1) &&
 		    !ref->force) {
@@ -284,7 +283,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, con
 		strcpy(old_hex, sha1_to_hex(ref->old_sha1));
 		new_hex = sha1_to_hex(ref->new_sha1);
 
-		if (!dry_run) {
+		if (!args.dry_run) {
 			if (ask_for_status_report) {
 				packet_write(out, "%s %s %s%c%s",
 					old_hex, new_hex, ref->name, 0,
@@ -306,7 +305,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, con
 			fprintf(stderr, "\n  from %s\n  to   %s\n",
 				old_hex, new_hex);
 		}
-		if (remote && !dry_run) {
+		if (remote && !args.dry_run) {
 			struct refspec rs;
 			rs.src = ref->name;
 			rs.dst = NULL;
@@ -325,7 +324,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, con
 	}
 
 	packet_flush(out);
-	if (new_refs && !dry_run)
+	if (new_refs && !args.dry_run)
 		ret = pack_objects(out, remote_refs);
 	close(out);
 
@@ -360,30 +359,25 @@ static void verify_remote_names(int nr_heads, const char **heads)
 	}
 }
 
-int main(int argc, char **argv)
+int cmd_send_pack(int argc, const char **argv, const char *prefix)
 {
 	int i, nr_heads = 0;
-	char *dest = NULL;
 	const char **heads = NULL;
-	int fd[2], ret;
-	pid_t pid;
-	char *remote_name = NULL;
+	const char *remote_name = NULL;
 	struct remote *remote = NULL;
-
-	setup_git_directory();
-	git_config(git_default_config);
+	const char *dest = NULL;
 
 	argv++;
 	for (i = 1; i < argc; i++, argv++) {
-		char *arg = *argv;
+		const char *arg = *argv;
 
 		if (*arg == '-') {
 			if (!prefixcmp(arg, "--receive-pack=")) {
-				receivepack = arg + 15;
+				args.receivepack = arg + 15;
 				continue;
 			}
 			if (!prefixcmp(arg, "--exec=")) {
-				receivepack = arg + 7;
+				args.receivepack = arg + 7;
 				continue;
 			}
 			if (!prefixcmp(arg, "--remote=")) {
@@ -391,23 +385,23 @@ int main(int argc, char **argv)
 				continue;
 			}
 			if (!strcmp(arg, "--all")) {
-				send_all = 1;
+				args.send_all = 1;
 				continue;
 			}
 			if (!strcmp(arg, "--dry-run")) {
-				dry_run = 1;
+				args.dry_run = 1;
 				continue;
 			}
 			if (!strcmp(arg, "--force")) {
-				force_update = 1;
+				args.force_update = 1;
 				continue;
 			}
 			if (!strcmp(arg, "--verbose")) {
-				verbose = 1;
+				args.verbose = 1;
 				continue;
 			}
 			if (!strcmp(arg, "--thin")) {
-				use_thin_pack = 1;
+				args.use_thin_pack = 1;
 				continue;
 			}
 			usage(send_pack_usage);
@@ -422,9 +416,8 @@ int main(int argc, char **argv)
 	}
 	if (!dest)
 		usage(send_pack_usage);
-	if (heads && send_all)
+	if (heads && args.send_all)
 		usage(send_pack_usage);
-	verify_remote_names(nr_heads, heads);
 
 	if (remote_name) {
 		remote = remote_get(remote_name);
@@ -434,10 +427,24 @@ int main(int argc, char **argv)
 		}
 	}
 
-	pid = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0);
+	return send_pack(&args, dest, remote, nr_heads, heads);
+}
+
+int send_pack(struct send_pack_args *my_args,
+	      const char *dest, struct remote *remote,
+	      int nr_heads, const char **heads)
+{
+	int fd[2], ret;
+	pid_t pid;
+
+	memcpy(&args, my_args, sizeof(args));
+
+	verify_remote_names(nr_heads, heads);
+
+	pid = git_connect(fd, dest, args.receivepack, args.verbose ? CONNECT_VERBOSE : 0);
 	if (pid < 0)
 		return 1;
-	ret = send_pack(fd[0], fd[1], remote, nr_heads, heads);
+	ret = do_send_pack(fd[0], fd[1], remote, nr_heads, heads);
 	close(fd[0]);
 	close(fd[1]);
 	ret |= finish_connect(pid);
diff --git a/builtin.h b/builtin.h
index ff84835..51747c7 100644
--- a/builtin.h
+++ b/builtin.h
@@ -69,6 +69,7 @@ extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
 extern int cmd_revert(int argc, const char **argv, const char *prefix);
 extern int cmd_rm(int argc, const char **argv, const char *prefix);
 extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
+extern int cmd_send_pack(int argc, const char **argv, const char *prefix);
 extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
 extern int cmd_show(int argc, const char **argv, const char *prefix);
 extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
diff --git a/git.c b/git.c
index 1b182e2..4893a85 100644
--- a/git.c
+++ b/git.c
@@ -370,6 +370,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
 		{ "rm", cmd_rm, RUN_SETUP | NEED_WORK_TREE },
 		{ "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },
+		{ "send-pack", cmd_send_pack, RUN_SETUP },
 		{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
 		{ "show-branch", cmd_show_branch, RUN_SETUP },
 		{ "show", cmd_show, RUN_SETUP | USE_PAGER },
diff --git a/send-pack.h b/send-pack.h
new file mode 100644
index 0000000..7a24f71
--- /dev/null
+++ b/send-pack.h
@@ -0,0 +1,17 @@
+#ifndef SEND_PACK_H
+#define SEND_PACK_H
+
+struct send_pack_args {
+	const char *receivepack;
+	unsigned verbose:1,
+		send_all:1,
+		force_update:1,
+		use_thin_pack:1,
+		dry_run:1;
+};
+
+int send_pack(struct send_pack_args *args,
+	      const char *dest, struct remote *remote,
+	      int nr_heads, const char **heads);
+
+#endif
-- 
1.5.3.4.1206.g5f96

^ permalink raw reply related

* Re: [PATCH 3/4] Build-in send-pack, with an API for other programs to call.
From: Daniel Barkalow @ 2007-10-30  1:19 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20071030011401.GU14735@spearce.org>

On Mon, 29 Oct 2007, Shawn O. Pearce wrote:

> Daniel Barkalow <barkalow@iabervon.org> wrote:
> > -int main(int argc, char **argv)
> > +void setup_send_pack(struct send_pack_args *args)
> > +{
> > +	receivepack = args->receivepack;
> > +	verbose = args->verbose;
> > +	send_all = args->send_all;
> > +	force_update = args->force_update;
> > +	use_thin_pack = args->use_thin_pack;
> > +	dry_run = args->dry_run;
> > +}
> ...
> > +struct send_pack_args {
> > +	const char *receivepack;
> > +	int verbose;
> > +	int send_all;
> > +	int force_update;
> > +	int use_thin_pack;
> > +	int dry_run;
> > +};
> > +
> 
> Ick.  How about doing what I did with builtin-fetch-pack.c which
> was to copy the args into a global "static struct fetch_pack_args"
> and make the struct a bitfield with these boolean items as ":1"
> rather than a full int?

Yeah, that's better. I'll respin parts 3 and 4 that way.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [PATCH 3/4] Build-in send-pack, with an API for other programs to call.
From: Shawn O. Pearce @ 2007-10-30  1:18 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <20071030011401.GU14735@spearce.org>

"Shawn O. Pearce" <spearce@spearce.org> wrote:
> Daniel Barkalow <barkalow@iabervon.org> wrote:
> > -int main(int argc, char **argv)
> > +void setup_send_pack(struct send_pack_args *args)
> > +{
> > +	receivepack = args->receivepack;
> > +	verbose = args->verbose;
> > +	send_all = args->send_all;
> > +	force_update = args->force_update;
> > +	use_thin_pack = args->use_thin_pack;
> > +	dry_run = args->dry_run;
> > +}
> ...
> > +struct send_pack_args {
> > +	const char *receivepack;
> > +	int verbose;
> > +	int send_all;
> > +	int force_update;
> > +	int use_thin_pack;
> > +	int dry_run;
> > +};
> > +
> 
> Ick.  How about doing what I did with builtin-fetch-pack.c [...]

To be more precise please refer to the following fetch-pack changes:

  fa74052922: Always obtain fetch-pack arguments from struct fetch_pack_args
  bbaf458428: Use 'unsigned:1' when we mean boolean options

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH 3/4] Build-in send-pack, with an API for other programs to call.
From: Shawn O. Pearce @ 2007-10-30  1:14 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0710292049350.7357@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> wrote:
> -int main(int argc, char **argv)
> +void setup_send_pack(struct send_pack_args *args)
> +{
> +	receivepack = args->receivepack;
> +	verbose = args->verbose;
> +	send_all = args->send_all;
> +	force_update = args->force_update;
> +	use_thin_pack = args->use_thin_pack;
> +	dry_run = args->dry_run;
> +}
...
> +struct send_pack_args {
> +	const char *receivepack;
> +	int verbose;
> +	int send_all;
> +	int force_update;
> +	int use_thin_pack;
> +	int dry_run;
> +};
> +

Ick.  How about doing what I did with builtin-fetch-pack.c which
was to copy the args into a global "static struct fetch_pack_args"
and make the struct a bitfield with these boolean items as ":1"
rather than a full int?

-- 
Shawn.

^ permalink raw reply

* [PATCH 4/4] Use built-in send-pack.
From: Daniel Barkalow @ 2007-10-30  1:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 transport.c |   53 ++++++++++++-----------------------------------------
 1 files changed, 12 insertions(+), 41 deletions(-)

diff --git a/transport.c b/transport.c
index 89b73dc..e4344b8 100644
--- a/transport.c
+++ b/transport.c
@@ -6,6 +6,7 @@
 #endif
 #include "pkt-line.h"
 #include "fetch-pack.h"
+#include "send-pack.h"
 #include "walker.h"
 #include "bundle.h"
 #include "dir.h"
@@ -653,48 +654,18 @@ static int fetch_refs_via_pack(struct transport *transport,
 
 static int git_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags) {
 	struct git_transport_data *data = transport->data;
-	const char **argv;
-	char *rem;
-	int argc;
-	int err;
+	struct send_pack_args args;
 
-	argv = xmalloc((refspec_nr + 11) * sizeof(char *));
-	argv[0] = "send-pack";
-	argc = 1;
-	if (flags & TRANSPORT_PUSH_ALL)
-		argv[argc++] = "--all";
-	if (flags & TRANSPORT_PUSH_FORCE)
-		argv[argc++] = "--force";
-	if (flags & TRANSPORT_PUSH_DRY_RUN)
-		argv[argc++] = "--dry-run";
-	if (data->receivepack) {
-		char *rp = xmalloc(strlen(data->receivepack) + 16);
-		sprintf(rp, "--receive-pack=%s", data->receivepack);
-		argv[argc++] = rp;
-	}
-	if (data->thin)
-		argv[argc++] = "--thin";
-	rem = xmalloc(strlen(transport->remote->name) + 10);
-	sprintf(rem, "--remote=%s", transport->remote->name);
-	argv[argc++] = rem;
-	argv[argc++] = transport->url;
-	while (refspec_nr--)
-		argv[argc++] = *refspec++;
-	argv[argc] = NULL;
-	err = run_command_v_opt(argv, RUN_GIT_CMD);
-	switch (err) {
-	case -ERR_RUN_COMMAND_FORK:
-		error("unable to fork for %s", argv[0]);
-	case -ERR_RUN_COMMAND_EXEC:
-		error("unable to exec %s", argv[0]);
-		break;
-	case -ERR_RUN_COMMAND_WAITPID:
-	case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
-	case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
-	case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
-		error("%s died with strange error", argv[0]);
-	}
-	return !!err;
+	args.receivepack = data->receivepack;
+	args.send_all = !!(flags & TRANSPORT_PUSH_ALL);
+	args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
+	args.use_thin_pack = data->thin;
+	args.verbose = transport->verbose;
+	args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
+
+	setup_send_pack(&args);
+
+	return send_pack(transport->url, transport->remote, refspec_nr, refspec);
 }
 
 static int disconnect_git(struct transport *transport)
-- 
1.5.3.4.1206.g5f96

^ permalink raw reply related

* [PATCH 3/4] Build-in send-pack, with an API for other programs to call.
From: Daniel Barkalow @ 2007-10-30  1:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Also marks some more things as const, as needed.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 Makefile                           |    1 +
 send-pack.c => builtin-send-pack.c |   40 +++++++++++++++++++++++++----------
 builtin.h                          |    1 +
 git.c                              |    1 +
 send-pack.h                        |   18 ++++++++++++++++
 5 files changed, 49 insertions(+), 12 deletions(-)
 rename send-pack.c => builtin-send-pack.c (93%)
 create mode 100644 send-pack.h

diff --git a/Makefile b/Makefile
index 64ad297..8b0c8cd 100644
--- a/Makefile
+++ b/Makefile
@@ -359,6 +359,7 @@ BUILTIN_OBJS = \
 	builtin-push.o \
 	builtin-read-tree.o \
 	builtin-reflog.o \
+	builtin-send-pack.o \
 	builtin-config.o \
 	builtin-rerere.o \
 	builtin-reset.o \
diff --git a/send-pack.c b/builtin-send-pack.c
similarity index 93%
rename from send-pack.c
rename to builtin-send-pack.c
index fe56617..931f994 100644
--- a/send-pack.c
+++ b/builtin-send-pack.c
@@ -5,6 +5,7 @@
 #include "pkt-line.h"
 #include "run-command.h"
 #include "remote.h"
+#include "send-pack.h"
 
 static const char send_pack_usage[] =
 "git-send-pack [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
@@ -178,7 +179,7 @@ static int receive_status(int in)
 	return ret;
 }
 
-static int send_pack(int in, int out, struct remote *remote, int nr_refspec, const char **refspec)
+static int do_send_pack(int in, int out, struct remote *remote, int nr_refspec, const char **refspec)
 {
 	struct ref *ref;
 	int new_refs;
@@ -360,22 +361,27 @@ static void verify_remote_names(int nr_heads, const char **heads)
 	}
 }
 
-int main(int argc, char **argv)
+void setup_send_pack(struct send_pack_args *args)
+{
+	receivepack = args->receivepack;
+	verbose = args->verbose;
+	send_all = args->send_all;
+	force_update = args->force_update;
+	use_thin_pack = args->use_thin_pack;
+	dry_run = args->dry_run;
+}
+
+int cmd_send_pack(int argc, const char **argv, const char *prefix)
 {
 	int i, nr_heads = 0;
-	char *dest = NULL;
 	const char **heads = NULL;
-	int fd[2], ret;
-	pid_t pid;
-	char *remote_name = NULL;
+	const char *remote_name = NULL;
 	struct remote *remote = NULL;
-
-	setup_git_directory();
-	git_config(git_default_config);
+	const char *dest = NULL;
 
 	argv++;
 	for (i = 1; i < argc; i++, argv++) {
-		char *arg = *argv;
+		const char *arg = *argv;
 
 		if (*arg == '-') {
 			if (!prefixcmp(arg, "--receive-pack=")) {
@@ -424,7 +430,6 @@ int main(int argc, char **argv)
 		usage(send_pack_usage);
 	if (heads && send_all)
 		usage(send_pack_usage);
-	verify_remote_names(nr_heads, heads);
 
 	if (remote_name) {
 		remote = remote_get(remote_name);
@@ -434,10 +439,21 @@ int main(int argc, char **argv)
 		}
 	}
 
+	return send_pack(dest, remote, nr_heads, heads);
+}
+
+int send_pack(const char *dest, struct remote *remote,
+	      int nr_heads, const char **heads)
+{
+	int fd[2], ret;
+	pid_t pid;
+
+	verify_remote_names(nr_heads, heads);
+
 	pid = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0);
 	if (pid < 0)
 		return 1;
-	ret = send_pack(fd[0], fd[1], remote, nr_heads, heads);
+	ret = do_send_pack(fd[0], fd[1], remote, nr_heads, heads);
 	close(fd[0]);
 	close(fd[1]);
 	ret |= finish_connect(pid);
diff --git a/builtin.h b/builtin.h
index ff84835..51747c7 100644
--- a/builtin.h
+++ b/builtin.h
@@ -69,6 +69,7 @@ extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
 extern int cmd_revert(int argc, const char **argv, const char *prefix);
 extern int cmd_rm(int argc, const char **argv, const char *prefix);
 extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
+extern int cmd_send_pack(int argc, const char **argv, const char *prefix);
 extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
 extern int cmd_show(int argc, const char **argv, const char *prefix);
 extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
diff --git a/git.c b/git.c
index 1b182e2..4893a85 100644
--- a/git.c
+++ b/git.c
@@ -370,6 +370,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
 		{ "rm", cmd_rm, RUN_SETUP | NEED_WORK_TREE },
 		{ "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },
+		{ "send-pack", cmd_send_pack, RUN_SETUP },
 		{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
 		{ "show-branch", cmd_show_branch, RUN_SETUP },
 		{ "show", cmd_show, RUN_SETUP | USE_PAGER },
diff --git a/send-pack.h b/send-pack.h
new file mode 100644
index 0000000..22b0624
--- /dev/null
+++ b/send-pack.h
@@ -0,0 +1,18 @@
+#ifndef SEND_PACK_H
+#define SEND_PACK_H
+
+struct send_pack_args {
+	const char *receivepack;
+	int verbose;
+	int send_all;
+	int force_update;
+	int use_thin_pack;
+	int dry_run;
+};
+
+void setup_send_pack(struct send_pack_args *args);
+
+int send_pack(const char *dest, struct remote *remote,
+	      int nr_heads, const char **heads);
+
+#endif
-- 
1.5.3.4.1206.g5f96

^ permalink raw reply related

* [PATCH 1/4] Miscellaneous const changes and utilities
From: Daniel Barkalow @ 2007-10-30  1:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

The list of remote refs in struct transport should be const, because
builtin-fetch will get confused if it changes.

The url in git_connect should be const (and work on a copy) instead of
requiring the caller to copy it.

match_refs doesn't modify the refspecs it gets.

get_fetch_map and get_remote_ref don't change the list they get.

Allow transport get_refs_list methods to modify the struct transport.

Add a function to copy a list of refs, when a function needs a mutable
copy of a const list.

Add a function to check the type of a ref, as per the code in connect.c

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 builtin-fetch.c |   10 +++++-----
 cache.h         |    2 +-
 connect.c       |   10 +++++++++-
 http-push.c     |    2 +-
 remote.c        |   32 ++++++++++++++++++++++----------
 remote.h        |   10 +++++++---
 send-pack.c     |    8 ++++----
 transport.c     |   10 +++++-----
 transport.h     |    6 +++---
 9 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index b9d2b0c..fb64353 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -29,7 +29,7 @@ static void unlock_pack_on_signal(int signo)
 }
 
 static void add_merge_config(struct ref **head,
-		           struct ref *remote_refs,
+			   const struct ref *remote_refs,
 		           struct branch *branch,
 		           struct ref ***tail)
 {
@@ -71,7 +71,7 @@ static struct ref *get_ref_map(struct transport *transport,
 	struct ref *ref_map = NULL;
 	struct ref **tail = &ref_map;
 
-	struct ref *remote_refs = transport_get_remote_refs(transport);
+	const struct ref *remote_refs = transport_get_remote_refs(transport);
 
 	if (ref_count || tags) {
 		for (i = 0; i < ref_count; i++) {
@@ -337,12 +337,12 @@ static struct ref *find_non_local_tags(struct transport *transport,
 	struct path_list new_refs = { NULL, 0, 0, 1 };
 	char *ref_name;
 	int ref_name_len;
-	unsigned char *ref_sha1;
-	struct ref *tag_ref;
+	const unsigned char *ref_sha1;
+	const struct ref *tag_ref;
 	struct ref *rm = NULL;
 	struct ref *ref_map = NULL;
 	struct ref **tail = &ref_map;
-	struct ref *ref;
+	const struct ref *ref;
 
 	for_each_ref(add_existing, &existing_refs);
 	for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
diff --git a/cache.h b/cache.h
index 27485d3..0e3848d 100644
--- a/cache.h
+++ b/cache.h
@@ -503,7 +503,7 @@ struct ref {
 #define REF_TAGS	(1u << 2)
 
 #define CONNECT_VERBOSE       (1u << 0)
-extern pid_t git_connect(int fd[2], char *url, const char *prog, int flags);
+extern pid_t git_connect(int fd[2], const char *url, const char *prog, int flags);
 extern int finish_connect(pid_t pid);
 extern int path_match(const char *path, int nr, char **match);
 extern int get_ack(int fd, unsigned char *result_sha1);
diff --git a/connect.c b/connect.c
index 3d5c4ab..2d62ea9 100644
--- a/connect.c
+++ b/connect.c
@@ -36,6 +36,11 @@ static int check_ref(const char *name, int len, unsigned int flags)
 	return !(flags & ~REF_NORMAL);
 }
 
+int check_ref_type(const struct ref *ref, int flags)
+{
+	return check_ref(ref->name, strlen(ref->name), flags);
+}
+
 /*
  * Read all the refs from the other end
  */
@@ -476,8 +481,9 @@ char *get_port(char *host)
  *
  * Does not return a negative value on error; it just dies.
  */
-pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
+pid_t git_connect(int fd[2], const char *url_orig, const char *prog, int flags)
 {
+	char *url = xstrdup(url_orig);
 	char *host, *path = url;
 	char *end;
 	int c;
@@ -566,6 +572,7 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
 			     prog, path, 0,
 			     target_host, 0);
 		free(target_host);
+		free(url);
 		if (free_path)
 			free(path);
 		return 0;
@@ -623,6 +630,7 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
 	fd[1] = pipefd[1][1];
 	close(pipefd[0][1]);
 	close(pipefd[1][0]);
+	free(url);
 	if (free_path)
 		free(path);
 	return pid;
diff --git a/http-push.c b/http-push.c
index c02a3af..f461bb3 100644
--- a/http-push.c
+++ b/http-push.c
@@ -2389,7 +2389,7 @@ int main(int argc, char **argv)
 	if (!remote_tail)
 		remote_tail = &remote_refs;
 	if (match_refs(local_refs, remote_refs, &remote_tail,
-		       nr_refspec, refspec, push_all))
+		       nr_refspec, (const char **) refspec, push_all))
 		return -1;
 	if (!remote_refs) {
 		fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
diff --git a/remote.c b/remote.c
index 170015a..ec89c97 100644
--- a/remote.c
+++ b/remote.c
@@ -485,7 +485,7 @@ struct ref *alloc_ref(unsigned namelen)
 	return ret;
 }
 
-static struct ref *copy_ref(struct ref *ref)
+static struct ref *copy_ref(const struct ref *ref)
 {
 	struct ref *ret = xmalloc(sizeof(struct ref) + strlen(ref->name) + 1);
 	memcpy(ret, ref, sizeof(struct ref) + strlen(ref->name) + 1);
@@ -493,6 +493,18 @@ static struct ref *copy_ref(struct ref *ref)
 	return ret;
 }
 
+struct ref *copy_ref_list(const struct ref *ref)
+{
+	struct ref *ret = NULL;
+	struct ref **tail = &ret;
+	while (ref) {
+		*tail = copy_ref(ref);
+		ref = ref->next;
+		tail = &((*tail)->next);
+	}
+	return ret;
+}
+
 void free_refs(struct ref *ref)
 {
 	struct ref *next;
@@ -710,7 +722,7 @@ static const struct refspec *check_pattern_match(const struct refspec *rs,
  * without thinking.
  */
 int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
-	       int nr_refspec, char **refspec, int all)
+	       int nr_refspec, const char **refspec, int all)
 {
 	struct refspec *rs =
 		parse_ref_spec(nr_refspec, (const char **) refspec);
@@ -810,10 +822,10 @@ int branch_merge_matches(struct branch *branch,
 	return ref_matches_abbrev(branch->merge[i]->src, refname);
 }
 
-static struct ref *get_expanded_map(struct ref *remote_refs,
+static struct ref *get_expanded_map(const struct ref *remote_refs,
 				    const struct refspec *refspec)
 {
-	struct ref *ref;
+	const struct ref *ref;
 	struct ref *ret = NULL;
 	struct ref **tail = &ret;
 
@@ -824,7 +836,7 @@ static struct ref *get_expanded_map(struct ref *remote_refs,
 		if (strchr(ref->name, '^'))
 			continue; /* a dereference item */
 		if (!prefixcmp(ref->name, refspec->src)) {
-			char *match;
+			const char *match;
 			struct ref *cpy = copy_ref(ref);
 			match = ref->name + remote_prefix_len;
 
@@ -842,9 +854,9 @@ static struct ref *get_expanded_map(struct ref *remote_refs,
 	return ret;
 }
 
-static struct ref *find_ref_by_name_abbrev(struct ref *refs, const char *name)
+static const struct ref *find_ref_by_name_abbrev(const struct ref *refs, const char *name)
 {
-	struct ref *ref;
+	const struct ref *ref;
 	for (ref = refs; ref; ref = ref->next) {
 		if (ref_matches_abbrev(name, ref->name))
 			return ref;
@@ -852,9 +864,9 @@ static struct ref *find_ref_by_name_abbrev(struct ref *refs, const char *name)
 	return NULL;
 }
 
-struct ref *get_remote_ref(struct ref *remote_refs, const char *name)
+struct ref *get_remote_ref(const struct ref *remote_refs, const char *name)
 {
-	struct ref *ref = find_ref_by_name_abbrev(remote_refs, name);
+	const struct ref *ref = find_ref_by_name_abbrev(remote_refs, name);
 
 	if (!ref)
 		die("Couldn't find remote ref %s\n", name);
@@ -887,7 +899,7 @@ static struct ref *get_local_ref(const char *name)
 	return ret;
 }
 
-int get_fetch_map(struct ref *remote_refs,
+int get_fetch_map(const struct ref *remote_refs,
 		  const struct refspec *refspec,
 		  struct ref ***tail)
 {
diff --git a/remote.h b/remote.h
index c62636d..723c21a 100644
--- a/remote.h
+++ b/remote.h
@@ -44,6 +44,10 @@ struct refspec {
 
 struct ref *alloc_ref(unsigned namelen);
 
+struct ref *copy_ref_list(const struct ref *ref);
+
+int check_ref_type(const struct ref *ref, int flags);
+
 /*
  * Frees the entire list and peers of elements.
  */
@@ -57,7 +61,7 @@ void ref_remove_duplicates(struct ref *ref_map);
 struct refspec *parse_ref_spec(int nr_refspec, const char **refspec);
 
 int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
-	       int nr_refspec, char **refspec, int all);
+	       int nr_refspec, const char **refspec, int all);
 
 /*
  * Given a list of the remote refs and the specification of things to
@@ -68,10 +72,10 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
  * beforehand, and will be set to the tail pointer of the list of
  * results afterward.
  */
-int get_fetch_map(struct ref *remote_refs, const struct refspec *refspec,
+int get_fetch_map(const struct ref *remote_refs, const struct refspec *refspec,
 		  struct ref ***tail);
 
-struct ref *get_remote_ref(struct ref *remote_refs, const char *name);
+struct ref *get_remote_ref(const struct ref *remote_refs, const char *name);
 
 /*
  * For the given remote, reads the refspec's src and sets the other fields.
diff --git a/send-pack.c b/send-pack.c
index e9b9a39..fe56617 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -178,7 +178,7 @@ static int receive_status(int in)
 	return ret;
 }
 
-static int send_pack(int in, int out, struct remote *remote, int nr_refspec, char **refspec)
+static int send_pack(int in, int out, struct remote *remote, int nr_refspec, const char **refspec)
 {
 	struct ref *ref;
 	int new_refs;
@@ -339,7 +339,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
 	return ret;
 }
 
-static void verify_remote_names(int nr_heads, char **heads)
+static void verify_remote_names(int nr_heads, const char **heads)
 {
 	int i;
 
@@ -364,7 +364,7 @@ int main(int argc, char **argv)
 {
 	int i, nr_heads = 0;
 	char *dest = NULL;
-	char **heads = NULL;
+	const char **heads = NULL;
 	int fd[2], ret;
 	pid_t pid;
 	char *remote_name = NULL;
@@ -416,7 +416,7 @@ int main(int argc, char **argv)
 			dest = arg;
 			continue;
 		}
-		heads = argv;
+		heads = (const char **) argv;
 		nr_heads = argc - i;
 		break;
 	}
diff --git a/transport.c b/transport.c
index 400af71..89b73dc 100644
--- a/transport.c
+++ b/transport.c
@@ -141,7 +141,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
 	}
 }
 
-static struct ref *get_refs_via_rsync(const struct transport *transport)
+static struct ref *get_refs_via_rsync(struct transport *transport)
 {
 	struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
 	struct ref dummy, *tail = &dummy;
@@ -427,7 +427,7 @@ static int missing__target(int code, int result)
 
 #define missing_target(a) missing__target((a)->http_code, (a)->curl_result)
 
-static struct ref *get_refs_via_curl(const struct transport *transport)
+static struct ref *get_refs_via_curl(struct transport *transport)
 {
 	struct buffer buffer;
 	char *data, *start, *mid;
@@ -524,7 +524,7 @@ struct bundle_transport_data {
 	struct bundle_header header;
 };
 
-static struct ref *get_refs_from_bundle(const struct transport *transport)
+static struct ref *get_refs_from_bundle(struct transport *transport)
 {
 	struct bundle_transport_data *data = transport->data;
 	struct ref *result = NULL;
@@ -596,7 +596,7 @@ static int set_git_option(struct transport *connection,
 	return 1;
 }
 
-static struct ref *get_refs_via_connect(const struct transport *transport)
+static struct ref *get_refs_via_connect(struct transport *transport)
 {
 	struct git_transport_data *data = transport->data;
 	struct ref *refs;
@@ -786,7 +786,7 @@ int transport_push(struct transport *transport,
 	return transport->push(transport, refspec_nr, refspec, flags);
 }
 
-struct ref *transport_get_remote_refs(struct transport *transport)
+const struct ref *transport_get_remote_refs(struct transport *transport)
 {
 	if (!transport->remote_refs)
 		transport->remote_refs = transport->get_refs_list(transport);
diff --git a/transport.h b/transport.h
index df12ea7..d27f562 100644
--- a/transport.h
+++ b/transport.h
@@ -8,7 +8,7 @@ struct transport {
 	struct remote *remote;
 	const char *url;
 	void *data;
-	struct ref *remote_refs;
+	const struct ref *remote_refs;
 
 	/**
 	 * Returns 0 if successful, positive if the option is not
@@ -18,7 +18,7 @@ struct transport {
 	int (*set_option)(struct transport *connection, const char *name,
 			  const char *value);
 
-	struct ref *(*get_refs_list)(const struct transport *transport);
+	struct ref *(*get_refs_list)(struct transport *transport);
 	int (*fetch)(struct transport *transport, int refs_nr, struct ref **refs);
 	int (*push)(struct transport *connection, int refspec_nr, const char **refspec, int flags);
 
@@ -61,7 +61,7 @@ int transport_set_option(struct transport *transport, const char *name,
 int transport_push(struct transport *connection,
 		   int refspec_nr, const char **refspec, int flags);
 
-struct ref *transport_get_remote_refs(struct transport *transport);
+const struct ref *transport_get_remote_refs(struct transport *transport);
 
 int transport_fetch_refs(struct transport *transport, struct ref *refs);
 void transport_unlock_pack(struct transport *transport);
-- 
1.5.3.4.1206.g5f96

^ permalink raw reply related

* [PATCH 2/4] Build-in peek-remote, using transport infrastructure.
From: Daniel Barkalow @ 2007-10-30  1:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 Makefile                               |    3 +-
 peek-remote.c => builtin-peek-remote.c |   55 ++++++++++++++-----------------
 builtin.h                              |    1 +
 git.c                                  |    1 +
 4 files changed, 29 insertions(+), 31 deletions(-)
 rename peek-remote.c => builtin-peek-remote.c (59%)

diff --git a/Makefile b/Makefile
index 72f5ef4..64ad297 100644
--- a/Makefile
+++ b/Makefile
@@ -240,7 +240,7 @@ PROGRAMS = \
 	git-fast-import$X \
 	git-daemon$X \
 	git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \
-	git-peek-remote$X git-receive-pack$X \
+	git-receive-pack$X \
 	git-send-pack$X git-shell$X \
 	git-show-index$X \
 	git-unpack-file$X \
@@ -353,6 +353,7 @@ BUILTIN_OBJS = \
 	builtin-mv.o \
 	builtin-name-rev.o \
 	builtin-pack-objects.o \
+	builtin-peek-remote.o \
 	builtin-prune.o \
 	builtin-prune-packed.o \
 	builtin-push.o \
diff --git a/peek-remote.c b/builtin-peek-remote.c
similarity index 59%
rename from peek-remote.c
rename to builtin-peek-remote.c
index ceb7871..b4106f5 100644
--- a/peek-remote.c
+++ b/builtin-peek-remote.c
@@ -1,38 +1,26 @@
+#include "builtin.h"
 #include "cache.h"
-#include "refs.h"
-#include "pkt-line.h"
+#include "transport.h"
+#include "remote.h"
 
 static const char peek_remote_usage[] =
 "git-peek-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>";
-static const char *uploadpack = "git-upload-pack";
 
-static int peek_remote(int fd[2], unsigned flags)
+int cmd_peek_remote(int argc, const char **argv, const char *prefix)
 {
-	struct ref *ref;
-
-	get_remote_heads(fd[0], &ref, 0, NULL, flags);
-	packet_flush(fd[1]);
-
-	while (ref) {
-		printf("%s	%s\n", sha1_to_hex(ref->old_sha1), ref->name);
-		ref = ref->next;
-	}
-	return 0;
-}
-
-int main(int argc, char **argv)
-{
-	int i, ret;
-	char *dest = NULL;
-	int fd[2];
-	pid_t pid;
+	int i;
+	const char *dest = NULL;
 	int nongit = 0;
 	unsigned flags = 0;
+	const char *uploadpack = NULL;
+
+	struct transport *transport;
+	const struct ref *ref;
 
 	setup_git_directory_gently(&nongit);
 
 	for (i = 1; i < argc; i++) {
-		char *arg = argv[i];
+		const char *arg = argv[i];
 
 		if (*arg == '-') {
 			if (!prefixcmp(arg, "--upload-pack=")) {
@@ -64,12 +52,19 @@ int main(int argc, char **argv)
 	if (!dest || i != argc - 1)
 		usage(peek_remote_usage);
 
-	pid = git_connect(fd, dest, uploadpack, 0);
-	if (pid < 0)
+	transport = transport_get(NULL, dest);
+	if (uploadpack != NULL)
+		transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
+
+	ref = transport_get_remote_refs(transport);
+
+	if (!ref)
 		return 1;
-	ret = peek_remote(fd, flags);
-	close(fd[0]);
-	close(fd[1]);
-	ret |= finish_connect(pid);
-	return !!ret;
+
+	while (ref) {
+		if (check_ref_type(ref, flags))
+			printf("%s	%s\n", sha1_to_hex(ref->old_sha1), ref->name);
+		ref = ref->next;
+	}
+	return 0;
 }
diff --git a/builtin.h b/builtin.h
index 65cc0fb..ff84835 100644
--- a/builtin.h
+++ b/builtin.h
@@ -54,6 +54,7 @@ extern int cmd_merge_file(int argc, const char **argv, const char *prefix);
 extern int cmd_mv(int argc, const char **argv, const char *prefix);
 extern int cmd_name_rev(int argc, const char **argv, const char *prefix);
 extern int cmd_pack_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_peek_remote(int argc, const char **argv, const char *prefix);
 extern int cmd_pickaxe(int argc, const char **argv, const char *prefix);
 extern int cmd_prune(int argc, const char **argv, const char *prefix);
 extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
diff --git a/git.c b/git.c
index 23a430c..1b182e2 100644
--- a/git.c
+++ b/git.c
@@ -355,6 +355,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
 		{ "name-rev", cmd_name_rev, RUN_SETUP },
 		{ "pack-objects", cmd_pack_objects, RUN_SETUP },
+		{ "peek-remote", cmd_peek_remote },
 		{ "pickaxe", cmd_blame, RUN_SETUP },
 		{ "prune", cmd_prune, RUN_SETUP },
 		{ "prune-packed", cmd_prune_packed, RUN_SETUP },
-- 
1.5.3.4.1206.g5f96

^ permalink raw reply related

* [PATCH 0/4] Build in some more things
From: Daniel Barkalow @ 2007-10-30  1:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

The main effect of this series is removing the fork/exec from pushing via 
the git protocol (aside from the later fork/exec in connect.c of course).

It also heads off some tempting transport-related fetch bugs, which I will 
not introduce in a later patch.

* Miscellaneous const changes and utilities
  Adds two small utility functions, and marks a bunch of stuff as const; 
  the const stuff is to keep builtin-fetch from getting messed up without 
  a warning, because it wants some lists not to change.

* Build-in peek-remote, using transport infrastructure.
* Build-in send-pack, with an API for other programs to call.
* Use built-in send-pack.

 Makefile                               |    4 ++-
 builtin-fetch.c                        |   10 +++---
 peek-remote.c => builtin-peek-remote.c |   55 +++++++++++++---------------
 send-pack.c => builtin-send-pack.c     |   46 ++++++++++++++++--------
 builtin.h                              |    2 +
 cache.h                                |    2 +-
 connect.c                              |   10 +++++-
 git.c                                  |    2 +
 http-push.c                            |    2 +-
 remote.c                               |   32 +++++++++++-----
 remote.h                               |   10 ++++--
 send-pack.h                            |   18 +++++++++
 transport.c                            |   63 +++++++++-----------------------
 transport.h                            |    6 ++--
 14 files changed, 146 insertions(+), 116 deletions(-)

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: How to merge git://repo.or.cz/git-gui into git.git
From: Shawn O. Pearce @ 2007-10-30  0:52 UTC (permalink / raw)
  To: Yin Ping; +Cc: Peter Baumann, git
In-Reply-To: <46dff0320710282345r2922ac7dj9c7a4eb3e20fd011@mail.gmail.com>

Yin Ping <pkufranky@gmail.com> wrote:
> On 10/28/07, Peter Baumann <waste.manager@gmx.de> wrote:
> >
> > Have a look at the subtree merge strategy [1] and at the following
> > explanations how git-gui got initally merged.
> >
> > -Peter
> >
> > [1]: http://www.gelato.unsw.edu.au/archives/git/0702/40139.html
> > [2]: http://www.gelato.unsw.edu.au/archives/git/0702/39661.html
> 
> When i merged git.git into git-gui with subtree strategy, I found all
> histories of git.git merged into histories of git-gui (from 584
> history entries to 11985). Is it possible that only histories related
> to git-gui subdirectory in git.git(i.e. histories displayed by git-log
> git-gui) are  merged into?
> 
> 2. pull with subtree strategy
> ~/git-gui$  git-pull -s subtree git master:master

You are merging in the wrong direction.  You want to merge git-gui
into git.git:

	git clone git://repo.or.cz/alt-git.git mygit
	cd mygit
	git pull -s subtree git://repo.or.cz/git-gui.git master

So you are pulling git-gui into git, not the reverse.  But yes,
when this happens the entire history of the pulled project (in the
above case git-gui) suddenly appears in the history of the parent
project (in this case git).  If you don't want this to happen then
you need to make git-gui into a submodule.  That has been talked
about being done, but hasn't happened yet in the main git repository.
git-gui is currently still being subtree merged in.

-- 
Shawn.

^ permalink raw reply

* Re: backup or mirror a repository
From: Johannes Schindelin @ 2007-10-30  0:33 UTC (permalink / raw)
  To: Dmitry Potapov; +Cc: Dan Farina, Junio C Hamano, git
In-Reply-To: <20071018053226.GA20588@dpotapov.dyndns.org>

Hi,

On Thu, 18 Oct 2007, Dmitry Potapov wrote:

> On Thu, Sep 27, 2007 at 11:27:06PM -0700, Junio C Hamano wrote:
> > The "git remote add --mirror" setup is about setting up the
> > local repository _AS_ the backup of the remote.  In other words,
> > the contents come from the remote by fetching from it and safely
> > kept away from disaster on the local side.  And for that,
> > "remote prune" is a perfect thing to do.
> 
> I have tried to do that but I am getting a warning:
> $ git remote prune origin
> Warning: unrecognized mapping in remotes.origin.fetch: +refs/*:refs/*
> and no branch is removed.
> 
> I suspect that the change that introduced --mirror option for the 'add' 
> command did not adjust the prune procedure to handle the new situation 
> properly. Or is just me doing something wrong?

No, you're right.  I did not anticipate git-remote to be written the way 
it is.  After fiddling with it for several hours, I am giving up for now.  
IMHO the script is too married to the idea that the remote branches live 
in refs/remotes/<remote>/*.  Probably it would be very easy by now to 
implement it as a builtin, using remote.[ch].

Ciao,
Dscho

^ permalink raw reply

* [PATCH (resend)] gitweb: Fix and simplify "split patch" detection
From: Jakub Narebski @ 2007-10-30  0:35 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski

There are some cases when one line from "raw" git-diff output (raw
format) corresponds to more than one patch in the patchset git-diff
output; we call this situation "split patch". Old code misdetected
subsequent patches (for different files) with the same pre-image and
post-image as fragments of "split patch", leading to mislabeled
from-file/to-file diff header etc.

Old code used pre-image and post-image SHA-1 identifier ('from_id' and
'to_id') to check if current patch corresponds to old raw diff format
line, to find if one difftree raw line coresponds to more than one
patch in the patch format.  Now we use post-image filename for that.
This assumes that post-image filename alone can be used to identify
difftree raw line.  In the case this changes (which is unlikely
considering current diff engine) we can add 'from_id' and 'to_id'
to detect "patch splitting" together with 'to_file'.

Because old code got pre-image and post-image SHA-1 identifier for the
patch from the "index" line in extended diff header, diff header had
to be buffered.  New code takes post-image filename from "git diff"
header, which is first line of a patch; this allows to simplify
git_patchset_body code.  A side effect of resigning diff header
buffering is that there is always "diff extended_header" div, even
if extended diff header is empty.


Alternate solution would be to check when git splits patches, and do
not check if parsed info from current patch corresponds to current or
next raw diff format output line.  Git splits patches only for 'T'
(typechange) status filepair, and there always two patches
corresponding to one raw diff line.  It was not used because it would
tie gitweb code to minute details of git diff output.


While at it, use newly introduced parsed_difftree_line wrapper
subroutine in git_difftree_body.

Noticed-by: Yann Dirson <ydirson@altern.org>
Diagnosed-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
Junio has decided in
  Message-ID: <7vmyw4ob7z.fsf@gitster.siamese.dyndns.org>
that tying gitweb to minute details of git diff output, namely that
we have "split patch" (two patches of patchset diff format for single
line of raw ditt format) only for typechange (status 'T') diffs.

We make other assumption instead, that post-image filename uniquely
defines line of raw git diff output. Currently diffcore is not
capable of producing other output; see Junio in
  Message-ID: <7vtzqcj9ni.fsf@gitster.siamese.dyndns.org>
This assumption simplifies git_patchset_body, as we no longer need
to cache extended diff header for "split patch" detection.

 gitweb/gitweb.perl |  152 +++++++++++++++++++++++-----------------------------
 1 files changed, 67 insertions(+), 85 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 48e21da..1537b0e 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2000,6 +2000,19 @@ sub parse_difftree_raw_line {
 	return wantarray ? %res : \%res;
 }
 
+# wrapper: return parsed line of git-diff-tree "raw" output
+# (the argument might be raw line, or parsed info)
+sub parsed_difftree_line {
+	my $line_or_ref = shift;
+
+	if (ref($line_or_ref) eq "HASH") {
+		# pre-parsed (or generated by hand)
+		return $line_or_ref;
+	} else {
+		return parse_difftree_raw_line($line_or_ref);
+	}
+}
+
 # parse line of git-ls-tree output
 sub parse_ls_tree_line ($;%) {
 	my $line = shift;
@@ -2043,6 +2056,7 @@ sub parse_from_to_diffinfo {
 			}
 		}
 	} else {
+		# ordinary (not combined) diff
 		$from->{'file'} = $diffinfo->{'from_file'} || $diffinfo->{'file'};
 		if ($diffinfo->{'status'} ne "A") { # not new (added) file
 			$from->{'href'} = href(action=>"blob", hash_base=>$hash_parent,
@@ -2766,6 +2780,7 @@ sub git_print_tree_entry {
 ## ......................................................................
 ## functions printing large fragments of HTML
 
+# get pre-image filenames for merge (combined) diff
 sub fill_from_file_info {
 	my ($diff, @parents) = @_;
 
@@ -2782,28 +2797,25 @@ sub fill_from_file_info {
 	return $diff;
 }
 
-# parameters can be strings, or references to arrays of strings
-sub from_ids_eq {
-	my ($a, $b) = @_;
-
-	if (ref($a) eq "ARRAY" && ref($b) eq "ARRAY" && @$a == @$b) {
-		for (my $i = 0; $i < @$a; ++$i) {
-			return 0 unless ($a->[$i] eq $b->[$i]);
-		}
-		return 1;
-	} elsif (!ref($a) && !ref($b)) {
-		return $a eq $b;
-	} else {
-		return 0;
-	}
-}
-
+# is current raw difftree line of file deletion
 sub is_deleted {
 	my $diffinfo = shift;
 
 	return $diffinfo->{'to_id'} eq ('0' x 40);
 }
 
+# does patch correspond to [previous] difftree raw line
+# $diffinfo  - hashref of parsed raw diff format
+# $patchinfo - hashref of parsed patch diff format
+#              (the same keys as in $diffinfo)
+sub is_patch_split {
+	my ($diffinfo, $patchinfo) = @_;
+
+	return defined $diffinfo && defined $patchinfo
+		&& ($diffinfo->{'to_file'} || $diffinfo->{'file'}) eq $patchinfo->{'to_file'};
+}
+
+
 sub git_difftree_body {
 	my ($difftree, $hash, @parents) = @_;
 	my ($parent) = $parents[0];
@@ -2840,13 +2852,7 @@ sub git_difftree_body {
 	my $alternate = 1;
 	my $patchno = 0;
 	foreach my $line (@{$difftree}) {
-		my $diff;
-		if (ref($line) eq "HASH") {
-			# pre-parsed (or generated by hand)
-			$diff = $line;
-		} else {
-			$diff = parse_difftree_raw_line($line);
-		}
+		my $diff = parsed_difftree_line($line);
 
 		if ($alternate) {
 			print "<tr class=\"dark\">\n";
@@ -3117,10 +3123,12 @@ sub git_patchset_body {
 	my ($fd, $difftree, $hash, @hash_parents) = @_;
 	my ($hash_parent) = $hash_parents[0];
 
+	my $is_combined = (@hash_parents > 1);
 	my $patch_idx = 0;
 	my $patch_number = 0;
 	my $patch_line;
 	my $diffinfo;
+	my $to_name;
 	my (%from, %to);
 
 	print "<div class=\"patchset\">\n";
@@ -3134,73 +3142,46 @@ sub git_patchset_body {
 
  PATCH:
 	while ($patch_line) {
-		my @diff_header;
-		my ($from_id, $to_id);
-
-		# git diff header
-		#assert($patch_line =~ m/^diff /) if DEBUG;
-		#assert($patch_line !~ m!$/$!) if DEBUG; # is chomp-ed
-		$patch_number++;
-		push @diff_header, $patch_line;
-
-		# extended diff header
-	EXTENDED_HEADER:
-		while ($patch_line = <$fd>) {
-			chomp $patch_line;
 
-			last EXTENDED_HEADER if ($patch_line =~ m/^--- |^diff /);
-
-			if ($patch_line =~ m/^index ([0-9a-fA-F]{40})..([0-9a-fA-F]{40})/) {
-				$from_id = $1;
-				$to_id   = $2;
-			} elsif ($patch_line =~ m/^index ((?:[0-9a-fA-F]{40},)+[0-9a-fA-F]{40})..([0-9a-fA-F]{40})/) {
-				$from_id = [ split(',', $1) ];
-				$to_id   = $2;
-			}
-
-			push @diff_header, $patch_line;
+		# parse "git diff" header line
+		if ($patch_line =~ m/^diff --git (\"(?:[^\\\"]*(?:\\.[^\\\"]*)*)\"|[^ "]*) (.*)$/) {
+			# $1 is from_name, which we do not use
+			$to_name = unquote($2);
+			$to_name =~ s!^b/!!;
+		} elsif ($patch_line =~ m/^diff --(cc|combined) ("?.*"?)$/) {
+			# $1 is 'cc' or 'combined', which we do not use
+			$to_name = unquote($2);
+		} else {
+			$to_name = undef;
 		}
-		my $last_patch_line = $patch_line;
 
 		# check if current patch belong to current raw line
 		# and parse raw git-diff line if needed
-		if (defined $diffinfo &&
-		    defined $from_id && defined $to_id &&
-		    from_ids_eq($diffinfo->{'from_id'}, $from_id) &&
-		    $diffinfo->{'to_id'} eq $to_id) {
+		if (is_patch_split($diffinfo, { 'to_file' => $to_name })) {
 			# this is continuation of a split patch
 			print "<div class=\"patch cont\">\n";
 		} else {
 			# advance raw git-diff output if needed
 			$patch_idx++ if defined $diffinfo;
 
-			# compact combined diff output can have some patches skipped
-			# find which patch (using pathname of result) we are at now
-			my $to_name;
-			if ($diff_header[0] =~ m!^diff --cc "?(.*)"?$!) {
-				$to_name = $1;
-			}
-
-			do {
-				# read and prepare patch information
-				if (ref($difftree->[$patch_idx]) eq "HASH") {
-					# pre-parsed (or generated by hand)
-					$diffinfo = $difftree->[$patch_idx];
-				} else {
-					$diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]);
-				}
+			# read and prepare patch information
+			$diffinfo = parsed_difftree_line($difftree->[$patch_idx]);
 
-				# check if current raw line has no patch (it got simplified)
-				if (defined $to_name && $to_name ne $diffinfo->{'to_file'}) {
+			# compact combined diff output can have some patches skipped
+			# find which patch (using pathname of result) we are at now;
+			if ($is_combined) {
+				while ($to_name ne $diffinfo->{'to_file'}) {
 					print "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
 					      format_diff_cc_simplified($diffinfo, @hash_parents) .
 					      "</div>\n";  # class="patch"
 
 					$patch_idx++;
 					$patch_number++;
+
+					last if $patch_idx > $#$difftree;
+					$diffinfo = parsed_difftree_line($difftree->[$patch_idx]);
 				}
-			} until (!defined $to_name || $to_name eq $diffinfo->{'to_file'} ||
-			         $patch_idx > $#$difftree);
+			}
 
 			# modifies %from, %to hashes
 			parse_from_to_diffinfo($diffinfo, \%from, \%to, @hash_parents);
@@ -3210,30 +3191,36 @@ sub git_patchset_body {
 			print "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n";
 		}
 
+		# git diff header
+		#assert($patch_line =~ m/^diff /) if DEBUG;
+		#assert($patch_line !~ m!$/$!) if DEBUG; # is chomp-ed
+		$patch_number++;
 		# print "git diff" header
-		$patch_line = shift @diff_header;
 		print format_git_diff_header_line($patch_line, $diffinfo,
 		                                  \%from, \%to);
 
 		# print extended diff header
-		print "<div class=\"diff extended_header\">\n" if (@diff_header > 0);
+		print "<div class=\"diff extended_header\">\n";
 	EXTENDED_HEADER:
-		foreach $patch_line (@diff_header) {
+		while ($patch_line = <$fd>) {
+			chomp $patch_line;
+
+			last EXTENDED_HEADER if ($patch_line =~ m/^--- |^diff /);
+
 			print format_extended_diff_header_line($patch_line, $diffinfo,
 			                                       \%from, \%to);
 		}
-		print "</div>\n"  if (@diff_header > 0); # class="diff extended_header"
+		print "</div>\n"; # class="diff extended_header"
 
 		# from-file/to-file diff header
-		$patch_line = $last_patch_line;
 		if (! $patch_line) {
 			print "</div>\n"; # class="patch"
 			last PATCH;
 		}
 		next PATCH if ($patch_line =~ m/^diff /);
 		#assert($patch_line =~ m/^---/) if DEBUG;
-		#assert($patch_line eq $last_patch_line) if DEBUG;
 
+		my $last_patch_line = $patch_line;
 		$patch_line = <$fd>;
 		chomp $patch_line;
 		#assert($patch_line =~ m/^\+\+\+/) if DEBUG;
@@ -3258,16 +3245,11 @@ sub git_patchset_body {
 
 	# for compact combined (--cc) format, with chunk and patch simpliciaction
 	# patchset might be empty, but there might be unprocessed raw lines
-	for ($patch_idx++ if $patch_number > 0;
+	for (++$patch_idx if $patch_number > 0;
 	     $patch_idx < @$difftree;
-	     $patch_idx++) {
+	     ++$patch_idx) {
 		# read and prepare patch information
-		if (ref($difftree->[$patch_idx]) eq "HASH") {
-			# pre-parsed (or generated by hand)
-			$diffinfo = $difftree->[$patch_idx];
-		} else {
-			$diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]);
-		}
+		$diffinfo = parsed_difftree_line($difftree->[$patch_idx]);
 
 		# generate anchor for "patch" links in difftree / whatchanged part
 		print "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
-- 
1.5.3

^ permalink raw reply related

* Re: [PATCH] Speedup scanning for excluded files.
From: Junio C Hamano @ 2007-10-30  0:00 UTC (permalink / raw)
  To: Morten Welinder; +Cc: Lars Knoll, git, Pierre Habouzit, Junio C Hamano
In-Reply-To: <118833cc0710291559kbd874a8o8111b9495090ef27@mail.gmail.com>

"Morten Welinder" <mwelinder@gmail.com> writes:

>> +                               } else if (x->flags & EXC_FLAG_ENDSWITH) {
>> +                                       if (!strcmp(exclude + 1, pathname + pathlen -x->patternlen + 1))
>
> Is there some guarantee that the result of that subtraction is still within
> the string?

Good eyes.

If pattern is "*.exe", patternlen is 5, and strcmp wants to
compare 4 chars, so pathlen is better be at least that long, and
we do allow that pattern to match a hidden file ".exe".

Like this?

	if (x->patternlen - 1 <= pathlen &&
        	!strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))
		return to_exclude;

^ permalink raw reply

* Re: remote#branch
From: Johannes Schindelin @ 2007-10-29 23:49 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Theodore Tso, Jan Hudec, Petr Baudis, Paolo Ciarrocchi, git
In-Reply-To: <alpine.LFD.0.999.0710291545250.30120@woody.linux-foundation.org>

Hi,

On Mon, 29 Oct 2007, Linus Torvalds wrote:

> And "standards" are only as good as they are useful. XML is a piece of 
> crap despite being a standard because it makes no sense.

To be fair, there are uses for XML.  On Halloween, for example.

Sorry, could not resist,
Dscho

^ permalink raw reply

* [PATCH 2/2] add throughput display to index-pack
From: Nicolas Pitre @ 2007-10-29 23:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

... and call it "Receiving objects" when over stdin to look clearer
to end users.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---

diff --git a/index-pack.c b/index-pack.c
index 2f149a4..d32c7b9 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -87,6 +87,8 @@ static void *fill(int min)
 				die("early EOF");
 			die("read error on input: %s", strerror(errno));
 		}
+		if (verbose && from_stdin)
+			display_throughput(&progress, ret);
 		input_len += ret;
 	} while (input_len < min);
 	return input_buffer;
@@ -406,7 +408,9 @@ static void parse_pack_objects(unsigned char *sha1)
 	 * - remember base (SHA1 or offset) for all deltas.
 	 */
 	if (verbose)
-		start_progress(&progress, "Indexing objects", nr_objects);
+		start_progress(&progress,
+			       from_stdin ? "Receiving objects" : "Indexing objects",
+			       nr_objects);
 	for (i = 0; i < nr_objects; i++) {
 		struct object_entry *obj = &objects[i];
 		data = unpack_raw_entry(obj, &delta->base);

^ permalink raw reply related

* [PATCH 1/2] add throughput to progress display
From: Nicolas Pitre @ 2007-10-29 23:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This adds the ability for the progress code to also display throughput
when that makes sense.

The math was inspired by commit c548cf4ee0737a321ffe94f6a97c65baf87281be
from Linus.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---

diff --git a/progress.c b/progress.c
index 7629e05..275579b 100644
--- a/progress.c
+++ b/progress.c
@@ -37,7 +37,7 @@ static void clear_progress_signal(void)
 
 static int display(struct progress *progress, unsigned n, int done)
 {
-	char *eol;
+	char *eol, *tp;
 
 	if (progress->delay) {
 		if (!progress_update || --progress->delay)
@@ -55,18 +55,20 @@ static int display(struct progress *progress, unsigned n, int done)
 	}
 
 	progress->last_value = n;
+	tp = (progress->throughput) ? progress->throughput->display : "";
 	eol = done ? ", done.   \n" : "   \r";
 	if (progress->total) {
 		unsigned percent = n * 100 / progress->total;
 		if (percent != progress->last_percent || progress_update) {
 			progress->last_percent = percent;
-			fprintf(stderr, "%s: %3u%% (%u/%u)%s", progress->title,
-				percent, n, progress->total, eol);
+			fprintf(stderr, "%s: %3u%% (%u/%u)%s%s",
+				progress->title, percent, n,
+				progress->total, tp, eol);
 			progress_update = 0;
 			return 1;
 		}
 	} else if (progress_update) {
-		fprintf(stderr, "%s: %u%s", progress->title, n, eol);
+		fprintf(stderr, "%s: %u%s%s", progress->title, n, tp, eol);
 		progress_update = 0;
 		return 1;
 	}
@@ -74,6 +76,59 @@ static int display(struct progress *progress, unsigned n, int done)
 	return 0;
 }
 
+void display_throughput(struct progress *progress, unsigned long n)
+{
+	struct throughput *tp = progress->throughput;
+	struct timeval tv;
+	unsigned int misecs;
+	
+	gettimeofday(&tv, NULL);
+
+	if (!tp) {
+		progress->throughput = tp = calloc(1, sizeof(*tp));
+		if (tp)
+			tp->prev_tv = tv;
+		return;
+	}
+
+	tp->count += n;
+
+	/*
+	 * We have x = bytes and y = microsecs.  We want z = KiB/s:
+	 *
+	 *	z = (x / 1024) / (y / 1000000)
+	 *	z = x / y * 1000000 / 1024
+	 *	z = x / (y * 1024 / 1000000)
+	 *	z = x / y'
+	 *
+	 * To simplify things we'll keep track of misecs, or 1024th of a sec
+	 * obtained with:
+	 *
+	 *	y' = y * 1024 / 1000000
+	 *
+	 * Taking care not to overflow y' we get:
+	 *
+	 *	y' = y / (1000000 / 1024)
+	 *	y' = y / 977
+	 */
+	misecs = (tv.tv_sec - tp->prev_tv.tv_sec) * 1024;
+	misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
+
+	if (misecs > 512) {
+		tp->prev_tv = tv;
+		tp->avg_bytes += tp->count;
+		tp->avg_misecs += misecs;
+		snprintf(tp->display, sizeof(tp->display),
+			 ", %lu KiB/s", tp->avg_bytes / tp->avg_misecs);
+		tp->avg_bytes -= tp->last_bytes[tp->idx];
+		tp->avg_misecs -= tp->last_misecs[tp->idx];
+		tp->last_bytes[tp->idx] = tp->count;
+		tp->last_misecs[tp->idx] = misecs;
+		tp->idx = (tp->idx + 1) % TP_IDX_MAX;
+		tp->count = 0;
+	}
+}
+
 int display_progress(struct progress *progress, unsigned n)
 {
 	return display(progress, n, 0);
@@ -104,4 +159,6 @@ void stop_progress(struct progress *progress)
 		display(progress, progress->last_value, 1);
 	}
 	clear_progress_signal();
+	free(progress->throughput);
+	progress->throughput = NULL;
 }
diff --git a/progress.h b/progress.h
index 07b56bd..eba457f 100644
--- a/progress.h
+++ b/progress.h
@@ -1,6 +1,21 @@
 #ifndef PROGRESS_H
 #define PROGRESS_H
 
+#include <sys/time.h>
+
+#define TP_IDX_MAX	8
+
+struct throughput {
+	struct timeval prev_tv;
+	unsigned long count;
+	unsigned long avg_bytes;
+	unsigned long last_bytes[TP_IDX_MAX];
+	unsigned int avg_misecs;
+	unsigned int last_misecs[TP_IDX_MAX];
+	unsigned int idx;
+	char display[20];
+};
+
 struct progress {
 	const char *title;
 	int last_value;
@@ -8,8 +23,10 @@ struct progress {
 	unsigned last_percent;
 	unsigned delay;
 	unsigned delayed_percent_treshold;
+	struct throughput *throughput;
 };
 
+void display_throughput(struct progress *progress, unsigned long n);
 int display_progress(struct progress *progress, unsigned n);
 void start_progress(struct progress *progress, const char *title,
 		    unsigned total);

^ permalink raw reply related

* Re: [PATCH] Speedup scanning for excluded files.
From: Morten Welinder @ 2007-10-29 22:59 UTC (permalink / raw)
  To: Lars Knoll; +Cc: git, Pierre Habouzit, Junio C Hamano
In-Reply-To: <200710290959.32538.lars@trolltech.com>

> +                               } else if (x->flags & EXC_FLAG_ENDSWITH) {
> +                                       if (!strcmp(exclude + 1, pathname + pathlen -x->patternlen + 1))

Is there some guarantee that the result of that subtraction is still within
the string?

Morten

^ permalink raw reply

* Re: remote#branch
From: Linus Torvalds @ 2007-10-29 22:57 UTC (permalink / raw)
  To: Theodore Tso
  Cc: Jan Hudec, Johannes Schindelin, Petr Baudis, Paolo Ciarrocchi,
	git
In-Reply-To: <20071029214925.GH21133@thunk.org>



On Mon, 29 Oct 2007, Theodore Tso wrote:
> 
> Well, the confusion is that we refer to things that look like
> "git://git.kernel.org/pub/scm/git/git.git" as if it were a URL.

Sure, but "URL" in human-speak has nothing to do with an RFC.

I dislike language-lawyerese. Why the hell do people think that human 
language should follow the RFC's?

Git addresses look like URL's, and they act like URL's, but dammit, git 
isn't a web browser, and it's not interested in acting like one. 

And "standards" are only as good as they are useful. XML is a piece of 
crap despite being a standard because it makes no sense. Similarly, "URL 
quoting" is a piece of crap when _it_ makes no sense. Having a RFC or an 
ISO standard doesn't change anything, and doesn't imply that human 
communication (or indeed, even machine communication) should care.

			Linus

^ permalink raw reply

* Re: [PATCH] Speedup scanning for excluded files.
From: Junio C Hamano @ 2007-10-29 22:17 UTC (permalink / raw)
  To: Lars Knoll; +Cc: git, Pierre Habouzit
In-Reply-To: <200710290959.32538.lars@trolltech.com>

Thanks.  This looks obviously correct and tempts me to apply
directly to 'master'.

There are similar logic on the gitattributes side (attr.c) which
might benefit from such an optimization as well.  In the longer
run, we might even want to introduce 'ignored' attribute to the
gitattributes mechanism and make the unified result to supersede
gitignore.

^ permalink raw reply

* Re: remote#branch
From: Theodore Tso @ 2007-10-29 21:49 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Jan Hudec, Johannes Schindelin, Petr Baudis, Paolo Ciarrocchi,
	git
In-Reply-To: <alpine.LFD.0.999.0710291112590.30120@woody.linux-foundation.org>

On Mon, Oct 29, 2007 at 11:17:12AM -0700, Linus Torvalds wrote:
> Git remote names already aren't "url"s in the http sense. 
> 
> We say "master:some.host/file/goes here/without/any/stupid/web-escapes" 
> for the ssh names, and the same goes for "file:///name here" etc.
> 
> People who think that git URL's are web-pages had better wake up and smell 
> the coffee. They aren't. They never were. They never *should* be.

Well, the confusion is that we refer to things that look like
"git://git.kernel.org/pub/scm/git/git.git" as if it were a URL.  In
fact, you did so yourself in the last paragraph above.  "People who
think that git URL's"....  but in fact, whether or not Universal
Resource Locators (URL's) in the RFC 3986 sense requires quoting
doesn't matter whether or not they are web pages or not.  If they are
formal URL's in the sense of RFC 3986, it doesn't matter whether they
are http URL's, or ldap URL's, or telephone URL's, etc. they are
supposed to be quoted whether or not they appear in a web form or not.
The whole point of URL's is that they are *uniform*.

So what that means is the much more correct statement is:

"People who think the names that people specify that to git, which
sometimes include names that look very much like URL's, especially
when they begin 'git://' or 'http://', and they think they are really
RFC 3986 URL's had better wake up and smell the coffee.  They aren't.
They never were.  The they never *should* be.  

The best that we can say given existing usage is that what git accepts
is a superset of what is allowable by RFC 3986 syntactically, and that
git in general doesn't do any URL-style quoting, even when given a
name that looks syntactically like a http-style URL that begins
'http://'."

What this means in practice though is that people would be well
advised not to pick locator names (NOT URL's) that contain characters
that normally would require escaping by RFC 3986 rules, since the
inconsistency of whether tools that expect URL-style quoting rules
will probably cause user and tools confusion.  Hence, it would
probably be a bad idea to place a directory pathname that included the
'#' character on a web server and expect that resulting git:// and
http:// names generated by an Apache web server and gitweb scripts to
do sane things, not to mention direct access via git:// names used
when you do a "git push" to said respository.  Sometimes the name will
require RFC 3968 quoting, and sometimes it may not be quoted using RFC
3968 rules, depending on which tool you are using.

I do agree that the Cogito '#' notation makes things worse, not
better, because it encourages a bigger separation between the RFC 3986
rules, and what the git tool accepts in practice --- which are not
URL's, no matter how much some of our git-style names superficially
look like URL's.   

							- Ted

^ permalink raw reply

* Re: [PATCH 6/7] include $PATH in generating list of commands for "help -a"
From: Junio C Hamano @ 2007-10-29 21:17 UTC (permalink / raw)
  To: Scott R Parish; +Cc: git
In-Reply-To: <1193628652-15647-1-git-send-email-srp@srparish.net>

Scott R Parish <srp@srparish.net> writes:

> Git had previously been using the $PATH for scripts--a previous
> patch moved exec'ed commands to also use the $PATH. For consistency
> "help -a" should also list commands in the $PATH.
>
> The main commands are still listed from the git_exec_path(), but
> the $PATH is walked and other git commands (probably extensions) are
> listed.
>
> Signed-off-by: Scott R Parish <srp@srparish.net>
> ---
>  help.c |  157 +++++++++++++++++++++++++++++++++++++++++++++++++---------------
>  1 files changed, 120 insertions(+), 37 deletions(-)

Thanks.

It's easier to read if you briefly describe the differences
between the replacement patch and the previous version of the
patch below the three-dash lines.  See for example Lars Knoll's
patch from today <200710290959.32538.lars@trolltech.com>.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox