* Re: git apply fails to apply a renamed file in a new directory
From: Alex Riesen @ 2007-10-25 21:35 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: git
In-Reply-To: <20071025213038.GC11308@steel.home>
Alex Riesen, Thu, Oct 25, 2007 23:30:38 +0200:
> Sam Ravnborg, Thu, Oct 25, 2007 20:07:37 +0200:
> > I just stumbled on what looks like a simple bug in git apply.
> > I had following diff:
> >
> > diff --git a/arch/i386/defconfig b/arch/x86/configs/i386_defconfig
> > similarity index 100%
> > rename from arch/i386/defconfig
> > rename to arch/x86/configs/i386_defconfig
> > diff --git a/arch/x86_64/defconfig b/arch/x86/configs/x86_64_defconfig
> > similarity index 100%
> > rename from arch/x86_64/defconfig
> > rename to arch/x86/configs/x86_64_defconfig
> > --
> > 1.5.3.4.1157.g0e74-dirty
.1157...-dirty. Your git looks heavily modified. Could you try with a
something like master of kernel.org?
Mine is based off d90a7fda355c251b8ffdd79617fb083c18245ec2
(builtin-fetch got merged).
> > When trying to apply this diff using:
> > git apply -p1 < .../patch
>
> works here. Don't use -p1, it is assumed
>
^ permalink raw reply
* Re: git apply fails to apply a renamed file in a new directory
From: Alex Riesen @ 2007-10-25 21:30 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: git
In-Reply-To: <20071025180737.GA13829@uranus.ravnborg.org>
Sam Ravnborg, Thu, Oct 25, 2007 20:07:37 +0200:
> I just stumbled on what looks like a simple bug in git apply.
> I had following diff:
>
> diff --git a/arch/i386/defconfig b/arch/x86/configs/i386_defconfig
> similarity index 100%
> rename from arch/i386/defconfig
> rename to arch/x86/configs/i386_defconfig
> diff --git a/arch/x86_64/defconfig b/arch/x86/configs/x86_64_defconfig
> similarity index 100%
> rename from arch/x86_64/defconfig
> rename to arch/x86/configs/x86_64_defconfig
> --
> 1.5.3.4.1157.g0e74-dirty
>
> When trying to apply this diff using:
> git apply -p1 < .../patch
works here. Don't use -p1, it is assumed
^ permalink raw reply
* Re: [PATCH] Fix generation of perl/perl.mak
From: Alex Riesen @ 2007-10-25 21:21 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Junio C Hamano
In-Reply-To: <Pine.LNX.4.64.0710252140500.4362@racer.site>
Johannes Schindelin, Thu, Oct 25, 2007 22:42:07 +0200:
> On Thu, 25 Oct 2007, Alex Riesen wrote:
>
> > Besides, a changed Git.pm is *NOT* a reason to rebuild all the perl
> > scripts, so remove the dependency too.
> >
> > [...]
> >
> > -perl/Makefile: perl/Git.pm perl/Makefile.PL GIT-CFLAGS
> > - (cd perl && $(PERL_PATH) Makefile.PL \
> > - PREFIX='$(prefix_SQ)')
> > -
>
> This is not really the dependency triggering a rebuild of all perl
> scripts, right?
In a way. This rebuilds perl/perl.mak which, in turn, can cause the
rebuild of all perl scripts. The rule you replaced with "[...]" does
the same, but uses perl/Makefile, which generates the perl.mak
depending on the NO_PERL_MAKEMAKER setting.
^ permalink raw reply
* Re: [PATCH] Fix generation of perl/perl.mak
From: Johannes Schindelin @ 2007-10-25 20:42 UTC (permalink / raw)
To: Alex Riesen; +Cc: git, Junio C Hamano
In-Reply-To: <20071025201724.GA11308@steel.home>
Hi,
On Thu, 25 Oct 2007, Alex Riesen wrote:
> Besides, a changed Git.pm is *NOT* a reason to rebuild all the perl
> scripts, so remove the dependency too.
>
> [...]
>
> @@ -931,10 +931,6 @@ $(XDIFF_LIB): $(XDIFF_OBJS)
> $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS)
>
>
> -perl/Makefile: perl/Git.pm perl/Makefile.PL GIT-CFLAGS
> - (cd perl && $(PERL_PATH) Makefile.PL \
> - PREFIX='$(prefix_SQ)')
> -
This is not really the dependency triggering a rebuild of all perl
scripts, right?
Ciao,
Dscho
^ permalink raw reply
* Re: recent change in git.git/master broke my repos
From: Andreas Ericsson @ 2007-10-25 20:42 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Karl Hasselström, Randal L. Schwartz, git
In-Reply-To: <alpine.LFD.0.9999.0710251637240.22100@xanadu.home>
Nicolas Pitre wrote:
> On Thu, 25 Oct 2007, Andreas Ericsson wrote:
>
>> Nicolas Pitre wrote:
>>> Isn't that called a remote branch that gets updated with "git fetch' ?
>>> You can even trick Git into not using the refs/remotes/ namespace for them
>>> if you wish.
>>>
>> You'd lose the ability to do "git diff origin/master" while disconnected
>> though. It's quite valuable.
>
> I don't see how you'd lose anything.
>
Sorry, I thought you were talking about a config along the lines of:
fetch = refs/heads/*:refs/heads/*
What other trick are you talking about?
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: recent change in git.git/master broke my repos
From: Nicolas Pitre @ 2007-10-25 20:38 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: Karl Hasselström, Randal L. Schwartz, git
In-Reply-To: <4720FB4E.3030300@op5.se>
On Thu, 25 Oct 2007, Andreas Ericsson wrote:
> Nicolas Pitre wrote:
> > Isn't that called a remote branch that gets updated with "git fetch' ?
> > You can even trick Git into not using the refs/remotes/ namespace for them
> > if you wish.
> >
>
> You'd lose the ability to do "git diff origin/master" while disconnected
> though. It's quite valuable.
I don't see how you'd lose anything.
Nicolas
^ permalink raw reply
* Re: best git practices, was Re: Git User's Survey 2007 unfinishedsummary continued
From: J. Bruce Fields @ 2007-10-25 20:27 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: Federico Mena Quintero, git
In-Reply-To: <4720FA6E.9040805@op5.se>
On Thu, Oct 25, 2007 at 10:19:58PM +0200, Andreas Ericsson wrote:
> Federico Mena Quintero wrote:
>> On Thu, 2007-10-25 at 12:38 -0400, J. Bruce Fields wrote:
>>> Also, there's
>>> the restriction that we'd like to keep it looking good in plain ascii,
>>> so diagrams have to be done in ascii somehow.
>> Hmm, what's the rationale for this? I'd assume that most people read
>> the user's manual as a web page (or as bedside reading if they can print
>> a PDF thereof), where diagrams can be pretty.
>
> man pages.
I think he's talking about Documentation/user-manual.txt, which isn't
turned into man pages. (Might be nice if it could be though, I
suppose.)
--b.
^ permalink raw reply
* Re: [PATCH 5/6] Do linear-time/space rename logic for exact renames
From: Linus Torvalds @ 2007-10-25 20:25 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0710251522190.7345@iabervon.org>
On Thu, 25 Oct 2007, Daniel Barkalow wrote:
>
> Creating a list of the pointers doesn't work correctly with the grow
> implementation, because growing the hash may turn a collision into a
> non-collision, at which point items other than the first cannot be found
> (since they're listed inside a bucket that's now wrong for them). AFAIK,
> resizing a hash table requires being able to figure out what happened with
> collisions.
Nope.
The hash algorithm is much smarter than that.
I *always* uses a full 32-bit hash, and no amount of resizing is ever
going to change that. The index into the hash-table is in fact entirely
unused.
This has several good properties:
- it means that hash-table resizing is a non-event
- it means that you always have the full 32-bit hash, and a collision in
the hash size never causes unnecessary work apart from the fact that
the code walks the hash table a bit more.
- because the hash is embedded in the table itself, it has relatively
good cache behaviour when compared to something that needs to actually
follow the pointer to validate the full data. So assuming that the full
32-bit hash is good enough to effectively never have any collisions
(or, assuming you don't even *care* about the collisions, which is the
case when you're just generating content fingerprints for lines when
comparing the data in two files), you never end up with unnecessarily
following pointers to cachelines that you are not interested in.
The last point at least somewhat mitigates the (inevitably) bad cache
behaviour that hash tables tend to have. It's not like it's going to be
wonderful in the cache, but at least it's less horrid than the more common
implementation that needs to follow the pointer to validate each hash
entry that may or may not be a collision.
but the important part is #1, which is what allows the code to be a
generic hash algorithm that resizes the hash table without even
understanding or caring what is behind the pointer.
Linus
^ permalink raw reply
* Re: recent change in git.git/master broke my repos
From: Andreas Ericsson @ 2007-10-25 20:23 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Karl Hasselström, Randal L. Schwartz, git
In-Reply-To: <alpine.LFD.0.9999.0710251344220.22100@xanadu.home>
Nicolas Pitre wrote:
> On Thu, 25 Oct 2007, Karl Hasselström wrote:
>
>> On 2007-10-25 07:32:36 -0700, Randal L. Schwartz wrote:
>>
>>> And when are we gonna get "fast forward only" for git-merge?
>> I'd like that too. For cases when I know I don't have to do a merge,
>> and want git to yell at me if I'm mistaken. For example, in a
>> repository that tracks an upstream so I can build the latest version,
>> but where I don't normally do any development.
>
> Isn't that called a remote branch that gets updated with "git fetch' ?
> You can even trick Git into not using the refs/remotes/ namespace for
> them if you wish.
>
You'd lose the ability to do "git diff origin/master" while disconnected
though. It's quite valuable.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH 5/6] Do linear-time/space rename logic for exact renames
From: Daniel Barkalow @ 2007-10-25 20:23 UTC (permalink / raw)
To: Jeff King; +Cc: Linus Torvalds, Junio C Hamano, Git Mailing List
In-Reply-To: <20071025194859.GB27745@coredump.intra.peff.net>
On Thu, 25 Oct 2007, Jeff King wrote:
> On Thu, Oct 25, 2007 at 03:43:46PM -0400, Daniel Barkalow wrote:
>
> > Creating a list of the pointers doesn't work correctly with the grow
> > implementation, because growing the hash may turn a collision into a
> > non-collision, at which point items other than the first cannot be found
> > (since they're listed inside a bucket that's now wrong for them). AFAIK,
> > resizing a hash table requires being able to figure out what happened with
> > collisions.
>
> I thought this at first, too, but there are two types of collisions in
> this hash implementation: those that come from having the actual 32-bit
> hash collide, and those that come from not having enough buckets.
>
> The client code gets a pointer kicked back to it when there is a
> collision on the actual hash value (i.e., two things had the exact same
> hash value). The number of buckets grows when you simply have more
> buckets filled than you like. Two different hashes that would be in the
> same bucket don't actually occupy the same bucket -- the second one to
> arrive gets shoved into the next available bucket.
Ah, right, nevermind. The comment might be a bit misleading in that case,
if we both missed this at first.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: best git practices, was Re: Git User's Survey 2007 unfinishedsummary continued
From: Andreas Ericsson @ 2007-10-25 20:19 UTC (permalink / raw)
To: Federico Mena Quintero; +Cc: J. Bruce Fields, git
In-Reply-To: <1193335562.4522.403.camel@cacharro.xalalinux.org>
Federico Mena Quintero wrote:
> On Thu, 2007-10-25 at 12:38 -0400, J. Bruce Fields wrote:
>
>> It's definitely not a simple cut-and-paste--even with permission from
>> the author of "Git for computer scientists", fitting this in would
>> require rethinking the ordering of topics in the manual.
>
> Oh, that can be done. It's easier to move text around than to
> rearchitect code :)
>
It misses the point though. Machines should work while humans are
lounging. If the humans have to read a lot to get the machines to
work, there's less time for lounging ;-)
>> Also, there's
>> the restriction that we'd like to keep it looking good in plain ascii,
>> so diagrams have to be done in ascii somehow.
>
> Hmm, what's the rationale for this? I'd assume that most people read
> the user's manual as a web page (or as bedside reading if they can print
> a PDF thereof), where diagrams can be pretty.
>
man pages.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Andreas Ericsson @ 2007-10-25 20:18 UTC (permalink / raw)
To: Junio C Hamano
Cc: Theodore Tso, Johannes Schindelin, Steffen Prohaska,
Peter Baumann, J. Bruce Fields, Jakub Narebski,
Federico Mena Quintero, git
In-Reply-To: <7vejfj11tk.fsf@gitster.siamese.dyndns.org>
Junio C Hamano wrote:
> Andreas Ericsson <ae@op5.se> writes:
>
>> However, there's still this issue:
>> $ git checkout -b foo origin/pu
>> Branch foo set up to track remote branch refs/remotes/origin/pu.
>> Switched to a new branch "foo"
>>
>> git checkout will say that every time a branch is created from a
>> tracking branch, unless one tells it --no-track (which people don't
>> learn about unless they're really into git), so it's quite natural
>> that people think git will actually make sure, within reasonable
>> limits, that 'foo' is kept in sync with refs/remotes/origin/pu.
>> That's not the case, however.
>>
>> So we could either change the message to be:
>> "Branch foo set up to track remote branch refs/remotes/origin/pu,
>> provided you only ever issue git-pull while having branch foo
>> checked out."
>>
>> Or we could make 'git checkout -b' default to --no-track, perhaps
>> giving annoying messages everytime someone "git-checkout -b"'s a
>> remote tracking branch.
>> Or we could make git-pull keep git checkout's promises.
>
> The thing is, if you have 200 local branches (because you
> interact with 50 repositories with 4 primary branches each), you
> do not constantly check all of them out anyway. And the only
> place that staleness of the local tracking fork matters is when
> you check it out (that is, as long as you train your users that
> the way to check differences with the upstream 'pu' in your case
> is by doing operations with 'origin/pu' not with your local
> 'foo').
>
Probably, although I think the confusion of 'foo' being something
else than 'origin/pu' after it's been checked out would be hard
to explain. I'll see how the patch turns out. If it all goes tits
up, I'll see if a post-checkout hook can solve it.
> With that in mind, how about making "git checkout foo", after
> foo is set up thusly, to show:
>
> git log --pretty=oneline --left-right origin/pu...foo
>
> if (and only if) they have diverged? Then you can deal with the
> staleness of local tracking fork 'foo' in any way you want.
>
> You could even go one step further and make this "checkout foo",
> in addition to or instead of showing the above left-right log,
>
> - automatically run "git merge origin/pu" if it is a
> fast-forward, and say it did _not_ run that merge if it is
> not a fast-forward;
>
> - automatically run "git merge origin/pu" always, even if it is
> not a fast-forward;
>
> - automatically run "git rebase origin/pu" always;
>
> Would that make your life easier?
That it would, except the confusion would then be that it's automatically
rebased for the branches one currently hasn't got checked out while pulling,
and the branch that *is* checked out gets merged (crazy, yes), so those
who prefer the rebase would get what they want by doing something completely
bonkers, such as:
git checkout -b just-gonna-pull HEAD^
git pull
git checkout whatever-other-branch-they-were-on
(yes, "aggresively ignorant", I think Ted said in an earlier mail)
It'd probably be better to go with Dscho's suggestion, although I'm not quite
sure what that was any more. It involved automagical rebasing on fetch or pull
though.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* [PATCH] Fix generation of perl/perl.mak
From: Alex Riesen @ 2007-10-25 20:17 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
The code generating perl/Makefile from Makefile.PL was causing trouble
because it didn't considered NO_PERL_MAKEMAKER and ran makemaker
unconditionally, rewriting perl.mak. Makemaker is FUBAR in ActiveState Perl,
and perl/Makefile has a replacement for it.
Besides, a changed Git.pm is *NOT* a reason to rebuild all the perl scripts,
so remove the dependency too.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
Makefile | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index b728920..72f5ef4 100644
--- a/Makefile
+++ b/Makefile
@@ -812,7 +812,7 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
-perl/perl.mak: GIT-CFLAGS
+perl/perl.mak: GIT-CFLAGS perl/Makefile perl/Makefile.PL
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F)
$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
@@ -931,10 +931,6 @@ $(XDIFF_LIB): $(XDIFF_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS)
-perl/Makefile: perl/Git.pm perl/Makefile.PL GIT-CFLAGS
- (cd perl && $(PERL_PATH) Makefile.PL \
- PREFIX='$(prefix_SQ)')
-
doc:
$(MAKE) -C Documentation all
--
1.5.3.4.403.g401f6
^ permalink raw reply related
* Re: best git practices, was Re: Git User's Survey 2007 unfinishedsummary continued
From: Andreas Ericsson @ 2007-10-25 20:08 UTC (permalink / raw)
To: Federico Mena Quintero; +Cc: Theodore Tso, git
In-Reply-To: <1193335339.4522.398.camel@cacharro.xalalinux.org>
Federico Mena Quintero wrote:
> On Thu, 2007-10-25 at 11:21 -0400, Theodore Tso wrote:
>
>> And of course it's inelegant. You just told us we were dealing with
>> CVS-brain-damaged corporate developers who can't be bothered to learn
>> about the fine points of using things the git way.
>
> Ignore the corporate developers who use SCMs only because their company
> requires them to. Git is not the right thing for them;
Quite contrary to what I think, and quite contrary to what Linus said in
his google speach. The problem with using a chainsaw instead of a tooth-
pick is that it's much easier to hurt yourself with a chainsaw. It's a
lot easier to get real work done though.
> some
> Eclipse-based monstrosity probably is. It's like the horrendous
> Oracle-based expense-reporting thing we have to use at Novell; I use it
> because they make me, not because I'm particularly excited about
> reporting expenses :)
>
Nobody's particularly excited about reporting expenses. That's why there
are so few OSS solutions for it, and the ones that exist suck horribly
because whoever got the job of making the system knew his users would
simply hate it, no matter how perfect it was. It's one of those things ;-)
> However, *do think* of the free software developers who have been using
> CVS forever. You won't make friends among them if you keep saying, "you
> use CVS? You are brain-damaged, then." CVS has been as good/bad to
> them as to anyone else, and they are probably delighted to get a better
> solution. That solution needs to take into account the concepts to
> which they have been exposed for the past N years. Just because your
> new concepts are better, doesn't mean that their old ones were wrong in
> their time.
>
Well, perhaps they were. CVS was a fairly important learning phase, much
like Thomas Edison who first discovered 2000 ways of not making a light-
bulb. It doesn't make them less valuable though, and the reason to keep
going until perfection is reached is that machines are made for work, and
humans are made for fun.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* stgit restrictions on patch names
From: Yann Dirson @ 2007-10-25 19:48 UTC (permalink / raw)
To: Catalin Marinas, Karl Hasselström; +Cc: GIT list
Looks like stgit is now more picky on patch names than in used to be:
$ stg branch --clone v2.0.6-debian
Checking for changes in the working directory ... done
Cloning current branch to "v2.0.6-debian" ...
No log for 01_springelectrical
stg branch: Invalid patch name: "10_g++4.0_build_failures"
$
=> the result of the cloning operation is a partial clone. Do we want to:
- implement a mechanism for checking beforehand that the operation
will not fail ? Seems awkward to duplicate checks already found
elsewhere.
- wait for proper transactions so we can rollback on error ?
- on clone error, delete the newly-created stack ? I'd vote for this
one, until the previous one gets done.
=> is there any particular reason why we would refuse "+" ?
^ permalink raw reply
* Re: Git and Windows
From: Robin Rosenberg @ 2007-10-25 19:54 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Bo Yang, git
In-Reply-To: <Pine.LNX.4.64.0710251517350.25221@racer.site>
torsdag 25 oktober 2007 skrev Johannes Schindelin:
> Hi,
>
> On Thu, 25 Oct 2007, Bo Yang wrote:
>
> > I am a new comer to this list but I have used git for two week
> > development control. I think it is a very cool tool, the only flaw is
> > that I have not found Windows version of it. Does git just aim at Linux
> > kernel development? Is there any plan or in the future to migrate it to
> > windows?
>
> Funny. The first three hits I get from Google are
>
> Wikipedia,
> GitWiki and
> msysgit
>
> The first two pointing to the third. And happily enough, there is a
> Download page at the third site. Oh, and it has a description what its
> affiliation with git is.
The "featured download" is still not the one I'd recommend.
-- robin
^ permalink raw reply
* Re: [PATCH 5/6] Do linear-time/space rename logic for exact renames
From: Jeff King @ 2007-10-25 19:48 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Linus Torvalds, Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0710251522190.7345@iabervon.org>
On Thu, Oct 25, 2007 at 03:43:46PM -0400, Daniel Barkalow wrote:
> Creating a list of the pointers doesn't work correctly with the grow
> implementation, because growing the hash may turn a collision into a
> non-collision, at which point items other than the first cannot be found
> (since they're listed inside a bucket that's now wrong for them). AFAIK,
> resizing a hash table requires being able to figure out what happened with
> collisions.
I thought this at first, too, but there are two types of collisions in
this hash implementation: those that come from having the actual 32-bit
hash collide, and those that come from not having enough buckets.
The client code gets a pointer kicked back to it when there is a
collision on the actual hash value (i.e., two things had the exact same
hash value). The number of buckets grows when you simply have more
buckets filled than you like. Two different hashes that would be in the
same bucket don't actually occupy the same bucket -- the second one to
arrive gets shoved into the next available bucket.
-Peff
^ permalink raw reply
* Re: [PATCH] git-cvsimport: Add -N option to force a new import
From: Robin Rosenberg @ 2007-10-25 19:45 UTC (permalink / raw)
To: Matt McCutchen; +Cc: Junio C Hamano, git
In-Reply-To: <1193284913.2619.23.camel@mattlaptop2>
torsdag 25 oktober 2007 skrev Matt McCutchen:
> On Wed, 2007-10-24 at 20:17 -0700, Junio C Hamano wrote:
> > Matt McCutchen <matt@mattmccutchen.net> writes:
> >
> > > I had a git repository for development of rsync and wanted to start
> > > importing the upstream CVS with git-cvsimport, but git-cvsimport saw
> > > that the git repository existed and insisted on updating a previous
> > > import. This patch adds an -N option to git-cvsimport to force a new
> > > import and updates the documentation appropriately.
> >
> > Sounds like a useful addition. Tests?
>
> Are there existing tests for git-cvsimport somewhere whose example I
> could follow? (I didn't see any in t/ .) If not, I suppose I will just
> write a simple script that runs git-cvsimport with and without -N and
> with and without an existing, empty git repository and checks that the
> right things happen.
None, but there should be. I also think cvsps should be included in the git
repo since it is required and AFAIK, only git people maintain it.
Now I don't use cvsimport to import my CVS repos, so I'll pass on adding test
cases. It is a non-trivial task
I did it for cvsexportcommit which didn't have any tests when I started
hacking it.
-- robin
^ permalink raw reply
* Re: [PATCH 5/6] Do linear-time/space rename logic for exact renames
From: Daniel Barkalow @ 2007-10-25 19:43 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <alpine.LFD.0.999.0710251120590.30120@woody.linux-foundation.org>
> +/*
> + * Insert a new hash entry pointer into the table.
> + *
> + * If that hash entry already existed, return the pointer to
> + * the existing entry (and the caller can create a list of the
> + * pointers or do anything else). If it didn't exist, return
> + * NULL (and the caller knows the pointer has been inserted).
> + */
Creating a list of the pointers doesn't work correctly with the grow
implementation, because growing the hash may turn a collision into a
non-collision, at which point items other than the first cannot be found
(since they're listed inside a bucket that's now wrong for them). AFAIK,
resizing a hash table requires being able to figure out what happened with
collisions.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: [PATCH 0/6] Cleaned-up rename detection patch-series
From: Jeff King @ 2007-10-25 19:08 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <alpine.LFD.0.999.0710251112120.30120@woody.linux-foundation.org>
On Thu, Oct 25, 2007 at 11:15:16AM -0700, Linus Torvalds wrote:
> Ok, here's the patch-series to do rename detection of exact renames in
> linear time, except it's cleaned up into a nice series of 6 patches. The
> end result is identical to the previous patches (which got smushed down
> into just two patches in Junio's tree), apart from a fixed dependency in
> the Makefile that caused me grief and a broken test-suite due to some
> object files simply not being correctly recompiled.
Thanks, I have been basing my inexact rename work off of your messy
patches, so I will rebase onto this.
Sorry I am lagging behind on getting that work out, but I hope to have
something to show soon.
-Peff
^ permalink raw reply
* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Carl Worth @ 2007-10-25 19:04 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Federico Mena Quintero, Andreas Ericsson, git
In-Reply-To: <Pine.LNX.4.64.0710230017120.25221@racer.site>
[-- Attachment #1: Type: text/plain, Size: 791 bytes --]
On Tue, 23 Oct 2007 00:21:03 +0100 (BST), Johannes Schindelin wrote:
> On Mon, 22 Oct 2007, Federico Mena Quintero wrote:
> >
> > The "branches should not track their origin by default"
Did this change recently? I just wrote a long message arguing for the
"autosetupmerge = 1" behavior by default, but when I tested with
1.5.3.4 it seems to be there already.
Am I seeing that correctly?
If so, thank you and congratulations! Not having to pass --track nor
manually configure autosetupmerge to get this very useful behavior is
a very nice change!
A nice followup would be to improve the documentation for "git pull"
to better indicate some of the smarts that are now inherent in it.
I'll take a whack at that, (just as soon as I finish reading the rest
of this giant thread...).
-Carl
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 0/6] Cleaned-up rename detection patch-series
From: Linus Torvalds @ 2007-10-25 18:37 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <alpine.LFD.0.999.0710251112120.30120@woody.linux-foundation.org>
Final notes:
- all of these were done on top of the current 'master' branch. Not that
it likely matters much, but I thought I'd mention it in case there are
conflicts with anything currently cooking in 'next'. I didn't even
check.
- The commits depend on each other, but apart from the ordering, they all
stand on their own. They pass the test-suite at all stages.
- In particular, the first four commits are cleanups and infrastructure
that really is totally independent of the last two. I'd argue that the
first one (the dependency fix) could/should be merged into stable, and
the next three can probably be merged more aggressively than the last
two.
- I *think* this series is good to go. I've used the new rename detection
code in my own "production" environment (ie the kernel) since sending
it out, and the end result of all these patches is identical - apart
from the the dependency fix - to what I've been running for the last
week. But maybe it makes more sense to merge the first four into
'next', and leave the last two in 'pu', for example (or 'master' and
'next' respectively, depending on how comfy people are with the
patches).
Splitting the thing up definitely makes the series more readable, and
maybe that means that somebody will actually comment on it. I don't think
I got any comments on the original series once I fixed the stupid bugs.
Hopefully the cleaner series is more amenable to people reviewing it.
Linus
^ permalink raw reply
* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Junio C Hamano @ 2007-10-25 18:33 UTC (permalink / raw)
To: Andreas Ericsson
Cc: Theodore Tso, Johannes Schindelin, Steffen Prohaska,
Peter Baumann, J. Bruce Fields, Jakub Narebski,
Federico Mena Quintero, git
In-Reply-To: <4720CCE0.2090007@op5.se>
Andreas Ericsson <ae@op5.se> writes:
> However, there's still this issue:
> $ git checkout -b foo origin/pu
> Branch foo set up to track remote branch refs/remotes/origin/pu.
> Switched to a new branch "foo"
>
> git checkout will say that every time a branch is created from a
> tracking branch, unless one tells it --no-track (which people don't
> learn about unless they're really into git), so it's quite natural
> that people think git will actually make sure, within reasonable
> limits, that 'foo' is kept in sync with refs/remotes/origin/pu.
> That's not the case, however.
>
> So we could either change the message to be:
> "Branch foo set up to track remote branch refs/remotes/origin/pu,
> provided you only ever issue git-pull while having branch foo
> checked out."
>
> Or we could make 'git checkout -b' default to --no-track, perhaps
> giving annoying messages everytime someone "git-checkout -b"'s a
> remote tracking branch.
> Or we could make git-pull keep git checkout's promises.
The thing is, if you have 200 local branches (because you
interact with 50 repositories with 4 primary branches each), you
do not constantly check all of them out anyway. And the only
place that staleness of the local tracking fork matters is when
you check it out (that is, as long as you train your users that
the way to check differences with the upstream 'pu' in your case
is by doing operations with 'origin/pu' not with your local
'foo').
With that in mind, how about making "git checkout foo", after
foo is set up thusly, to show:
git log --pretty=oneline --left-right origin/pu...foo
if (and only if) they have diverged? Then you can deal with the
staleness of local tracking fork 'foo' in any way you want.
You could even go one step further and make this "checkout foo",
in addition to or instead of showing the above left-right log,
- automatically run "git merge origin/pu" if it is a
fast-forward, and say it did _not_ run that merge if it is
not a fast-forward;
- automatically run "git merge origin/pu" always, even if it is
not a fast-forward;
- automatically run "git rebase origin/pu" always;
Would that make your life easier?
^ permalink raw reply
* Re: recent change in git.git/master broke my repos
From: Randal L. Schwartz @ 2007-10-25 18:29 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Karl Hasselström, git
In-Reply-To: <alpine.LFD.0.9999.0710251344220.22100@xanadu.home>
>>>>> "Nicolas" == Nicolas Pitre <nico@cam.org> writes:
Nicolas> Isn't that called a remote branch that gets updated with "git fetch' ?
Nicolas> You can even trick Git into not using the refs/remotes/ namespace for
Nicolas> them if you wish.
No. I have a local master, and I want to be able to blindly say
"git-merge" on that master when doing so is only a fast forward.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
^ permalink raw reply
* [PATCH 5/6] Do linear-time/space rename logic for exact renames
From: Linus Torvalds @ 2007-10-25 18:23 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <alpine.LFD.0.999.0710251112120.30120@woody.linux-foundation.org>
From: Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 5/6] Do linear-time/space rename logic for exact renames
This implements a smarter rename detector for exact renames, which
rather than doing a pairwise comparison (time O(m*n)) will just hash the
files into a hash-table (size O(n+m)), and only do pairwise comparisons
to renames that have the same hash (time O(n+m) except for unrealistic
hash collissions, which we just cull aggressively).
Admittedly the exact rename case is not nearly as interesting as the
generic case, but it's an important case none-the-less.A similar general
approach should work for the generic case too, but even then you do need
to handle the exact renames/copies separately (to avoid the inevitable
added cost factor that comes from the _size_ of the file), so this is
worth doing.
In the expectation that we will indeed do the same hashing trick for the
general rename case, this code uses a generic hash-table implementation
that can be used for other things too. In fact, we might be able to
consolidate some of our existing hash tables with the new generic code
in hash.[ch].
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
This is obviously the actual meat of the new exact rename detection:
everything else was just leading up to this.
I could have split out "hash.[ch]" as a separate patch just to introduce
the infrastructure, but I hate patches that add code that isn't used at
all. But hash.[ch] really is potentially independently useful, and has
nothing that is specific to the rename detection per se in it.
Makefile | 4 +-
diffcore-rename.c | 211 +++++++++++++++++++++++++++++++++++++----------------
hash.c | 110 +++++++++++++++++++++++++++
hash.h | 43 +++++++++++
4 files changed, 303 insertions(+), 65 deletions(-)
create mode 100644 hash.c
create mode 100644 hash.h
diff --git a/Makefile b/Makefile
index 8a0082d..845f811 100644
--- a/Makefile
+++ b/Makefile
@@ -290,7 +290,7 @@ LIB_H = \
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h \
- mailmap.h remote.h transport.h diffcore.h
+ mailmap.h remote.h transport.h diffcore.h hash.h
DIFF_OBJS = \
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@ -300,7 +300,7 @@ DIFF_OBJS = \
LIB_OBJS = \
blob.o commit.o connect.o csum-file.o cache-tree.o base85.o \
date.o diff-delta.o entry.o exec_cmd.o ident.o \
- interpolate.o \
+ interpolate.o hash.o \
lockfile.o \
patch-ids.o \
object.o pack-check.o pack-write.o patch-delta.o path.o pkt-line.o \
diff --git a/diffcore-rename.c b/diffcore-rename.c
index edb2424..e7e370b 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -4,6 +4,7 @@
#include "cache.h"
#include "diff.h"
#include "diffcore.h"
+#include "hash.h"
/* Table of rename/copy destinations */
@@ -93,29 +94,6 @@ static struct diff_rename_src *register_rename_src(struct diff_filespec *one,
return &(rename_src[first]);
}
-static int is_exact_match(struct diff_filespec *src,
- struct diff_filespec *dst,
- int contents_too)
-{
- if (src->sha1_valid && dst->sha1_valid &&
- !hashcmp(src->sha1, dst->sha1))
- return 1;
- if (!contents_too)
- return 0;
- if (diff_populate_filespec(src, 1) || diff_populate_filespec(dst, 1))
- return 0;
- if (src->size != dst->size)
- return 0;
- if (src->sha1_valid && dst->sha1_valid)
- return !hashcmp(src->sha1, dst->sha1);
- if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
- return 0;
- if (src->size == dst->size &&
- !memcmp(src->data, dst->data, src->size))
- return 1;
- return 0;
-}
-
static int basename_same(struct diff_filespec *src, struct diff_filespec *dst)
{
int src_len = strlen(src->path), dst_len = strlen(dst->path);
@@ -242,56 +220,163 @@ static int score_compare(const void *a_, const void *b_)
return b->score - a->score;
}
+struct file_similarity {
+ int src_dst, index;
+ struct diff_filespec *filespec;
+ struct file_similarity *next;
+};
+
+static int find_identical_files(struct file_similarity *src,
+ struct file_similarity *dst)
+{
+ int renames = 0;
+
+ /*
+ * Walk over all the destinations ...
+ */
+ do {
+ struct diff_filespec *one = dst->filespec;
+ struct file_similarity *p, *best;
+ int i = 100;
+
+ /*
+ * .. to find the best source match
+ */
+ best = NULL;
+ for (p = src; p; p = p->next) {
+ struct diff_filespec *two = p->filespec;
+
+ /* False hash collission? */
+ if (hashcmp(one->sha1, two->sha1))
+ continue;
+ /* Non-regular files? If so, the modes must match! */
+ if (!S_ISREG(one->mode) || !S_ISREG(two->mode)) {
+ if (one->mode != two->mode)
+ continue;
+ }
+ best = p;
+ if (basename_same(one, two))
+ break;
+
+ /* Too many identical alternatives? Pick one */
+ if (!--i)
+ break;
+ }
+ if (best) {
+ record_rename_pair(dst->index, best->index, MAX_SCORE);
+ renames++;
+ }
+ } while ((dst = dst->next) != NULL);
+ return renames;
+}
+
+/*
+ * Note: the rest of the rename logic depends on this
+ * phase also populating all the filespecs for any
+ * entry that isn't matched up with an exact rename.
+ */
+static void free_similarity_list(struct file_similarity *p)
+{
+ while (p) {
+ struct file_similarity *entry = p;
+ p = p->next;
+
+ /* Stupid special case, see note above! */
+ diff_populate_filespec(entry->filespec, 0);
+ free(entry);
+ }
+}
+
+static int find_same_files(void *ptr)
+{
+ int ret;
+ struct file_similarity *p = ptr;
+ struct file_similarity *src = NULL, *dst = NULL;
+
+ /* Split the hash list up into sources and destinations */
+ do {
+ struct file_similarity *entry = p;
+ p = p->next;
+ if (entry->src_dst < 0) {
+ entry->next = src;
+ src = entry;
+ } else {
+ entry->next = dst;
+ dst = entry;
+ }
+ } while (p);
+
+ /*
+ * If we have both sources *and* destinations, see if
+ * we can match them up
+ */
+ ret = (src && dst) ? find_identical_files(src, dst) : 0;
+
+ /* Free the hashes and return the number of renames found */
+ free_similarity_list(src);
+ free_similarity_list(dst);
+ return ret;
+}
+
+static unsigned int hash_filespec(struct diff_filespec *filespec)
+{
+ unsigned int hash;
+ if (!filespec->sha1_valid) {
+ if (diff_populate_filespec(filespec, 0))
+ return 0;
+ hash_sha1_file(filespec->data, filespec->size, "blob", filespec->sha1);
+ }
+ memcpy(&hash, filespec->sha1, sizeof(hash));
+ return hash;
+}
+
+static void insert_file_table(struct hash_table *table, int src_dst, int index, struct diff_filespec *filespec)
+{
+ void **pos;
+ unsigned int hash;
+ struct file_similarity *entry = xmalloc(sizeof(*entry));
+
+ entry->src_dst = src_dst;
+ entry->index = index;
+ entry->filespec = filespec;
+ entry->next = NULL;
+
+ hash = hash_filespec(filespec);
+ pos = insert_hash(hash, entry, table);
+
+ /* We already had an entry there? */
+ if (pos) {
+ entry->next = *pos;
+ *pos = entry;
+ }
+}
+
/*
* Find exact renames first.
*
* The first round matches up the up-to-date entries,
* and then during the second round we try to match
* cache-dirty entries as well.
- *
- * Note: the rest of the rename logic depends on this
- * phase also populating all the filespecs for any
- * entry that isn't matched up with an exact rename,
- * see "is_exact_match()".
*/
static int find_exact_renames(void)
{
- int rename_count = 0;
- int contents_too;
-
- for (contents_too = 0; contents_too < 2; contents_too++) {
- int i;
-
- for (i = 0; i < rename_dst_nr; i++) {
- struct diff_filespec *two = rename_dst[i].two;
- int j;
-
- if (rename_dst[i].pair)
- continue; /* dealt with an earlier round */
- for (j = 0; j < rename_src_nr; j++) {
- int k;
- struct diff_filespec *one = rename_src[j].one;
- if (!is_exact_match(one, two, contents_too))
- continue;
+ int i;
+ struct hash_table file_table;
- /* see if there is a basename match, too */
- for (k = j; k < rename_src_nr; k++) {
- one = rename_src[k].one;
- if (basename_same(one, two) &&
- is_exact_match(one, two,
- contents_too)) {
- j = k;
- break;
- }
- }
-
- record_rename_pair(i, j, (int)MAX_SCORE);
- rename_count++;
- break; /* we are done with this entry */
- }
- }
- }
- return rename_count;
+ init_hash(&file_table);
+ for (i = 0; i < rename_src_nr; i++)
+ insert_file_table(&file_table, -1, i, rename_src[i].one);
+
+ for (i = 0; i < rename_dst_nr; i++)
+ insert_file_table(&file_table, 1, i, rename_dst[i].two);
+
+ /* Find the renames */
+ i = for_each_hash(&file_table, find_same_files);
+
+ /* .. and free the hash data structure */
+ free_hash(&file_table);
+
+ return i;
}
void diffcore_rename(struct diff_options *options)
diff --git a/hash.c b/hash.c
new file mode 100644
index 0000000..7b492d4
--- /dev/null
+++ b/hash.c
@@ -0,0 +1,110 @@
+/*
+ * Some generic hashing helpers.
+ */
+#include "cache.h"
+#include "hash.h"
+
+/*
+ * Look up a hash entry in the hash table. Return the pointer to
+ * the existing entry, or the empty slot if none existed. The caller
+ * can then look at the (*ptr) to see whether it existed or not.
+ */
+static struct hash_table_entry *lookup_hash_entry(unsigned int hash, struct hash_table *table)
+{
+ unsigned int size = table->size, nr = hash % size;
+ struct hash_table_entry *array = table->array;
+
+ while (array[nr].ptr) {
+ if (array[nr].hash == hash)
+ break;
+ nr++;
+ if (nr >= size)
+ nr = 0;
+ }
+ return array + nr;
+}
+
+
+/*
+ * Insert a new hash entry pointer into the table.
+ *
+ * If that hash entry already existed, return the pointer to
+ * the existing entry (and the caller can create a list of the
+ * pointers or do anything else). If it didn't exist, return
+ * NULL (and the caller knows the pointer has been inserted).
+ */
+static void **insert_hash_entry(unsigned int hash, void *ptr, struct hash_table *table)
+{
+ struct hash_table_entry *entry = lookup_hash_entry(hash, table);
+
+ if (!entry->ptr) {
+ entry->ptr = ptr;
+ entry->hash = hash;
+ table->nr++;
+ return NULL;
+ }
+ return &entry->ptr;
+}
+
+static void grow_hash_table(struct hash_table *table)
+{
+ unsigned int i;
+ unsigned int old_size = table->size, new_size;
+ struct hash_table_entry *old_array = table->array, *new_array;
+
+ new_size = alloc_nr(old_size);
+ new_array = xcalloc(sizeof(struct hash_table_entry), new_size);
+ table->size = new_size;
+ table->array = new_array;
+ table->nr = 0;
+ for (i = 0; i < old_size; i++) {
+ unsigned int hash = old_array[i].hash;
+ void *ptr = old_array[i].ptr;
+ if (ptr)
+ insert_hash_entry(hash, ptr, table);
+ }
+ free(old_array);
+}
+
+void *lookup_hash(unsigned int hash, struct hash_table *table)
+{
+ if (!table->array)
+ return NULL;
+ return &lookup_hash_entry(hash, table)->ptr;
+}
+
+void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table)
+{
+ unsigned int nr = table->nr;
+ if (nr >= table->size/2)
+ grow_hash_table(table);
+ return insert_hash_entry(hash, ptr, table);
+}
+
+int for_each_hash(struct hash_table *table, int (*fn)(void *))
+{
+ int sum = 0;
+ unsigned int i;
+ unsigned int size = table->size;
+ struct hash_table_entry *array = table->array;
+
+ for (i = 0; i < size; i++) {
+ void *ptr = array->ptr;
+ array++;
+ if (ptr) {
+ int val = fn(ptr);
+ if (val < 0)
+ return val;
+ sum += val;
+ }
+ }
+ return sum;
+}
+
+void free_hash(struct hash_table *table)
+{
+ free(table->array);
+ table->array = NULL;
+ table->size = 0;
+ table->nr = 0;
+}
diff --git a/hash.h b/hash.h
new file mode 100644
index 0000000..a8b0fbb
--- /dev/null
+++ b/hash.h
@@ -0,0 +1,43 @@
+#ifndef HASH_H
+#define HASH_H
+
+/*
+ * These are some simple generic hash table helper functions.
+ * Not necessarily suitable for all users, but good for things
+ * where you want to just keep track of a list of things, and
+ * have a good hash to use on them.
+ *
+ * It keeps the hash table at roughly 50-75% free, so the memory
+ * cost of the hash table itself is roughly
+ *
+ * 3 * 2*sizeof(void *) * nr_of_objects
+ *
+ * bytes.
+ *
+ * FIXME: on 64-bit architectures, we waste memory. It would be
+ * good to have just 32-bit pointers, requiring a special allocator
+ * for hashed entries or something.
+ */
+struct hash_table_entry {
+ unsigned int hash;
+ void *ptr;
+};
+
+struct hash_table {
+ unsigned int size, nr;
+ struct hash_table_entry *array;
+};
+
+extern void *lookup_hash(unsigned int hash, struct hash_table *table);
+extern void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table);
+extern int for_each_hash(struct hash_table *table, int (*fn)(void *));
+extern void free_hash(struct hash_table *table);
+
+static inline void init_hash(struct hash_table *table)
+{
+ table->size = 0;
+ table->nr = 0;
+ table->array = NULL;
+}
+
+#endif
--
1.5.3.4.330.g1dec6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox