Git development
 help / color / mirror / Atom feed
* Re: Problems setting up bare repository (git 1.5.3.3)
From: Johannes Schindelin @ 2007-10-02 17:45 UTC (permalink / raw)
  To: Carl Worth; +Cc: Junio C Hamano, Barry Fishman, git
In-Reply-To: <87641psey8.wl%cworth@cworth.org>

Hi,

On Tue, 2 Oct 2007, Carl Worth wrote:

> On Tue, 2 Oct 2007 10:46:56 +0100 (BST), Johannes Schindelin wrote:
> > On Mon, 1 Oct 2007, Carl Worth wrote:
> > > And why is that?
> >
> > Well, if the OP had used "git push <bla> master" instead of "... 
> > master:master", it would have worked.  I am unaware of any tutorial 
> > that suggests the latter, only of tutorials that suggest the former.
> 
> OK. I was wrong. Somehow I got stuck thinking that "git push <bla> 
> master" wouldn't create a new remote master branch if it didn't 
> previously exist. (It's bizarre that I forgot since I've used that for a 
> long time).
> 
> Sorry about the noise.

Nothing to be sorry about.  It got me thinking.  People propose that "git 
push <nick> master:blub" should create the branch "refs/heads/blub" on the 
remote side.

My initial reaction was "then you have to be precise, because we do not 
know if you want to push it as a branch, or as a lightweight tag".

But then I stepped back a little: What is most likely meant when you say 
"master:blub" and there is no tag/branch of name "blub" on the remote 
side?  Exactly, you want a branch to be created.

_Except_ if you had a typo, such as "git push ko master:po" where you want 
to be warned that that ref is not present on the remote side.

So I am less opposed to making "master:blub" automatically create a branch 
"blub" if it does not exist yet.  But opposed nevertheless.

Ciao,
Dscho

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Junio C Hamano @ 2007-10-02 17:44 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: git, Steffen Prohaska
In-Reply-To: <vpqr6keos6e.fsf@bauges.imag.fr>

Matthieu Moy <Matthieu.Moy@imag.fr> writes:

> I'd add this to be consistant with "git status". I find the "needs
> update" really short, and especially confusing for centralized systems
> users, for whom "needs update" would probably mean "new version
> available, please run '$VCS update'".

Yeah, and "needs merge" solicits 'SCM merge'.

> diff --git a/read-cache.c b/read-cache.c
> index 2e40a34..3745a48 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -869,7 +869,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
>                         }
>                         if (quiet)
>                                 continue;
> -                       printf("%s: needs update\n", ce->name);
> +                       printf("%s: Changed but not updated\n", ce->name);
>                         has_errors = 1;
>                         continue;
>                 }

I tried to stay away from touching that part on purpose.  Doing
this unconditionally may break people's existing scripts that
use update-index --refresh plumbing.

We could introduce a new option to "update-index --refresh" that
makes the output more machine readable by either NUL terminating
or c_quoting ce->name to protect the caller from potential
spaces and newlines in the name, and use that from the caller.

But for this particular case, I think a much simpler alternative
would be to do it this way:

>  # The tree must be really really clean.
> -git update-index --refresh || exit
> +git update-index -q --refresh || {
+	git status
> +	printf "cannot rebase: the work tree is not clean.\n"
> +	exit 1
> +}
>  diff=$(git diff-index --cached --name-status -r HEAD)
>  case "$diff" in
>  ?*)	echo "cannot rebase: your index is not up-to-date"

^ permalink raw reply

* Re: Problems setting up bare repository (git 1.5.3.3)
From: Johannes Schindelin @ 2007-10-02 17:40 UTC (permalink / raw)
  To: Barry Fishman; +Cc: git
In-Reply-To: <m34ph9tye1.fsf@barry_fishman.acm.org>

Hi,

[please do not cull me from the Cc: list, especially when you are quoting 
me]

On Tue, 2 Oct 2007, Barry Fishman wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> > Well, if the OP had used "git push <bla> master" instead of "... 
> > master:master", it would have worked.  I am unaware of any tutorial 
> > that suggests the latter, only of tutorials that suggest the former.
> 
> I did recheck the tutorials, and did not find the code I was
> using.  So there was nothing incorrect in the documentation.

Good.  Just for my curiousity: where in the documentation did you look for 
help?  (We might want to advertise "git push <nick> <branch>" more loudly 
there.)

> What distracted me was that after the "git --bare init", there seemed to 
> be a incompletely defined setup.  This sent me down the wrong path.
> 
> Although there was a master branch to which HEAD pointed, there was no
> ref/heads/master file or even a "packed-refs".

That means that there was no master branch.  Before the first commit, a 
branch does not exist.  We are stricter in that regard than other SCMs.

> If there isn't an initial master branch, then shouldn't "git branch" be
> able to create one.

Why?  I really do not see the point in creating a branch which is named 
different than "master", when you have nothing to begin with.

Just use "master".  As easy as that.

If you really have to paint the bike shed, you can always rename your 
branch later, when you got something, by "git branch -m <new-branch-name>".

>   This command creates an empty git repository - basically a .git directory
>   with subdirectories for objects, refs/heads, refs/tags, and template
>   files. An initial HEAD file references the refs/heads/master branch
>   which is created with the first commit.

How about "Your first commit will create the master branch" instead of the 
last sentence?

Ciao,
Dscho

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Jeff King @ 2007-10-02 17:39 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <86ve9p32cp.fsf@lola.quinscape.zz>

On Tue, Oct 02, 2007 at 06:31:18PM +0200, David Kastrup wrote:

> This does not actually require an actual merge _sort_ AFAICS: do the
> "sort file.hashed" step using qsort.  The comparison step does not
> actually need to produce merged output, but merely advances through
> two hash arrays and generates statistics.

Right, that's why I used "merge" in quotes. The sort used in the O(n)
step is irrelevant, but we are doing a merge-sort-like behavior in the
second step (except instead of actually merging into a new list, we are
summarizing the comparisons in a numeric "difference" variable). But I
think we are on the same page.

> This should already beat the pants off the current implementation,
> even when the hash array is sparse, simply because our inner loop then
> has perfect hash coherence.

Yes, I hope so. We'll see. :)

> Getting rid of this outer O(n^2) remains an interesting challenge,
> though.  One way would be the following: fill a _single_ array with
> entries containing _both_ hash and file number.  Sort this, and then
> gather the statistics of hash runs by making a single pass through.
> That reduces the O(n^2) behavior to only those parts with actual hash
> collisions.

Interesting. Care to take a stab at implementing it?

-Peff

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Daniel Barkalow @ 2007-10-02 17:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3awunjup.fsf@gitster.siamese.dyndns.org>

On Mon, 1 Oct 2007, Junio C Hamano wrote:

