Git development
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] Add Git::config_path()
From: Junio C Hamano @ 2011-10-07 22:26 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Cord Seele, Matthieu Moy, git, Eric Wong, Cord Seele
In-Reply-To: <201110072344.46556.jnareb@gmail.com>

Jakub Narebski <jnareb@gmail.com> writes:

>   char *expand_user_path(const char *path)
>   [...]
>                 if (username_len == 0) {
>                         const char *home = getenv("HOME");
>                         if (!home)
>                                 goto return_null;
>                         strbuf_add(&user_path, home, strlen(home));
>                 } else {
>   [...]

Ahh, Ok. I was afraid getpwnam() codepath might interfere with it.

^ permalink raw reply

* Re: [PATCH 0/7] pickaxe: plug memory leaks, deduplicate code
From: Junio C Hamano @ 2011-10-07 22:47 UTC (permalink / raw)
  To: René Scharfe; +Cc: Git Mailing List
In-Reply-To: <4E8DD065.3040607@lsrfire.ath.cx>

Impressed; very nicely done.

Thanks.

^ permalink raw reply

* [PATCH 3/4] fetch: honor the user-provided refspecs when pruning refs
From: Carlos Martín Nieto @ 2011-10-07 22:51 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1318027869-4037-1-git-send-email-cmn@elego.de>

If the user gave us refspecs on the command line, we should use those
when deciding whether to prune a ref instead of relying on the
refspecs in the config.

Previously, running

    git fetch --prune origin refs/heads/master:refs/remotes/origin/master

would delete every other ref under the origin namespace because we
were using the refspec to filter the available refs but using the
configured refspec to figure out if a ref had been deleted on the
remote. This is clearly the wrong thing to do.

Change prune_refs and get_stale_heads to simply accept a list of
references and a list of refspecs. The caller of either function needs
to decide what refspecs should be used to decide whether a ref is
stale.

Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
 builtin/fetch.c  |   12 ++++++---
 builtin/remote.c |    3 +-
 remote.c         |   66 ++++++++++++++++++++++++++++++++++++++++++++++-------
 remote.h         |    2 +-
 t/t5510-fetch.sh |    4 +-
 5 files changed, 70 insertions(+), 17 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 30b485e..041f79e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -505,10 +505,10 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
 	return ret;
 }
 
-static int prune_refs(struct transport *transport, struct ref *ref_map)
+static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
 {
 	int result = 0;
-	struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map);
+	struct ref *ref, *stale_refs = get_stale_heads(ref_map, refs, ref_count);
 	const char *dangling_msg = dry_run
 		? _("   (%s will become dangling)\n")
 		: _("   (%s has become dangling)\n");
@@ -699,8 +699,12 @@ static int do_fetch(struct transport *transport,
 		free_refs(ref_map);
 		return 1;
 	}
-	if (prune)
-		prune_refs(transport, ref_map);
+	if (prune) {
+		if (ref_count)
+			prune_refs(refs, ref_count, ref_map);
+		else
+			prune_refs(transport->remote->fetch, transport->remote->fetch_refspec_nr, ref_map);
+	}
 	free_refs(ref_map);
 
 	/* if neither --no-tags nor --tags was specified, do automated tag
diff --git a/builtin/remote.c b/builtin/remote.c
index f2a9c26..79d898b 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -349,7 +349,8 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
 		else
 			string_list_append(&states->tracked, abbrev_branch(ref->name));
 	}
-	stale_refs = get_stale_heads(states->remote, fetch_map);
+	stale_refs = get_stale_heads(fetch_map, states->remote->fetch,
+				     states->remote->fetch_refspec_nr);
 	for (ref = stale_refs; ref; ref = ref->next) {
 		struct string_list_item *item =
 			string_list_append(&states->stale, abbrev_branch(ref->name));
diff --git a/remote.c b/remote.c
index b8ecfa5..13c9153 100644
--- a/remote.c
+++ b/remote.c
@@ -1681,36 +1681,84 @@ struct ref *guess_remote_head(const struct ref *head,
 }
 
 struct stale_heads_info {
-	struct remote *remote;
 	struct string_list *ref_names;
 	struct ref **stale_refs_tail;
+	struct refspec *refs;
+	int ref_count;
 };
 
+/* Returns 0 on success, -1 if it couldn't find a match in the refspecs. */
+static int find_in_refs(struct refspec *refs, int ref_count, struct refspec *query)
+{
+	int i;
+	struct refspec *refspec;
+
+	for (i = 0; i < ref_count; ++i) {
+		refspec = &refs[i];
+
+		/* No dst means it can't be used for prunning. */
+		if (!refspec->dst)
+			continue;
+
+		/*
+		 * No '*' means that it must match exactly. If it does
+		 * have it, try to match it against the pattern. If
+		 * the refspec matches, store the ref name as it would
+		 * appear in the server in query->src.
+		 */
+		if (!strchr(refspec->dst, '*')) {
+			if (!strcmp(query->dst, refspec->dst)) {
+				query->src = xstrdup(refspec->src);
+				return 0;
+			}
+		} else if (match_name_with_pattern(refspec->dst, query->dst,
+						    refspec->src, &query->src)) {
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
 static int get_stale_heads_cb(const char *refname,
 	const unsigned char *sha1, int flags, void *cb_data)
 {
 	struct stale_heads_info *info = cb_data;
 	struct refspec refspec;
+	int ret;
 	memset(&refspec, 0, sizeof(refspec));
 	refspec.dst = (char *)refname;
-	if (!remote_find_tracking(info->remote, &refspec)) {
-		if (!((flags & REF_ISSYMREF) ||
-		    string_list_has_string(info->ref_names, refspec.src))) {
-			struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
-			hashcpy(ref->new_sha1, sha1);
-		}
+
+	ret = find_in_refs(info->refs, info->ref_count, &refspec);
+
+	/* No matches */
+	if (ret)
+		return 0;
+
+	/*
+	 * If we did find a suitable refspec and it's not a symref and
+	 * it's not in the list of refs that currently exist in that
+	 * remote we consider it to be stale.
+	 */
+	if (!((flags & REF_ISSYMREF) ||
+	      string_list_has_string(info->ref_names, refspec.src))) {
+		struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
+		hashcpy(ref->new_sha1, sha1);
 	}
+
+	free(refspec.src);
 	return 0;
 }
 
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map)
+struct ref *get_stale_heads(struct ref *fetch_map, struct refspec *refs, int ref_count)
 {
 	struct ref *ref, *stale_refs = NULL;
 	struct string_list ref_names = STRING_LIST_INIT_NODUP;
 	struct stale_heads_info info;
-	info.remote = remote;
 	info.ref_names = &ref_names;
 	info.stale_refs_tail = &stale_refs;
+	info.refs = refs;
+	info.ref_count = ref_count;
 	for (ref = fetch_map; ref; ref = ref->next)
 		string_list_append(&ref_names, ref->name);
 	sort_string_list(&ref_names);
diff --git a/remote.h b/remote.h
index 9a30a9d..5d70aff 100644
--- a/remote.h
+++ b/remote.h
@@ -164,6 +164,6 @@ struct ref *guess_remote_head(const struct ref *head,
 			      int all);
 
 /* Return refs which no longer exist on remote */
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map);
+struct ref *get_stale_heads(struct ref *fetch_map, struct refspec *refs, int ref_count);
 
 #endif
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 8b5e925..581049b 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -86,7 +86,7 @@ test_expect_success 'fetch --prune on its own works as expected' '
 	test_must_fail git rev-parse origin/extrabranch
 '
 
-test_expect_failure 'fetch --prune with a branch name keeps branches' '
+test_expect_success 'fetch --prune with a branch name keeps branches' '
 	cd "$D" &&
 	git clone . prune-branch &&
 	cd prune-branch &&
@@ -96,7 +96,7 @@ test_expect_failure 'fetch --prune with a branch name keeps branches' '
 	git rev-parse origin/extrabranch
 '
 
-test_expect_failure 'fetch --prune with a namespace keeps other namespaces' '
+test_expect_success 'fetch --prune with a namespace keeps other namespaces' '
 	cd "$D" &&
 	git clone . prune-namespace &&
 	cd prune-namespace &&
-- 
1.7.5.2.354.g349bf

^ permalink raw reply related

* [PATCH 2/4] t5510: add tests for fetch --prune
From: Carlos Martín Nieto @ 2011-10-07 22:51 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1318027869-4037-1-git-send-email-cmn@elego.de>

The failures will be fixed in later commits.

Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
 t/t5510-fetch.sh |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 7e433b1..8b5e925 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -76,6 +76,56 @@ test_expect_success "fetch test for-merge" '
 	cut -f -2 .git/FETCH_HEAD >actual &&
 	test_cmp expected actual'
 
+test_expect_success 'fetch --prune on its own works as expected' '
+	cd "$D" &&
+	git clone . prune &&
+	cd prune &&
+	git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+
+	git fetch --prune origin &&
+	test_must_fail git rev-parse origin/extrabranch
+'
+
+test_expect_failure 'fetch --prune with a branch name keeps branches' '
+	cd "$D" &&
+	git clone . prune-branch &&
+	cd prune-branch &&
+	git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+
+	git fetch --prune origin master &&
+	git rev-parse origin/extrabranch
+'
+
+test_expect_failure 'fetch --prune with a namespace keeps other namespaces' '
+	cd "$D" &&
+	git clone . prune-namespace &&
+	cd prune-namespace &&
+
+	git fetch --prune origin refs/heads/a/*:refs/remotes/origin/a/* &&
+	git rev-parse origin/master
+'
+
+test_expect_failure 'fetch --prune --tags does not delete the remote-tracking branches' '
+	cd "$D" &&
+	git clone . prune-tags &&
+	cd prune-tags &&
+	git fetch origin refs/heads/master:refs/tags/sometag &&
+
+	git fetch --prune --tags origin &&
+	git rev-parse origin/master &&
+	test_must_fail git rev-parse somebranch
+'
+
+test_expect_failure 'fetch --prune --tags with branch does not delete other remote-tracking branches' '
+	cd "$D" &&
+	git clone . prune-tags-branch &&
+	cd prune-tags-branch &&
+	git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+
+	git fetch --prune --tags origin master &&
+	git rev-parse origin/extrabranch
+'
+
 test_expect_success 'fetch tags when there is no tags' '
 
     cd "$D" &&
-- 
1.7.5.2.354.g349bf

^ permalink raw reply related

* [PATCHv3 0/4] Be more careful when prunning
From: Carlos Martín Nieto @ 2011-10-07 22:51 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, mathstuf

Hello,

The first patch is not that big a deal, but it's better if we're
freeing the refspecs, we might as well free all of them.

The second patch introduces expected failures for the features that
this series fixes.

The third patch changes prune_resf and get_stale_heads so the caller
has to decide which refspecs are the appropriate ones to use. For
example, running

    git fetch --prune origin refs/heads/master:refs/heads/master

doesn't remove the other branches anymore. For a more interesting (and
believable) example, let's take

    git fetch --prune origin refs/heads/b/*:refs/heads/b/*

because you want to prune the refs inside the b/ namespace
only. Currently git will delete all the refs that aren't under that
namespace. With the second patch applied, git won't remove any refs
outside the b/ namespace.

What is probably the most usual case is covered by the forth patch,
which pretends that a "refs/tags/*:refs/tags/*" refspec was given on
the command-line. That fixes the

    git fetch --prune --tags origin

case. The non-tag refs are kept now.

Cheers,
   cmn

Carlos Martín Nieto (4):
  fetch: free all the additional refspecs
  t5510: add tests for fetch --prune
  fetch: honor the user-provided refspecs when pruning refs
  fetch: treat --tags like refs/tags/*:refs/tags/* when pruning

 builtin/fetch.c  |   33 +++++++++++++++++++++++----
 builtin/remote.c |    3 +-
 remote.c         |   66 ++++++++++++++++++++++++++++++++++++++++++++++-------
 remote.h         |    2 +-
 t/t5510-fetch.sh |   50 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 138 insertions(+), 16 deletions(-)

-- 
1.7.5.2.354.g349bf

^ permalink raw reply

* [PATCH 1/4] fetch: free all the additional refspecs
From: Carlos Martín Nieto @ 2011-10-07 22:51 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1318027869-4037-1-git-send-email-cmn@elego.de>

Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
 builtin/fetch.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7a4e41c..30b485e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -883,7 +883,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
 	atexit(unlock_pack);
 	refspec = parse_fetch_refspec(ref_nr, refs);
 	exit_code = do_fetch(transport, refspec, ref_nr);
-	free(refspec);
+	free_refspec(ref_nr, refspec);
 	transport_disconnect(transport);
 	transport = NULL;
 	return exit_code;
-- 
1.7.5.2.354.g349bf

^ permalink raw reply related

* [PATCH 4/4] fetch: treat --tags like refs/tags/*:refs/tags/* when pruning
From: Carlos Martín Nieto @ 2011-10-07 22:51 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1318027869-4037-1-git-send-email-cmn@elego.de>

If --tags is specified, add that refspec to the list given to
prune_refs so it knows to treat it as a filter on what refs to
should consider for prunning. This way

    git fetch --prune --tags origin

only prunes tags and doesn't delete the branch refs.

Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
 builtin/fetch.c  |   23 +++++++++++++++++++++--
 t/t5510-fetch.sh |    4 ++--
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 041f79e..0f8170c 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -700,10 +700,29 @@ static int do_fetch(struct transport *transport,
 		return 1;
 	}
 	if (prune) {
-		if (ref_count)
+		/* If --tags was specified, pretend the user gave us the canonical tags refspec */
+		if (tags == TAGS_SET) {
+			const char *tags_str = "refs/tags/*:refs/tags/*";
+			struct refspec *tags_refspec, *refspec;
+
+			/* Copy the refspec and add the tags to it */
+			refspec = xcalloc(ref_count + 1, sizeof(struct refspec));
+			tags_refspec = parse_fetch_refspec(1, &tags_str);
+			memcpy(refspec, refs, ref_count * sizeof(struct refspec));
+			memcpy(&refspec[ref_count], tags_refspec, sizeof(struct refspec));
+			ref_count++;
+
+			prune_refs(refspec, ref_count, ref_map);
+
+			ref_count--;
+			/* The rest of the strings belong to fetch_one */
+			free_refspec(1, tags_refspec);
+			free(refspec);
+		} else if (ref_count) {
 			prune_refs(refs, ref_count, ref_map);
-		else
+		} else {
 			prune_refs(transport->remote->fetch, transport->remote->fetch_refspec_nr, ref_map);
+		}
 	}
 	free_refs(ref_map);
 
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 581049b..e0af4c4 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -105,7 +105,7 @@ test_expect_success 'fetch --prune with a namespace keeps other namespaces' '
 	git rev-parse origin/master
 '
 
-test_expect_failure 'fetch --prune --tags does not delete the remote-tracking branches' '
+test_expect_success 'fetch --prune --tags does not delete the remote-tracking branches' '
 	cd "$D" &&
 	git clone . prune-tags &&
 	cd prune-tags &&
@@ -116,7 +116,7 @@ test_expect_failure 'fetch --prune --tags does not delete the remote-tracking br
 	test_must_fail git rev-parse somebranch
 '
 
-test_expect_failure 'fetch --prune --tags with branch does not delete other remote-tracking branches' '
+test_expect_success 'fetch --prune --tags with branch does not delete other remote-tracking branches' '
 	cd "$D" &&
 	git clone . prune-tags-branch &&
 	cd prune-tags-branch &&
-- 
1.7.5.2.354.g349bf

^ permalink raw reply related

* Re: [WIP PATCH 0/2] Be more careful when prunning
From: Junio C Hamano @ 2011-10-07 23:00 UTC (permalink / raw)
  To: Carlos Martín Nieto; +Cc: git
In-Reply-To: <1317920187-17389-1-git-send-email-cmn@elego.de>

Carlos Martín Nieto <cmn@elego.de> writes:

> Now comes the interesting part: when --tags is given, there is no
> refspec set up, fetch just sets up a global variable. What I'm
> thinking (and going to implement after dinner, unless people cry out
> against it) is this: just before calling prune_refs, add a refspec to
> the user-provided list with the refspec refs/tags/*:refs/tags/*
> similar to what fetch_one does if you gave it "tag v1.5.6". This would
> cause us to ignore the configured refspec and keep the branches. The
> lack of '+' is most certainly on purpose. Is there anything
> fundamentally wrong with that idea?

It sounds like that the approach should work and preserve the current
"fetch --tags" semantics, but with one small caveat (which is not a
downside).

As was discussed in a few separate threads last month, in the longer term
I think we should fix the semantics of "fetch --tags" to mean "in addition
to what you usually fetch with the configured refspecs, add that all
matching refs/tags/*:refs/tags/* to the refspec" to reduce confusion.
"Only fetch tags" may make sense if you have everything else, but by
itself it is somewhat a senseless thing to do.

The semantics has been kept this way only from fear of breaking backward
compatibility, but because nobody wants to only fetch tags without
branches, this forces people to say "git fetch && git fetch --tags".

We should re-evaluate the design and change it at a major version
boundary, I would think. And when that happens, we may need to rip out the
special case you discussed above.

Thanks.

^ permalink raw reply

* Re: [PATCH] git-svn: Allow certain refs to be ignored
From: Junio C Hamano @ 2011-10-07 23:23 UTC (permalink / raw)
  To: Eric Wong; +Cc: Michael Olson, git
In-Reply-To: <CAN4ruPiSgY+LPdDgS021WQyoHMuNrJDzrqMuCt9G5qfZ=XtjoQ@mail.gmail.com>

Asking Eric to comment when he has time to do so.

I find these pattern matches that are not anchored on either side 
somewhat disturbing (e.g. --ignore-refs=master would ignore master2)
but ignore-paths codepath seems to follow the same pattern, so perhaps it
is in line with what git-svn users want. I dunno.

Michael Olson <mwolson@gnu.org> writes:

> Implement a new --ignore-refs option which specifies a regex of refs
> to ignore while importing svn history.
>
> This is a useful supplement to the --ignore-paths option, as that
> option only operates on the contents of branches and tags, not the
> branches and tags themselves.
>
> Signed-off-by: Michael Olson <mwolson@gnu.org>
> ---
> Re-sent by request of Piotr Krukowiecki.  This is against v1.7.4.1,
> and I've been using it stably for a while.
>
>  git-svn.perl |   38 +++++++++++++++++++++++++++++++++-----
>  1 files changed, 33 insertions(+), 5 deletions(-)
>
> diff --git a/git-svn.perl b/git-svn.perl
> index 177dd25..541fa2d 100755
> --- a/git-svn.perl
> +++ b/git-svn.perl
> @@ -90,7 +90,8 @@ $_q ||= 0;
>  my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
>                      'config-dir=s' => \$Git::SVN::Ra::config_dir,
>                      'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
> -                    'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
> +                    'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex,
> +                    'ignore-refs=s' => \$Git::SVN::Ra::_ignore_refs_regex );
>  my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
>  		'authors-file|A=s' => \$_authors,
>  		'authors-prog=s' => \$_authors_prog,
> @@ -380,9 +381,12 @@ sub do_git_init_db {
>  		command_noisy('config', "$pfx.$i", $icv{$i});
>  		$set = $i;
>  	}
> -	my $ignore_regex = \$SVN::Git::Fetcher::_ignore_regex;
> -	command_noisy('config', "$pfx.ignore-paths", $$ignore_regex)
> -		if defined $$ignore_regex;
> +	my $ignore_paths_regex = \$SVN::Git::Fetcher::_ignore_regex;
> +	command_noisy('config', "$pfx.ignore-paths", $$ignore_paths_regex)
> +		if defined $$ignore_paths_regex;
> +	my $ignore_refs_regex = \$Git::SVN::Ra::_ignore_refs_regex;
> +	command_noisy('config', "$pfx.ignore-refs", $$ignore_refs_regex)
> +		if defined $$ignore_refs_regex;
>  }
>
>  sub init_subdir {
> @@ -1831,6 +1835,8 @@ sub read_all_remotes {
>  			$r->{$1}->{svm} = {};
>  		} elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
>  			$r->{$1}->{url} = $2;
> +		} elsif (m!^(.+)\.ignore-refs=\s*(.*)\s*$!) {
> +			$r->{$1}->{ignore_refs_regex} = $2;
>  		} elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
>  			my ($remote, $t, $local_ref, $remote_ref) =
>  			                                     ($1, $2, $3, $4);
> @@ -1867,6 +1873,16 @@ sub read_all_remotes {
>  		}
>  	} keys %$r;
>
> +	foreach my $remote (keys %$r) {
> +		foreach ( grep { defined $_ }
> +			  map { $r->{$remote}->{$_} } qw(branches tags) ) {
> +			foreach my $rs ( @$_ ) {
> +				$rs->{ignore_refs_regex} =
> +				    $r->{$remote}->{ignore_refs_regex};
> +			}
> +		}
> +	}
> +
>  	$r;
>  }
>
> @@ -4876,7 +4892,7 @@ sub apply_diff {
>  }
>
>  package Git::SVN::Ra;
> -use vars qw/@ISA $config_dir $_log_window_size/;
> +use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
>  use strict;
>  use warnings;
>  my ($ra_invalid, $can_do_switch, %ignored_err, $RA);
> @@ -5334,6 +5350,17 @@ sub get_dir_globbed {
>  	@finalents;
>  }
>
> +# return value: 0 -- don't ignore, 1 -- ignore
> +sub is_ref_ignored {
> +	my ($g, $p) = @_;
> +	my $refname = $g->{ref}->full_path($p);
> +	return 1 if defined($g->{ignore_refs_regex}) &&
> +	            $refname =~ m!$g->{ignore_refs_regex}!;
> +	return 0 unless defined($_ignore_refs_regex);
> +	return 1 if $refname =~ m!$_ignore_refs_regex!o;
> +	return 0;
> +}
> +
>  sub match_globs {
>  	my ($self, $exists, $paths, $globs, $r) = @_;
>
> @@ -5370,6 +5397,7 @@ sub match_globs {
>  			next unless /$g->{path}->{regex}/;
>  			my $p = $1;
>  			my $pathname = $g->{path}->full_path($p);
> +			next if is_ref_ignored($g, $p);
>  			next if $exists->{$pathname};
>  			next if ($self->check_path($pathname, $r) !=
>  			         $SVN::Node::dir);

^ permalink raw reply

* Re: [PATCH] git-svn: Allow certain refs to be ignored
From: Michael Olson @ 2011-10-07 23:33 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Eric Wong, git
In-Reply-To: <7vvcs0s7xa.fsf@alter.siamese.dyndns.org>

On Fri, Oct 7, 2011 at 4:23 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Asking Eric to comment when he has time to do so.
>
> I find these pattern matches that are not anchored on either side
> somewhat disturbing (e.g. --ignore-refs=master would ignore master2)
> but ignore-paths codepath seems to follow the same pattern, so perhaps it
> is in line with what git-svn users want. I dunno.

My own personal use of this takes a list of patterns, concatenates
them into one giant pattern, adds '^', '$', and writes it out to
.gitconfig.  So I don't really have a preference, other than to make
both options consistent.

-- 
Michael Olson  |  http://mwolson.org/

^ permalink raw reply

* Re: How pretty is pretty? git cat-file -p inconsistency
From: Jakub Narebski @ 2011-10-07 23:50 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <4E8F6088.8060300@drmicha.warpmail.net>

Michael J Gruber <git@drmicha.warpmail.net> writes:

[cut]
> I never knew how ugly the output of "git tag-file tree sha1" is. I guess
> it's the type of object whose format I don't know... We don't have an
> object format description in Doc/technical, do we? tree.c doesn't tell
> me much.

I had to handle this in my attempt to write "git blame <directory>" in Perl,
which was using `git cat-file --batch`, and that gives raw data and not
pretty-printed.

Tree object consist of zero or more entries.  Each item consist of mode,
filename, and sha1:

  <mode> SPC <filename> NUL <sha1>

where

1. <mode> is variable-length (!) text (!) containing mode of an
   entry. It encodes type of entry: if it is blob (including special
   case: symbolic link), tree i.e. directory, or a commit
   i.e. submodule.  Does not include leading zeros.

2. <filename> is variable-length null-terminated ("\0") name of a file
   or directory, or name of directory where submodule is attached

3. <sha1> is 40-bytes _binary_ identifier.

HTH
-- 
Jakub Narębski

^ permalink raw reply

* Re: [PATCH] fmt-merge-msg: use branch.$name.description
From: Jakub Narebski @ 2011-10-08  0:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michael J Gruber, Jonathan Nieder, git, Jeff King
In-Reply-To: <7vobxstt4w.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
> > Alternatively, one could store the description in a blob and refer to
> > that directly, of course. I.e., have
> >
> > refs/description/foo
> >
> > point to a blob whose content is the description of the ref
> >
> > ref/foo
> >
> > That would be unversioned, and one could decide more easily which
> > descriptions to share. (A notes tree you either push or don't.)
[...]

> But it remains that any of these approaches assume branch names are
> universal. Unlike other systems, what we call branches do not have their
> own identity, so if you really want to go that route (and we _might_ need
> to in the longer term, but I am not convinced at this point yet), you
> would first need to define how that local namespace would look like, how
> people interact with it, etc. It might be just the matter of declaring a
> convention e.g. "Among people who meet at this central repository,
> everybody must map the branches identically to their local branch
> namespace, and all sharing must go through the central repository", and
> calling a tuple <central repository URL, branch name in that repository>
> with a name that cannot be confused with "branch" (so "remote branch" is
> out), such as "(development) track".

Well, git could by default imply that 'refs/heads/*:refs/remotes/foo/*'
implies 'refs/description/*:refs/remote-descriptions/foo/*'...

...one more argument for hierarchical remote-tracking refs namespace,
i.e. 'refs/remotes/foo/refs/heads/*', and not current 'refs/remotes/foo/*'

Just my 3 eurocents^W groszy.
-- 
Jakub Narębski

^ permalink raw reply

* Re: [PATCH 1/3] completion: unite --reuse-message and --reedit-message handling
From: SZEDER Gábor @ 2011-10-08  1:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Teemu Matilainen, git, Shawn O. Pearce
In-Reply-To: <7vd3e9yap7.fsf@alter.siamese.dyndns.org>

Hi,

On Thu, Oct 06, 2011 at 04:14:28PM -0700, Junio C Hamano wrote:
> All three patches make sense to me. Thanks.

This is a good cleanup/deduplication; there are a few places where
similar cleanup can be done.  Since this conflicted with one of my
more intrusive WIP branches, I figured it's better to clean up those
first, too.


Best,
Gábor

^ permalink raw reply

* [PATCH 1/2] completion: unite --reuse-message and --reedit-message for 'notes'
From: SZEDER Gábor @ 2011-10-08  1:06 UTC (permalink / raw)
  To: Junio C Hamano, Shawn O. Pearce; +Cc: Teemu Matilainen, git
In-Reply-To: <20111008010432.GA11561@goldbirke>

Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
---
 contrib/completion/git-completion.bash |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 847e6e9a..98282435 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1668,11 +1668,9 @@ _git_notes ()
 			;;
 		esac
 		;;
-	add,--reuse-message=*|append,--reuse-message=*)
-		__gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
-		;;
+	add,--reuse-message=*|append,--reuse-message=*|\
 	add,--reedit-message=*|append,--reedit-message=*)
-		__gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
+		__gitcomp "$(__git_refs)" "" "${cur#*=}"
 		;;
 	add,--*|append,--*)
 		__gitcomp '--file= --message= --reedit-message=
-- 
1.7.7.187.ga41de

^ permalink raw reply related

* [PATCH 2/2] completion: unite --format and --pretty for 'log' and 'show'
From: SZEDER Gábor @ 2011-10-08  1:09 UTC (permalink / raw)
  To: Junio C Hamano, Shawn O. Pearce; +Cc: Teemu Matilainen, git
In-Reply-To: <20111008010432.GA11561@goldbirke>

Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
---
 contrib/completion/git-completion.bash |   18 ++++--------------
 1 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 98282435..b36f9e70 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1553,14 +1553,9 @@ _git_log ()
 		merge="--merge"
 	fi
 	case "$cur" in
-	--pretty=*)
+	--pretty=*|--format=*)
 		__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-			" "" "${cur##--pretty=}"
-		return
-		;;
-	--format=*)
-		__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-			" "" "${cur##--format=}"
+			" "" "${cur#*=}"
 		return
 		;;
 	--date=*)
@@ -2365,14 +2360,9 @@ _git_show ()
 	__git_has_doubledash && return
 
 	case "$cur" in
-	--pretty=*)
-		__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-			" "" "${cur##--pretty=}"
-		return
-		;;
-	--format=*)
+	--pretty=*|--format=*)
 		__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
-			" "" "${cur##--format=}"
+			" "" "${cur#*=}"
 		return
 		;;
 	--*)
-- 
1.7.7.187.ga41de

^ permalink raw reply related

* Re: unexpected behavior with `git log --skip filename`
From: Andrew McNabb @ 2011-10-08  2:36 UTC (permalink / raw)
  To: Jay Soffian; +Cc: git
In-Reply-To: <CAG+J_DwnUOeDTiUW-UUJGLLg8jJ4EhXN21B7o_hOMnyowM9a8g@mail.gmail.com>

On Fri, Oct 07, 2011 at 05:54:36PM -0400, Jay Soffian wrote:
> 
> Hmm:
> 
> $ git log --oneline GIT-VERSION-GEN | head -2
> 7f41b6bbe3 Post 1.7.7 first wave
> 703f05ad58 Git 1.7.7
> 
> $ git log --oneline --skip=1 -n 1 GIT-VERSION-GEN
> 703f05ad58 Git 1.7.7

I went back to reproduce this, and I think I may have been using the
--follow option earlier.  In my private repository, git log gives
identical output for the last two commits when I don't specify --skip:

$ git log -n 2 --oneline httpd.conf.orig
f0026e9 updated many of the *.orig files to the latest version
e57e840 moved the .orig files into place, too
$ git log --follow -n 2 --oneline httpd.conf.orig
f0026e9 updated many of the *.orig files to the latest version
e57e840 moved the .orig files into place, too
$

But when I specify --skip=1, the output is different:

$ git log -n 1 --skip=1 --oneline httpd.conf.orig
e57e840 moved the .orig files into place, too
$ git log --follow -n 1 --skip=1 --oneline httpd.conf.orig
f0026e9 updated many of the *.orig files to the latest version
$


GIT-VERSION-GEN example that you shared, I don't notice this difference.
It's not immediately obvious to me what's different between the two
examples.

--
Andrew McNabb
http://www.mcnabbs.org/andrew/
PGP Fingerprint: 8A17 B57C 6879 1863 DE55  8012 AB4D 6098 8826 6868

^ permalink raw reply

* [PATCH 0/3] jp/get-ref-dir-unsorted fixups
From: Brandon Casey @ 2011-10-08  3:20 UTC (permalink / raw)
  To: git; +Cc: julian

Here are a few fixups I found while investigating a segfault on IRIX.

The first patch fixes a potential segfault due to an uninitialized
variable, but it has already been made moot by Michael Haggerty's
updates to refs.c that are merged in next.  So, not sure if it's worth
applying or not.

The second one fixes the segfault on IRIX and is a valid thing to do
anyway.

The third one plugs a little memory leak that may never occur.

Built on top of jp/get-ref-dir-unsorted e9c4c111.

-Brandon

Brandon Casey (3):
  refs.c: ensure struct whose member may be passed to realloc is
    initialized
  refs.c: abort ref search if ref array is empty
  refs.c: free duplicate entries in the ref array instead of leaking
    them

 refs.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

-- 
1.7.7

^ permalink raw reply

* [PATCH 1/3] refs.c: ensure struct whose member may be passed to realloc is initialized
From: Brandon Casey @ 2011-10-08  3:20 UTC (permalink / raw)
  To: git; +Cc: julian, Brandon Casey
In-Reply-To: <3k7giKa3PkJZo51iAXivXCFEZpYY2WC3depjtuvksrCQPax7dSLVCXpMlqLxWtZfSp6P10yMhMg@cipher.nrlssc.navy.mil>

From: Brandon Casey <drafnel@gmail.com>

The variable "refs" is allocated on the stack but is not initialized.  It
is passed to read_packed_refs(), and its struct members may eventually be
passed to add_ref() and ALLOC_GROW().  Since the structure has not been
initialized, its members may contain random non-zero values.  So let's
initialize it.

The call sequence looks something like this:

   resolve_gitlink_packed_ref(...) {

       struct cached_refs refs;
       ...
       read_packed_refs(f, &refs);
       ...
   }

   read_packed_refs(FILE*, struct cached_refs *cached_refs) {
       ...
       add_ref(name, sha1, flag, &cached_refs->packed, &last);
       ...
   }

   add_ref(..., struct ref_array *refs, struct ref_entry **) {
       ...
       ALLOC_GROW(refs->refs, refs->nr + 1, refs->alloc);
   }

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
 refs.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/refs.c b/refs.c
index 5835b40..c31b461 100644
--- a/refs.c
+++ b/refs.c
@@ -360,6 +360,7 @@ static int resolve_gitlink_packed_ref(char *name, int pathlen, const char *refna
 	f = fopen(name, "r");
 	if (!f)
 		return -1;
+	memset(&refs, 0, sizeof(refs));
 	read_packed_refs(f, &refs);
 	fclose(f);
 	ref = search_ref_array(&refs.packed, refname);
-- 
1.7.7

^ permalink raw reply related

* [PATCH 2/3] refs.c: abort ref search if ref array is empty
From: Brandon Casey @ 2011-10-08  3:20 UTC (permalink / raw)
  To: git; +Cc: julian, Brandon Casey
In-Reply-To: <3k7giKa3PkJZo51iAXivXCFEZpYY2WC3depjtuvksrCQPax7dSLVCXpMlqLxWtZfSp6P10yMhMg@cipher.nrlssc.navy.mil>

From: Brandon Casey <drafnel@gmail.com>

The bsearch() implementation on IRIX 6.5 segfaults if it is passed NULL
for the base array argument even if number-of-elements is zero.  So, let's
work around it by detecting an empty array and aborting early.

This is a useful optimization in its own right anyway, since we avoid a
useless allocation and initialization of the ref_entry when the ref array
is empty.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
 refs.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/refs.c b/refs.c
index c31b461..cbc4c5d 100644
--- a/refs.c
+++ b/refs.c
@@ -110,6 +110,9 @@ static struct ref_entry *search_ref_array(struct ref_array *array, const char *n
 	if (name == NULL)
 		return NULL;
 
+	if (!array->nr)
+		return NULL;
+
 	len = strlen(name) + 1;
 	e = xmalloc(sizeof(struct ref_entry) + len);
 	memcpy(e->name, name, len);
-- 
1.7.7

^ permalink raw reply related

* [PATCH 3/3] refs.c: free duplicate entries in the ref array instead of leaking them
From: Brandon Casey @ 2011-10-08  3:20 UTC (permalink / raw)
  To: git; +Cc: julian, Brandon Casey
In-Reply-To: <3k7giKa3PkJZo51iAXivXCFEZpYY2WC3depjtuvksrCQPax7dSLVCXpMlqLxWtZfSp6P10yMhMg@cipher.nrlssc.navy.mil>

From: Brandon Casey <drafnel@gmail.com>


Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
 refs.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/refs.c b/refs.c
index cbc4c5d..df39297 100644
--- a/refs.c
+++ b/refs.c
@@ -94,6 +94,7 @@ static void sort_ref_array(struct ref_array *array)
 				die("Duplicated ref, and SHA1s don't match: %s",
 				    a->name);
 			warning("Duplicated ref: %s", a->name);
+			free(b);
 			continue;
 		}
 		i++;
-- 
1.7.7

^ permalink raw reply related

* Re: [PATCH v3] gitk: Teach gitk to respect log.showroot
From: Paul Mackerras @ 2011-10-08  6:47 UTC (permalink / raw)
  To: Marcus Karlsson; +Cc: zbyszek, gitster, git
In-Reply-To: <20111004200813.GA16596@kennedy.acc.umu.se>

On Tue, Oct 04, 2011 at 10:08:13PM +0200, Marcus Karlsson wrote:
> Teach gitk to respect log.showroot.

Sounds reasonable, ...

> -	set cmd [concat | git diff-tree -r $flags $ids]
> +	set cmd [concat | git diff-tree -r]
> +	if {$log_showroot eq true} {
> +	    set cmd [concat $cmd --root]
> +	}
> +	set cmd [concat $cmd $flags $ids]

but is there any reason not to do it like this?

	if {$log_showroot} {
	    lappend flags --root
	}
	set cmd [concat | git diff-tree -r $flags $ids]

I.e., do you particularly want the --root before the other flags?

Paul.

^ permalink raw reply

* Re: gitk: 'j' and 'k' keyboard shortcuts backward
From: Paul Mackerras @ 2011-10-08  7:04 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Clemens Buchacher, Josh Triplett, Pat Thoyts, Robert Suetterlin,
	git
In-Reply-To: <20110919164950.GB2861@elie>

On Mon, Sep 19, 2011 at 11:49:50AM -0500, Jonathan Nieder wrote:

> How about this patch?
> 
> -- >8 --
> Subject: gitk: Make vi-style keybindings more vi-like

Thanks, applied, minus the .po file updates.  The translaters seem to
prefer that I leave the .po file updates to them.

Paul.

^ permalink raw reply

* [PATCH] git-difftool: allow skipping file by typing 'n' at prompt
From: Sitaram Chamarty @ 2011-10-08 13:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Phil Hord, Sitaram Chamarty, git
In-Reply-To: <7vwrcgtvh4.fsf@alter.siamese.dyndns.org>

This is useful if you forgot to restrict the diff to the paths you want
to see, or selecting precisely the ones you want is too much typing.

Signed-off-by: Sitaram Chamarty <sitaram@atc.tcs.com>
---

On Fri, Oct 07, 2011 at 01:09:11PM -0700, Junio C Hamano wrote:

> Looks OK from a cursory viewing. Do we want some additional tests?
> 
> For that matter, have you run the test suite with this patch applied (I
> haven't)?

OK; done.  I got some "broken" but nothing "failed":

    make aggregate-results
    make[3]: Entering directory `/home/sitaram/clones/git/t'
    for f in test-results/t*-*.counts; do \
            echo "$f"; \
    done | '/bin/sh' ./aggregate-results.sh
    fixed   0
    success 7377
    failed  0
    broken  49
    total   7461

Hope that is not a problem.

However, I'm not sure the file names that 'git difftool'
comes up with are in a predictable order.  That would mess
up the test, but I can neither make it fail not find
definitive information on the order in which the changed
files are processed.

 git-difftool--helper.sh |    9 +++++----
 t/t7800-difftool.sh     |   44 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index 8452890..0468446 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -38,15 +38,16 @@ launch_merge_tool () {
 
 	# $LOCAL and $REMOTE are temporary files so prompt
 	# the user with the real $MERGED name before launching $merge_tool.
+	ans=y
 	if should_prompt
 	then
 		printf "\nViewing: '$MERGED'\n"
 		if use_ext_cmd
 		then
-			printf "Hit return to launch '%s': " \
+			printf "Launch '%s' [Y/n]: " \
 				"$GIT_DIFFTOOL_EXTCMD"
 		else
-			printf "Hit return to launch '%s': " "$merge_tool"
+			printf "Launch '%s' [Y/n]: " "$merge_tool"
 		fi
 		read ans
 	fi
@@ -54,9 +55,9 @@ launch_merge_tool () {
 	if use_ext_cmd
 	then
 		export BASE
-		eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
+		test "$ans" != "n" && eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"'
 	else
-		run_merge_tool "$merge_tool"
+		test "$ans" != "n" && run_merge_tool "$merge_tool"
 	fi
 }
 
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 395adfc..f547e0b 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -38,7 +38,18 @@ restore_test_defaults()
 prompt_given()
 {
 	prompt="$1"
-	test "$prompt" = "Hit return to launch 'test-tool': branch"
+	test "$prompt" = "Launch 'test-tool' [Y/n]: branch"
+}
+
+stdin_contains()
+{
+	grep >/dev/null "$1"
+}
+
+stdin_doesnot_contain()
+{
+	grep >/dev/null "$1" && return 1
+	return 0
 }
 
 # Create a file on master and change it on branch
@@ -265,4 +276,35 @@ test_expect_success PERL 'difftool --extcmd cat arg2' '
 	test "$diff" = branch
 '
 
+# Create a second file on master and a different version on branch
+test_expect_success PERL 'setup with 2 files different' '
+	echo m2 >file2 &&
+	git add file2 &&
+	git commit -m "added file2" &&
+
+	git checkout branch &&
+	echo br2 >file2 &&
+	git add file2 &&
+	git commit -a -m "branch changed file2" &&
+	git checkout master
+'
+
+test_expect_success PERL 'say no to the first file' '
+	diff=$((echo n; echo) | git difftool -x cat branch) &&
+
+	echo "$diff" | stdin_contains m2 &&
+	echo "$diff" | stdin_contains br2 &&
+	echo "$diff" | stdin_doesnot_contain master &&
+	echo "$diff" | stdin_doesnot_contain branch
+'
+
+test_expect_success PERL 'say no to the second file' '
+	diff=$((echo; echo n) | git difftool -x cat branch) &&
+
+	echo "$diff" | stdin_contains master &&
+	echo "$diff" | stdin_contains branch &&
+	echo "$diff" | stdin_doesnot_contain m2 &&
+	echo "$diff" | stdin_doesnot_contain br2
+'
+
 test_done
-- 
1.7.6

^ permalink raw reply related

* Display line numbers in gitk?
From: Sebastian Schuberth @ 2011-10-08 13:27 UTC (permalink / raw)
  To: git; +Cc: Pat Thoyts

Hi,

is there currently a way to display line numbers next to each line in 
the diff shown by gitk, e.g. in some kind of gutter?

If that's currently not possible, how much work would it require to add 
that feature as an option?

-- 
Sebastian Schuberth

^ permalink raw reply

* Re: How pretty is pretty? git cat-file -p inconsistency
From: Michael J Gruber @ 2011-10-08 14:47 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <m3r52o1hxr.fsf@localhost.localdomain>

Jakub Narebski venit, vidit, dixit 08.10.2011 01:50:
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
> [cut]
>> I never knew how ugly the output of "git tag-file tree sha1" is. I guess
>> it's the type of object whose format I don't know... We don't have an
>> object format description in Doc/technical, do we? tree.c doesn't tell
>> me much.
> 
> I had to handle this in my attempt to write "git blame <directory>" in Perl,
> which was using `git cat-file --batch`, and that gives raw data and not
> pretty-printed.
> 
> Tree object consist of zero or more entries.  Each item consist of mode,
> filename, and sha1:
> 
>   <mode> SPC <filename> NUL <sha1>
> 
> where
> 
> 1. <mode> is variable-length (!) text (!) containing mode of an
>    entry. It encodes type of entry: if it is blob (including special
>    case: symbolic link), tree i.e. directory, or a commit
>    i.e. submodule.  Does not include leading zeros.
> 
> 2. <filename> is variable-length null-terminated ("\0") name of a file
>    or directory, or name of directory where submodule is attached
> 
> 3. <sha1> is 40-bytes _binary_ identifier.
> 
> HTH

It does help, thanks.

Though I'm beginning to think we have a crazy object format. Not only do
we have a lot of indirections (like ascii representation of decimal
representation of length), but we store sha1 as ascii in commit and tag
objects and as binary in tree objects. Which makes tree objects the only
unpleasant ones to look at (and parse) in raw form. (I was hoping we can
dispose of/deprecate cat-file -p in favor of show). Oh well.

Michael

^ 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