Git development
 help / color / mirror / Atom feed
* Re: [PATCH] Support ent:relative_path
From: Alex Riesen @ 2007-05-04 17:17 UTC (permalink / raw)
  To: Dana How; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <56b7f5510705040957v4580b6c1xbe767892ada3bcde@mail.gmail.com>

On 5/4/07, Dana How <danahow@gmail.com> wrote:
> > > This all depends on deciding that :relpath should be the (incompatible)
> > > new default, and I'm not sure that's going to happen.
> >
> > If we are to stay that compatible, maybe ":./" for relative paths and the
> > old syntax left to mean top-level would the best choice for now.
>
> Let's summarize so far:  I think everyone's convinced me we need
> to be careful,  so this email will be more tedious than I'd like.
>
> (a) :./relpath clearly inidicates relative path. [Also take :../relpath .]

Ack

> (b) I'd like a more natural way to do :./relpath (e.g. :relpath),
>      or at least a future path to such.
> (c) We would like to avoid new special characters beyond ":".
>      This means everything has to be done with "." and "/".

And new semantics, if possible

> (d) We are left with the following patterns:
>      1. :string

Probably breaks something

>      2. :/string

Taken

>      3. ://string

Ugly (and breaks tab completion)

> [ We need a clear way to say relative, a clear way to say absolute,
> and the current :string can change from absolute to relative some time
> in the future if we so decide. ]
>
> Ideas for (d) 2&3:
> I. Make :/string actually match the RE ^[/]*string,  and ://string a full path.
>    The leading [/]* is a very small change to get_sha1_oneline().
>    [Or change prefixcmp() to strstr() in get_sha1_oneline().]
>    How often do commit messages start with / ?

How often should they start to justify any decision?

> II. Make :/string a full path, and ://string match ^string .
>    Is changing the current :/string to ://string less painful/dangerous?

Johannes?

> III. Make :/string match ^string when string has no slashes,
>     :/string a full path when string does have slashes,
>     and ://string match ^string . Hmm,  seems confusing.

Very/

> Do you use :/string now?  Since it's a case-sensitive exact match,

No. It just exists, AFAICS

> I don't think I'd even use it.
> I find idea (II) most natural: absolute paths have one /,
> and string matches have 2 suggesting an RE.

I think, I'd be convinced by this one too, if not for "//" making
no sense anywhere but root accidentally typed twice.
I'd even sacrifice (or change) the search syntax for good.

^ permalink raw reply

* Re: repack: handling of .keep files
From: Junio C Hamano @ 2007-05-04 16:59 UTC (permalink / raw)
  To: Alex Riesen; +Cc: Git Mailing List
In-Reply-To: <81b0412b0705040342p4fed3a4bnee92cce6b5fb6b9@mail.gmail.com>

"Alex Riesen" <raa.lkml@gmail.com> writes:

> Still, git-log shouldn't crash (nothing should, of course).

Honestly, I think that's borderline.  If you "dd if=/dev/random
of=/dev/hda", should the kernel keep going, perhaps gracefully
declining access to the filesystem on that drive?

> And, the temporary pack is created in working tree, instead of in GIT_DIR
> (why not GIT_OBJECT_DIR, btw?)

Not limited to the temporary pack (the detail of exact use
pattern escapes me -- I do not think it was temporary pack that
initiated the use of GIT_DIR for temporary things), I think
trying to not create things in the working tree came after
somebody who had a read-only (to him, not necessarily to
everybody) working tree and read-write GIT_DIR (separate
location, specified with the environment variable) had trouble.
At least the theory was GIT_DIR would be writable as long as you
are doing a "write" oriented operation, regardless of what.

Back then we did not support working in subdirectory of the
project as fully as we do now, so using such configuration was
not much less convenient than you have the normal layout of
having $project/.git directory at the top of the working tree.

While I do not think it is worth to try "supporting" use of
read-only working tree for write oriented operations, which
means that it should be safe to assume that the working tree is
writable and we _could_ create temporary pack in working tree
instead, I do not think the "_could_" means we should.  In the
case of temporary pack I do not think there would be a risk of
filename collisions, I think it makes sense to use either
GIT_DIR or GIT_OBJECT_DIRECTORY instead of the working tree.  

I do not know pros-and-cons between .git/ and .git/objects/;
filesystems tend to cluster nearby things better, so the latter
might be more logical, but packs are about using smaller (much
much much smaller) number of files than you would use otherwise
to store objects _and_ keeping them in use, so I suspect it
would not make much practical difference even if we try to
encourage the filesystem to allocate the disk blocks for new
pack near existing packs by creating the temporary file.

^ permalink raw reply

* Re: [PATCH] Support ent:relative_path
From: Dana How @ 2007-05-04 16:57 UTC (permalink / raw)
  To: Alex Riesen; +Cc: Junio C Hamano, Git Mailing List, danahow
In-Reply-To: <81b0412b0705040246r5a2726b8g4323cadeacee3aa7@mail.gmail.com>

On 5/4/07, Alex Riesen <raa.lkml@gmail.com> wrote:
> On 5/4/07, Dana How <danahow@gmail.com> wrote:
> > > I'd suggest to define a special character for _top_ level. Real pity
> > > ":/" is taken.
> > We could use ://fullpath for top level,
>
> No good. How'd you find a commit starting with "/" than? (without
> changing ":/" syntax).
Oh blechh.  get_sha1_oneline uses prefixcmp(), not strstr().
Are there are any commits in git or the kernel starting with "/" ?

> > and :relpath for relative. Then "string" in :/string couldn't start with /,
> > which shouldn't be a problem (right?).  I've certainly seen double
> > slashes before;
> > perforce in fact uses them for the root of the repository (depot).
>
> And I really hate perforce for its stupid redundancy (and changing of
> meaning of well-known idioms: why should // be anything special
> but plain top level or root?! Why the hell do they need them at if
> you cannot use relative paths in client specs at all?! Why can't the
> p4 command-line tool figure the fact from context or request the
> context be provided by user?! IOW, Perforce is a real bad example
> of how you do version control).
Whoa!  I'm stuck using perforce too; I'm not holding it up as a *big*
example.  I originally saw // meaning root in the Apollo DOMAIN
system,  so for that reason it makes sense to me.  I think it also
means network root in Windoze (well, \\ does ;-) )..

> > This all depends on deciding that :relpath should be the (incompatible)
> > new default, and I'm not sure that's going to happen.
>
> If we are to stay that compatible, maybe ":./" for relative paths and the
> old syntax left to mean top-level would the best choice for now.

Let's summarize so far:  I think everyone's convinced me we need
to be careful,  so this email will be more tedious than I'd like.

(a) :./relpath clearly inidicates relative path. [Also take :../relpath .]
(b) I'd like a more natural way to do :./relpath (e.g. :relpath),
     or at least a future path to such.
(c) We would like to avoid new special characters beyond ":".
     This means everything has to be done with "." and "/".
(d) We are left with the following patterns:
     1. :string
     2. :/string
     3. ://string

[ We need a clear way to say relative, a clear way to say absolute,
and the current :string can change from absolute to relative some time
in the future if we so decide. ]

Ideas for (d) 2&3:
I. Make :/string actually match the RE ^[/]*string,  and ://string a full path.
   The leading [/]* is a very small change to get_sha1_oneline().
   [Or change prefixcmp() to strstr() in get_sha1_oneline().]
   How often do commit messages start with / ?
II. Make :/string a full path, and ://string match ^string .
   Is changing the current :/string to ://string less painful/dangerous?
III. Make :/string match ^string when string has no slashes,
    :/string a full path when string does have slashes,
    and ://string match ^string . Hmm,  seems confusing.
Do you use :/string now?  Since it's a case-sensitive exact match,
I don't think I'd even use it.
I find idea (II) most natural: absolute paths have one /,
and string matches have 2 suggesting an RE.

Concerning the current :string , perhaps we could do the following.
There would be 2 internal fixed mode variables (NOT config variables) which
do the following.  The first controls whether this means an absolute
or relative path.  The second controls whether a warning message
is printed whenever the first is consulted to make a decision.  The
interpretation of :string is left as-is, but motivated janitors (like me
in this case) can use the second mode variable to change all
:string patterns to :/string or ://string in scripts,   letting us
switch over later
by changing one mode variable.

Someone mentioned DWIM for :string -- check both absolute and relative,
in that order for compatibility probably.  This seems a messy
definition to me.  Comments?

Anyway,  this is more involved than I'd hoped,
but it's good to think about consequences.

Thanks,
-- 
Dana L. How  danahow@gmail.com  +1 650 804 5991 cell

^ permalink raw reply

* Re: FFmpeg considering GIT
From: Nicolas Pitre @ 2007-05-04 16:40 UTC (permalink / raw)
  To: Michael Niedermayer; +Cc: git
In-Reply-To: <loom.20070504T143538-533@post.gmane.org>

On Fri, 4 May 2007, Michael Niedermayer wrote:

> well, my example above was exagerated, noone ever reindented the whole
> ffmpeg or checked in a old version over HEAD. what did and does occasionally
> happen is that people check in several things at once (like a 100k reindenton
> mixed with various functional changes)
> for these we currently copy the last good version of the affected files
> over the current one with svn cp and then apply the changes in nicely
> split manner. (possibly without the reindention if its uneeded ...)
> Another thing that happens occasionally is that complete nonsense is checked
> in like checking in the wrong file or some "private" debuging code
> 
> we never use the svn cp method to revert normal buggy code ...

A big difference between git and svn is that git allows you to commit 
your changes individually to your local repository before pushing them 
out to the world.  With svn you make your changes visible to the world 
as soon as you commit something, including the commit screwups.

With Git you always have the opportunity to look at your commits and 
test them all together before pushing which should make commit mistakes 
obvious before they leave your machine.  If a mistake happened in one of 
those commits you can ammend them, rebase them, etc. and only push when 
they're satisfactory, something that svn doesn't allow.

So I think that something that you got used to with svn simply has no 
serious need for with git.


Nicolas

^ permalink raw reply

* Re: [RFD/PATCH] Implement pack.compression and pack-objects --compression=N
From: Nicolas Pitre @ 2007-05-04 16:30 UTC (permalink / raw)
  To: Dana How; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <56b7f5510705040910i3cac723co3aed45034c097def@mail.gmail.com>

On Fri, 4 May 2007, Dana How wrote:

> On 5/4/07, Nicolas Pitre <nico@cam.org> wrote:
> > On Thu, 3 May 2007, Junio C Hamano wrote:
> > 
> > > "Dana How" <danahow@gmail.com> writes:
> > >
> > > > So for a 25% increase in blob size I get 33% less elapsed time
> > > > in git-add, all by changing core.compression from -1 to 1.
> > > > I'll definitely take that improvement.  [For the compressible files
> > > > we typically have, using 0 is a bad idea:  the CPU "advantage"
> > > > is swamped out by the time to write a much larger file.]
> > >
> > > The above number is about loose objects, right?
> > >
> > > > Since I don't care [to the same degree] about the responsiveness of
> > > > packing,  I'd rather pack with -1 or better to keep packs small.
> > >
> > > I see.  You are saying that the fact that core.compression is
> > > used also for packing makes the variable less useful.
> > 
> > I think that would make sense to have separate configs for pack and
> > loose object compression.  When not specified they should simply default
> > to core.compression if it exists.  Otherwise I'd suggest that pack
> > compression default level be Z_DEFAULT_COMPRESSION and loose object
> > compression default level be Z_BEST_SPEED.  This would make interactive
> > operations like git-add and git-commit even faster by default.
> 
> I agree with your Z_BEST_SPEED idea.  I did not include it in
> the patch b/c I didn't want to change any behavior in the absence
> of new config settings.
> 
> Are you actually arguing for *3* different compression-related config
> variables?

Yes.

> How about:
> (a) core.compression controls loose objects. defaults to Z_BEST_SPEED.
> (b) pack.compression controls packing. defaults to Z_DEFAULT_COMPRESSION
> if neither variable exists. defaults to core.compression if only that exists

Yes, although I wouldn't default pack.compression to core.compression  
if pack.compression doesn't exist.  The documentation about 
core.compression currently talks 
(wrongly) only about loose objects anyway, so making pack.compression 
stand on its own won't be that bad.


Nicolas

^ permalink raw reply

* Re: [RFD/PATCH] Implement pack.compression and pack-objects --compression=N
From: Dana How @ 2007-05-04 16:10 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, Git Mailing List, danahow
In-Reply-To: <alpine.LFD.0.99.0705040937250.24220@xanadu.home>

On 5/4/07, Nicolas Pitre <nico@cam.org> wrote:
> On Thu, 3 May 2007, Junio C Hamano wrote:
>
> > "Dana How" <danahow@gmail.com> writes:
> >
> > > So for a 25% increase in blob size I get 33% less elapsed time
> > > in git-add, all by changing core.compression from -1 to 1.
> > > I'll definitely take that improvement.  [For the compressible files
> > > we typically have, using 0 is a bad idea:  the CPU "advantage"
> > > is swamped out by the time to write a much larger file.]
> >
> > The above number is about loose objects, right?
> >
> > > Since I don't care [to the same degree] about the responsiveness of
> > > packing,  I'd rather pack with -1 or better to keep packs small.
> >
> > I see.  You are saying that the fact that core.compression is
> > used also for packing makes the variable less useful.
>
> I think that would make sense to have separate configs for pack and
> loose object compression.  When not specified they should simply default
> to core.compression if it exists.  Otherwise I'd suggest that pack
> compression default level be Z_DEFAULT_COMPRESSION and loose object
> compression default level be Z_BEST_SPEED.  This would make interactive
> operations like git-add and git-commit even faster by default.

I agree with your Z_BEST_SPEED idea.  I did not include it in
the patch b/c I didn't want to change any behavior in the absence
of new config settings.

Are you actually arguing for *3* different compression-related config
variables?  How about:
(a) core.compression controls loose objects. defaults to Z_BEST_SPEED.
(b) pack.compression controls packing. defaults to Z_DEFAULT_COMPRESSION
if neither variable exists. defaults to core.compression if only that exists

The last sentence mimics current behavior and to me seems least
surprising.  Or pack.compression could be simpler: default to
Z_DEFAULT_COMPRESSION if pack.compression doesn't exist
(no interaction with core.compression).

Thanks,
-- 
Dana L. How  danahow@gmail.com  +1 650 804 5991 cell

^ permalink raw reply

* Re: FFmpeg considering GIT
From: Johannes Sixt @ 2007-05-04 16:09 UTC (permalink / raw)
  To: git
In-Reply-To: <200705041653.49486.andyparkins@gmail.com>

Andy Parkins wrote:
> On Friday 2007 May 04, Michael Niedermayer wrote:
> > for these we currently copy the last good version of the affected files
> > over the current one with svn cp and then apply the changes in nicely
> > split manner. (possibly without the reindention if its uneeded ...)
> 
> I might be misunderstanding, but doesn't that leave the "bad" commit in the
> history?

In the history? Yes.
In the blame? No.

> 
>  * -- * -- G -- B -- !B -- 1 -- 2 -- 3
> 
> B is the bad commit; !B would be the result of the svn cp from the previous
> known-good revision, "G"; then 1, 2, and 3 would be the correctly split
> version of "B".

With svn cp you actually create this "blame" history:

* -- * -- G -- B
           \
             ----- G* -- 1 -- 2 -- 3

where G* is a new revision, but since it is otherwise identical to G, it
does not introduce new blame-able lines.

-- Hannes

^ permalink raw reply

* Re: FFmpeg considering GIT
From: Andy Parkins @ 2007-05-04 15:53 UTC (permalink / raw)
  To: git; +Cc: Michael Niedermayer
In-Reply-To: <loom.20070504T143538-533@post.gmane.org>

On Friday 2007 May 04, Michael Niedermayer wrote:

> well, my example above was exagerated, noone ever reindented the whole
> ffmpeg or checked in a old version over HEAD. what did and does
> occasionally happen is that people check in several things at once (like a
> 100k reindenton mixed with various functional changes)
> for these we currently copy the last good version of the affected files
> over the current one with svn cp and then apply the changes in nicely
> split manner. (possibly without the reindention if its uneeded ...)

I might be misunderstanding, but doesn't that leave the "bad" commit in the 
history?

 * -- * -- G -- B -- !B -- 1 -- 2 -- 3

B is the bad commit; !B would be the result of the svn cp from the previous 
known-good revision, "G"; then 1, 2, and 3 would be the correctly split 
version of "B".

Have I correctly understood?  If so - git would have no trouble at all 
emulating that.  !B would actually be easier to create because you could use 
git-revert to automatically create the inverse of B.  If you wanted to only 
revert a single file, well you could use

  git-checkout G-REVISION -- file

To pull only that file out of G, and then commit that back, before starting 
the tidy up.



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com

^ permalink raw reply

* Re: [PATCH] Have git-revert, git-cherry-pick cleanup ./.msg upon successful completion.
From: Alex Riesen @ 2007-05-04 15:28 UTC (permalink / raw)
  To: git
In-Reply-To: <20070504143210.8690.qmail@a4171e0dbe98e3.315fe32.mid.smarden.org>

On 5/4/07, Gerrit Pape <pape@smarden.org> wrote:
> git-revert and git-cherry-pick left behind the commit message file ./.msg,
> have them use the -f option to git-commit to properly cleanup the
> automatically created file.

Could we also have the files in $GIT_DIR instead of in working directory?

^ permalink raw reply

* [PATCH] Have git-revert, git-cherry-pick cleanup ./.msg upon successful completion.
From: Gerrit Pape @ 2007-05-04 14:32 UTC (permalink / raw)
  To: git
In-Reply-To: <20070504143022.8539.qmail@4071cc1c178e73.315fe32.mid.smarden.org>

git-revert and git-cherry-pick left behind the commit message file ./.msg,
have them use the -f option to git-commit to properly cleanup the
automatically created file.

Signed-off-by: Gerrit Pape <pape@smarden.org>
---
 builtin-revert.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin-revert.c b/builtin-revert.c
index 4ba0ee6..9acdf47 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -376,10 +376,10 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 
 	if (!no_commit) {
 		if (edit)
-			return execl_git_cmd("commit", "-n", "-F", ".msg",
+			return execl_git_cmd("commit", "-n", "-f", ".msg",
 				"-e", NULL);
 		else
-			return execl_git_cmd("commit", "-n", "-F", ".msg",
+			return execl_git_cmd("commit", "-n", "-f", ".msg",
 				NULL);
 	}
 	if (reencoded_message)
-- 
1.5.1.2

^ permalink raw reply related

* [PATCH] git-commit -f <file>: take message from file, and remove file upon completion.
From: Gerrit Pape @ 2007-05-04 14:30 UTC (permalink / raw)
  To: git

Change (undocumented) git commit -f option from a synonym for git-commit -F
to "Take the commit message from the given file, and remove the file upon
successful commit".

git-revert and git-cherry-pick should make use of this to properly cleanup
the automatically created ./.msg file.

Signed-off-by: Gerrit Pape <pape@smarden.org>
---
 Documentation/git-commit.txt |    7 ++++---
 git-commit.sh                |   25 +++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 53a7bb0..da68c81 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git-commit' [-a | --interactive] [-s] [-v]
-	   [(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
+	   [(-c | -C) <commit> | (-F | -f) <file> | -m <msg> | --amend]
 	   [--no-verify] [-e] [--author <author>]
 	   [--] [[-i | -o ]<file>...]
 
@@ -63,9 +63,10 @@ OPTIONS
 	invoked; with '-c' the user can further edit the commit
 	message.
 
--F <file>::
+-F or -f <file>::
 	Take the commit message from the given file.  Use '-' to
-	read the message from the standard input.
+	read the message from the standard input.  With '-f', the
+	file is removed upon successful commit; with '-F' not.
 
 --author <author>::
 	Override the author name used in the commit.  Use
diff --git a/git-commit.sh b/git-commit.sh
index f28fc24..e4518c4 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -74,6 +74,7 @@ also=
 interactive=
 only=
 logfile=
+logfile_rm=
 use_commit=
 amend=
 edit_flag=
@@ -90,15 +91,31 @@ untracked_files=
 while case "$#" in 0) break;; esac
 do
 	case "$1" in
-	-F|--F|-f|--f|--fi|--fil|--file)
+	-f)
 		case "$#" in 1) usage ;; esac
 		shift
 		no_edit=t
 		log_given=t$log_given
 		logfile="$1"
+		test "$logfile" = '-' || logfile_rm=1
 		shift
 		;;
-	-F*|-f*)
+	-F|--F|--f|--fi|--fil|--file)
+		case "$#" in 1) usage ;; esac
+		shift
+		no_edit=t
+		log_given=t$log_given
+		logfile="$1"
+		shift
+		;;
+	-f*)
+		no_edit=t
+		log_given=t$log_given
+		logfile=`expr "z$1" : 'z-[Ff]\(.*\)'`
+		test "$logfile" = '-' || logfile_rm=1
+		shift
+		;;
+	-F*)
 		no_edit=t
 		log_given=t$log_given
 		logfile=`expr "z$1" : 'z-[Ff]\(.*\)'`