> * db/fetch-pack (Mon Oct 1 00:59:39 2007 +0100) 49 commits
>  + fetch/push: readd rsync support
>  + Introduce remove_dir_recursively()
>  + bundle transport: fix an alloc_ref() call
>  + Allow abbreviations in the first refspec to be merged
>  + Prevent send-pack from segfaulting when a branch doesn't match
>  + Cleanup unnecessary break in remote.c
>  ...
> 
> Has been cooking for quite long time.
> 
> There was a regression that made me quite unhappy about the
> rewrite, but Daniel fixed it, so I should be happy.  There is
> another usability regression: http transport is now totally
> silent.

I think this is due to passing through equal verbosity levels, when the 
non-verbose case for the native protocols was a lot less silent than the 
non-verbose case for http. "git fetch -v -v" does show everything. I think 
just replacing "transport->verbose" with "1" on line 347 of transport.c 
would give the old default behavior, but fetch probably needs a more quiet 
setting than the default, as well as the current more verbose than 
default. I'll put together a patch for this when I get a chance.

> Even when you fetch daily, if the other end frequently
> repacks everything into one big ball of wax like repo.or.cz
> does, you will end up transferring quite a large pack every
> time, and the total lack of progress report is unacceptably
> unnerving.  At least we should reinstate "Fetching blah from URL
> using http", and preferrably "walk $object_name" lines.  The
> latter could be replaced with just series of CR + "walked N
> commits..." if we do not like many output from the current "walk
> $object_name" lines scrolling the other information away.

The right thing for now is probably to match the old git-fetch's behavior, 
once I can remember what it is. (I've been using my C version for my 
personal use long enough that I can't remember everything the shell 
version did. My new version should be sufficiently flexible to accomodate 
most things without too much trouble, but I've lost my ability to notice 
differences without prompting.)

After the implementation change is in, we can look at improving 
user-visible things. I think a display like the "counting objects" display 
(number that counts up in place), plus progress bars for big downloads, would 
be ideal.

> I am not sure the quality of "rsync" transport near the tip,
> either, but at least the change should not affect other
> transports.  Nobody should using about rsync transport these
> days anyway.  Perhaps we should put a deprecation notice in the
> release notes to 1.5.4, and remove it three months later.

I think that rsync should be kept until we've got sftp in place, which 
should cover the same cases and be better overall. 

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: David Kastrup @ 2007-10-02 16:31 UTC (permalink / raw)
  To: git
In-Reply-To: <20071002161114.GC6828@coredump.intra.peff.net>

Jeff King <peff@peff.net> writes:

> On Tue, Oct 02, 2007 at 08:10:28AM +0200, David Kastrup wrote:

[...]

> The algorithm is something like this: We have N files, and we want
> to find "similar" candidates. So we go through each file and
> generate a table of fingperint hashes
> (diffcore-rename.c:hash_chars), and then compare each file with
> every other file, using the hash tables to do the comparison.
>
> So the comparison step for two files is currently something like:
>
>   for each hash in file1
>     hash2 = look up hash in file2
>     compare hash and hash2
>
> and if they were sorted, perhaps we could do something merge-like:
>
>   while hashes are left to compare
>       compare file1.next, file2.next
>       advance file1, file2, or both (depending on comparison)
>
>> When we are talking about buzzword compliance, "keep sorted" with
>> the meaning of "maintain sorted across modifications" has an O(n^2)
>> or at least O(nm) ring to it.  However, if it is possible to sort
>> it just once, and then then only merge with other lists...
>
> It would be sort once. I.e.,:
>
>   for each file
>      generate file.hashes
>      sort file.hashes
>   for each file1
>     for each file2
>       compare file1.hashes to file2.hashes
>
> where that 'compare' step is taking most of the CPU time (for the
> obvious reason that we call it in an O(n^2) loop).
>
> I will try to implement this as time permits, but if you want to
> tinker with it in the meantime, feel free.

This does not actually require an actual merge _sort_ AFAICS: do the
"sort file.hashed" step using qsort.  The comparison step does not
actually need to produce merged output, but merely advances through
two hash arrays and generates statistics.

This should already beat the pants off the current implementation,
even when the hash array is sparse, simply because our inner loop then
has perfect hash coherence.

Getting rid of this outer O(n^2) remains an interesting challenge,
though.  One way would be the following: fill a _single_ array with
entries containing _both_ hash and file number.  Sort this, and then
gather the statistics of hash runs by making a single pass through.
That reduces the O(n^2) behavior to only those parts with actual hash
collisions.

-- 
David Kastrup

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Jeff King @ 2007-10-02 16:11 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <86ejge6o8b.fsf@lola.quinscape.zz>

On Tue, Oct 02, 2007 at 08:10:28AM +0200, David Kastrup wrote:

> I have not actually looked at the actual task that the structures are
> going to be used in, and whether "reusing" the information is likely
> to be worth the trouble.

The algorithm is something like this:  We have N files, and we want to
find "similar" candidates. So we go through each file and generate a
table of fingperint hashes (diffcore-rename.c:hash_chars), and then
compare each file with every other file, using the hash tables to do the
comparison.

So the comparison step for two files is currently something like:

  for each hash in file1
    hash2 = look up hash in file2
    compare hash and hash2

and if they were sorted, perhaps we could do something merge-like:

  while hashes are left to compare
      compare file1.next, file2.next
      advance file1, file2, or both (depending on comparison)

> When we are talking about buzzword compliance, "keep sorted" with the
> meaning of "maintain sorted across modifications" has an O(n^2) or at
> least O(nm) ring to it.  However, if it is possible to sort it just
> once, and then then only merge with other lists...

It would be sort once. I.e.,:

  for each file
     generate file.hashes
     sort file.hashes
  for each file1
    for each file2
      compare file1.hashes to file2.hashes

where that 'compare' step is taking most of the CPU time (for the
obvious reason that we call it in an O(n^2) loop).

I will try to implement this as time permits, but if you want to tinker
with it in the meantime, feel free.

-Peff

^ permalink raw reply

* Re: [PATCH 1/2] Change "refs/" references to symbolic constants
From: Jeff King @ 2007-10-02 15:58 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200710020941.05288.andyparkins@gmail.com>

On Tue, Oct 02, 2007 at 09:41:03AM +0100, Andy Parkins wrote:

> Excellent!  Well done.  I spent a couple of hours last night going through 
> every changed line and have spotted the TAGS mistake but didn't spot the 
> STRLEN being wrong.  Amazing how easy it is to become blind to these things.  
> There were a couple of errors in "/" placement too, but I don't think they 
> were causing any trouble, just doubled up "/" characters.

I wonder if you could check the patch mechanically (i.e., write a script
to confirm that '5' got replaced by tokens equal to '5'), though that
might require some tricky parsing of C.

