Git development
 help / color / mirror / Atom feed
* [PATCH 1/4] Teach send-pack a mirror mode
From: Andy Whitcroft @ 2007-11-09 23:32 UTC (permalink / raw)
  To: git
In-Reply-To: <20071109233041.GC301@shadowen.org>


Existing "git push --all" is almost perfect for backing up to
another repository, except that "--all" only means "all
branches" in modern git, and it does not delete old branches and
tags that exist at the back-up repository that you have removed
from your local repository.

This teaches "git-send-pack" a new "--mirror" option.  The
difference from the "--all" option are that (1) it sends all
refs, not just branches, and (2) it deletes old refs you no
longer have on the local side from the remote side.

Original patch by Junio C Hamano.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
---
 builtin-send-pack.c |   46 ++++++++++++++++++++++++++++++++++------------
 http-push.c         |    4 ++--
 remote.c            |   15 ++++++++++-----
 remote.h            |    7 +++++++
 send-pack.h         |    1 +
 5 files changed, 54 insertions(+), 19 deletions(-)
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index 5a0f5c6..d42164e 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -8,7 +8,7 @@
 #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"
+"git-send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
 "  --all and explicit <ref> specification are mutually exclusive.";
 
 static struct send_pack_args args = {
@@ -227,6 +227,12 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 	int allow_deleting_refs = 0;
 	int expect_status_report = 0;
 	int shown_dest = 0;
+	int flags = MATCH_REFS_NONE;
+
+	if (args.send_all)
+		flags |= MATCH_REFS_ALL;
+	if (args.send_mirror)
+		flags |= MATCH_REFS_MIRROR;
 
 	/* No funny business with the matcher */
 	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
@@ -242,7 +248,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 	if (!remote_tail)
 		remote_tail = &remote_refs;
 	if (match_refs(local_refs, remote_refs, &remote_tail,
-		       nr_refspec, refspec, args.send_all))
+					       nr_refspec, refspec, flags))
 		return -1;
 
 	if (!remote_refs) {
@@ -259,20 +265,28 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 		char old_hex[60], *new_hex;
 		int will_delete_ref;
 		const char *pretty_ref;
-		const char *pretty_peer;
+		const char *pretty_peer = NULL; /* only used when not deleting */
+		const unsigned char *new_sha1;
 
-		if (!ref->peer_ref)
-			continue;
+		if (!ref->peer_ref) {
+			if (!args.send_mirror)
+				continue;
+			new_sha1 = null_sha1;
+		}
+		else
+			new_sha1 = ref->peer_ref->new_sha1;
 
 		if (!shown_dest) {
 			fprintf(stderr, "To %s\n", dest);
 			shown_dest = 1;
 		}
 
+		will_delete_ref = is_null_sha1(new_sha1);
+
 		pretty_ref = prettify_ref(ref->name);
-		pretty_peer = prettify_ref(ref->peer_ref->name);
+		if (!will_delete_ref)
+			pretty_peer = prettify_ref(ref->peer_ref->name);
 
-		will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
 		if (will_delete_ref && !allow_deleting_refs) {
 			fprintf(stderr, " ! %-*s %s (remote does not support deleting refs)\n",
 					SUMMARY_WIDTH, "[rejected]", pretty_ref);
@@ -280,7 +294,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 			continue;
 		}
 		if (!will_delete_ref &&
-		    !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
+		    !hashcmp(ref->old_sha1, new_sha1)) {
 			if (args.verbose)
 				fprintf(stderr, " = %-*s %s -> %s\n",
 					SUMMARY_WIDTH, "[up to date]",
@@ -312,8 +326,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 		    !is_null_sha1(ref->old_sha1) &&
 		    !ref->force) {
 			if (!has_sha1_file(ref->old_sha1) ||
-			    !ref_newer(ref->peer_ref->new_sha1,
-				       ref->old_sha1)) {
+			    !ref_newer(new_sha1, ref->old_sha1)) {
 				/* We do not have the remote ref, or
 				 * we know that the remote ref is not
 				 * an ancestor of what we are trying to
@@ -328,7 +341,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 				continue;
 			}
 		}
-		hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
+		hashcpy(ref->new_sha1, new_sha1);
 		if (!will_delete_ref)
 			new_refs++;
 		strcpy(old_hex, sha1_to_hex(ref->old_sha1));
@@ -459,6 +472,10 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 				args.dry_run = 1;
 				continue;
 			}
+			if (!strcmp(arg, "--mirror")) {
+				args.send_mirror = 1;
+				continue;
+			}
 			if (!strcmp(arg, "--force")) {
 				args.force_update = 1;
 				continue;
@@ -483,7 +500,12 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 	}
 	if (!dest)
 		usage(send_pack_usage);
-	if (heads && args.send_all)
+	/*
+	 * --all and --mirror are incompatible; neither makes sense
+	 * with any refspecs.
+	 */
+	if ((heads && (args.send_all || args.send_mirror)) ||
+					(args.send_all && args.send_mirror))
 		usage(send_pack_usage);
 
 	if (remote_name) {
diff --git a/http-push.c b/http-push.c
index 99328f5..66b81f1 100644
--- a/http-push.c
+++ b/http-push.c
@@ -78,7 +78,7 @@ static struct curl_slist *no_pragma_header;
 static struct curl_slist *default_headers;
 
 static int push_verbosely;
-static int push_all;
+static int push_all = MATCH_REFS_NONE;
 static int force_all;
 static int dry_run;
 
@@ -2300,7 +2300,7 @@ int main(int argc, char **argv)
 
 		if (*arg == '-') {
 			if (!strcmp(arg, "--all")) {
-				push_all = 1;
+				push_all = MATCH_REFS_ALL;
 				continue;
 			}
 			if (!strcmp(arg, "--force")) {
diff --git a/remote.c b/remote.c
index 59defdb..09b7aad 100644
--- a/remote.c
+++ b/remote.c
@@ -722,10 +722,12 @@ 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, const char **refspec, int all)
+	       int nr_refspec, const char **refspec, int flags)
 {
 	struct refspec *rs =
 		parse_ref_spec(nr_refspec, (const char **) refspec);
+	int send_all = flags & MATCH_REFS_ALL;
+	int send_mirror = flags & MATCH_REFS_MIRROR;
 
 	if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec))
 		return -1;
@@ -742,7 +744,7 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
 			if (!pat)
 				continue;
 		}
-		else if (prefixcmp(src->name, "refs/heads/"))
+		else if (!send_mirror && prefixcmp(src->name, "refs/heads/"))
 			/*
 			 * "matching refs"; traditionally we pushed everything
 			 * including refs outside refs/heads/ hierarchy, but
@@ -763,10 +765,13 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
 		if (dst_peer && dst_peer->peer_ref)
 			/* We're already sending something to this ref. */
 			goto free_name;
-		if (!dst_peer && !nr_refspec && !all)
-			/* Remote doesn't have it, and we have no
+
+		if (!dst_peer && !nr_refspec && !(send_all || send_mirror))
+			/*
+			 * Remote doesn't have it, and we have no
 			 * explicit pattern, and we don't have
-			 * --all. */
+			 * --all nor --mirror.
+			 */
 			goto free_name;
 		if (!dst_peer) {
 			/* Create a new one and link it */
diff --git a/remote.h b/remote.h
index 6a4c7a0..b10036c 100644
--- a/remote.h
+++ b/remote.h
@@ -102,4 +102,11 @@ struct branch *branch_get(const char *name);
 int branch_has_merge_config(struct branch *branch);
 int branch_merge_matches(struct branch *, int n, const char *);
 
+/* Flags to match_refs. */
+enum match_refs_flags {
+	MATCH_REFS_NONE		= 0,
+	MATCH_REFS_ALL 		= (1 << 0),
+	MATCH_REFS_MIRROR	= (1 << 1),
+};
+
 #endif
diff --git a/send-pack.h b/send-pack.h
index 7a24f71..8ff1dc3 100644
--- a/send-pack.h
+++ b/send-pack.h
@@ -5,6 +5,7 @@ struct send_pack_args {
 	const char *receivepack;
 	unsigned verbose:1,
 		send_all:1,
+		send_mirror:1,
 		force_update:1,
 		use_thin_pack:1,
 		dry_run:1;

^ permalink raw reply related

* [PATCH 2/4] git-push: plumb in --mirror mode
From: Andy Whitcroft @ 2007-11-09 23:32 UTC (permalink / raw)
  To: git
In-Reply-To: <20071109233041.GC301@shadowen.org>


Plumb in the --mirror mode for git-push.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
---
 builtin-push.c |   14 ++++++++++++--
 transport.c    |    7 +++++++
 transport.h    |    1 +
 3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/builtin-push.c b/builtin-push.c
index 2c56195..d49157c 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -10,7 +10,7 @@
 #include "parse-options.h"
 
 static const char * const push_usage[] = {
-	"git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
+	"git-push [--all | --mirror] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
 	NULL,
 };
 
@@ -91,6 +91,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 {
 	int flags = 0;
 	int all = 0;
+	int mirror = 0;
 	int dry_run = 0;
 	int force = 0;
 	int tags = 0;
@@ -100,6 +101,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		OPT__VERBOSE(&verbose),
 		OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
 		OPT_BOOLEAN( 0 , "all", &all, "push all refs"),
+		OPT_BOOLEAN( 0 , "mirror", &mirror, "mirror all refs"),
 		OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
 		OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"),
 		OPT_BOOLEAN('f', "force", &force, "force updates"),
@@ -119,13 +121,21 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		add_refspec("refs/tags/*");
 	if (all)
 		flags |= TRANSPORT_PUSH_ALL;
+	if (mirror)
+		flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
 
 	if (argc > 0) {
 		repo = argv[0];
 		set_refspecs(argv + 1, argc - 1);
 	}
-	if ((flags & TRANSPORT_PUSH_ALL) && refspec)
+	if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
 		usage_with_options(push_usage, options);
 
+	if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
+				(TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
+		error("--all and --mirror are incompatible");
+		usage_with_options(push_usage, options);
+	}
+
 	return do_push(repo, flags);
 }
diff --git a/transport.c b/transport.c
index 83677fc..fad97d7 100644
--- a/transport.c
+++ b/transport.c
@@ -284,6 +284,9 @@ static int rsync_transport_push(struct transport *transport,
 	struct child_process rsync;
 	const char *args[10];
 
+	if (flags & TRANSPORT_PUSH_MIRROR)
+		return error("rsync transport does not support mirror mode");
+
 	/* first push the objects */
 
 	strbuf_addstr(&buf, transport->url);
@@ -387,6 +390,9 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
 	int argc;
 	int err;
 
+	if (flags & TRANSPORT_PUSH_MIRROR)
+		return error("http transport does not support mirror mode");
+
 	argv = xmalloc((refspec_nr + 11) * sizeof(char *));
 	argv[0] = "http-push";
 	argc = 1;
@@ -655,6 +661,7 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const
 
 	args.receivepack = data->receivepack;
 	args.send_all = !!(flags & TRANSPORT_PUSH_ALL);
+	args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
 	args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
 	args.use_thin_pack = data->thin;
 	args.verbose = transport->verbose;
diff --git a/transport.h b/transport.h
index d27f562..7f337d2 100644
--- a/transport.h
+++ b/transport.h
@@ -30,6 +30,7 @@ struct transport {
 #define TRANSPORT_PUSH_ALL 1
 #define TRANSPORT_PUSH_FORCE 2
 #define TRANSPORT_PUSH_DRY_RUN 4
+#define TRANSPORT_PUSH_MIRROR 8
 
 /* Returns a transport suitable for the url */
 struct transport *transport_get(struct remote *, const char *);

^ permalink raw reply related

* [PATCH 3/4] Add tests for git push'es mirror mode
From: Andy Whitcroft @ 2007-11-09 23:32 UTC (permalink / raw)
  To: git
In-Reply-To: <20071109233041.GC301@shadowen.org>


Add some tests for git push --mirror mode.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
---
 t/t5517-push-mirror.sh |  228 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 228 insertions(+), 0 deletions(-)
diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh
new file mode 100755
index 0000000..0fc6778
--- /dev/null
+++ b/t/t5517-push-mirror.sh
@@ -0,0 +1,228 @@
+#!/bin/sh
+
+test_description='pushing to a mirror repository'
+
+. ./test-lib.sh
+
+D=`pwd`
+
+invert () {
+	if "$@"; then
+		return 1
+	else
+		return 0
+	fi
+}
+
+mk_repo_pair () {
+	rm -rf master mirror &&
+	mkdir mirror &&
+	(
+		cd mirror &&
+		git init
+	) &&
+	mkdir master &&
+	(
+		cd master &&
+		git init &&
+		git config remote.up.url ../mirror
+	)
+}
+
+
+# BRANCH tests
+test_expect_success 'push mirror does not create new branches' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+	test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror does not update existing branches' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git push --mirror up &&
+		echo two >foo && git add foo && git commit -m two &&
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+	test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror does not force update existing branches' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git push --mirror up &&
+		echo two >foo && git add foo && git commit -m two &&
+		git push --mirror up &&
+		git reset --hard HEAD^
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+	test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror does not remove branches' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git branch remove master &&
+		git push --mirror up &&
+		git branch -D remove
+		git push --mirror up
+	) &&
+	(
+		cd mirror &&
+		invert git show-ref -s --verify refs/heads/remove
+	)
+
+'
+
+test_expect_success 'push mirror does not add, update and remove branches together' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git branch remove master &&
+		git push --mirror up &&
+		git branch -D remove &&
+		git branch add master &&
+		echo two >foo && git add foo && git commit -m two &&
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+	master_add=$(cd master && git show-ref -s --verify refs/heads/add) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+	mirror_add=$(cd mirror && git show-ref -s --verify refs/heads/add) &&
+	test "$master_master" = "$mirror_master" &&
+	test "$master_add" = "$mirror_add" &&
+	(
+		cd mirror &&
+		invert git show-ref -s --verify refs/heads/remove
+	)
+
+'
+
+
+# TAG tests
+test_expect_success 'push mirror does not create new tags' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git tag -f tmaster master &&
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+	test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror does not update existing tags' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git tag -f tmaster master &&
+		git push --mirror up &&
+		echo two >foo && git add foo && git commit -m two &&
+		git tag -f tmaster master &&
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+	test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror does not force update existing tags' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git tag -f tmaster master &&
+		git push --mirror up &&
+		echo two >foo && git add foo && git commit -m two &&
+		git tag -f tmaster master &&
+		git push --mirror up &&
+		git reset --hard HEAD^
+		git tag -f tmaster master &&
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+	test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror does not remove tags' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git tag -f tremove master &&
+		git push --mirror up &&
+		git tag -d tremove
+		git push --mirror up
+	) &&
+	(
+		cd mirror &&
+		invert git show-ref -s --verify refs/tags/tremove
+	)
+
+'
+
+test_expect_success 'push mirror does not add, update and remove tags together' '
+
+	mk_repo_pair &&
+	(
+		cd master &&
+		echo one >foo && git add foo && git commit -m one &&
+		git tag -f tmaster master &&
+		git tag -f tremove master &&
+		git push --mirror up &&
+		git tag -d tremove &&
+		git tag tadd master &&
+		echo two >foo && git add foo && git commit -m two &&
+		git tag -f tmaster master &&
+		git push --mirror up
+	) &&
+	master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+	master_add=$(cd master && git show-ref -s --verify refs/tags/tadd) &&
+	mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+	mirror_add=$(cd mirror && git show-ref -s --verify refs/tags/tadd) &&
+	test "$master_master" = "$mirror_master" &&
+	test "$master_add" = "$mirror_add" &&
+	(
+		cd mirror &&
+		invert git show-ref -s --verify refs/tags/tremove
+	)
+
+'
+
+test_done

^ permalink raw reply related

* [PATCH 4/4] git-push: add documentation for the newly added --mirror mode
From: Andy Whitcroft @ 2007-11-09 23:32 UTC (permalink / raw)
  To: git
In-Reply-To: <20071109233041.GC301@shadowen.org>


Add some basic documentation on the --mirror mode for git-push.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
---
 Documentation/git-push.txt |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index e5dd4c1..3fa5992 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -63,6 +63,14 @@ the remote repository.
 	Instead of naming each ref to push, specifies that all
 	refs under `$GIT_DIR/refs/heads/` be pushed.
 
+\--mirror::
+	Instead of naming each ref to push, specifies that all
+	refs under `$GIT_DIR/refs/heads/` and `$GIT_DIR/refs/tags/`
+	be mirrored to the remote repository.  Newly created local
+	refs will be pushed to the remote end, locally updated refs
+	will be force updated on the remote end, and deleted refs
+	will be removed from the remote end.
+
 \--dry-run::
 	Do everything except actually send the updates.
 

^ permalink raw reply related

* Reducing the memory footprint
From: Jon Smirl @ 2007-11-09 23:38 UTC (permalink / raw)
  To: Git Mailing List

I'm using this config file:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        packedGitWindowSize = 1M
        packedGitLimit = 1M
        deltaBaseCacheLimit = 1M
[pack]
        windowMemory = 1M
        deltaCacheSize = 1M

And I have NO_MMAP compiled in.

git is still using over 200MB of memory or address space, my process
gets killed either way.

Ideas on how to reduce the foot print more?

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: [PATCH 2/2] --pretty=format: on-demand format expansion
From: Paul Mackerras @ 2007-11-09 23:39 UTC (permalink / raw)
  To: René Scharfe
  Cc: Junio C Hamano, Git Mailing List, Pierre Habouzit,
	Johannes Schindelin
In-Reply-To: <4733AEA6.1040802@lsrfire.ath.cx>

Thanks for doing this.

Could I ask for a couple more things?  I would find it useful to have
format codes for the number of characters in the commit body.  Having
a code for the number of bytes in the commit body would also be
useful.  When reading commits in with Tcl, the number of characters is
more useful, but I can use the number of bytes (and I imagine others
would find that useful).

Paul.

^ permalink raw reply

* Re: [PATCH 01/11] Fix memory leak in traverse_commit_list
From: Johannes Schindelin @ 2007-11-09 23:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Shawn O. Pearce, git
In-Reply-To: <7vmytnqbu2.fsf@gitster.siamese.dyndns.org>

Hi,

On Fri, 9 Nov 2007, Junio C Hamano wrote:

> "Shawn O. Pearce" <spearce@spearce.org> writes:
> 
> > diff --git a/list-objects.c b/list-objects.c
> > index e5c88c2..713bef9 100644
> > --- a/list-objects.c
> > +++ b/list-objects.c
> > @@ -170,4 +170,11 @@ void traverse_commit_list(struct rev_info *revs,
> >  	}
> >  	for (i = 0; i < objects.nr; i++)
> >  		show_object(&objects.objects[i]);
> > +	free(objects.objects);
> > +	if (revs->pending.nr) {
> > +		revs->pending.nr = 0;
> > +		revs->pending.alloc = 0;
> > +		revs->pending.objects = NULL;
> > +		free(revs->pending.objects);

Umm. Isn't this the wrong way around?  Should you not free() first, and 
then set to NULL?

Ciao,
Dscho

^ permalink raw reply

* `git-send-email' doesn't specify `Content-Type'
From: Ludovic Courtès @ 2007-11-10  0:14 UTC (permalink / raw)
  To: git

Hi,

Apparently, `git-send-email' doesn't specify the email's `Content-Type',
notably its charset, while it should really add something like:

  Content-Type: text/plain; charset=UTF-8

Or did I miss an option or something?

Thanks,
Ludovic.

^ permalink raw reply

* Re: [PATCH 2/2] --pretty=format: on-demand format expansion
From: Johannes Schindelin @ 2007-11-10  0:31 UTC (permalink / raw)
  To: René Scharfe
  Cc: Jeff King, Junio C Hamano, Paul Mackerras, Git Mailing List,
	Pierre Habouzit
In-Reply-To: <4734EA4E.8070405@lsrfire.ath.cx>

Hi,

On Sat, 10 Nov 2007, Ren? Scharfe wrote:

> (next)
> $ time git log --pretty=format:"* %cd %cn%n%n%s%n%b" >/dev/null
> 
> real    0m0.631s
> user    0m0.584s
> sys     0m0.040s
> 
> (next+patch)
> $ time git log --pretty=format:"* %cd %cn%n%n%s%n%b" >/dev/null
> 
> real    0m0.570s
> user    0m0.512s
> sys     0m0.044s

Wow.

If you keep going like that, "git log" will be slower than "git log 
--pretty=format:bla" soon.

Ciao,
Dscho

^ permalink raw reply

* Re: git pull opinion
From: Linus Torvalds @ 2007-11-10  0:36 UTC (permalink / raw)
  To: Aghiles; +Cc: Bill Lear, Junio C Hamano, git
In-Reply-To: <3abd05a90711071325y397434efq7d4e50cb7a1cf07e@mail.gmail.com>



On Wed, 7 Nov 2007, Aghiles wrote:

> > [...]
> > Now, I do think that we could relax the rule so that "files that are
> > modified must be clean in the working tree" could instead become "files
> > that actually don't merge _trivially_ must be clean in the working tree".
> > But basically, if it's not a trivial merge, then since it's done in the
> > working tree, the working tree has to be clean (or the merge would
> > overwrite it).
> >[...]
> 
> I really think this is a good idea. It seems to me that the first "bad"
> surprise a svn/cvs/bk user will have is the result of a "git pull" command
> on a dirty tree. With the proposed change, and if I understand correctly:
>   - users that are used to commit often and fetch into clean trees
> will never be bothered by this change.
>   - users that are used to "update" often are expecting to resolve
> conflicts in their working copy anyway.
> 
> In both cases git does not get in your way and everyone is happy.

Well, there will still be cases where people won't be happy.

That said, all fast-forward cases (which is, I guess, a fairly common way 
of operating for anybody who has ever just uses anoncvs to track others) 
would be handled by the "three-way-merge dirty data for trivial merges". 

So even if it would only handle that special case (and it handles a *lot* 
of other cases too!) it probably would be useful to some people.

That said, I still don't think I have the energy to actually try to do it. 
I do suspect it's not that hard, and I outlined where it would go, but 
it's really quite core and important code... IOW, this needs *lots* of 
deep thought and care.

			Linus

^ permalink raw reply

* Re: git submodules and diffing
From: Sven Herzberg @ 2007-11-10  0:46 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <1194649057-19676-1-git-send-email-jnareb@gmail.com>

Hey Jakub,

Am 09.11.2007 um 23:57 schrieb Jakub Narebski:

> Sven Herzberg wrote:
>
>> When I started working with git submodules, I realized that git-diff
>> only lists the revision ids of a submodule if it has changed. I have
>> created a repository which includes a diff command for git-submodule,
>> so you can use it like "gut submodule diff <modules...>"
>>
>> I pushed my git tree at git://git.imendio.com/sven/git.git

>   http://git.imendio.com/?p=sven/git.git
>
>> Feel free to look into the changes and request improvements or merge
>> it into your tree.
>
> Although having "git submodule diff" is quite nice, I'd rather have
> "git diff --recurse-submodules" (or something like that) if I want to
> get diff of submodules.

I think it's pretty nice if git-submodule is the only command that  
knows about submodules.

> From browsing commitdiff
>   http://git.imendio.com/?p=sven/ 
> git.git;a=commitdiff;h=7fa1d4911d1ac2590ab1eccd84a7f235aca7878e
> I'd like to mention that instead of
>
>   (unset GIT_DIR && cd "$path" && git diff $flag "$sha1..HEAD")
>
> you can simply use
>
>   git --git-dir="$path" diff $flag "$sha1..HEAD"

It wasn't exactly that simple (I has to add `pwd` and "/.git") but  
thats for the hint. See the updated version in my repository.

>> PS: Please CC me, I'm not on this list
>
> You can always read list using NNTP / news / Usenet interface at
>   nntp://news.gmane.org/gmane.comp.version-control.git
> or one of the mailing list archives, see
>   http://git.or.cz/gitwiki/GitCommunity

I know, but being CCed is a simple task and makes it even easier for  
me to contribute in irregular intervals.

Thank you,
   Sven

^ permalink raw reply

* Re: [PATCH 2/2] --pretty=format: on-demand format expansion
From: Jeff King @ 2007-11-10  0:46 UTC (permalink / raw)
  To: René Scharfe
  Cc: Junio C Hamano, Paul Mackerras, Git Mailing List, Pierre Habouzit,
	Johannes Schindelin
In-Reply-To: <4734EA4E.8070405@lsrfire.ath.cx>

On Sat, Nov 10, 2007 at 12:16:30AM +0100, René Scharfe wrote:

> > A partial patch on top of yours is below (it caches commit and tree 
> > abbreviations; parent abbreviations and person-parsing are probably 
> > worth doing). Some timings:
> 
> ... but I object to the choice of items to cache.  Are there real-world
> formats containing the same placeholder twice or even more often?

My choice of items was more "here is what I am talking about" and not
"this is the best set of items."

As for what real-world workloads are like, part of the _point_ of
--pretty=format: is for one-off formats that users use in their
workflow. So yes, I have used formats that repeat specifiers, but they
are probably not common.

The point of my timings was to show not only that we sped up that
uncommon case, but that there was negligible cost to the common case.
And since we don't know what formats users will provide, it makes sense
not to have lousy performance on the uncommon.

> There is probably more to gain from the interdependencies of different
> placeholders.  The patch below attempts to avoid parsing the commit
> twice, by saving pointers to the different parts.

Looks sane, although I don't see any reason this couldn't just go on top
of my patch, and then we can speed up both cases.

> (next)
> $ time git log --pretty=format:"* %cd %cn%n%n%s%n%b" >/dev/null
> real    0m0.631s
[...]
> (next+patch)
> $ time git log --pretty=format:"* %cd %cn%n%n%s%n%b" >/dev/null
> real    0m0.570s

Great, you have sped up the uncommon case. But what is the cost to "git
log --pretty=format:" and "git log --pretty=format:%cd"?

-Peff

^ permalink raw reply

* Re: [PATCH 2/2] --pretty=format: on-demand format expansion
From: Jeff King @ 2007-11-10  0:49 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: René Scharfe, Junio C Hamano, Paul Mackerras,
	Git Mailing List, Pierre Habouzit
In-Reply-To: <Pine.LNX.4.64.0711100030090.4362@racer.site>

On Sat, Nov 10, 2007 at 12:31:41AM +0000, Johannes Schindelin wrote:

> If you keep going like that, "git log" will be slower than "git log 
> --pretty=format:bla" soon.

Maybe I am dreaming, but the code might be much simpler and more
readable if --pretty=* were implemented in terms of --pretty=format,
assuming the speeds are equivalent.

-Peff

^ permalink raw reply

* Re: [PATCH 2/2] --pretty=format: on-demand format expansion
From: Jeff King @ 2007-11-10  0:51 UTC (permalink / raw)
  To: René Scharfe
  Cc: Junio C Hamano, Paul Mackerras, Git Mailing List, Pierre Habouzit,
	Johannes Schindelin
In-Reply-To: <4734EB36.2030408@lsrfire.ath.cx>

On Sat, Nov 10, 2007 at 12:20:22AM +0100, René Scharfe wrote:

> > This void cast is pointless, since all pointers types convert implicitly
> > to void pointers anyway. At best, it does nothing, and at worst, it
> > hides an actual type error if the function signature or the type of
> > 'commit' change.
> 
> When commit (of type const struct commit*) is implicitly converted to
> void *, gcc complains because the "const" qualifier is silently dropped.

Bleh. You're right, of course. I don't like casting away constness, but
it is stupid for strbuf_expand to take a "const void *" since it has no
idea how it will be used (although I note your caching patch also neatly
does away with this, anyway).

-Peff

^ permalink raw reply

* Re: `git-send-email' doesn't specify `Content-Type'
From: Johannes Schindelin @ 2007-11-10  0:52 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: git
In-Reply-To: <87ode3klc7.fsf@chbouib.org>

Hi,

On Sat, 10 Nov 2007, Ludovic Court?s wrote:

> Apparently, `git-send-email' doesn't specify the email's `Content-Type',
> notably its charset, while it should really add something like:
> 
>   Content-Type: text/plain; charset=UTF-8
> 
> Or did I miss an option or something?

Apparently.  There was a thread some days ago, about that very issue.  
Please find and read it.

Ciao,
Dscho

^ permalink raw reply

* Re: Reducing the memory footprint
From: Brian Downing @ 2007-11-10  0:53 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Git Mailing List
In-Reply-To: <9e4733910711091538h260fbcd2s5783f01e7db4b19a@mail.gmail.com>

On Fri, Nov 09, 2007 at 06:38:00PM -0500, Jon Smirl wrote:
> I'm using this config file:
> 
> [pack]
>         windowMemory = 1M
>         deltaCacheSize = 1M
> 
> And I have NO_MMAP compiled in.
> 
> git is still using over 200MB of memory or address space, my process
> gets killed either way.

I'm assuming it's dying on repacking since you included the pack
parameters.

How big is your biggest object?  Even with pack.windowMemory, it still
keeps the last object around to try and delta against (in other words,
the window only shrinks to size 1), which means you have to have room
for it and its delta index.

-bcd

^ permalink raw reply

* Re: Reducing the memory footprint
From: Jon Smirl @ 2007-11-10  1:05 UTC (permalink / raw)
  To: Brian Downing; +Cc: Git Mailing List
In-Reply-To: <20071110005327.GH6212@lavos.net>

On 11/9/07, Brian Downing <bdowning@lavos.net> wrote:
> On Fri, Nov 09, 2007 at 06:38:00PM -0500, Jon Smirl wrote:
> > I'm using this config file:
> >
> > [pack]
> >         windowMemory = 1M
> >         deltaCacheSize = 1M
> >
> > And I have NO_MMAP compiled in.
> >
> > git is still using over 200MB of memory or address space, my process
> > gets killed either way.
>
> I'm assuming it's dying on repacking since you included the pack
> parameters.
>
> How big is your biggest object?  Even with pack.windowMemory, it still
> keeps the last object around to try and delta against (in other words,
> the window only shrinks to size 1), which means you have to have room
> for it and its delta index.

It's a Linux kernel repository. Git receive-pack is going over 200MB
and getting zapped.  I don't understand why the process is so large. I
am compiled with -DNO_MMAP.

I think I have a achieved a work around. I rsync'd in my last several
weeks of changes. Now I can 'git push' small amounts of changes
without getting killed.

I'm begging dreamhost to simply install git. Installed commands don't
get zapped.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* gitweb, updating 'last changed' column on the project page
From: Jon Smirl @ 2007-11-10  1:09 UTC (permalink / raw)
  To: Git Mailing List

At http://git.digispeaker.com/ the 'last change' column is not getting updated.

mpc5200b.git
	DigiSpeaker for Freescale MPC5200B.
	Jon Smirl
	5 weeks ago
	summary | shortlog | log | tree

It still says 5 weeks ago, but if I click on the project last change is today.

What controls this? I tried running update-server-info

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: *[PATCH] builtin-commit: Refresh cache after adding files.
From: Junio C Hamano @ 2007-11-10  1:40 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Kristian Høgsberg, git
In-Reply-To: <7vhcjvtgz5.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> This discussion exposes a problem with add_files_to_cache()
> function.
> ...
> And add_file_to_cache(), which calls add_file_to_index() on
> the_index, does call the fill_stat_cache_info() to sync the stat
> information by itself, as it should be.  I am still puzzled with
> this.

Blech.  I think it is 0781b8a9b2fe760fc4ed519a3a26e4b9bd6ccffe
(add_file_to_index: skip rehashing if the cached stat already
matches) that broke "git add".  I get the same problem not just
with "git add -u" but also with an explicit "git add Makefile".

In add_file_to_index(), we check if ie_modified() says if the
path is modified, but that is actually a very wrong check in
that function.  ie_modified() knows the racy git condition and
digs deeper to find if the file in the work tree is really
different.  We end up saying "ah, Ok, if that is the same, then
we do not add it to the index again", which is why we do not
update the stat info in this case.

Instead, we should ask ie_match_stat() which answers "does not
match" for a entry that _could_ be racily clean, so that we make
sure we re-add such an entry to clear the stat info.

This applies to maint and all the way up.

I also suspect that run_diff_files() that is called from
builtin-add.c:update() needs to tell ie_match_stat() to assume
that a racily clean path is unclean (that is what bit (1<<1) of
the third parameter to ie_match_stat() is about), so that "add
-u" will call the add_file_to_index() function, but that would
be a bigger patch.

---

 read-cache.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/read-cache.c b/read-cache.c
index 928e8fa..75e2d46 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -420,7 +420,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 	pos = index_name_pos(istate, ce->name, namelen);
 	if (0 <= pos &&
 	    !ce_stage(istate->cache[pos]) &&
-	    !ie_modified(istate, istate->cache[pos], &st, 1)) {
+	    !ie_match_stat(istate, istate->cache[pos], &st, 3)) {
 		/* Nothing changed, really */
 		free(ce);
 		return 0;

^ permalink raw reply related

* Re: gitweb, updating 'last changed' column on the project page
From: Jakub Narebski @ 2007-11-10  1:58 UTC (permalink / raw)
  To: git
In-Reply-To: <9e4733910711091709k173bf23flf2824673f82de9bb@mail.gmail.com>

Jon Smirl wrote:

> At http://git.digispeaker.com/ the 'last change' column is not getting updated.
> 
> mpc5200b.git
>       DigiSpeaker for Freescale MPC5200B.
>       Jon Smirl
>       5 weeks ago
>       summary | shortlog | log | tree
> 
> It still says 5 weeks ago, but if I click on the project last change is today.
> 
> What controls this? I tried running update-server-info

What does

  git for-each-ref --format="%(refname):%09%(committer)" --sort=-committerdate
      refs/heads

return? Does adding --count select proper branch, with proper update
date?

Which gitweb version is this?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: *[PATCH] builtin-commit: Refresh cache after adding files.
From: Johannes Schindelin @ 2007-11-10  2:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Kristian Høgsberg, git
In-Reply-To: <7v640ari76.fsf@gitster.siamese.dyndns.org>

Hi,

On Fri, 9 Nov 2007, Junio C Hamano wrote:

> Junio C Hamano <gitster@pobox.com> writes:
> 
> > This discussion exposes a problem with add_files_to_cache()
> > function.
> > ...
> > And add_file_to_cache(), which calls add_file_to_index() on
> > the_index, does call the fill_stat_cache_info() to sync the stat
> > information by itself, as it should be.  I am still puzzled with
> > this.
> 
> Blech.  I think it is 0781b8a9b2fe760fc4ed519a3a26e4b9bd6ccffe 
> (add_file_to_index: skip rehashing if the cached stat already matches) 
> that broke "git add".  I get the same problem not just with "git add -u" 
> but also with an explicit "git add Makefile".

But I think that we still need to refresh the index.  It outputs which 
files names were new, and which ones were removed.  Otherwise git commit 
would be eerily silent on those.

Ciao,
Dscho

^ permalink raw reply

* [PATCH] git-add: make the entry stat-clean after re-adding the same contents
From: Junio C Hamano @ 2007-11-10  2:22 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Kristian Høgsberg, git
In-Reply-To: <7vhcjvtgz5.fsf@gitster.siamese.dyndns.org>

Earlier in commit 0781b8a9b2fe760fc4ed519a3a26e4b9bd6ccffe
(add_file_to_index: skip rehashing if the cached stat already
matches), add_file_to_index() were taught not to re-add the path
if it already matches the index.

The change meant well, but was not executed quite right.  It
used ie_modified() to see if the file on the work tree is really
different from the index, and skipped adding the contents if the
function says "not modified".

This was wrong.  There are three possible comparison results
between the index and the file in the work tree:

 - with lstat(2) we _know_ they are different.  E.g. if the
   length or the owner in the cached stat information is
   different from the length we just obtained from lstat(2), we
   can tell the file is modified without looking at the actual
   contents.

 - with lstat(2) we _know_ they are the same.  The same length,
   the same owner, the same everything (but this has a twist, as
   described below).

 - we cannot tell from lstat(2) information alone and need to go
   to the filesystem to actually compare.

The last case arises from what we call 'racy git' situation,
that can be caused with this sequence:

    $ echo hello >file
    $ git add file
    $ echo aeiou >file ;# the same length

If the second "echo" is done within the same filesystem
timestamp granularity as the first "echo", then the timestamp
recorded by "git add" and the timestamp we get from lstat(2)
will be the same, and we can mistakenly say the file is not
modified.  The path is called 'racily clean'.  We need to
reliably detect racily clean paths are in fact modified.

To solve this problem, when we write out the index, we mark the
index entry that has the same timestamp as the index file itself
(that is the time from the point of view of the filesystem) to
tell any later code that does the lstat(2) comparison not to
trust the cached stat info, and ie_modified() then actually goes
to the filesystem to compare the contents for such a path.

That's all good, but it should not be used for this "git add"
optimization, as the goal of "git add" is to actually update the
path in the index and make it stat-clean.  With the false
optimization, we did _not_ cause any data loss (after all, what
we failed to do was only to update the cached stat information),
but it made the following sequence leave the file stat dirty:

    $ echo hello >file
    $ git add file
    $ echo hello >file ;# the same contents
    $ git add file

The solution is not to use ie_modified() which goes to the
filesystem to see if it is really clean, but instead use
ie_match_stat() with "assume racily clean paths are dirty"
option, to force re-adding of such a path.

There was another problem with "git add -u".  The codepath
shares the same issue when adding the paths that are found to be
modified, but in addition, it asked "git diff-files" machinery
run_diff_files() function (which is "git diff-files") to list
the paths that are modified.  But "git diff-files" machinery
uses the same ie_modified() call so that it does not report
racily clean _and_ actually clean paths as modified, which is
not what we want.

The patch allows the callers of run_diff_files() to pass the
same "assume racily clean paths are dirty" option, and makes
"git-add -u" codepath to use that option, to discover and re-add
racily clean _and_ actually clean paths.

We could further optimize on top of this patch to differentiate
the case where the path really needs re-adding (i.e. the content
of the racily clean entry was indeed different) and the case
where only the cached stat information needs to be refreshed
(i.e. the racily clean entry was actually clean), but I do not
think it is worth it.

This patch applies to maint and all the way up.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 * Blech.  This took longer than I thought.  It's only cached
   stat info and does not cause real data breakage, but I think
   it is a good thing to fix nevertheless.

 builtin-add.c |    2 +-
 diff-lib.c    |    6 ++++--
 diff.h        |    2 +-
 read-cache.c  |    2 +-
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/builtin-add.c b/builtin-add.c
index 373f87f..b6d6bbe 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -123,7 +123,7 @@ static void update(int verbose, const char *prefix, const char **files)
 	rev.diffopt.format_callback_data = &verbose;
 	if (read_cache() < 0)
 		die("index file corrupt");
-	run_diff_files(&rev, 0);
+	run_diff_files(&rev, 2);
 }
 
 static void refresh(int verbose, const char **pathspec)
diff --git a/diff-lib.c b/diff-lib.c
index da55713..b83f650 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -332,10 +332,12 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
 	return run_diff_files(revs, silent_on_removed);
 }
 
-int run_diff_files(struct rev_info *revs, int silent_on_removed)
+int run_diff_files(struct rev_info *revs, int option)
 {
 	int entries, i;
 	int diff_unmerged_stage = revs->max_count;
+	int silent_on_removed = option & 01;
+	int assume_racy_is_modified = option & 02;
 
 	if (diff_unmerged_stage < 0)
 		diff_unmerged_stage = 2;
@@ -441,7 +443,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
 				       ce->sha1, ce->name, NULL);
 			continue;
 		}
-		changed = ce_match_stat(ce, &st, 0);
+		changed = ce_match_stat(ce, &st, assume_racy_is_modified);
 		if (!changed && !revs->diffopt.find_copies_harder)
 			continue;
 		oldmode = ntohl(ce->ce_mode);
diff --git a/diff.h b/diff.h
index 4546aad..040e18c 100644
--- a/diff.h
+++ b/diff.h
@@ -224,7 +224,7 @@ extern void diff_flush(struct diff_options*);
 
 extern const char *diff_unique_abbrev(const unsigned char *, int);
 
-extern int run_diff_files(struct rev_info *revs, int silent_on_removed);
+extern int run_diff_files(struct rev_info *revs, int option);
 extern int setup_diff_no_index(struct rev_info *revs,
 		int argc, const char ** argv, int nongit, const char *prefix);
 extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv);
diff --git a/read-cache.c b/read-cache.c
index 928e8fa..75e2d46 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -420,7 +420,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 	pos = index_name_pos(istate, ce->name, namelen);
 	if (0 <= pos &&
 	    !ce_stage(istate->cache[pos]) &&
-	    !ie_modified(istate, istate->cache[pos], &st, 1)) {
+	    !ie_match_stat(istate, istate->cache[pos], &st, 3)) {
 		/* Nothing changed, really */
 		free(ce);
 		return 0;
-- 
1.5.3.5.1651.g30bf0

^ permalink raw reply related

* Re: *[PATCH] builtin-commit: Refresh cache after adding files.
From: Junio C Hamano @ 2007-11-10  2:26 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Kristian Høgsberg, git
In-Reply-To: <Pine.LNX.4.64.0711100201310.4362@racer.site>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> But I think that we still need to refresh the index.

You are correct.  See

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

^ permalink raw reply

* Re: [PATCH] git-add: make the entry stat-clean after re-adding the same contents
From: Linus Torvalds @ 2007-11-10  2:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, Kristian Høgsberg, git
In-Reply-To: <7vzlxmq1oj.fsf_-_@gitster.siamese.dyndns.org>



On Fri, 9 Nov 2007, Junio C Hamano wrote:
>  
> -int run_diff_files(struct rev_info *revs, int silent_on_removed)
> +int run_diff_files(struct rev_info *revs, int option)

Wouldn't it be much better to now 
 - make it "unsigned int flags"
 - create a few enums or #define's to make the usage be more readable?

Because this:

>-       run_diff_files(&rev, 0);
>+       run_diff_files(&rev, 2);
> -	    !ie_modified(istate, istate->cache[pos], &st, 1)) {
> +	    !ie_match_stat(istate, istate->cache[pos], &st, 3)) {

just went from subtle to "incredibly non-obvious".

I realize that 3 is "silent + assume_racy" and 2 is just "assume_racy", 
but I may realize that now, and in a month? I'd need to look it up.

		Linus

^ permalink raw reply

* git packs
From: bob @ 2007-11-10  4:47 UTC (permalink / raw)
  To: git

When a repository is packed such as for a clone or fetch, is there  
just one pack file created that is used for the transfer?

^ 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