@@ -653,6 +670,10 @@ then
 		       --summary --root HEAD --`
 		echo "Created${initial_commit:+ initial} commit $commit"
 	fi
+	if test -n "$logfile_rm"
+	then
+		rm -f "$logfile"
+	fi
 fi
 
 exit "$ret"
-- 
1.5.1.2

^ permalink raw reply related

* Re: FFmpeg considering GIT
From: Michael Niedermayer @ 2007-05-04 13:46 UTC (permalink / raw)
  To: git
In-Reply-To: <20070503200013.GG4489@pasky.or.cz>

Petr Baudis <pasky <at> suse.cz> writes:
[...]
> > 	let me explain a little bit why this is critically needed
> > 	think of someone misstakely commiting the whole ffmpeg
> > 	reindented or mistakely commiting a old ffmpeg version over the
> > 	new or another total messup, these things do happen, and
> > 	especially if they cannot be corrected and at the time where
> > 	none of the developers is around
> > 
[...]
>   Still, if this kind of bogus change checkins happens at any frequent
> rate in the ffmpeg project, there is a serious problem somewhere. 

well, my example above was exagerated, noone ever reindented the whole
ffmpeg or checked in a old version over HEAD. what did and does occasionally
happen is that people check in several things at once (like a 100k reindenton
mixed with various functional changes)
for these we currently copy the last good version of the affected files
over the current one with svn cp and then apply the changes in nicely
split manner. (possibly without the reindention if its uneeded ...)
Another thing that happens occasionally is that complete nonsense is checked
in like checking in the wrong file or some "private" debuging code

we never use the svn cp method to revert normal buggy code ...



> But I think the git way of alleviating this problem would be to have a
> way to hint the pickaxe and blame tools to ignore changes in given
> commits. So, you don't _cover up_ the messy things that happened during
> the history, but avoid in getting in the way in your view. You can still
> look it up (with git log or something) in case you'd need to (perhaps
> the revert patch was a bit complicated because of conflicting with some
> other changes, and a subtle bug was introduced; this would be thousand
> times harder to track down if you would've rewritten the history).
> 
>   Would crafting up a patch to implement something like this help ffmpeg
> people in their decision?

well if git blame and others could somehow be told to automatically ignore
nonsense changes and matching nonsense reverts that would be great
maybe by searching for some keyword in the revert message?

ignoring all or no reverts though would again be suboptimal as that would
also ignore some reverts due to normal buggy changes

actually i think ive found an almost working solution for replacing svn cp
(though i dont know if its safe on a public repo? or if theres some other
issue with it iam missing)

ascii > testfile
git add testfile ; git commit
Created initial commit c14755cd59af4b0e6c53fb3d4bf8fa7d5aad3f3d
 1 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 testfile

vim testfile 
git add testfile ; git commit
Created commit 0fd74c0955ae4281ac17520eabefea639f635354
 1 files changed, 2 insertions(+), 2 deletions(-)

vim testfile 
git add testfile ; git commit
Created commit d1dce0e5a20603faa0e64b722d93e847f5b80845
 1 files changed, 23 insertions(+), 23 deletions(-)

git checkout 0fd74c0955ae4281ac17520eabefea639f635354
Note: moving to "0fd74c0955ae4281ac17520eabefea639f635354" which 
isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 0fd74c0... good change

cp testfile testbak
git add testbak ; git commit
Created commit 0e55c6f422005e64fd3b73595f0fe409148d725f
 1 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 testbak

git checkout d1dce0e5a20603faa0e64b722d93e847f5b80845
HEAD is now at d1dce0e... bad change
$git rm testfile 
rm 'testfile'

git merge 0e55c6f422005e64fd3b73595f0fe409148d725f
 100% (1/1) done
Merge made by recursive.
 testbak |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 testbak

git mv testbak testfile 
fatal: destination exists, source=testbak, destination=testfile
git rm testfile 
rm 'testfile'
git mv testbak testfile 

git commit
Created commit ca5bcbcadb9799b0a6eaa792fae322d511ecd55f
 2 files changed, 23 insertions(+), 46 deletions(-)
 delete mode 100644 testbak

git blame -C1 -C1 -M testfile
(this just shows ca5bcbca)

vim testfile (changing a single line)
git add testfile ; git commit
Created commit 7a0a828629935ce139177fc4623a0eb9916b78fd
 1 files changed, 1 insertions(+), 1 deletions(-)

git blame -C1 -C1 -M testfile | cut -d ' ' -f 1
^c14755c
^c14755c
^c14755c
^c14755c
^c14755c
0fd74c09
0fd74c09
^c14755c
^c14755c
^c14755c
^c14755c
^c14755c
^c14755c
^c14755c
^c14755c
^c14755c
7a0a8286
ca5bcbca
ca5bcbca
ca5bcbca
ca5bcbca
ca5bcbca
ca5bcbca

this is correct except the last 6 lines

[...]

Michael

^ permalink raw reply

* Re: [RFD/PATCH] Implement pack.compression and pack-objects --compression=N
From: Nicolas Pitre @ 2007-05-04 13:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Dana How, Git Mailing List
In-Reply-To: <7vejlxxho1.fsf@assigned-by-dhcp.cox.net>

On Thu, 3 May 2007, Junio C Hamano wrote:

> "Dana How" <danahow@gmail.com> writes:
> 
> > So for a 25% increase in blob size I get 33% less elapsed time
> > in git-add, all by changing core.compression from -1 to 1.
> > I'll definitely take that improvement.  [For the compressible files
> > we typically have, using 0 is a bad idea:  the CPU "advantage"
> > is swamped out by the time to write a much larger file.]
> 
> The above number is about loose objects, right?
> 
> > Since I don't care [to the same degree] about the responsiveness of
> > packing,  I'd rather pack with -1 or better to keep packs small.
> 
> I see.  You are saying that the fact that core.compression is
> used also for packing makes the variable less useful.

I think that would make sense to have separate configs for pack and 
loose object compression.  When not specified they should simply default 
to core.compression if it exists.  Otherwise I'd suggest that pack 
compression default level be Z_DEFAULT_COMPRESSION and loose object 
compression default level be Z_BEST_SPEED.  This would make interactive 
operations like git-add and git-commit even faster by default.


Nicolas

^ permalink raw reply

* Re: [RFC] Optimize diff-delta.c
From: Nicolas Pitre @ 2007-05-04 13:35 UTC (permalink / raw)
  To: Martin Koegler; +Cc: git
In-Reply-To: <20070504064024.GA11788@auto.tuwien.ac.at>

On Fri, 4 May 2007, Martin Koegler wrote:

> On 2007-05-01 16:05:24, Nicolas Pitre wrote:
> > > On Tue, 1 May 2007, Martin Koegler wrote:
> > Right.  I think it would be a good idea to extend the delta format as 
> > well to allow for larger offsets in pack v4.
> 
> Is git://repo.or.cz/git/fastimport.git#sp/pack4 the current version of
> pack v4 efforts?

Yes.  It is lagging behind current git though, and not usable yet.

> > > The delta index has approximately the same size in memory as the
> > > uncompressed blob ((blob size)/16*(sizeof(index_entry)).
> > 
> > One thing that could be done with really large blobs is to create a 
> > sparser index, i.e. have a larger step than 16.  Because the delta match 
> > loop scans backward after a match the sparse index shouldn't affect 
> > compression that much on large blobs and the index could be 
> > significantly smaller.
> 
> In the long term, I think, that the delta generation code needs to get
> tunable.

No.  It should be self-tunable certainly, but there are way too many 
config options already, and another one for the inner working of the 
delta algorithm would be a bit too esoteric for most users and they 
won't get advantage of it.  This thing really has to self tune itself.

> > > I tried to speed up the delta generation by searching for a common 
> > > prefix, as my blobs are mostly append only. I tested it with about 
> > > less than 1000 big blobs. The time for finding the deltas decreased 
> > > from 17 to 14 minutes cpu time.
> > 
> > I'm surprised that your patch makes so much of a difference.  Normally 
> > the first window should always match in the case you're trying to 
> > optimize and the current code should already perform more or less the 
> > same as your common prefix match does.
> 
> A block is limited to 64k. If the file has some hundred MBs, it has to
> match many blocks.

Only if the first match is smaller than 64K.  If the first match is 64K 
in size then the rest of the file is not considered at all.

> My patch can process everything except the few last thousand lines by
> doing a memcmp.
> 
> Additionally, nearly every line starts with the same, longer than 16
> byte prefix. So its likely, that many blocks map to the same hash
> value.

The hash index only remembers the lowest of consecutive identical blocks 
so repeated blocks are indexed only with the first one.  If however you 
happen to have many identical blocks interlaced between other blocks 
then there is not much that can be done.  What the code does in that 
case is to trim those hash buckets that gets too large by keeping only a 
few entries across the reference buffer to avoid a O(n^2) behavior. But 
that happens only when your line beginnings are located on the same 
block boundary (but with a block size of 16 this is rather likely in the 
presence of lots of lines I suppose).

I'll be very interested in the results you get with my suggested patch.


Nicolas

^ permalink raw reply

* Re: how to filter a pull
From: marc zonzon @ 2007-05-04 13:13 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: Junio C Hamano, Peter Baumann, Alex Riesen, git
In-Reply-To: <20070504101329.GA16446@diana.vm.bytemark.co.uk>

On 5/4/07, Karl Hasselström <kha@treskal.com> wrote:

> It should be straightforward (and efficient) to make a script that
> takes an existing branch and makes a parallel branch that contains
> only one subtree of the first branch. This derived branch can then be
> used as a subproject or whatever.
>
> Or is there some obvious reason why this wouldn't work, or would be
> inconvenient?

This was my initial idea,  pull and filter!, but of course it is
somewhat a hack, you pull inside git, and filter outside git, I don't
know how to keep history, it seems that once filtered the origin of
the subtree is lost. But I lack of git proficiency, I have no
experience wich git core and mainly have used it at the user
'porcelain' level.
I have had some hope that there is some mean to forward the internal
state recording of the database state.
The solution proposed by alex does not seem to be an option, if you
draw from many projects, you cannot host the whole trees because some
nodes are duplicates, and if they are outside your field you don't
bother of merging them.
Moreover I don't know how you mark what belongs to your small project
island, among this big ocean.

So if I have no further advice I think the wiser is to try the raw
script option, at least for the next 6 months the time to git, and my
own proficiency to ripen..

Marc

^ permalink raw reply

* Re: [RFC?] Telling git about more complex relationships between commits (Was: Re: FFmpeg considering GIT)
From: Johan Herland @ 2007-05-04 12:30 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200705041239.22300.andyparkins@gmail.com>

On Friday 04 May 2007, Andy Parkins wrote:
> As for custom headers - it's a great idea; here's the one that would be
> most useful:
>
>  X-Git-SVN-ID: 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
>
> That way git-svn wouldn't (necessarily) need to keep its .rev_db file, and
> it wouldn't need any special handling to allow the repository to be cloned.

That's _exactly_ the kind of use of this I'd like to see. Great example. :)


Have fun!

...Johan

-- 
Johan Herland, <johan@herland.net>
www.herland.net

^ permalink raw reply

* Re: [RFC?] Telling git about more complex relationships between commits (Was: Re: FFmpeg considering GIT)
From: Johan Herland @ 2007-05-04 12:22 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20070504111057.GI4489@pasky.or.cz>

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

On Friday 04 May 2007, Petr Baudis wrote:
> On Fri, May 04, 2007 at 09:21:29AM CEST, Johan Herland wrote:
> > On Friday 04 May 2007, Jakub Narebski wrote:
> > > Besides I think it would be better to teach blame to ignore reversion
> > > commits (for example based on first line of commit message) than to
> > > mess with the history.
> >
> > I'm starting to see a pattern where people would like to tell git about
> > more complicated relationships between commits, so that git can make
> > more intelligent decisions when doing merge, blame, pickaxe, etc.
> >
> > Adding these relationships as part of the commit message seems like a
> > really stupid idea because git suddenly has to make sense of something
> > it has never parsed before, thus making all future and former git
> > commit messages a potential target for pattern (mis)matching by git.
> > Also, we seem to forget that we already have the perfect place to put
> > such information: The header fields preceding the commit message.
> >
> > I therefore propose adding header field names to commit objects that
> > illustrate the relationships people want to tell git about.
>
>   So I've looked it up, and the Linus' writeup on this is at
>
> 	http://news.gmane.org/find-root.php?message_id=<Pine.LNX.4.64.060425075800
>0.3701@g5.osdl.org>

Thanks a lot for the link. I hadn't seen that writeup.

For the record: I'm only interested in adding "machine-readable" headers in 
cases where _both_ of the following holds:
1. The header has a _clear_ and _unambiguous_ _meaning_.
2. git can use the header in a well-defined manner to make informed and better 
decisions on how to behave.

In Linus' writeup, he's correct in that "prior" is too loosely defined. 
However, if we can meet Linus' requirements for clearness and semantics, I 
actually think the core idea is very good.

> > 1. "Reverts": Mark a commit as reverting another commit. This could be
> > used by git-log to cancel out pairs of commits, resulting in a cleaner
> > view of history. It can help blame/annotate. There are probably other
> > tools that can benefit from this information also.
>
>   Actually I think git-log is the one tool which shouldn't cancel it
> out. The number of reverts likely won't be overwhelming and reverting is
> actually pretty important event - it says "this has been tried and we
> decided it's not the way", also can have social meanings etc. It is an
> important piece of history. And people still want to actually see the
> change and possibly revive it. BTW, imagine their confusion if the
> history looks like
>
> 	1abcd5 Feature X
> 	37efab Release 2.3.1
> 	724b9c Revert feature X
>
> and git log would cancel out 1abcd5 and 724b9c. Feature X is part of
> 2.3.1 but not in the log..?!
>
>   The point is that the reverting/reverted commit pairs don't affect
> your current content (except maybe in an highly abstract way), and this
> is why pickaxe and blame should skip it (by default).

Of course git-log shouldn't skip reverted commit pairs _by_default_. But if 
someone is interested in a cleaner view of history (e.g. when making a 
changelog or whatnot), a command-line option for turning on this behaviour 
might be useful. Or maybe we don't want git-log to be affected by "Reverts" 
at all. But if pickaxe and blame can make real use of this header, that's 
sufficient reason to add it, I think.

>   The question wrt. Linus' criteria is if "it has enough of a meaning",
> and I wonder about that too. I think it does, though.

As stated above, I don't want header fields unless they have clearly defined 
meaning and semantics. I doubt that all of my examples will fulfill these 
criteria, but some of them should, and that may be useful enough.

>   For the other suggested headers, it should be already mostly obvious
> from Linus' writeup why they shouldn't qualify, though.

I agree with Linus in that if we cannot define clear meaning and accompanying 
semantics, then adding a header is useless. I do, however, think that there 
are cases where we _can_ define the meaning and semantics, and in those 
cases, I do believe header fields to be a good idea.

As for "Cherry-Pick", it is of course not useful when the commit pointed to is 
not in the repo, but in the cases where it _is_, it might be very useful. 
It's a tradeoff, and we might end up deciding that "Cherry-Pick" is not worth 
it, but we should at least consider the possibility.


Have fun!

...Johan

-- 
Johan Herland, <johan@herland.net>
www.herland.net

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC?] Telling git about more complex relationships between commits (Was: Re: FFmpeg considering GIT)
From: Andrew Ruder @ 2007-05-04 12:06 UTC (permalink / raw)
  To: git
In-Reply-To: <200705041239.22300.andyparkins@gmail.com>

On Fri, May 04, 2007 at 12:39:18PM +0100, Andy Parkins wrote:
> That way git-svn wouldn't (necessarily) need to keep its .rev_db file, and it 
> wouldn't need any special handling to allow the repository to be cloned.

Which, BTW, would be a great thing as on subversion repositories with
lots of revisions and lots of branches/tags, the disk space for all those
.rev_db files gets pretty bad.  i.e. du -sh .git/objects == 14M, du -sh
.git == 120M.

- Andy

-- 
Andrew Ruder <andy@aeruder.net>
http://www.aeruder.net

^ permalink raw reply

* Re: [RFC?] Telling git about more complex relationships between commits (Was: Re: FFmpeg considering GIT)
From: Johan Herland @ 2007-05-04 11:53 UTC (permalink / raw)
  To: Alex Riesen; +Cc: git
In-Reply-To: <81b0412b0705040236w1d5f26bx8ac351ade2f4ea6a@mail.gmail.com>

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

On Friday 04 May 2007, Alex Riesen wrote:
> On 5/4/07, Johan Herland <johan@herland.net> wrote:
> > 1. "Reverts": Mark a commit as reverting another commit. This could be
> > used by git-log to cancel out pairs of commits, resulting in a cleaner
> > view of history. It can help blame/annotate. There are probably other
> > tools that can benefit from this information also.
> >
> > 2. "Cherry-Pick": When cherry-picking a commit onto another branch, you
> > should be able to tell git which commit you are cherry-picking
> > (git-cherry-pick would of course do this automatically). This could
> > enable git to make smarter decisions when merging the two branches: If
> > the cherry-picked commit would cause a conflict with the original
> > commit, git can either skip it (since it knows that one version of this
> > patch is already present), or it can at least present the conflict to
> > the user with some more context than what is available today. Not to
> > mention how this information could be used by blame/annotate.
>
> These are completely useless after the first "git gc --prune" or "git
> clone" unless these tools taught to preserve the reverted or cherry-picked
> commits (and all their history). And if you are about to teach them that,
> please notice that as for now cloning and repacking does not even look at
> the
> objects contents.
> You'll absolutely kill their performance.

Of course I don't want "git gc --prune" or "git clone" to follow these links, 
or know anything about them at all.

As for "Reverts", the commit pointed to should already be in your history, 
since you cannot revert something that hasn't already been applied at an 
earlier point in your history. In other words, the reverted commit will 
automatically be included in your "git gc --prune" or "git clone" regardless 
of the "Reverts" fields, since "Reverts" can only point to an ancestor.

As for "Cherry-Pick", it's a fairly weak relationship that shouldn't affect 
anything except to give a hint to merge, blame, and similar tools. 
If "Cherry-Pick" identifies an object not in your repo (because of "git 
gc --prune" or "git clone"), that is obviously equivalent to not having 
a "Cherry-Pick" field in the first place. "Cherry-Pick" is only useful when 
you have access to the original commit (pointed to by "Cherry-Pick"), but in 
that case I think it could be _really_ useful.


Have fun!

...Johan

-- 
Johan Herland, <johan@herland.net>
www.herland.net

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC?] Telling git about more complex relationships between commits (Was: Re: FFmpeg considering GIT)
From: Andy Parkins @ 2007-05-04 11:39 UTC (permalink / raw)
  To: git; +Cc: Alex Riesen, Johan Herland
In-Reply-To: <81b0412b0705040236w1d5f26bx8ac351ade2f4ea6a@mail.gmail.com>

On Friday 2007 May 04, Alex Riesen wrote:
> On 5/4/07, Johan Herland <johan@herland.net> wrote:
> > 1. "Reverts": Mark a commit as reverting another commit. This could be

> These are completely useless after the first "git gc --prune" or "git

Agreed for the cherry pick (and the rebase), but the original of a revert 
won't be pruned - in fact it's almost certain that the original is a subset 
of the revert itself (otherwise the revert wouldn't have applied cleanly).

 * --- * --- X --- * --- !X --- * --- *

See?  X won't ever be pruned without !X having been pruned first.

It doesn't seem unreasonable to record in a machine readable manner that !X 
undid X.  It might be useful to someone one day.

As for custom headers - it's a great idea; here's the one that would be most 
useful:

 X-Git-SVN-ID: 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

That way git-svn wouldn't (necessarily) need to keep its .rev_db file, and it 
wouldn't need any special handling to allow the repository to be cloned.



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com

^ permalink raw reply

* [PATCH] git-config: add --remote option for reading config from remote repo
From: Sven Verdoolaege @ 2007-05-04 10:49 UTC (permalink / raw)
  To: git; +Cc: Sven Verdoolaege
In-Reply-To: <11782757671754-git-send-email-skimo@liacs.nl>

From: Sven Verdoolaege <skimo@kotnet.org>

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
 Documentation/git-config.txt |   33 +++++++++++++++++++++---------
 builtin-config.c             |   44 ++++++++++++++++++++++++++++++++---------
 cache.h                      |    1 +
 config.c                     |   26 ++++++++++++++++++++++++
 4 files changed, 84 insertions(+), 20 deletions(-)

diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 280ef20..76398ab 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -9,16 +9,25 @@ git-config - Get and set repository or global options
 SYNOPSIS
 --------
 [verse]
-'git-config' [--system | --global] [type] name [value [value_regex]]
-'git-config' [--system | --global] [type] --add name value
-'git-config' [--system | --global] [type] --replace-all name [value [value_regex]]
-'git-config' [--system | --global] [type] --get name [value_regex]
-'git-config' [--system | --global] [type] --get-all name [value_regex]
-'git-config' [--system | --global] [type] --unset name [value_regex]
-'git-config' [--system | --global] [type] --unset-all name [value_regex]
-'git-config' [--system | --global] [type] --rename-section old_name new_name
-'git-config' [--system | --global] [type] --remove-section name
-'git-config' [--system | --global] -l | --list
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] name [value [value_regex]]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --add name value
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --replace-all name [value [value_regex]]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --get name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --get-all name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --unset name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --unset-all name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --rename-section old_name new_name
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+	     [type] --remove-section name
+'git-config' [--system | --global | --remote=[<host>:]<directory ] -l | --list
 
 DESCRIPTION
 -----------
@@ -80,6 +89,10 @@ OPTIONS
 	Use system-wide $(prefix)/etc/gitconfig rather than the repository
 	.git/config.
 
+--remote=[<host>:]<directory
+	Use remote config instead of the repository .git/config.
+	Only available for reading options.
+
 --remove-section::
 	Remove the given section from the configuration file.
 
diff --git a/builtin-config.c b/builtin-config.c
index b2515f7..3a1e86c 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -2,8 +2,10 @@
 #include "cache.h"
 
 static const char git_config_set_usage[] =
-"git-config [ --global | --system ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
+"git-config [ --global | --system | --remote=[<host>:]<directory ] "
+"[ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
 
+static char *dest;
 static char *key;
 static regex_t *key_regexp;
 static regex_t *regexp;
@@ -104,15 +106,19 @@ static int get_value(const char* key_, const char* regex_)
 		}
 	}
 
-	if (do_all && system_wide)
-		git_config_from_file(show_config, system_wide);
-	if (do_all && global)
-		git_config_from_file(show_config, global);
-	git_config_from_file(show_config, local);
-	if (!do_all && !seen && global)
-		git_config_from_file(show_config, global);
-	if (!do_all && !seen && system_wide)
-		git_config_from_file(show_config, system_wide);
+	if (dest)
+		git_config_from_remote(show_config, dest);
+	else {
+		if (do_all && system_wide)
+			git_config_from_file(show_config, system_wide);
+		if (do_all && global)
+			git_config_from_file(show_config, global);
+		git_config_from_file(show_config, local);
+		if (!do_all && !seen && global)
+			git_config_from_file(show_config, global);
+		if (!do_all && !seen && system_wide)
+			git_config_from_file(show_config, system_wide);
+	}
 
 	free(key);
 	if (regexp) {
@@ -155,8 +161,14 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		}
 		else if (!strcmp(argv[1], "--system"))
 			setenv("GIT_CONFIG", ETC_GITCONFIG, 1);
+		else if (!prefixcmp(argv[1], "--remote="))
+			dest = xstrdup(argv[1]+9);
 		else if (!strcmp(argv[1], "--rename-section")) {
 			int ret;
+			if (dest) {
+				fprintf(stderr, "Cannot rename on remote\n");
+				return 1;
+			}
 			if (argc != 4)
 				usage(git_config_set_usage);
 			ret = git_config_rename_section(argv[2], argv[3]);
@@ -170,6 +182,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		}
 		else if (!strcmp(argv[1], "--remove-section")) {
 			int ret;
+			if (dest) {
+				fprintf(stderr, "Cannot remove on remote\n");
+				return 1;
+			}
 			if (argc != 3)
 				usage(git_config_set_usage);
 			ret = git_config_rename_section(argv[2], NULL);
@@ -191,6 +207,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 	case 2:
 		return get_value(argv[1], NULL);
 	case 3:
+		if (dest && prefixcmp(argv[1], "--get")) {
+			fprintf(stderr, "Cannot (un)set on remote\n");
+			return 1;
+		}
 		if (!strcmp(argv[1], "--unset"))
 			return git_config_set(argv[2], NULL);
 		else if (!strcmp(argv[1], "--unset-all"))
@@ -209,6 +229,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 
 			return git_config_set(argv[1], argv[2]);
 	case 4:
+		if (dest && prefixcmp(argv[1], "--get")) {
+			fprintf(stderr, "Cannot (un)set on remote\n");
+			return 1;
+		}
 		if (!strcmp(argv[1], "--unset"))
 			return git_config_set_multivar(argv[2], NULL, argv[3], 0);
 		else if (!strcmp(argv[1], "--unset-all"))
diff --git a/cache.h b/cache.h
index 8e76152..e8c7791 100644
--- a/cache.h
+++ b/cache.h
@@ -499,6 +499,7 @@ extern int update_server_info(int);
 typedef int (*config_fn_t)(const char *, const char *);
 extern int git_default_config(const char *, const char *);
 extern int git_config_from_file(config_fn_t fn, const char *);
+extern int git_config_from_remote(config_fn_t fn, char *dest);
 extern int git_config(config_fn_t fn);
 extern int git_config_int(const char *, const char *);
 extern int git_config_bool(const char *, const char *);
diff --git a/config.c b/config.c
index 70d1055..0da74e0 100644
--- a/config.c
+++ b/config.c
@@ -6,9 +6,12 @@
  *
  */
 #include "cache.h"
+#include "pkt-line.h"
 
 #define MAXNAME (256)
 
+static const char *dumpconfig = "git-dump-config";
+
 static FILE *config_file;
 static const char *config_file_name;
 static int config_linenr;
@@ -392,6 +395,29 @@ int git_config_from_file(config_fn_t fn, const char *filename)
 	return ret;
 }
 
+int git_config_from_remote(config_fn_t fn, char *dest)
+{
+	int ret;
+	int fd[2];
+	pid_t pid;
+	static char var[MAXNAME];
+	static char value[1024];
+
+	pid = git_connect(fd, dest, dumpconfig);
+	if (pid < 0)
+		return 1;
+	ret = 0;
+	while (packet_read_line(fd[0], var, sizeof(var))) {
+		if (!packet_read_line(fd[0], value, sizeof(value)))
+			die("Missing value");
+		fn(var, value);
+	}
+	close(fd[0]);
+	close(fd[1]);
+	ret |= finish_connect(pid);
+	return !!ret;
+}
+
 int git_config(config_fn_t fn)
 {
 	int ret = 0;
-- 
1.5.2.rc1.25.g889f-dirty

^ permalink raw reply related

* [PATCH] git-config: read remote config files over HTTP
From: Sven Verdoolaege @ 2007-05-04 10:49 UTC (permalink / raw)
  To: git; +Cc: Sven Verdoolaege
In-Reply-To: <11782757671754-git-send-email-skimo@liacs.nl>

From: Sven Verdoolaege <skimo@kotnet.org>

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
 Makefile           |    6 +++++-
 config.c           |   14 ++++++++++++++
 http.c             |   10 ++++++++--
 http_config.h      |    1 +
 http_config_curl.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 http_config_none.c |    6 ++++++
 6 files changed, 83 insertions(+), 3 deletions(-)
 create mode 100644 http_config.h
 create mode 100644 http_config_curl.c
 create mode 100644 http_config_none.c

diff --git a/Makefile b/Makefile
index 0185386..b782111 100644
--- a/Makefile
+++ b/Makefile
@@ -311,7 +311,7 @@ LIB_OBJS = \
 	write_or_die.o trace.o list-objects.o grep.o match-trees.o \
 	alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
 	color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
-	convert.o attr.o decorate.o progress.o mailmap.o
+	convert.o attr.o decorate.o progress.o mailmap.o $(HTTP_CONFIG_OBJ)
 
 BUILTIN_OBJS = \
 	builtin-add.o \
@@ -518,6 +518,10 @@ ifndef NO_CURL
 	ifndef NO_EXPAT
 		EXPAT_LIBEXPAT = -lexpat
 	endif
+	HTTP_CONFIG_OBJ = http_config_curl.o http.o
+	EXTLIBS += $(CURL_LIBCURL)
+else
+	HTTP_CONFIG_OBJ = http_config_none.o
 endif
 
 ifndef NO_OPENSSL
diff --git a/config.c b/config.c
index 0da74e0..36e3b97 100644
--- a/config.c
+++ b/config.c
@@ -7,6 +7,7 @@
  */
 #include "cache.h"
 #include "pkt-line.h"
+#include "http_config.h"
 
 #define MAXNAME (256)
 
@@ -395,6 +396,16 @@ int git_config_from_file(config_fn_t fn, const char *filename)
 	return ret;
 }
 
+static int config_from_http(config_fn_t fn, char *dest)
+{
+	static char *config_temp = "config.temp";
+	if (git_http_fetch_config(dest, config_temp))
+		return 1;
+	git_config_from_file(fn, config_temp);
+	unlink(config_temp);
+	return 0;
+}
+
 int git_config_from_remote(config_fn_t fn, char *dest)
 {
 	int ret;
@@ -403,6 +414,9 @@ int git_config_from_remote(config_fn_t fn, char *dest)
 	static char var[MAXNAME];
 	static char value[1024];
 
+	if (!prefixcmp(dest, "http://"))
+		return config_from_http(fn, dest);
+
 	pid = git_connect(fd, dest, dumpconfig);
 	if (pid < 0)
 		return 1;
diff --git a/http.c b/http.c
index ae27e0c..3e1ccce 100644
--- a/http.c
+++ b/http.c
@@ -25,6 +25,10 @@ long curl_low_speed_limit = -1;
 long curl_low_speed_time = -1;
 int curl_ftp_no_epsv = 0;
 
+#ifdef USE_CURL_MULTI
+void (*fill_active_slots)(void) = NULL;
+#endif
+
 struct curl_slist *pragma_header;
 
 struct active_request_slot *active_queue_head = NULL;
@@ -394,7 +398,8 @@ void step_active_slots(void)
 	} while (curlm_result == CURLM_CALL_MULTI_PERFORM);
 	if (num_transfers < active_requests) {
 		process_curl_messages();
-		fill_active_slots();
+		if (fill_active_slots)
+			fill_active_slots();
 	}
 }
 #endif
@@ -459,7 +464,8 @@ void release_active_slot(struct active_request_slot *slot)
 		slot->curl = NULL;
 	}
 #ifdef USE_CURL_MULTI
-	fill_active_slots();
+	if (fill_active_slots)
+		fill_active_slots();
 #endif
 }
 
diff --git a/http_config.h b/http_config.h
new file mode 100644
index 0000000..0fddf98
--- /dev/null
+++ b/http_config.h
@@ -0,0 +1 @@
+int git_http_fetch_config(const char *repo, const char *config_file);
diff --git a/http_config_curl.c b/http_config_curl.c
new file mode 100644
index 0000000..3047ea2
--- /dev/null
+++ b/http_config_curl.c
@@ -0,0 +1,49 @@
+#include "http_config.h"
+#include "http.h"
+
+int git_http_fetch_config(const char *repo, const char *config)
+{
+	char url[PATH_MAX];
+	int len = strlen(repo);
+
+	FILE *configfile;
+	struct active_request_slot *slot;
+	struct slot_results results;
+
+	strcpy(url, repo);
+	while (len > 0 && url[len-1] == '/')
+		--len;
+	snprintf(url+len, sizeof(url)-len, "/config");
+
+	configfile = fopen(config, "w");
+	if (!configfile)
+		return error("Unable to open local file %s for config",
+			     config);
+
+	http_init();
+
+	slot = get_active_slot();
+	slot->results = &results;
+	curl_easy_setopt(slot->curl, CURLOPT_FILE, configfile);
+	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
+	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
+	slot->local = configfile;
+
+	if (start_active_slot(slot)) {
+		run_active_slot(slot);
+		if (results.curl_result != CURLE_OK) {
+			fclose(configfile);
+			return error("Unable to get config %s\n%s", url,
+				     curl_errorstr);
+		}
+	} else {
+		fclose(configfile);
+		return error("Unable to start request");
+	}
+
+	http_cleanup();
+
+	fclose(configfile);
+
+	return 0;
+}
diff --git a/http_config_none.c b/http_config_none.c
new file mode 100644
index 0000000..303160b
--- /dev/null
+++ b/http_config_none.c
@@ -0,0 +1,6 @@
+#include "http_config.h"
+
+int git_http_fetch_config(const char *repo, const char *config_file)
+{
+	return error("Reading http config files not supported");
+}
-- 
1.5.2.rc1.25.g889f-dirty

^ permalink raw reply related

* [PATCH] git-clone: add --submodules for cloning submodules
From: Sven Verdoolaege @ 2007-05-04 10:49 UTC (permalink / raw)
  To: git; +Cc: Sven Verdoolaege
In-Reply-To: <11782757671754-git-send-email-skimo@liacs.nl>

From: Sven Verdoolaege <skimo@kotnet.org>

When the --submodules option is specified, git-clone will search
for submodule.<submodule>.url options in the remote configuration
and clone each submodule using the first url that it can use from
the local site.

The submodules are currently not checked out.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
 Documentation/config.txt    |    3 ++
 Documentation/git-clone.txt |    6 +++-
 git-clone.sh                |   68 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 24f9655..92747d8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -597,6 +597,9 @@ showbranch.default::
 	The default set of branches for gitlink:git-show-branch[1].
 	See gitlink:git-show-branch[1].
 
+submodule.<submodule>.url
+	The URL of a submodule.  See gitlink:git-clone[1].
+
 tar.umask::
 	By default, gitlink:git-tar-tree[1] sets file and directories modes
 	to 0666 or 0777. While this is both useful and acceptable for projects
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 6d32c49..b112a6a 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -11,7 +11,7 @@ SYNOPSIS
 [verse]
 'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
 	  [-o <name>] [-u <upload-pack>] [--reference <repository>]
-	  [--depth <depth>] <repository> [<directory>]
+	  [--depth <depth>] [--submodules] <repository> [<directory>]
 
 DESCRIPTION
 -----------
@@ -105,6 +105,10 @@ OPTIONS
 	with a long history, and would want to send in a fixes
 	as patches.
 
+--submodules::
+	Clone submodules specified in (remote) configuration parameters
+	submodule.<submodule>.url.
+
 <repository>::
 	The (possibly remote) repository to clone from.  It can
 	be any URL git-fetch supports.
diff --git a/git-clone.sh b/git-clone.sh
index cad5c0c..3a9b09c 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -14,7 +14,7 @@ die() {
 }
 
 usage() {
-	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
+	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] [--submodules] <repo> [<dir>]"
 }
 
 get_repo_base() {
@@ -67,6 +67,60 @@ Perhaps git-update-server-info needs to be run there?"
 	rm -f "$GIT_DIR/REMOTE_HEAD"
 }
 
+local_URL() {
+	# tranforms a "URL" on the remote to a URL that works on the local machine
+	# $1 - remote, $2 - URL on remote
+	case "$1" in
+	https://*|http://*|ftp://*)
+		case "$2" in
+		https://*|http://*|ftp://*)
+			echo $2
+		esac
+		;;
+	ssh://*)
+		case "$2" in
+		https://*|http://*|ftp://*)
+			echo $2
+			;;
+		/*)
+			echo $(echo $1 | sed -e 's/\(ssh:\/\/[^\/]*\)\/.*/\1/')$2
+		esac
+		;;
+	/*)
+		echo $2
+		;;
+	*)
+		case "$2" in
+		https://*|http://*|ftp://*)
+			echo $2
+		esac
+	esac
+}
+
+clone_submodules () {
+	# $1 - remote
+	previous=
+	git-config --remote=$1 --get-regexp 'submodule\..*\.url' | \
+	sed -e 's/^submodule\.//;s/\.url / /' |
+	while read submodule URL
+	do
+		echo "$submodule $URL"
+		if test "$submodule" = "$previous"
+		then
+			continue;
+		fi
+		URL=$(local_URL "$1" "$URL")
+		echo "$submodule $URL"
+		if test -z "$URL"
+		then
+			continue;
+		fi
+		git-clone -n "$URL" "$submodule"
+		git-config "submodule.$submodule.url" "$URL"
+		previous="$submodule"
+	done
+}
+
 quiet=
 local=no
 use_local=no
@@ -81,6 +135,7 @@ origin_override=
 use_separate_remote=t
 depth=
 no_progress=
+submodules=
 test -t 1 || no_progress=--no-progress
 while
 	case "$#,$1" in
@@ -131,6 +186,8 @@ while
 	*,--depth)
 		shift
 		depth="--depth=$1";;
+	*,--su|*,--sub|*,--subm|*,--submo|*,--submod|*,--submodu|*,--submodul|\
+	*,--submodule|*,--submodules) submodules=yes ;;
 	*,-*) usage ;;
 	*) break ;;
 	esac
@@ -149,6 +206,10 @@ then
 	then
 		die '--bare and --origin $origin options are incompatible.'
 	fi
+	if test yes = "$submodules"
+	then
+		die '--bare and --submodules origin options are incompatible.'
+	fi
 	no_checkout=yes
 	use_separate_remote=
 fi
@@ -394,6 +455,11 @@ then
 		git-config branch."$head_points_at".merge "refs/heads/$head_points_at"
 	esac
 
+	if test yes = "$submodules"
+	then
+		clone_submodules "$repo"
+	fi
+
 	case "$no_checkout" in
 	'')
 		test "z$quiet" = z -a "z$no_progress" = z && v=-v || v=
-- 
1.5.2.rc1.25.g889f-dirty

^ permalink raw reply related

* [PATCH] Add dump-config
From: Sven Verdoolaege @ 2007-05-04 10:49 UTC (permalink / raw)
  To: git; +Cc: Sven Verdoolaege
In-Reply-To: <11782757671754-git-send-email-skimo@liacs.nl>

From: Sven Verdoolaege <skimo@kotnet.org>

This command dumps the config of a repository and will be used
to read config options from a remote site.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
 .gitignore                        |    1 +
 Documentation/cmd-list.perl       |    1 +
 Documentation/git-dump-config.txt |   37 +++++++++++++++++++++++++++++++++++++
 Makefile                          |    1 +
 daemon.c                          |    7 +++++++
 dump-config.c                     |   29 +++++++++++++++++++++++++++++
 6 files changed, 76 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/git-dump-config.txt
 create mode 100644 dump-config.c

diff --git a/.gitignore b/.gitignore
index 4dc0c39..d4e5492 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,7 @@ git-diff-files
 git-diff-index
 git-diff-tree
 git-describe
+git-dump-config
 git-fast-import
 git-fetch
 git-fetch--tool
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 443802a..fa04615 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -103,6 +103,7 @@ git-diff-files                          plumbinginterrogators
 git-diff-index                          plumbinginterrogators
 git-diff                                mainporcelain
 git-diff-tree                           plumbinginterrogators
+git-dump-config                         synchelpers
 git-fast-import				ancillarymanipulators
 git-fetch                               mainporcelain
 git-fetch-pack                          synchingrepositories
diff --git a/Documentation/git-dump-config.txt b/Documentation/git-dump-config.txt
new file mode 100644
index 0000000..370781c
--- /dev/null
+++ b/Documentation/git-dump-config.txt
@@ -0,0 +1,37 @@
+git-dump-config(1)
+====================
+
+NAME
+----
+git-dump-config - Dump config options
+
+
+SYNOPSIS
+--------
+'git-dump-config' <directory>
+
+DESCRIPTION
+-----------
+Invoked by 'git-config --remote' and dumps the config file to the
+other end over the git protocol.
+
+This command is usually not invoked directly by the end user.  The UI
+for the protocol is on the 'git-config' side, where it is used to get
+options from a remote repository.
+
+OPTIONS
+-------
+<directory>::
+	The repository to get the config options from.
+
+Author
+------
+Written by Sven Verdoolaege.
+
+Documentation
+--------------
+Documentation by Sven Verdoolaege.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Makefile b/Makefile
index e0a1308..0185386 100644
--- a/Makefile
+++ b/Makefile
@@ -232,6 +232,7 @@ PROGRAMS = \
 	git-fast-import$X \
 	git-merge-base$X \
 	git-daemon$X \
+	git-dump-config$X \
 	git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \
 	git-peek-remote$X git-receive-pack$X \
 	git-send-pack$X git-shell$X \
diff --git a/daemon.c b/daemon.c
index e74ecac..3e5ebf3 100644
--- a/daemon.c
+++ b/daemon.c
@@ -378,10 +378,17 @@ static int receive_pack(void)
 	return -1;
 }
 
+static int dump_config(void)
+{
+	execl_git_cmd("dump-config", ".", NULL);
+	return -1;
+}
+
 static struct daemon_service daemon_service[] = {
 	{ "upload-archive", "uploadarch", upload_archive, 0, 1 },
 	{ "upload-pack", "uploadpack", upload_pack, 1, 1 },
 	{ "receive-pack", "receivepack", receive_pack, 0, 1 },
+	{ "dump-config", "dumpconfig", dump_config, 0, 1 },
 };
 
 static void enable_service(const char *name, int ena) {
diff --git a/dump-config.c b/dump-config.c
new file mode 100644
index 0000000..355920d
--- /dev/null
+++ b/dump-config.c
@@ -0,0 +1,29 @@
+#include "git-compat-util.h"
+#include "cache.h"
+#include "pkt-line.h"
+
+static const char dump_config_usage[] = "git-dump-config <dir>";
+
+static int dump_config(const char *var, const char *value)
+{
+	packet_write(1, "%s", var);
+	packet_write(1, "%s", value);
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+	char *dir;
+
+	if (argc != 2)
+		usage(dump_config_usage);
+
+	dir = argv[1];
+	if (!enter_repo(dir, 0))
+		die("'%s': unable to chdir or not a git archive", dir);
+
+	git_config(dump_config);
+	packet_flush(1);
+
+	return 0;
+}
-- 
1.5.2.rc1.25.g889f-dirty

^ permalink raw reply related

* [PATCH] http.h: make fill_active_slots a function pointer
From: Sven Verdoolaege @ 2007-05-04 10:49 UTC (permalink / raw)
  To: git; +Cc: Sven Verdoolaege
In-Reply-To: <11782757671754-git-send-email-skimo@liacs.nl>

From: Sven Verdoolaege <skimo@kotnet.org>

This allows us to use the methods provided by http.c
from within libgit, in particular config.c.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
 http-fetch.c |    5 ++++-
 http-push.c  |    5 ++++-
 http.h       |    2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/http-fetch.c b/http-fetch.c
index 09baedc..53fb2a9 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -317,7 +317,7 @@ static void release_object_request(struct object_request *obj_req)
 }
 
 #ifdef USE_CURL_MULTI
-void fill_active_slots(void)
+static void fetch_fill_active_slots(void)
 {
 	struct object_request *obj_req = object_queue_head;
 	struct active_request_slot *slot = active_queue_head;
@@ -1031,6 +1031,9 @@ int main(int argc, const char **argv)
 	}
 	url = argv[arg];
 
+#ifdef USE_CURL_MULTI
+	fill_active_slots = fetch_fill_active_slots;
+#endif
 	http_init();
 
 	no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
diff --git a/http-push.c b/http-push.c
index e3f7675..d4c850b 100644
--- a/http-push.c
+++ b/http-push.c
@@ -794,7 +794,7 @@ static void finish_request(struct transfer_request *request)
 }
 
 #ifdef USE_CURL_MULTI
-void fill_active_slots(void)
+static void push_fill_active_slots(void)
 {
 	struct transfer_request *request = request_queue_head;
 	struct transfer_request *next;
@@ -2355,6 +2355,9 @@ int main(int argc, char **argv)
 
 	memset(remote_dir_exists, -1, 256);
 
+#ifdef USE_CURL_MULTI
+	fill_active_slots = push_fill_active_slots;
+#endif
 	http_init();
 
 	no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
diff --git a/http.h b/http.h
index 69b6b66..7a41cde 100644
--- a/http.h
+++ b/http.h
@@ -69,7 +69,7 @@ extern void finish_all_active_slots(void);
 extern void release_active_slot(struct active_request_slot *slot);
 
 #ifdef USE_CURL_MULTI
-extern void fill_active_slots(void);
+extern void (*fill_active_slots)(void);
 extern void step_active_slots(void);
 #endif
 
-- 
1.5.2.rc1.25.g889f-dirty

^ permalink raw reply related


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