If you a post an updated version, I will try to read through it
carefully, as two eyes are better than one (er, four eyes, I guess).

> I noticed a couple of places where memcmp() has been used where prefixcmp() 
> would work fine.  I'm tempted to change them too - what do you think?  
> Perhaps a separate patch?

When in doubt, I would suggest a separate patch, as it makes the review
easier.

> I'm happy to do prepare a patch against any revision, I was really
> waiting for feedback from Junio as to how he'd like to manage it.
> Last time I submitted this patch he (quite correctly) asked that I
> delay until after the next point release; of course I promptly found
> other things to do and never resubmitted :-)

Yes, you should definitely listen to Junio on such issues, and not me.
:)

-Peff

^ permalink raw reply

* Re: what's a useful definition of full text index on a repository?
From: Jon Smirl @ 2007-10-02 15:48 UTC (permalink / raw)
  To: David Tweed; +Cc: Git Mailing List
In-Reply-To: <e1dab3980710020234l1951349r38657c68aa7ef5@mail.gmail.com>

On 10/2/07, David Tweed <david.tweed@gmail.com> wrote:
> > Full text indexing can also achieve high levels of compression as
> > stated in the earlier threads. It is full scale dictionary
> > compression. When it is being used for compression you want to apply
> > it to all revisions.
>
> Well, as I say I'm not convinced it makes sense to integrate this with
> existing pack stuff precisely because I don't think it's universally
> useful. So you seem to end up with all the usual tricks, eg, Golomb
> coding inverted indexes, etc, _if_ you treat each blob as completely
> independent. I was wondering if there was anything else you can do
> given the special structure that might be both more useful and more
> compact?

Dictionary compression can be used without full-text indexes. It is
just really easy to build the full-text index if the data is already
dictionary compressed. Dictionary compression works for everything
except binary or random data.

Git is already using a small scale dictionary compressor via zip. I
suspect doing a full scale dictionary for a pack file and then using
arithmetic encoding of the tokens would provide substantially more
compression. The big win is having a single dictionary instead of a
new dictionary each time zip is used.

When we were working on Mozilla, Mozilla changed licenses three times.
The license text ended up taking about 30MB in the current scheme.
With full dictionary compression this would reduce down to a few kb.

More compression is good for git. It means we can keep more data in
RAM and reduce download times. With current hardware it is almost
always better to trade off CPU to reduce IO.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: Problems setting up bare repository (git 1.5.3.3)
From: Carl Worth @ 2007-10-02 15:39 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, Barry Fishman, git
In-Reply-To: <Pine.LNX.4.64.0710021045430.28395@racer.site>

[-- Attachment #1: Type: text/plain, Size: 587 bytes --]

On Tue, 2 Oct 2007 10:46:56 +0100 (BST), Johannes Schindelin wrote:
> On Mon, 1 Oct 2007, Carl Worth wrote:
> > And why is that?
>
> Well, if the OP had used "git push <bla> master" instead of
> "... master:master", it would have worked.  I am unaware of any tutorial
> that suggests the latter, only of tutorials that suggest the former.

OK. I was wrong. Somehow I got stuck thinking that "git push <bla>
master" wouldn't create a new remote master branch if it didn't
previously exist. (It's bizarre that I forgot since I've used that for
a long time).

Sorry about the noise.

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] git-push: plumb in --mirror mode
From: Andy Whitcroft @ 2007-10-02 14:21 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0710021347530.28395@racer.site>

On Tue, Oct 02, 2007 at 01:50:28PM +0100, Johannes Schindelin wrote:
> Hi,
> 
> On Tue, 2 Oct 2007, Andy Whitcroft wrote:
> 
> > @@ -137,5 +144,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
> >  	if (all && refspec)
> >  		usage(push_usage);
> >  
> > +	if (modes_specified > 1) {
> > +		error("--all and --mirror are incompatible");
> > +		usage(push_usage);
> > +	}
> > +
> 
> Why not
> 
> 	if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))?
> 
> It's more explicit.

Yep, that does seem cleaner.

> > @@ -667,6 +673,8 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const
> >  		argv[argc++] = "--all";
> >  	if (flags & TRANSPORT_PUSH_FORCE)
> >  		argv[argc++] = "--force";
> > +	if (flags & TRANSPORT_PUSH_MIRROR)
> > +		argv[argc++] = "--mirror";
> >  	if (data->receivepack) {
> >  		char *rp = xmalloc(strlen(data->receivepack) + 16);
> >  		sprintf(rp, "--receive-pack=%s", data->receivepack);
> 
> Shouldn't you then increment the "11" a few lines before that, to ensure 
> enough space for the new argument?

I should have mentioned I'd not even reviewed it as the basic underlying
functionality seemed to be broken.  I'll look over it if I get a chance
to try and debug the underlying failure.

-apw

^ permalink raw reply

* [PATCH] gitk: Do not pick up file names of "copy from" lines
From: Johannes Sixt @ 2007-10-02 14:21 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Junio C Hamano, Git Mailing List

A file copy would be detected only if the original file was modified in the
same commit. This implies that there will be a patch listed under the
original file name, and we would expect that clicking the original file
name in the file list warps the patch window to that file's patch. (If the
original file was not modified, the copy would not be detected in the first
place, the copied file would be listed as "new file", and this whole matter
would not apply.)

However, if the name of the copy is sorted after the original file's patch,
then the logic introduced by commit d1cb298b0b (which picks up the link
information from the "copy from" line) would overwrite the link
information that is already present for the original file name, which was
parsed earlier. Hence, this patch reverts part of said commit.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
  gitk |    3 +--
  1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/gitk b/gitk
index b3ca704..1306382 100755
--- a/gitk
+++ b/gitk
@@ -5216,8 +5216,7 @@ proc getblobdiffline {bdf ids} {
  	    set diffinhdr 0

  	} elseif {$diffinhdr} {
-	    if {![string compare -length 12 "rename from " $line] ||
-		![string compare -length 10 "copy from " $line]} {
+	    if {![string compare -length 12 "rename from " $line]} {
  		set fname [string range $line [expr 6 + [string first " from " $line] ] end]
  		if {[string index $fname 0] eq "\""} {
  		    set fname [lindex $fname 0]
-- 
1.5.3.716.gb8ce0-dirty

^ permalink raw reply related

* Re: Problems setting up bare repository (git 1.5.3.3)
From: Barry Fishman @ 2007-10-02 13:54 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0710021045430.28395@racer.site>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Well, if the OP had used "git push <bla> master" instead of 
> "... master:master", it would have worked.  I am unaware of any tutorial 
> that suggests the latter, only of tutorials that suggest the former.

I did recheck the tutorials, and did not find the code I was
using.  So there was nothing incorrect in the documentation.

As for "master working where "master:master" didn't, this only exposes a
more complex set of rules.  I was not hoping for a more complex set of
rules to learn, as GIT tried to figure out what I meant.  I was hoping
for a simpler command that did what I told it to do, and I was given it
by Junio Hamano.

What distracted me was that after the "git --bare init", there seemed to
be a incompletely defined setup.  This sent me down the wrong path.

Although there was a master branch to which HEAD pointed, there was no
ref/heads/master file or even a "packed-refs".  This also confuses the
the "git branch" command, so that when I initial tried "git --bare
branch" it seemed unaware of any master branch.  I then tried:

$ git --bare branch refs/heads/master
fatal: Not a valid object name: 'master'.

If there isn't an initial master branch, then shouldn't "git branch" be
able to create one.  And if there is one, shouldn't the automatic rules
explained in git-rev-parse man page find it?  The error messages from
the branch command is what got me on the wrong logical path.

The man page for git-init says:

  This command creates an empty git repository - basically a .git directory
  with subdirectories for objects, refs/heads, refs/tags, and template
  files. An initial HEAD file that references the HEAD of the master branch
  is also created.

Which is true, but although there is a HEAD that references the
master branch, there isn't really any master branch.  It might
say something like:

  This command creates an empty git repository - basically a .git directory
  with subdirectories for objects, refs/heads, refs/tags, and template
  files. An initial HEAD file references the refs/heads/master branch
  which is created with the first commit.

This would at least somewhat explain "git branch" results.

The man page for git-push seems clear to me now.  I should have
more closely read the last example.  The first example might
be changed to say:

git push origin master
    Find a ref that matches master in the source repository (most
    likely, it would find refs/heads/master), and update (or create) the
    same ref, refs/heads/master, in the origin repository with it.

-- 
Barry Fishman

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Johannes Schindelin @ 2007-10-02 12:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3awunjup.fsf@gitster.siamese.dyndns.org>

Hi,

On Mon, 1 Oct 2007, Junio C Hamano wrote:

> I am not sure the quality of "rsync" transport near the tip, either, but 
> at least the change should not affect other transports.  Nobody should 
> using about rsync transport these days anyway.  Perhaps we should put a 
> deprecation notice in the release notes to 1.5.4, and remove it three 
> months later.

Why not keep it?  It's not like it hurts somebody, and in some 
circumstances (lacking git on the remote side, where it was served via 
http) I found it really convenient.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] git-push: plumb in --mirror mode
From: Johannes Schindelin @ 2007-10-02 12:50 UTC (permalink / raw)
  To: Andy Whitcroft; +Cc: Junio C Hamano, git
In-Reply-To: <20071002120051.GC30636@shadowen.org>

Hi,

On Tue, 2 Oct 2007, Andy Whitcroft wrote:

> @@ -137,5 +144,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
>  	if (all && refspec)
>  		usage(push_usage);
>  
> +	if (modes_specified > 1) {
> +		error("--all and --mirror are incompatible");
> +		usage(push_usage);
> +	}
> +

Why not

	if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))?

It's more explicit.


> @@ -667,6 +673,8 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const
>  		argv[argc++] = "--all";
>  	if (flags & TRANSPORT_PUSH_FORCE)
>  		argv[argc++] = "--force";
> +	if (flags & TRANSPORT_PUSH_MIRROR)
> +		argv[argc++] = "--mirror";
>  	if (data->receivepack) {
>  		char *rp = xmalloc(strlen(data->receivepack) + 16);
>  		sprintf(rp, "--receive-pack=%s", data->receivepack);

Shouldn't you then increment the "11" a few lines before that, to ensure 
enough space for the new argument?

Ciao,
Dscho

^ permalink raw reply

* Re: git: avoiding merges, rebasing
From: Eric Blake @ 2007-10-02 12:16 UTC (permalink / raw)
  To: Bruno Haible; +Cc: bug-gnulib, git
In-Reply-To: <200710021350.54625.bruno@clisp.org>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

[adding the git list]

According to Bruno Haible on 10/2/2007 5:50 AM:
> Hello Benoit,
> 
>>>     $ git stash
>>>     $ git pull
>>>     $ git stash apply
>>>     $ git stash clean              ; typo!
>>>     $ git stash clear              ; fatal correction to typo!
>>>
>>> and lost 20 modified files. Well, not really lost. Just took me a  
>>> while to
>> I don't really see how and why you "lost 20 modified files".
> 
> I lost modifications to 20 files. "git stash clean" moved these modifications
> into a stash named "clean", and "git stash clear" killed it.

While we're at it, I wish 'git stash clear' would take an optional
argument that says which stash(es) to clear, rather than blindly clearing
the entire stash.

Short of that, there's always manually editing .git/logs/refs/stash, to
delete the lines to the stashes you no longer need, without killing the
ones you want kept.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHAjaY84KuGfSFAYARAjqCAJ9qRzVxWpujzTGU9zdDi1UkQiSLggCeMien
LJhXdjlNHQYv0BUMCyZQo20=
=xPKQ
-----END PGP SIGNATURE-----

^ permalink raw reply

* trailing whitespace problem
From: lode leroy @ 2007-10-02 12:07 UTC (permalink / raw)
  To: git

when I use git commit -a, I get the following message:

*
* You have some suspicious patch lines:
*
* In src/test.c
* trailing whitespace (line 60)
src/test.c:60: }

when I fix the whitespace problem,  and do "git commit -a" again,
I still get the same message.

Only after adding the file again, with "git add src/test.c",
I can commit my changes.

git version 1.5.3.2 (on cygwin)

ps: not related to CR/LF...

^ permalink raw reply

* [PATCH] git-push: plumb in --mirror mode
From: Andy Whitcroft @ 2007-10-02 12:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vhclalzlq.fsf@gitster.siamese.dyndns.org>

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

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
---
 builtin-push.c |   14 +++++++++++++-
 transport.c    |    8 ++++++++
 transport.h    |    1 +
 3 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/builtin-push.c b/builtin-push.c
index 4ee36c2..e421e96 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -8,7 +8,7 @@
 #include "remote.h"
 #include "transport.h"
 
-static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
+static const char push_usage[] = "git-push [--all | --mirror] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
 
 static int all, thin, verbose;
 static const char *receivepack;
@@ -85,6 +85,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 {
 	int i;
 	int flags = 0;
+	int modes_specified = 0;
 	const char *repo = NULL;	/* default repository */
 
 	for (i = 1; i < argc; i++) {
@@ -105,6 +106,12 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		}
 		if (!strcmp(arg, "--all")) {
 			flags |= TRANSPORT_PUSH_ALL;
+			modes_specified++;
+			continue;
+		}
+		if (!strcmp(arg, "--mirror")) {
+			flags |= TRANSPORT_PUSH_MIRROR;
+			modes_specified++;
 			continue;
 		}
 		if (!strcmp(arg, "--tags")) {
@@ -137,5 +144,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	if (all && refspec)
 		usage(push_usage);
 
+	if (modes_specified > 1) {
+		error("--all and --mirror are incompatible");
+		usage(push_usage);
+	}
+
 	return do_push(repo, flags);
 }
diff --git a/transport.c b/transport.c
index 7266fd3..e45f3c0 100644
--- a/transport.c
+++ b/transport.c
@@ -281,6 +281,9 @@ static int rsync_transport_push(struct transport *transport,
 	struct child_process rsync;
 	const char *args[8];
 
+	if (flags & TRANSPORT_PUSH_MIRROR)
+		return error("rsync transport does not support mirror mode");
+
 	/* first push the objects */
 
 	strbuf_addstr(&buf, transport->url);
@@ -373,6 +376,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;
@@ -667,6 +673,8 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const
 		argv[argc++] = "--all";
 	if (flags & TRANSPORT_PUSH_FORCE)
 		argv[argc++] = "--force";
+	if (flags & TRANSPORT_PUSH_MIRROR)
+		argv[argc++] = "--mirror";
 	if (data->receivepack) {
 		char *rp = xmalloc(strlen(data->receivepack) + 16);
 		sprintf(rp, "--receive-pack=%s", data->receivepack);
diff --git a/transport.h b/transport.h
index 6e318e4..8383774 100644
--- a/transport.h
+++ b/transport.h
@@ -29,6 +29,7 @@ struct transport {
 
 #define TRANSPORT_PUSH_ALL 1
 #define TRANSPORT_PUSH_FORCE 2
+#define TRANSPORT_PUSH_MIRROR 4
 
 /* Returns a transport suitable for the url */
 struct transport *transport_get(struct remote *, const char *);

^ permalink raw reply related

* Re: mirror pushing
From: Andy Whitcroft @ 2007-10-02 11:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vhclalzlq.fsf@gitster.siamese.dyndns.org>

On Tue, Oct 02, 2007 at 12:55:45AM -0700, Junio C Hamano wrote:
> 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.
> 
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> 
>  * This even applies to "maint", but it probably should be done
>    on top of Daniel's remote.c changes.  Teaching this to "git
>    push" wrapper is left as an exercise to the reader.
> 
>  remote.c    |   15 ++++++++++-----
>  send-pack.c |   35 ++++++++++++++++++++++++-----------
>  2 files changed, 34 insertions(+), 16 deletions(-)
> 
> diff --git a/remote.c b/remote.c
> index bb774d0..a3aa5ad 100644
> --- a/remote.c
> +++ b/remote.c
> @@ -574,10 +574,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, char **refspec, int all)
> +	       int nr_refspec, char **refspec, int flags)
>  {
>  	struct refspec *rs =
>  		parse_ref_spec(nr_refspec, (const char **) refspec);
> +	int send_all = flags & 01;
> +	int send_mirror = flags & 02;
>  
>  	if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec))
>  		return -1;
> @@ -594,7 +596,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
> @@ -615,10 +617,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/send-pack.c b/send-pack.c
> index 9fc8a81..39b4b17 100644
> --- a/send-pack.c
> +++ b/send-pack.c
> @@ -7,11 +7,12 @@
>  #include "remote.h"
>  
>  static const char send_pack_usage[] =
> -"git-send-pack [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
> +"git-send-pack [--all | --mirror] [--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 send_mirror;
>  static int force_update;
>  static int use_thin_pack;
>  
> @@ -200,7 +201,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
>  	if (!remote_tail)
>  		remote_tail = &remote_refs;
>  	if (match_refs(local_refs, remote_refs, &remote_tail,
> -		       nr_refspec, refspec, send_all))
> +		       nr_refspec, refspec, (send_all | (send_mirror << 1))))
>  		return -1;
>  
>  	if (!remote_refs) {
> @@ -215,19 +216,24 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
>  	for (ref = remote_refs; ref; ref = ref->next) {
>  		char old_hex[60], *new_hex;
>  		int will_delete_ref;
> +		const unsigned char *new_sha1;
>  
> -		if (!ref->peer_ref)
> -			continue;
> -
> +		if (!ref->peer_ref) {
> +			if (!send_mirror)
> +				continue;
> +			new_sha1 = null_sha1;
> +		}
> +		else
> +			new_sha1 = ref->peer_ref->new_sha1;
>  
> -		will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
> +		will_delete_ref = is_null_sha1(new_sha1);
>  		if (will_delete_ref && !allow_deleting_refs) {
>  			error("remote does not support deleting refs");
>  			ret = -2;
>  			continue;
>  		}
>  		if (!will_delete_ref &&
> -		    !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
> +		    !hashcmp(ref->old_sha1, new_sha1)) {
>  			if (verbose)
>  				fprintf(stderr, "'%s': up-to-date\n", ref->name);
>  			continue;
> @@ -257,8 +263,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
>  		    !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
> @@ -276,7 +281,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
>  				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));
> @@ -396,6 +401,10 @@ int main(int argc, char **argv)
>  				send_all = 1;
>  				continue;
>  			}
> +			if (!strcmp(arg, "--mirror")) {
> +				send_mirror = 1;
> +				continue;
> +			}
>  			if (!strcmp(arg, "--force")) {
>  				force_update = 1;
>  				continue;
> @@ -420,7 +429,11 @@ int main(int argc, char **argv)
>  	}
>  	if (!dest)
>  		usage(send_pack_usage);
> -	if (heads && send_all)
> +	/*
> +	 * --all and --mirror are incompatible; neither makes sense
> +	 * with any refspecs.
> +	 */
> +	if ((heads && (send_all || send_mirror)) || (send_all && send_mirror))
>  		usage(send_pack_usage);
>  	verify_remote_names(nr_heads, heads);

Ok, I put together a patch to tie this in (will post that following this
email).  However this mirror mode seems to do something odd.  With
matching repo's it reports all the tags as missing on the remote end,
and attempts to resend them:

$ git push --mirror ssh://.../~apw/git/git 
updating 'junio-gpg-pub'
  from 0000000000000000000000000000000000000000
  to   a0e7d36193b96f552073558acf5fcc1f10528917
updating 'v0.99'
  from 0000000000000000000000000000000000000000
  to   d6602ec5194c87b0fc87103ca4d67251c76f233a
[...]
Generating pack...
Done counting 0 objects.
Writing 0 objects...
Total 0 (delta 0), reused 0 (delta 0)
error: Ref junio-gpg-pub is at a0e7d36193b96f552073558acf5fcc1f10528917 but expected 0000000000000000000000000000000000000000
error: failed to lock junio-gpg-pub
error: Ref v0.99 is at d6602ec5194c87b0fc87103ca4d67251c76f233a but expected 0000000000000000000000000000000000000000
error: failed to lock v0.99
[...]

It appears that they are ending up in the wrong place:

apw@kernel:~/git/git$ ls .git
branches       v0.99.5   v0.99.9a  v1.0.0b  v1.0rc5  v1.3.0      v1.4.2.1
config         v0.99.6   v0.99.9b  v1.0.10  v1.0rc6  v1.3.0-rc1  v1.4.2.2
description    v0.99.7   v0.99.9c  v1.0.11  v1.1.0   v1.3.0-rc2  v1.4.2.3
HEAD           v0.99.7a  v0.99.9d  v1.0.12  v1.1.1   v1.3.0-rc3  v1.4.2.4
hooks          v0.99.7b  v0.99.9e  v1.0.13  v1.1.2   v1.3.0-rc4  v1.4.2-rc1
index          v0.99.7c  v0.99.9f  v1.0.3   v1.1.3   v1.3.1      v1.4.2-rc2
info           v0.99.7d  v0.99.9g  v1.0.4   v1.1.4   v1.3.2      v1.4.2-rc3
junio-gpg-pub  v0.99.8   v0.99.9h  v1.0.5   v1.1.5   v1.3.3      v1.4.2-rc4
logs           v0.99.8a  v0.99.9i  v1.0.6   v1.1.6   v1.4.0      v1.4.3
objects        v0.99.8b  v0.99.9j  v1.0.7   v1.2.0   v1.4.0-rc1  v1.4.3.1
refs           v0.99.8c  v0.99.9k  v1.0.8   v1.2.1   v1.4.0-rc2  v1.4.3.2
v0.99          v0.99.8d  v0.99.9l  v1.0.9   v1.2.2   v1.4.1      v1.4.3-rc1
v0.99.1        v0.99.8e  v0.99.9m  v1.0rc1  v1.2.3   v1.4.1.1    v1.4.3-rc2
v0.99.2        v0.99.8f  v0.99.9n  v1.0rc2  v1.2.4   v1.4.1-rc1  v1.4.3-rc3
v0.99.3        v0.99.8g  v1.0.0    v1.0rc3  v1.2.5   v1.4.1-rc2
v0.99.4        v0.99.9   v1.0.0a   v1.0rc4  v1.2.6   v1.4.2

-apw

^ permalink raw reply

* Re: git-http-push / webDAV
From: Thomas Pasch @ 2007-10-02 11:15 UTC (permalink / raw)
  To: Eygene Ryabinkin; +Cc: git
In-Reply-To: <20071002104646.GY975@void.codelabs.ru>

Dear Eygene,

I used a rather small test repo with only 2 or 3
commits.

The last tests I did with the a (current) git repo clone:

> git clone --bare git://git.kernel.org/pub/scm/git/git.git

e147e54b14828fa2e88e88907e0ca4dc3d694448 has indeed *not*
found its way into the http push repo. For me it looks
like that the push *first* updates refs/heads/master
(successfully) but fails to transfer the object itself.

Perhaps it would be more graceful that the object is
transfered *first* and then the remote tip is updated...

What version of git do you use?

Cheers,

Thomas

Eygene Ryabinkin wrote:
> Thomas,
> 
> Tue, Oct 02, 2007 at 11:57:10AM +0200, Thomas Pasch wrote:
>> well, *somewhat* better with the trailing slash:
>>
>>> echo "modified" >>grep.c
>>> git commit -a
>> Created commit e147e54: mod
>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>> git push -v
>> Pushing to http://test@x.x.x.x/git/git.git/
>> Fetching remote heads...
>>   refs/
>>   refs/heads/
>>   refs/tags/
>> updating 'refs/heads/master'
>>   from 34c6dbdef439f7cd93d3fe22493a3c1496ce96f7
>>   to   e147e54b14828fa2e88e88907e0ca4dc3d694448
>>     sending 3 objects
>>     done
>> Updating remote server info
>>
>> There's no more error message.
> 
> OK, that's fine: the previous error was tied to the fact that
> when you're getting /git/git.git from the Web-server, it notices
> that it is a directory and redirects you to the /git/git.git/.
> But (IIRC) curl does not follow such redirections.
> 
>> However, push has still
>> not worked. If I try to check out the new HEAD:
>>
>>> git clone http://test@x.x.x.x/git/git.git/
>> Initialized empty Git repository in /home/tpasch/tmp/git/.git/
>> Getting alternates list for http://test@x.x.x.x/git/git.git
>> Getting pack list for http://test@x.x.x.x/git/git.git
>> Getting index for pack 563e2090185692c7d765775569a0ce986840fd17
>> Getting pack 563e2090185692c7d765775569a0ce986840fd17
>>  which contains 3af9d3e08da868c3a7687ab38d72f4296a99005d
>> [...]
>> walk 24778e335a6450e34257a311d0bf4a12bdb3006c
>> walk 19b2860cba5742ab31fd682b80fefefac19be141
>> walk bf0c6e839c692142784caf07b523cd69442e57a5
>> walk e497ea2a9b6c378f01d092c210af20cbee762475
>> walk 8bc9a0c769ac1df7820f2dbf8f7b7d64835e3c68
>> walk e83c5163316f89bfbde7d9ab23ca2e25604af290
>> Getting alternates list for http://test@x.x.x.x/git/git.git
>> Getting pack list for http://test@x.x.x.x/git/git.git
>> error: Unable to find e147e54b14828fa2e88e88907e0ca4dc3d694448 under
>> http://test@x.x.x.x/git/git.git
>> Cannot obtain needed object e147e54b14828fa2e88e88907e0ca4dc3d694448
> 
> OK, I will try to do this on my server with 2.2.6.  How big
> is your repository?  Both size and commit number.
> 
> Thanks.

^ permalink raw reply

* [PATCH] Add a test script for for-each-ref, including test of date formatting Signed-off-by: Andy Parkins <andyparkins@gmail.com>
From: Andy Parkins @ 2007-10-02 11:02 UTC (permalink / raw)
  To: git

---
 t/t6300-for-each-ref.sh |  164 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 164 insertions(+), 0 deletions(-)
 create mode 100644 t/t6300-for-each-ref.sh

diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
new file mode 100644
index 0000000..b07f157
--- /dev/null
+++ b/t/t6300-for-each-ref.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Andy Parkins
+#
+
+test_description='for-each-ref test'
+
+. ./test-lib.sh
+
+# Mon Jul 3 15:18:43 2006 +0000
+datestamp=1151939923
+setdate_and_increment () {
+    GIT_COMMITTER_DATE="$datestamp +0200"
+    datestamp=$(expr "$datestamp" + 1)
+    GIT_AUTHOR_DATE="$datestamp +0200"
+    datestamp=$(expr "$datestamp" + 1)
+    export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
+}
+
+test_expect_success 'Create sample commit with known timestamp' '
+	setdate_and_increment &&
+	echo "Using $datestamp" > one &&
+	git add one &&
+	git commit -m "Initial" &&
+	setdate_and_increment &&
+	git tag -a -m "Tagging at $datestamp" testtag
+'
+
+test_expect_success 'Check atom names are valid' '
+	git for-each-ref --format="refname=%(refname)" refs/heads &&
+	git for-each-ref --format="objecttype=%(objecttype)" refs/heads &&
+	git for-each-ref --format="objectsize=%(objectsize)" refs/heads &&
+	git for-each-ref --format="objectname=%(objectname)" refs/heads &&
+	git for-each-ref --format="tree=%(tree)" refs/heads &&
+	git for-each-ref --format="parent=%(parent)" refs/heads &&
+	git for-each-ref --format="numparent=%(numparent)" refs/heads &&
+	git for-each-ref --format="object=%(object)" refs/heads &&
+	git for-each-ref --format="type=%(type)" refs/heads &&
+	git for-each-ref --format="author=%(author)" refs/heads &&
+	git for-each-ref --format="authorname=%(authorname)" refs/heads &&
+	git for-each-ref --format="authoremail=%(authoremail)" refs/heads &&
+	git for-each-ref --format="authordate=%(authordate)" refs/heads &&
+	git for-each-ref --format="committer=%(committer)" refs/heads &&
+	git for-each-ref --format="committername=%(committername)" refs/heads &&
+	git for-each-ref --format="committeremail=%(committeremail)" refs/heads &&
+	git for-each-ref --format="committerdate=%(committerdate)" refs/heads &&
+	git for-each-ref --format="tag=%(tag)" refs/tags &&
+	git for-each-ref --format="tagger=%(tagger)" refs/tags &&
+	git for-each-ref --format="taggername=%(taggername)" refs/tags &&
+	git for-each-ref --format="taggeremail=%(taggeremail)" refs/tags &&
+	git for-each-ref --format="taggerdate=%(taggerdate)" refs/tags &&
+	git for-each-ref --format="creator=%(creator)" refs/tags &&
+	git for-each-ref --format="creatordate=%(creatordate)" refs/tags &&
+	git for-each-ref --format="subject=%(subject)" refs/heads &&
+	git for-each-ref --format="body=%(body)" refs/heads &&
+	git for-each-ref --format="contents=%(contents)" refs/heads
+'
+
+test_expect_failure 'Check invalid atoms names are errors' '
+	git-for-each-ref --format="%(INVALID)" refs/heads
+'
+
+test_expect_success 'Check format specifiers are ignored in naming date atoms' '
+	git-for-each-ref --format="%(authordate)" refs/heads &&
+	git-for-each-ref --format="%(authordate:default) %(authordate)" refs/heads &&
+	git-for-each-ref --format="%(authordate) %(authordate:default)" refs/heads &&
+	git-for-each-ref --format="%(authordate:default) %(authordate:default)" refs/heads
+'
+
+test_expect_success 'Check valid format specifiers for date fields' '
+	git-for-each-ref --format="%(authordate:default)" refs/heads &&
+	git-for-each-ref --format="%(authordate:relative)" refs/heads &&
+	git-for-each-ref --format="%(authordate:short)" refs/heads &&
+	git-for-each-ref --format="%(authordate:local)" refs/heads &&
+	git-for-each-ref --format="%(authordate:iso8601)" refs/heads &&
+	git-for-each-ref --format="%(authordate:rfc2822)" refs/heads
+'
+
+test_expect_failure 'Check invalid format specifiers are errors' '
+	git-for-each-ref --format="%(authordate:INVALID)" refs/heads
+'
+
+cat >expected <<\EOF
+'refs/heads/master' 'Mon Jul 3 17:18:43 2006 +0200' 'Mon Jul 3 17:18:44 2006 +0200'
+'refs/tags/testtag' 'Mon Jul 3 17:18:45 2006 +0200'
+EOF
+
+test_expect_success 'Check unformatted date fields output' '
+	(git for-each-ref --shell --format="%(refname) %(committerdate) %(authordate)" refs/heads &&
+	git for-each-ref --shell --format="%(refname) %(taggerdate)" refs/tags) >actual &&
+	git diff expected actual
+'
+
+test_expect_success 'Check format "default" formatted date fields output' '
+	f=default &&
+	(git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
+	git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
+	git diff expected actual
+'
+
+# Don't know how to do relative check because I can't know when this script
+# is going to be run and can't fake the current time to git, and hence can't
+# provide expected output.  Instead, I'll just make sure that "relative"
+# doesn't exit in error
+#
+#cat >expected <<\EOF
+#
+#EOF
+#
+test_expect_success 'Check format "relative" date fields output' '
+	f=relative &&
+	(git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
+	git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual
+'
+
+cat >expected <<\EOF
+'refs/heads/master' '2006-07-03' '2006-07-03'
+'refs/tags/testtag' '2006-07-03'
+EOF
+
+test_expect_success 'Check format "short" date fields output' '
+	f=short &&
+	(git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
+	git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
+	git diff expected actual
+'
+
+cat >expected <<\EOF
+'refs/heads/master' 'Mon Jul 3 15:18:43 2006' 'Mon Jul 3 15:18:44 2006'
+'refs/tags/testtag' 'Mon Jul 3 15:18:45 2006'
+EOF
+
+test_expect_success 'Check format "local" date fields output' '
+	f=local &&
+	(git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
+	git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
+	git diff expected actual
+'
+
+cat >expected <<\EOF
+'refs/heads/master' '2006-07-03 17:18:43 +0200' '2006-07-03 17:18:44 +0200'
+'refs/tags/testtag' '2006-07-03 17:18:45 +0200'
+EOF
+
+test_expect_success 'Check format "iso8601" date fields output' '
+	f=iso8601 &&
+	(git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
+	git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
+	git diff expected actual
+'
+
+cat >expected <<\EOF
+'refs/heads/master' 'Mon, 3 Jul 2006 17:18:43 +0200' 'Mon, 3 Jul 2006 17:18:44 +0200'
+'refs/tags/testtag' 'Mon, 3 Jul 2006 17:18:45 +0200'
+EOF
+
+test_expect_success 'Check format "rfc2822" date fields output' '
+	f=rfc2822 &&
+	(git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
+	git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
+	git diff expected actual
+'
+
+test_done
-- 
1.5.3.2.105.gf47f2-dirty

^ permalink raw reply related

* [PATCH] for-each-ref's new per-atom formatting was failing if there were multiple fields per line
From: Andy Parkins @ 2007-10-02 11:02 UTC (permalink / raw)
  To: git

builtin-for-each-ref.c was searching backwards for ":" in the atom searches
performed by parse_atom.  In implementing the format handler I had
assumed that parse_atom was being handed a single atom pointer.  That
was not the case.  In fact the "atom" pointer is just a pointer within
the longer format string, that means that the NUL for the end of the
string is not at the end of the current atom, but at the end of the
format string.

Finding the ":" separating the atom name from the format was done with
strrchr(), which searches from the end of the string.  That would be
fine if it was searching a single atom string, but in the case of:

 --format="%(atom:format) %(atom:format)"

When the first atom is being parsed a backwards search actually finds
the second colon, making the atom name look like:

 "atom:format) %(atom"

Which obviously doesn't match any valid atom name and so exits with
"unknown field name".

The fix is to abandon the reverse search (which was only to allow colons
in atom names, which was redundant as there are no atom names with
colons) and replace it with a forward search.  The potential presence of
a second ":" also requires a check to confirm that the found ":" is
between the start and end pointers, which this patch also adds.

Signed-off-by: Andy Parkins <andyparkins@gmail.com>
---
 builtin-for-each-ref.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index 2ca4fc6..f06d006 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -109,8 +109,8 @@ static int parse_atom(const char *atom, const char *ep)
 		/* If the atom name has a colon, strip it and everything after
 		 * it off - it specifies the format for this entry, and
 		 * shouldn't be used for checking against the valid_atom table */
-		const char *formatp = strrchr(sp, ':' );
-		if (formatp == NULL )
+		const char *formatp = strchr(sp, ':' );
+		if (formatp == NULL || formatp > ep )
 			formatp = ep;
 		if (len == formatp - sp && !memcmp(valid_atom[i].name, sp, len))
 			break;
@@ -366,7 +366,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
 	 * it's not possible that <something> is not ":<format>" because
 	 * parse_atom() wouldn't have allowed it, so we can assume that no
 	 * ":" means no format is specified, use the default */
-	formatp = strrchr( atomname, ':' );
+	formatp = strchr( atomname, ':' );
 	if (formatp != NULL) {
 		formatp++;
 		date_mode = parse_date_format(formatp);
-- 
1.5.3.2.105.gf47f2-dirty

^ permalink raw reply related

* Re: git-http-push / webDAV
From: Eygene Ryabinkin @ 2007-10-02 10:46 UTC (permalink / raw)
  To: Thomas Pasch; +Cc: git
In-Reply-To: <470215F6.2060105@jentro.com>

Thomas,

Tue, Oct 02, 2007 at 11:57:10AM +0200, Thomas Pasch wrote:
> well, *somewhat* better with the trailing slash:
> 
> > echo "modified" >>grep.c
> > git commit -a
> Created commit e147e54: mod
>  1 files changed, 1 insertions(+), 0 deletions(-)
> > git push -v
> Pushing to http://test@192.1.1.184/git/git.git/
> Fetching remote heads...
>   refs/
>   refs/heads/
>   refs/tags/
> updating 'refs/heads/master'
>   from 34c6dbdef439f7cd93d3fe22493a3c1496ce96f7
>   to   e147e54b14828fa2e88e88907e0ca4dc3d694448
>     sending 3 objects
>     done
> Updating remote server info
> 
> There's no more error message.

OK, that's fine: the previous error was tied to the fact that
when you're getting /git/git.git from the Web-server, it notices
that it is a directory and redirects you to the /git/git.git/.
But (IIRC) curl does not follow such redirections.

> However, push has still
> not worked. If I try to check out the new HEAD:
> 
> > git clone http://test@192.1.1.184/git/git.git/
> Initialized empty Git repository in /home/tpasch/tmp/git/.git/
> Getting alternates list for http://test@192.1.1.184/git/git.git
> Getting pack list for http://test@192.1.1.184/git/git.git
> Getting index for pack 563e2090185692c7d765775569a0ce986840fd17
> Getting pack 563e2090185692c7d765775569a0ce986840fd17
>  which contains 3af9d3e08da868c3a7687ab38d72f4296a99005d
> [...]
> walk 24778e335a6450e34257a311d0bf4a12bdb3006c
> walk 19b2860cba5742ab31fd682b80fefefac19be141
> walk bf0c6e839c692142784caf07b523cd69442e57a5
> walk e497ea2a9b6c378f01d092c210af20cbee762475
> walk 8bc9a0c769ac1df7820f2dbf8f7b7d64835e3c68
> walk e83c5163316f89bfbde7d9ab23ca2e25604af290
> Getting alternates list for http://test@192.1.1.184/git/git.git
> Getting pack list for http://test@192.1.1.184/git/git.git
> error: Unable to find e147e54b14828fa2e88e88907e0ca4dc3d694448 under
> http://test@192.1.1.184/git/git.git
> Cannot obtain needed object e147e54b14828fa2e88e88907e0ca4dc3d694448

OK, I will try to do this on my server with 2.2.6.  How big
is your repository?  Both size and commit number.

Thanks.
-- 
Eygene

^ permalink raw reply

* Re: [PATCH] Adding rebase merge strategy
From: Tom Clarke @ 2007-10-02 10:29 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Shawn O. Pearce, Carl Worth, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0710021056280.28395@racer.site>

On 10/2/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> It's all about convenience: in many repos, I just to "git pull", because
> there is really only one upstream.
>
> But in one repo, the upstream is svn, and I mistakenly checked in a merge.
> Not wanting to know svn deeply, I have no nice way (as I would have with
> git) to cover up my mistake.  So in this repo, I would have liked to set
> branch.master.mergeOptions to '-s rebase'.

That's a good point, in addition to being able to do a git pull that
uses rebase, it would be useful make this configurable so you can
always safely do 'git pull'.

So it's perhaps the question is whether rebasing should be treated as
a kind of merging, or as an alternative to merging when pulling.
Incidentally, are there any other cases other than pulling where using
rebase as an alternative merge strategy is useful?

-Tom

^ permalink raw reply

* Re: [PATCH] Adding rebase merge strategy
From: Johannes Schindelin @ 2007-10-02 10:00 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Tom Clarke, Carl Worth, Junio C Hamano, git
In-Reply-To: <20071001223050.GE2137@spearce.org>

Hi,

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

> But I have to agree with (was it Junio who said this?) doing a rebase
> in a merge strategy doesn't make sense when conflicts come into play.

In contrast, I think that it makes sense, absolutely.  If you asked for 
"rebase", you _have_ to know what is coming.

It's all about convenience: in many repos, I just to "git pull", because 
there is really only one upstream.

But in one repo, the upstream is svn, and I mistakenly checked in a merge.  
Not wanting to know svn deeply, I have no nice way (as I would have with 
git) to cover up my mistake.  So in this repo, I would have liked to set 
branch.master.mergeOptions to '-s rebase'.

Ciao,
Dscho

^ 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