Git development
 help / color / mirror / Atom feed
* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Linus Torvalds @ 2006-03-01 18:25 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: Andreas Ericsson, Eric Wong, Martin Langhoff, git
In-Reply-To: <200603011906.33433.Josef.Weidendorfer@gmx.de>



On Wed, 1 Mar 2006, Josef Weidendorfer wrote:
>
> On Wednesday 01 March 2006 18:40, Linus Torvalds wrote:
> > But if somebody does the get_sha1() magic, and Junio agrees, then I think 
> > it would be a great thing to do.
> 
> Yes.
> 
> 	git log origin/master..
> 
> is really not that bad

It really is.

Think like a user. If I pull from "origin", then the name of that thing is 
"origin", not "origin/master" or "o/master". A user doesn't care what the 
remote branch name is - the whole _point_ of the .git/remotes/xyzzy file 
is to give a short description that includes the names of the branches you 
pull from.

The good news is that "get_sha1()" shouldn't be that hard to extend on. 
Just add a case at the end that says "do we have a .git/remotes/%s file, 
and if so, parse it".

				Linus

^ permalink raw reply

* [PATCH] git-mv: fixes for path handling
From: Josef Weidendorfer @ 2006-03-01 18:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Moving a directory ending in a slash was not working as the
destination was not calculated correctly.
E.g. in the git repo,

 git-mv t/ Documentation

gave the error

 Error: destination 'Documentation' already exists

To get rid of this problem, strip trailing slashes from all arguments.
The comment in cg-mv made me curious about this issue; Pasky, thanks!
As result, the workaround in cg-mv is not needed any more.

Also, another bug was shown by cg-mv. When moving files outside of
a subdirectory, it typically calls git-mv with something like

 git-mv Documentation/git.txt Documentation/../git-mv.txt

which triggers the following error from git-update-index:

 Ignoring path Documentation/../git-mv.txt

The result is a moved file, removed from git revisioning, but not
added again. To fix this, the paths have to be normalized not have ".."
in the middle. This was already done in git-mv, but only for
a better visual appearance :(

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>

---

 git-mv.perl |   24 +++++++++++++-----------
 1 files changed, 13 insertions(+), 11 deletions(-)

15d94ce0807c1d99d10f6c3ddd32963b1ac0fece
diff --git a/git-mv.perl b/git-mv.perl
index 8cd95c4..9b43dcc 100755
--- a/git-mv.perl
+++ b/git-mv.perl
@@ -31,11 +31,12 @@ chomp($GIT_DIR);
 my (@srcArgs, @dstArgs, @srcs, @dsts);
 my ($src, $dst, $base, $dstDir);
 
+# remove any trailing slash in arguments
+for (@ARGV) { s/\/*$//; }
+
 my $argCount = scalar @ARGV;
 if (-d $ARGV[$argCount-1]) {
 	$dstDir = $ARGV[$argCount-1];
-	# remove any trailing slash
-	$dstDir =~ s/\/$//;
 	@srcArgs = @ARGV[0..$argCount-2];
 	
 	foreach $src (@srcArgs) {
@@ -61,6 +62,16 @@ else {
     $dstDir = "";
 }
 
+# normalize paths, needed to compare against versioned files and update-index
+# also, this is nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c"
+for (@srcArgs, @dstArgs) {
+    s|^\./||;
+    s|/\./|/| while (m|/\./|);
+    s|//+|/|g;
+    # Also "a/b/../c" ==> "a/c"
+    1 while (s,(^|/)[^/]+/\.\./,$1,);
+}
+
 my (@allfiles,@srcfiles,@dstfiles);
 my $safesrc;
 my (%overwritten, %srcForDst);
@@ -79,15 +90,6 @@ while(scalar @srcArgs > 0) {
     $dst = shift @dstArgs;
     $bad = "";
 
-    for ($src, $dst) {
-	# Be nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c"
-	s|^\./||;
-	s|/\./|/| while (m|/\./|);
-	s|//+|/|g;
-	# Also "a/b/../c" ==> "a/c"
-	1 while (s,(^|/)[^/]+/\.\./,$1,);
-    }
-
     if ($opt_v) {
 	print "Checking rename of '$src' to '$dst'\n";
     }
-- 
1.2.0.g719b

^ permalink raw reply related

* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Josef Weidendorfer @ 2006-03-01 18:06 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andreas Ericsson, Eric Wong, Martin Langhoff, git
In-Reply-To: <Pine.LNX.4.64.0603010935201.22647@g5.osdl.org>

On Wednesday 01 March 2006 18:40, Linus Torvalds wrote:
> But if somebody does the get_sha1() magic, and Junio agrees, then I think 
> it would be a great thing to do.

Yes.

	git log origin/master..

is really not that bad. And if somebody complains about typing, git-clone
could get an option "--remote-name=o" to allow for

	git log o/master..

Josef

^ permalink raw reply

* Re: impure renames / history tracking
From: Martin Langhoff @ 2006-03-01 18:05 UTC (permalink / raw)
  To: paul; +Cc: Andreas Ericsson, git list
In-Reply-To: <Pine.LNX.4.64.0603011558390.13612@sheen.jakma.org>

On 3/2/06, Paul Jakma <paul@clubi.ie> wrote:
> I mean:
>
>         $ git checkout project
>         $ git pull . master
>         $ git checkout -b tmp project
>         $ git diff project..master | <git apply I think>

The moment you 'merge' by using git-diff | patch you lose all the
support git gives you, because you are discarding all of git's
metadata! git's metadata is about all the commits you are merging, and
is good enough that it will help future merges across renames.

You should really use git-pull/git-merge at that point.

My guess is that you do this to achieve what you describe later:

> Presume that 'project' in the workflow is defined as
>
>         "achieve one goal with one commit to the master"
>
> So by definition, it always correct that the project only ever has
> one commit.

What happens if you rephrase that to read: "achieve one goal with one
merge to the master"? Long term, it gives you much better support from
the SCM. If a particular commit broke something, you can use
whatchanged, log, annotate and bisect to figure out in which /small/
commit things went astray.

And you can modify your practices ever so slightly to match the
benefits of the old model:

 - force merge message editing in git-merge, and prepare appropriate
commit messages for your merges
 - write a modified git-log that displays only the merges to master

that way, you get the best of both worlds.

> The trouble is that /sometimes/ projects do indeed 'rename and
> rewrite' a file. At present, chances are git might not notice this,

It will, if you preserve git's metadata.

The thing is that with any scm that tracks metadata of some kind, the
moment you bypass its tools and do diff|patch to discard the
metadata... well, you lose its benefits...

And what I've found, managing a project with 13K files, is that in
practice git does far better tracking renames than several SCMs that
do explicit tracking. Don't be distracted by the 'we don't track
renames posturing'. We do, and it's so magic that it just works.

cheers,



^ permalink raw reply

* Re: [PATCH] Teach git-checkout-index to read filenames from stdin.
From: Shawn Pearce @ 2006-03-01 17:56 UTC (permalink / raw)
  To: Christopher Faylor; +Cc: git
In-Reply-To: <20060301155053.GC1010@trixie.casa.cgf.cx>

Christopher Faylor <me@cgf.cx> wrote:
> AFAIK, the length of the command line for cygwin apps is very large --
> if you're using recent versions of Cygwin.  I believe that it is longer
> than the linux default.  We bypass the Windows mechanism for setting the
> command line when a cygwin program starts a cygwin program.
> 
> For native Windows programs, the command line length is ~32K but I don't
> think that git uses any native Windows programs, does it?

No.  Currently GIT is entirely dependent on Cygwin.  So GIT
wouldn't bump into the ~32K limit due to the cygwin-cygwin feature
you mention.  But thanks for the information.  I had thought I had
read somewhere in the Cygwin documentation that the command line
length was rather limited (even under cygwin-cygwin calls).  Maybe
I was just seeing things.  :-)

But even if we can get a long set of args into git-checkout-index its
probably still better to stream them as you can get both programs
working at the same time (rather than waiting for xargs to build
the argument buffer) and you are saving yourself at least one fork
as you don't need to start xargs just to feed git-checkout-index.
Even on Linux where fork is cheap, that's still soemething saved.

-- 
Shawn.

^ permalink raw reply

* Re: bug?: stgit creates (unneccessary?) conflicts when pulling
From: Catalin Marinas @ 2006-03-01 17:53 UTC (permalink / raw)
  To: cel; +Cc: Karl Hasselström, git
In-Reply-To: <4405DC41.8020700@citi.umich.edu>

On 01/03/06, Chuck Lever <cel@citi.umich.edu> wrote:
> Catalin Marinas wrote:
> > I attached another patch that should work properly. It also pushes
> > empty patches on the stack if they were merged upstream (a 'stg clean'
> > is required to remove them). This is useful for the push --undo
> > command if you are not happy with the result.
>
> if maintainer X takes a patch "a" from developer Y, but modifies patch
> "a" before committing it, then your nifty automated mechanism will still
> have trouble merging developer Y's stack when Y pulls again.
>
> the convention might be that maintainers who accept patches will always
> accept exactly what was sent, and then immediately apply another commit
> that addresses any issues they have with the original commit.

This won't solve the problem since testing whether patch "a" was
merged upstream will fail because its reverse won't apply cleanly onto
the upstream HEAD. Of course, you can try combination of upstream
commits and local patches but it's not really feasible.

As I said, this method doesn't solve all the upstream merge situations
but it is OK for most of them.

--
Catalin

^ permalink raw reply

* Re: impure renames / history tracking
From: Andreas Ericsson @ 2006-03-01 17:43 UTC (permalink / raw)
  To: Paul Jakma; +Cc: git list
In-Reply-To: <Pine.LNX.4.64.0603011558390.13612@sheen.jakma.org>

Paul Jakma wrote:
> On Wed, 1 Mar 2006, Andreas Ericsson wrote:
> 
>>> o: commit
>>> m: merge
>>>
>>>    o---o-m--o-o-o--o----m <- project
>>>   /     /              /
>>> o-o-o-o-o--o-o-o--o-o-o <- main branch
>>>
>>> The project merge back to main in one 'big' combined merge 
>>> (collapsing all of the commits on 'project' into one commit). This 
>>> leads to 'impure renames' being not uncommon. The desired end-result 
>>> of merging back to 'main' being to rebase 'project' as one commit 
>>> against 'main', and merge that single commit back, a la:
>>>
>>>    o---o-m--o-o-o--o----m <- project
>>>   /     /              /
>>> o-o-o-o-o--o-o-o--o-o-o---m <- main branch
>>>                        \ /
>>>                         o <- project_collapsed
>>>
>>> So that 'm' on 'main' is that one commit[1].
> 
> 
>> I think you're misunderstanding the git meaning of rebase here. "git 
>> rebase" moves all commits since "project" forked from "main branch" to 
>> the tip of "main branch".
> 
> 
> Right, I'm referring to 'rebase' generally, as a concept, not to 
> git-rebase specifically. E.g. git diff main..project is another way of 
> rebasing I think.
> 

Yes, but imo a poor one, as you're losing all the history. git *can* do 
what you want, but it was designed to maintain a long history so that 
everyone can see it and improve on the code with many chains of small 
and simultanous changes.


>> Other than that, this is the recommended workflow, and exactly how 
>> Linux and git both are managed (i.e. topic branches eventually merged 
>> into 'master').
> 
> 
> They're not rebased though, generally. They're pulled. Ie, in Linux and 
> git when 'project' is merged, things look like:
> 
>     o---o-m--o-o-o--o----m   <- project
>    /     /              / \
> o-o-o-o-o--o-o-o--o-o-o----m <- main branch
> 
> The rest of the world sees /all/ the individual commits of 'project' 
> right? The traditional process for the case I'm thinking of results in 
> the 'main' tree seeing only /one/ single commit for the project.
> 

Perhpas we have a nomenclature clash here. When you say "one single 
commit", I can't help but thinking "snapshot". It's completely 
impossible to fold *ALL* the history into a single commit, and since you 
want heuristics I would imagine you wouldn't want that either.


>> I'm not sure what you mean by 'project_collapsed' though.
> 
> 
> All the commits on the project branch are 'collapsed' into one single 
> commit/delta, and then that /single/ commit is merged to 'main'. Rest of 
> the world sees:
> 
> o-o-o-o-o--o-o-o--o-o-o---m <- main branch
>                        \ /
>                         o <- project
> 

The only sane way to represent this is by doing a mega-patch and 
applying it with a new commit message. That way renamed files will show 
up as

	renamed from /path/to/foo
	renamed to /path/to/some/where/else

Since you're removing all the history in between one mega-patch and the 
next (as if Linus would have v2.6.12 one day and in the next commit it 
would be v2.6.13... strange thought), the history for that tree can't 
well know about renames that doesn't exist in its history. Again, if you 
wan't to keep "master" (can we please call it that? I can't keep up with 
what you call "project" and "main branch") to a single commit you'll 
have no history in it. In essence, that's a snapshot (or a release, 
which is just a snapshot with a tag).

>> Personally I think metadata is evil.
> 
> 
> Not sure I agree. Silly/redundant meta-data can be evil alright. But I'm 
> talking about meta-data which is not there and potentially not 
> reconstructable.
> 
>> Renames will still be auto-detected anyway,
> 
> 
> Chances are so, yes. Definitely with the git and Linux workflows.
> 
> The traditional workflow for the software project I'm thinking of is 
> different though. One commit may encompass multiple renames and edits of 
> a file (discouraged, but it's possible).
> 
> If my understanding is correct, following back history for such cases 
> would be difficult.
> 

It would be impossible. At best you can get "before mega-patch 64, the 
tree looked like this", "after mega-patch 64, it looked like this, and 
here are the files with 80% of above similarity index".


> There is an argument that that 'traditional' process should be changed. 
> However, leaving aside that argument, I'd like to know if git could 
> accomodate that process.
> 
>> be able to detect a rename is if you rename a file and hack it up so 
>> it doesn't even come close to matching its origin (close in this case 
>> is 80% by default, I think). In those cases it isn't so much a rename 
>> as a rewrite.
> 
> 
> Exactly - this is the case I'm concerned about. Imagine that you'd like 
> to be follow the history back through the rewrite and through to the 
> original file.
> 

I'm confused. First you say you want to have one single mega-patch for 
each commit, then you say you want to be able to follow history back. 
It's like deciding to throw away your wallet and then trying to get 
someone to pick it up and carry it around for you.

>> IMO this is far better than having to tell git "I renamed this file to 
>> that", since it also detects code-copying with modifications, and it's 
>> usually quick enough to find those renames as well.
> 
> 
> I think so too, but that involves arguing that very very long-standing 
> workflows should be changed to accomodate git. I intend to make that 
> argument to the 'project' concerned, however I would also like to be say 
> git could equally well deal with the 'traditional' workflow, modulo 
> having to explicitely use (say) git-mv.
> 

The simple fact is that once you start juggling 12MB patches instead of 
keeping the commits, your history is out the window anyway. Adding 
meta-data to accommodate for the lack of history when you throw it away 
is, to be honest, an approach that leaves "insane" in the dust.

As for convincing others, shove git-bisect under their noses and ask 
them if they'd like a tool to find their bugs for them.


>>
>>     $ git checkout master
>>     $ git pull . project
> 
> 
> Right, but 'pull' isn't what I mean :).
> 
> I mean:
> 
>     $ git checkout project
>     $ git pull . master
>     $ git checkout -b tmp project
>     $ git diff project..master | <git apply I think>
>

This way, 'project' and 'tmp' both would hold all patches since you 
merge 'master' into 'project' before creating the 'tmp' branch at the 
head of 'project'. As such, 'project' is ahead of 'master' (it has its 
own changes, those in master and the merge between 'project' and 
'master'), so the diff will be empty.

If 'master' is where you commit regularly (i.e. not mega-patches), you 
can do these two steps to create the mega-patch branch

	$ git checkout -b mega; # create the mega-patch branch
	$ # rewind the mega-patch branch to the dawn of time
	$ git reset --hard $(git rev-list HEAD | tail -n 1)

And for each mega-patch, do this:

	$ # create and apply mega-patch 1
	$ git diff project..master | git apply
	$ # commit the changes we just applied
	$ git commit -s -a -m "mega-patch 1"
	$ git checkout project; # back to project branch
	$ # Merge with 'master', or the next mega-patch won't apply
	$ git pull . master


>> Then you can apply patch-file to whatever branch you want and make the 
>> commit as if it was a single change-set. I'd recommend against it 
>> unless you're just toying around though. It's a bad idea to lie in a 
>> projects history.
> 
> 
> Presume that 'project' in the workflow is defined as
> 
>     "achieve one goal with one commit to the master"
> 
> So by definition, it always correct that the project only ever has one 
> commit.
> 

But that can't be true either, unless you intend to stop working at the 
project. At "best", you could be able to get a chain of commits in 
'master' where each commit hold several tons of changes.

The topic-branch approach to this would be to
a) Implement all changes required for a certain feature in one go and 
commit all of them. do "git pull . topic-branch" when on master branch. 
This will result in a "fast-forward" (i.e. top of 'master' is the 
merge-base between 'master' and 'topic-branch'), so no merge will happen.

b) Implement all changes required for a certain feature in small steps 
and then apply the diff between 'master..topic-branch' to master. The 
topic-branch has to be thrown away, since it can't ever be merged back 
into master, and master can't be merged into the topic-branch (that's 
ok, topic-branches are made to throw away).

For small changes, or one change and some stupid bugfixes, I'd say b) is 
a viable option. The kind of changes you talk about, with several 
renames of files and sometimes near-complete rewrite of them, would 
certainly warrant a merge (or a fast-forward).


> The trouble is that /sometimes/ projects do indeed 'rename and rewrite' 
> a file. At present, chances are git might not notice this, and ability 
> to follow history through the rename+rewrite would be lost.
> 
> I'm wondering whether:
> 
> - this could be solved?


Not with the mega-patch approach.

> - how? (some additional advisory-only meta-data in the
>   index-cache and commit?)
> 

You could maintain that data yourself in either an external or versioned 
file. I've never heard of anyone employing the workflow you describe so 
I doubt it's very common. I also shudder to think that git will be made 
less efficient for the benefit of throwing history away, when tracking 
history efficiently is what it's all about in the first place.


> If there is consensus on an acceptable way, I'm willing to implement it. 
> (I was thinking of just adding 'rename' headers to the commit objects, 
> then teaching diffcore to consider them in addition to current heuristics).
> 

The code is mightier than the mail. Perhaps if I see an implementation 
of this I could wrap my head around what you really mean. I'm sure I 
must misunderstand you one way or another.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Linus Torvalds @ 2006-03-01 17:40 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: Andreas Ericsson, Eric Wong, Martin Langhoff, git
In-Reply-To: <200603011814.43573.Josef.Weidendorfer@gmx.de>



On Wed, 1 Mar 2006, Josef Weidendorfer wrote:
>
> On Wednesday 01 March 2006 17:24, Linus Torvalds wrote:
> > The thing about it being .git/refs/heads/svn/xyzzy is that then you can do
> > 
> > 	git checkout svn/xyzzy
> > 
> > and start modifying it. Which is exactly against the point: the thing is 
> > _not_ a branch and you must _not_ commit to it.
> > 
> > It's much more like a tag: it's a pointer to the last point of an 
> > svn-import.
> 
> Isn't it the same with tracked branches of a remote git repo?
> With this reasoning, all heads that git-clone clones aside from the
> special "master" should not be under .git/refs/heads, but better
> under .git/refs/remotes/<remoteRepoName>/ ?

Yes, I think that would make tons of sense.

> <remoteRepoName> is "origin" in the case of git-clone, so .git/remotes/origin
> would contain
>  URL: http://host/repo.git
>  Pull: master:remotes/origin/master
> 
> Then there would not be the need for the confusing special branch "origin"
> after cloning, as namespaces are separate.

I think that would make things a lot more flexible, and yes, it sounds 
like a good idea.

HOWEVER.

I think it's not only very common, but quite useful, to do what we do now, 
ie

	git log origin..

to see "what is in origin but not in HEAD".

So there's a big usability issue: I don't think it's good to have to say

	git log remotes/origin/master..

to do the same.

So from a usability standpoint, we'd have to teach "get_sha1()" about 
parsing .git/remotes/* files if it cannot find a branch or a tag with that 
name (which it wouldn't be able to, since even if it were to walk the 
directories udner .git/refs/ recursively, it would be named "master" 
there).

But if somebody does the get_sha1() magic, and Junio agrees, then I think 
it would be a great thing to do.

			Linus

^ permalink raw reply

* Re: bug?: stgit creates (unneccessary?) conflicts when pulling
From: Chuck Lever @ 2006-03-01 17:39 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: Karl Hasselström, git
In-Reply-To: <b0943d9e0602281445w7160d915y@mail.gmail.com>

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

Catalin Marinas wrote:
> On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:
> 
>>An idea (untested, I don't even know whether it's feasible) would be to
>>check which patches were merged by reverse-applying them starting with
>>the last. In this situation, all the merged patches should just revert
>>their changes. You only need to do a git-diff between the bottom and the
>>top of the patch and git-apply the output (maybe without even modifying
>>the tree). If this operation succeeds, the patch was integrated and you
>>don't even need to push it.
> 
> 
> I attached another patch that should work properly. It also pushes
> empty patches on the stack if they were merged upstream (a 'stg clean'
> is required to remove them). This is useful for the push --undo
> command if you are not happy with the result.
> 
> I'll try this patch for a bit more before pushing into the repository.

i think this is a cool idea.  but it seems still to require a bit of 
convention on the part of the maintainer.

if maintainer X takes a patch "a" from developer Y, but modifies patch 
"a" before committing it, then your nifty automated mechanism will still 
have trouble merging developer Y's stack when Y pulls again.

the convention might be that maintainers who accept patches will always 
accept exactly what was sent, and then immediately apply another commit 
that addresses any issues they have with the original commit.  this is 
also a good idea so that the history contains the exact attribution of 
each change.

[-- Attachment #2: cel.vcf --]
[-- Type: text/x-vcard, Size: 451 bytes --]

begin:vcard
fn:Chuck Lever
n:Lever;Charles
org:Network Appliance, Incorporated;Open Source NFS Client Development
adr:535 West William Street, Suite 3100;;Center for Information Technology Integration;Ann Arbor;MI;48103-4943;USA
email;internet:cel@citi.umich.edu
title:Member of Technical Staff
tel;work:+1 734 763-4415
tel;fax:+1 734 763 4434
tel;home:+1 734 668-1089
x-mozilla-html:FALSE
url:http://troy.citi.umich.edu/u/cel/
version:2.1
end:vcard


^ permalink raw reply

* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Shawn Pearce @ 2006-03-01 17:28 UTC (permalink / raw)
  To: Josef Weidendorfer
  Cc: Linus Torvalds, Andreas Ericsson, Eric Wong, Martin Langhoff, git
In-Reply-To: <200603011814.43573.Josef.Weidendorfer@gmx.de>

Josef Weidendorfer <Josef.Weidendorfer@gmx.de> wrote:
> On Wednesday 01 March 2006 17:24, Linus Torvalds wrote:
> > The thing about it being .git/refs/heads/svn/xyzzy is that then you can do
> > 
> > 	git checkout svn/xyzzy
> > 
> > and start modifying it. Which is exactly against the point: the thing is 
> > _not_ a branch and you must _not_ commit to it.
> > 
> > It's much more like a tag: it's a pointer to the last point of an 
> > svn-import.
> 
> Isn't it the same with tracked branches of a remote git repo?
> With this reasoning, all heads that git-clone clones aside from the
> special "master" should not be under .git/refs/heads, but better
> under .git/refs/remotes/<remoteRepoName>/ ?
> 
> <remoteRepoName> is "origin" in the case of git-clone, so .git/remotes/origin
> would contain
>  URL: http://host/repo.git
>  Pull: master:remotes/origin/master
> 
> Then there would not be the need for the confusing special branch "origin"
> after cloning, as namespaces are separate.

This is a really good idea.  It certainly would prevent polluting the
heads namespace.  And its a lot easier to explain to someone than the
mapping in the Pull line usually is.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] diff-delta: bound hash list length to avoid O(m*n) behavior
From: Nicolas Pitre @ 2006-03-01 17:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vmzgajvpl.fsf@assigned-by-dhcp.cox.net>

On Wed, 1 Mar 2006, Junio C Hamano wrote:

> Nicolas Pitre <nico@cam.org> writes:
> 
> >> I tried an experimental patch to cull collided hash buckets
> >> very aggressively.  I haven't applied your last "reuse index"
> >> patch, though -- I think that is orthogonal and I'd like to
> >> leave that to the next round.
> >
> > It is indeed orthogonal and I think you could apply it to the next 
> > branch without the other patches (it should apply with little problems).  
> > This is an obvious and undisputable gain, even more if pack-objects is 
> > reworked to reduce memory usage by keeping only one live index for 
> > multiple consecutive deltaattempts.
> 
> Umm.  The hash-index is rather huge, isn't it?  I did not
> realize it was two-pointer structure for every byte in the
> source material, and we typically delta from larger to smaller,
> so we will keep about 10x the unpacked source.  Until we swap
> the windowing around, that means about 100x the unpacked source
> with the default window size.

That's why I said that the window reversal has to be done as well to be 
effective.  As for the index itself it can be reduced to a single 
pointer since the "ptr" value can be deduced from the offset of the 
index entry.

> Also, I am not sure which one is more costly: hash-index
> building or use of that to search inside target.  I somehow got
> an impression that the former is relatively cheap, and that is
> what is being cached here.

Yes, but caching it saves 10% on CPU time, probably more when the window 
is swapped around due to less memory usage.

> > Let's suppose the reference buffer has:
> >  
> > ***********************************************************************/
> >...
> > One improvement might consist of counting the number of consecutive 
> > identical bytes when starting a compare, and manage to skip as many hash 
> > entries (minus the block size) before looping again with more entries in 
> > the same hash bucket.
> 
> Umm, again.  Consecutive identical bytes (BTW, I think "* * *"
> and "** ** **" patterns have the same collision issues without
> being consecutive bytes, so such an optimization may be trickier
> and cost more),

First, those "** ** **" are less frequent in general. Next, they will be 
spread amongst 3 hash buckets instead of all the same one.  And with 
large binary files with lots of zeroes then scanning over those areas in 
one pass instead of iterating over them from every offset would help 
enormously as well, even without limiting the hash list length.

 when emitted as literals, would compress well,
> wouldn't they?  At the end of the day, I think what matters is
> the size of deflated delta, since going to disk to read it out
> is more expensive than deflating and applying.  I think you made
> a suggestion along the same line, capping the max delta used by
> try_delta() more precisely by taking the deflated size into
> account.

Yes.  But deflating a bunch of characters will never be as dense as a 4 
byte delta sequence that might expand to hundreds.


Nicolas

^ permalink raw reply

* [PATCH] git-mv: Allow -h without repo & fix error message
From: Josef Weidendorfer @ 2006-03-01 17:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This fixes "git-mv -h" to output the usage without the need
to be in a git repository.
Additionally:
- fix confusing error message when only one arg was given
- fix typo in error message

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>

---

 git-mv.perl |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

2f1dc137362cfa84553340a8f1310bc784e5935b
diff --git a/git-mv.perl b/git-mv.perl
index 2ea852c..8cd95c4 100755
--- a/git-mv.perl
+++ b/git-mv.perl
@@ -19,15 +19,15 @@ EOT
 	exit(1);
 }
 
-my $GIT_DIR = `git rev-parse --git-dir`;
-exit 1 if $?; # rev-parse would have given "not a git dir" message.
-chomp($GIT_DIR);
-
 our ($opt_n, $opt_f, $opt_h, $opt_k, $opt_v);
 getopts("hnfkv") || usage;
 usage() if $opt_h;
 @ARGV >= 1 or usage;
 
+my $GIT_DIR = `git rev-parse --git-dir`;
+exit 1 if $?; # rev-parse would have given "not a git dir" message.
+chomp($GIT_DIR);
+
 my (@srcArgs, @dstArgs, @srcs, @dsts);
 my ($src, $dst, $base, $dstDir);
 
@@ -46,10 +46,14 @@ if (-d $ARGV[$argCount-1]) {
 	}
 }
 else {
-    if ($argCount != 2) {
+    if ($argCount < 2) {
+	print "Error: need at least two arguments\n";
+	exit(1);
+    }
+    if ($argCount > 2) {
 	print "Error: moving to directory '"
 	    . $ARGV[$argCount-1]
-	    . "' not possible; not exisiting\n";
+	    . "' not possible; not existing\n";
 	exit(1);
     }
     @srcArgs = ($ARGV[0]);
-- 
1.2.0.g719b

^ permalink raw reply related

* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Josef Weidendorfer @ 2006-03-01 17:14 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andreas Ericsson, Eric Wong, Martin Langhoff, git
In-Reply-To: <Pine.LNX.4.64.0603010821590.22647@g5.osdl.org>

On Wednesday 01 March 2006 17:24, Linus Torvalds wrote:
> The thing about it being .git/refs/heads/svn/xyzzy is that then you can do
> 
> 	git checkout svn/xyzzy
> 
> and start modifying it. Which is exactly against the point: the thing is 
> _not_ a branch and you must _not_ commit to it.
> 
> It's much more like a tag: it's a pointer to the last point of an 
> svn-import.

Isn't it the same with tracked branches of a remote git repo?
With this reasoning, all heads that git-clone clones aside from the
special "master" should not be under .git/refs/heads, but better
under .git/refs/remotes/<remoteRepoName>/ ?

<remoteRepoName> is "origin" in the case of git-clone, so .git/remotes/origin
would contain
 URL: http://host/repo.git
 Pull: master:remotes/origin/master

Then there would not be the need for the confusing special branch "origin"
after cloning, as namespaces are separate.

Josef

^ permalink raw reply

* Re: impure renames / history tracking
From: Linus Torvalds @ 2006-03-01 17:13 UTC (permalink / raw)
  To: Paul Jakma; +Cc: Andreas Ericsson, git list
In-Reply-To: <Pine.LNX.4.64.0603011558390.13612@sheen.jakma.org>



On Wed, 1 Mar 2006, Paul Jakma wrote:
> 
> FWIW, I think git's rename handling is really nice. It's just I suspect, being
> a heuristic, it won't be able to follow history reliably across 'very impure'
> renames.

The thing is, it does better than anything that _tries_ to be "reliable".

I can pretty much _guarantee_ that you can't do it better.

Tracking "inodes" - aka file identities - (which is what BK does, and I 
assume what SVN does) is fundamentally problematic. I particular, it's a 
horrible problem when two inodes "meet" under the same name. You now have 
two identities for the same file, and you're fundamentally screwed.

And don't tell me it doesn't happen. It _does_ happen, and it did happen 
with the kernel under BK.

It doesn't even need renames to be a problem. JUST THE FACT THAT YOU TRY 
TO TRACK FILE "IDENTITY" HISTORY IS BROKEN. For example, take CVS, which 
doesn't actually try to do renames, but _does_ try to track the identity 
of a file, since all the history is tied into that identity: think about 
what happens in Attic when a file is deleted. Completely broken model.

Now, CVS doesn't tend to show the problems very much, because people don't 
actually use branches that much (they are a pain in the neck), and they 
sure as hell try to avoid deleting and creating the same filename under a 
branch and on HEAD. I'm sure you can do it, but I'm also pretty sure 
there's a lot of old projects around that have ended up moving the ,v 
files around to play rename/delete games.

And that's really fundamental. CVS doesn't show the problems so much, 
because CVS actively tries to make it hard to do these things.

With renames-tracking-file-identities, it's _really_ easy to get some 
major confusion going. What happens when one branch creates a file, and 
another one renames a file to that same name, and they merge?

Don't tell me it doesn't happen. It happened under BK. The way BK "solved" 
it was to keep the two separate identities: one of them got resolved to 
the new filename, the other one went into the "deleted" directory. Guess 
what happens when the side that got merged into "deleted" continues to 
edit the file? That's right - their edits happen on the deleted file, and 
never show up in the real tree in a subsequent merge ever again.

And as far as I can tell, BK really did the best you can do. Following 
file identities really _is_ fundamentally broken. It sounds like a nice 
idea, but while you migth solve a few problems, you create a whole raft of 
much more fundamental problems.

So next time you think about a merge that migt have been improved by 
tracking renames, please also think about a merge where one of the 
filenames came from two or more different sources through an earlier 
merge, and thank your benevolent Gods that they instructed me to make git 
be based purely on file contents.

		Linus

^ permalink raw reply

* Merge question
From: Bertrand Jacquin @ 2006-03-01 16:31 UTC (permalink / raw)
  To: git

Hello,

Maybe someone could explain me something I can't find in docs.

In a have a repo a, and a repo b.
The a's arbo is :
            2eme_annee/jacqui_b/C/projects/
The b's orbo is :
            my_ls-l

How could I merge b in a and merge b's blob in
2eme_annee/jacqui_b/C/projects/ to have
2eme_annee/jacqui_b/C/projects/my_ls-l ?

--
Beber
#e.fr@freenode

^ permalink raw reply

* Re: impure renames / history tracking
From: Paul Jakma @ 2006-03-01 16:27 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: git list
In-Reply-To: <4405C012.6080407@op5.se>

On Wed, 1 Mar 2006, Andreas Ericsson wrote:

> Mainly for two reasons, iirc:

> 1. Extensive metadata is evil.

Only if /required/. I wouldn't argue for rename meta-data to be 
'core', only as an additional hint into the rename-detection process.

FWIW, I think git's rename handling is really nice. It's just I 
suspect, being a heuristic, it won't be able to follow history 
reliably across 'very impure' renames.

> 2. Backwards compatibility. Old repos should always work with new 
> tools. Old tools should work with new repos, at least until a new 
> major-release is released.

Absolutely.

>> o: commit
>> m: merge
>>
>>    o---o-m--o-o-o--o----m <- project
>>   /     /              /
>> o-o-o-o-o--o-o-o--o-o-o <- main branch
>> 
>> The project merge back to main in one 'big' combined merge (collapsing all 
>> of the commits on 'project' into one commit). This leads to 'impure 
>> renames' being not uncommon. The desired end-result of merging back to 
>> 'main' being to rebase 'project' as one commit against 'main', and merge 
>> that single commit back, a la:
>>
>>    o---o-m--o-o-o--o----m <- project
>>   /     /              /
>> o-o-o-o-o--o-o-o--o-o-o---m <- main branch
>>                        \ /
>>                         o <- project_collapsed
>> 
>> So that 'm' on 'main' is that one commit[1].

> I think you're misunderstanding the git meaning of rebase here. 
> "git rebase" moves all commits since "project" forked from "main 
> branch" to the tip of "main branch".

Right, I'm referring to 'rebase' generally, as a concept, not to 
git-rebase specifically. E.g. git diff main..project is another way 
of rebasing I think.

> Other than that, this is the recommended workflow, and exactly how Linux and 
> git both are managed (i.e. topic branches eventually merged into 'master').

They're not rebased though, generally. They're pulled. Ie, in Linux 
and git when 'project' is merged, things look like:

     o---o-m--o-o-o--o----m   <- project
    /     /              / \
o-o-o-o-o--o-o-o--o-o-o----m <- main branch

The rest of the world sees /all/ the individual commits of 'project' 
right? The traditional process for the case I'm thinking of results 
in the 'main' tree seeing only /one/ single commit for the project.

> I'm not sure what you mean by 'project_collapsed' though.

All the commits on the project branch are 'collapsed' into one single 
commit/delta, and then that /single/ commit is merged to 'main'. Rest 
of the world sees:

o-o-o-o-o--o-o-o--o-o-o---m <- main branch
                        \ /
                         o <- project

> correctly, each branch-head represents one 'collapse'.

Not quite. It represents a branch with one or more commits. In the 
Linux and git work flow, multiple commits are left as is.

> gitk is great for visualizing what you've done and what the repo 
> looks like. Use and abuse it frequently every time you're unsure 
> what was you just did. It's the best way to quickly learn what 
> happens, really.

I do. It rocks! :)

> If you just want to distribute snapshots I suggest you do take a 
> look at git-tar-tree. Junio makes nice use of it in the git 
> Makefile (the dist: target).

Neat.

Though, I probably should stay away from the git Makefile for now. 
<cough>.

> Personally I think metadata is evil.

Not sure I agree. Silly/redundant meta-data can be evil alright. But 
I'm talking about meta-data which is not there and potentially not 
reconstructable.

> Renames will still be auto-detected anyway,

Chances are so, yes. Definitely with the git and Linux workflows.

The traditional workflow for the software project I'm thinking of is 
different though. One commit may encompass multiple renames and edits 
of a file (discouraged, but it's possible).

If my understanding is correct, following back history for such cases 
would be difficult.

There is an argument that that 'traditional' process should be 
changed. However, leaving aside that argument, I'd like to know if 
git could accomodate that process.

> be able to detect a rename is if you rename a file and hack it up 
> so it doesn't even come close to matching its origin (close in this 
> case is 80% by default, I think). In those cases it isn't so much a 
> rename as a rewrite.

Exactly - this is the case I'm concerned about. Imagine that you'd 
like to be follow the history back through the rewrite and through to 
the original file.

> IMO this is far better than having to tell git "I renamed this file 
> to that", since it also detects code-copying with modifications, 
> and it's usually quick enough to find those renames as well.

I think so too, but that involves arguing that very very 
long-standing workflows should be changed to accomodate git. I intend 
to make that argument to the 'project' concerned, however I would 
also like to be say git could equally well deal with the 
'traditional' workflow, modulo having to explicitely use (say) 
git-mv.

>> 1. Git currently doesn't have 'porcelain' to do this, presumably there'd be 
>> no objection to one?
>> 
>
> 	$ git checkout master
> 	$ git pull . project

Right, but 'pull' isn't what I mean :).

I mean:

 	$ git checkout project
 	$ git pull . master
 	$ git checkout -b tmp project
 	$ git diff project..master | <git apply I think>

> If, for some reason, you want to combine lots of commits into a single 
> mega-patch (like Linus does for each release of the kernel), you can do:
>
> 	$ git diff $(git merge-base main project) project > patch-file

Right.

> Then you can apply patch-file to whatever branch you want and make 
> the commit as if it was a single change-set. I'd recommend against 
> it unless you're just toying around though. It's a bad idea to lie 
> in a projects history.

Presume that 'project' in the workflow is defined as

 	"achieve one goal with one commit to the master"

So by definition, it always correct that the project only ever has 
one commit.

The trouble is that /sometimes/ projects do indeed 'rename and 
rewrite' a file. At present, chances are git might not notice this, 
and ability to follow history through the rename+rewrite would be 
lost.

I'm wondering whether:

- this could be solved?
- how? (some additional advisory-only meta-data in the
   index-cache and commit?)

If there is consensus on an acceptable way, I'm willing to implement 
it. (I was thinking of just adding 'rename' headers to the commit 
objects, then teaching diffcore to consider them in addition to 
current heuristics).

regards,
-- 
Paul Jakma	paul@clubi.ie	paul@jakma.org	Key ID: 64A2FF6A
Fortune:
Be nice to people on the way up, because you'll meet them on your way down.
 		-- Wilson Mizner

^ permalink raw reply

* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Linus Torvalds @ 2006-03-01 16:24 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Eric Wong, Martin Langhoff, git
In-Reply-To: <4405C6BE.2000706@op5.se>



On Wed, 1 Mar 2006, Andreas Ericsson wrote:
> 
> Personally I'm all for namespace separation. I'm assuming the script has the
> tracker-branch hardcoded anyway, so I don't really understand why it would be
> necessary to keep other refs in a separate directory and, if it *is*
> necessary, why that subdirectory can't be .git/refs/heads/svn.
> 
> Eric mentioned earlier that the tracking-branch can't be committed to (ever),
> so the user convenience for searching other directories should be nearly
> non-existant.

The thing about it being .git/refs/heads/svn/xyzzy is that then you can do

	git checkout svn/xyzzy

and start modifying it. Which is exactly against the point: the thing is 
_not_ a branch and you must _not_ commit to it.

It's much more like a tag: it's a pointer to the last point of an 
svn-import.

So I think it should either _be_ a tag (although Dscho worries about some 
broken porcelain being confused by tags changing) or it should be in a 
namespace all it's own. Not under .git/refs/heads/ at any point, because 
it is _not_ a head of development.

		Linus

^ permalink raw reply

* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Andreas Ericsson @ 2006-03-01 16:07 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Eric Wong, Martin Langhoff, git
In-Reply-To: <Pine.LNX.4.64.0603010745320.22647@g5.osdl.org>

Linus Torvalds wrote:
> 
> On Wed, 1 Mar 2006, Andreas Ericsson wrote:
> 
>>Eric Wong wrote:
>>
>>>Should rev-parse be taught to be less strict and look for basenames
>>>that can't be found in heads/ and tags/ in other directories?
>>
>>It already does. The search order is this, for a ref named 'foo':
>>	$GIT_DIR/foo
>>	$GIT_DIR/refs/foo
>>	$GIT_DIR/refs/tags/foo
>>	$GIT_DIR/refs/heads/foo
> 
> 
> Yes, but I think Eric wanted to avoid having to write the prefix part, 
> which git won't let you do right now.
> 
> If you have a ref in .git/refs/svn-tracker/git-svn-HEAD, you would have to 
> write out all of "svn-tracker/git-svn-HEAD", because unlike a "real 
> branch", get_sha1() won't look into the "svn-tracker" without it being 
> explicitly mentioned.
> 
> Now, some tools will actually do "for_each_ref()" and check the ref-name 
> against each of them (so if you pass in "foo", it will check them afainst 
> _any_ ref-subdirectory that contains "foo"). But get_sha1() won't.
> 

Didn't know that. The day is not a complete waste then.


> We could fix get_sha1(), but part of the logic was that other 
> subdirectories are special, and as such they _should_ be mentioned, so 
> that a file in such a special directory isn't ever confused with a real 
> branch.
> 
> But if you were to use for example .git/refs/git-svn/tracking as the 
> svn-tracking reference head, and then you'd be perfectly able to use
> 
> 	git log git-svn/tracking..
> 
> to see what you've done since the last svn import?
> 

Personally I'm all for namespace separation. I'm assuming the script has 
the tracker-branch hardcoded anyway, so I don't really understand why it 
would be necessary to keep other refs in a separate directory and, if it 
*is* necessary, why that subdirectory can't be .git/refs/heads/svn.

Eric mentioned earlier that the tracking-branch can't be committed to 
(ever), so the user convenience for searching other directories should 
be nearly non-existant.

Perhaps I'm missing something obvious. Perhaps I'm just stupid. Perhaps 
the pub just opened and I don't feel like reading it twice to make sure 
I understood. ;)

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: [PATCH] Teach git-checkout-index to use file suffixes.
From: Mark Wooding @ 2006-03-01 15:56 UTC (permalink / raw)
  To: git
In-Reply-To: <20060301150629.GB3456@spearce.org>

Shawn Pearce <spearce@spearce.org> wrote:

> I thought about using instead:
>
>   --stage=all --suffix1=\#1 --suffix2\=#2 --suffix3=\#3

How about something like

  --suffixes=:#1:#2:#3

uses first character as a delimiter to separate the suffixes.  A single
--suffix option could plausibly provide the suffix if only one stage is
being checked out, and doesn't have the grim delimiter wart.

I suppose, though, that if this is going to be wrapped up in a script,
it doesn't really matter that much.

-- [mdw]

^ permalink raw reply

* Re: git-svn and huge data and modifying the git-svn-HEAD branch directly
From: Linus Torvalds @ 2006-03-01 15:53 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Eric Wong, Martin Langhoff, git
In-Reply-To: <44056BF1.6000109@op5.se>



On Wed, 1 Mar 2006, Andreas Ericsson wrote:
>
> Eric Wong wrote:
> > 
> > Should rev-parse be taught to be less strict and look for basenames
> > that can't be found in heads/ and tags/ in other directories?
> 
> It already does. The search order is this, for a ref named 'foo':
> 	$GIT_DIR/foo
> 	$GIT_DIR/refs/foo
> 	$GIT_DIR/refs/tags/foo
> 	$GIT_DIR/refs/heads/foo

Yes, but I think Eric wanted to avoid having to write the prefix part, 
which git won't let you do right now.

If you have a ref in .git/refs/svn-tracker/git-svn-HEAD, you would have to 
write out all of "svn-tracker/git-svn-HEAD", because unlike a "real 
branch", get_sha1() won't look into the "svn-tracker" without it being 
explicitly mentioned.

Now, some tools will actually do "for_each_ref()" and check the ref-name 
against each of them (so if you pass in "foo", it will check them afainst 
_any_ ref-subdirectory that contains "foo"). But get_sha1() won't.

We could fix get_sha1(), but part of the logic was that other 
subdirectories are special, and as such they _should_ be mentioned, so 
that a file in such a special directory isn't ever confused with a real 
branch.

But if you were to use for example .git/refs/git-svn/tracking as the 
svn-tracking reference head, and then you'd be perfectly able to use

	git log git-svn/tracking..

to see what you've done since the last svn import?

(or use HEAD, if you prefer that over "tracking")

		Linus

^ permalink raw reply

* Re: [PATCH] Teach git-checkout-index to read filenames from stdin.
From: Christopher Faylor @ 2006-03-01 15:50 UTC (permalink / raw)
  To: git
In-Reply-To: <20060301024333.GB21186@spearce.org>

On Tue, Feb 28, 2006 at 09:43:33PM -0500, Shawn Pearce wrote:
>Since git-checkout-index is often used from scripts which may have a
>stream of filenames they wish to checkout it is more convenient to use
>--stdin than xargs.  On platforms where fork performance is currently
>sub-optimal and the length of a command line is limited (*cough* Cygwin
>*cough*)

AFAIK, the length of the command line for cygwin apps is very large --
if you're using recent versions of Cygwin.  I believe that it is longer
than the linux default.  We bypass the Windows mechanism for setting the
command line when a cygwin program starts a cygwin program.

For native Windows programs, the command line length is ~32K but I don't
think that git uses any native Windows programs, does it?

cgf

^ permalink raw reply

* Re: bug?: stgit creates (unneccessary?) conflicts when pulling
From: Shawn Pearce @ 2006-03-01 15:50 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <b0943d9e0603010708l72cb14d1w@mail.gmail.com>

Catalin Marinas <catalin.marinas@gmail.com> wrote:
> On 01/03/06, Shawn Pearce <spearce@spearce.org> wrote:
> > True.  The constant reapplication does really slow it down.  So does
> > grabbing the reverse patch and seeing if it applies backwards
> > cleanly.  Neither operation is fast, and neither is really going
> > to be fast.
> 
> I realised that, depending on the number of patches merged upstream,
> using this option can make StGIT faster. That's because when pushing a
> patch (without the --merged option), StGIT first tries a diff | apply
> followed by a three-way merge (even slower) if the former method
> fails. This means that for all the patches merged upstream, StGIT
> tries both methods since diff | apply fails anyway. With the --merged
> option, StGIT would only try the reverse-diff | apply and, if this
> succeeds, it will skip the normal push methods.

Speaking of making StGIT faster: earlier we were talking about how
git-diff|git-apply is faster than a 3 way git-read-tree on large
merges when there are many structural changes in the tree due to
the smaller number of process spawns required.

You might want to take a look at pg--merge-all: This is sort of based
on git-merge-recursive, but I've gotten it down to just a handful
of process spawns, aside from the stupidity of git-checkout-index.
(My recent git-checkout-index patches are working to correct that.)

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH 2/2] git-log (internal): more options.
From: Linus Torvalds @ 2006-03-01 15:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqwqgxo8.fsf@assigned-by-dhcp.cox.net>



On Wed, 1 Mar 2006, Junio C Hamano wrote:
>
> This ports the following options from rev-list based git-log
> implementation:
> 
>  * -<n>, -n<n>, and -n <n>.  I am still wondering if we want
>     this natively supported by setup_revisions(), which already
>     takes --max-count.  We may want to move them in the next
>     round.  Also I am not sure if we can get away with not
>     setting revs->limited when we set max-count.  The latest
>     rev-list.c and revision.c in this series do not, so I left
>     them as they are.
> 
>  * --pretty and --pretty=<fmt>.
> 
>  * --abbrev=<n> and --no-abbrev.

Looks good.

I _suspect_ that we want to handle them all in setup_revision(), but I 
wasn't sure, so I left them in rev-list.c originally.

Most helpers that want a list of commits probably want the printing 
options too, and the ones that do not probably simply don't care (ie if 
they silently pass a "--pretty=raw" without it affecting anything, who 
really cares?)

> The previous commit already handles time-based limiters
> (--since, --until and friends).  The remaining things that
> rev-list based git-log happens to do are not useful in a pure
> log-viewing purposes, and not ported:
> 
>  * --bisect (obviously).
> 
>  * --header.  I am actually in favor of doing the NUL
>    terminated record format, but rev-list based one always
>    passed --pretty, which defeated this option.  Maybe next
>    round.
> 
>  * --parents.  I do not think of a reason a log viewer wants
>    this.  The flag is primarily for feeding squashed history
>    via pipe to downstream tools.

I can actually imagine using "--parents" as a way of parsing both the 
commit log and the history. Of course, any such use is likely in a script, 
at which point the script probably doesn't actually want "git log", but 
just a raw "git-rev-list".

After all, the only _real_ difference between "git log" and "git-rev-list" 
is the purely syntactic one (things like defaulting to HEAD in "git log" 
and requiring revisions in git-rev-list), and the use of PAGER.

To me, the question whether a flag would be parsed in the "revision.c" 
library or in the "rev-list.c" binary was more a question of whether that 
flag makes sense for other things than just "git log". 

For example, "git whatchanged" and "git diff" could both use 
setup_revision(), although "git diff" wouldn't actually _walk_ the 
revisions (it would just look at the "revs->commits" list to see what was 
passed in).

"git whatchanged" would obviously take all the same flags "git log" does, 
and "git diff" could take them and just test the values for sanity (ie 
error out if min/max_date is not -1, for example).

"git show" is like a "git-whatchanged" except it wouldn't walk the diffs 
(I considered adding a "--nowalk" option to setup_revisions(), which would 
just suppress the "add_parents_to_list()" entirely)

			Linus

^ permalink raw reply

* Re: impure renames / history tracking
From: Andreas Ericsson @ 2006-03-01 15:38 UTC (permalink / raw)
  To: Paul Jakma; +Cc: git list
In-Reply-To: <Pine.LNX.4.64.0603011343170.13612@sheen.jakma.org>

Paul Jakma wrote:
> 
> - git obviously detects pure renames perfectly well
> 
> - git doesn't however record renames, so 'impure' renames may not be
>   detected
> 
> My question is:
> 
> - why not record rename information explicitely in the commit object?
> 

Mainly for two reasons, iirc:
1. Extensive metadata is evil.
2. Backwards compatibility. Old repos should always work with new tools. 
Old tools should work with new repos, at least until a new major-release 
is released.


> I.e. so as to be able to follow history information through 'impure' 
> renames without having to resort to heuristics.
> 
> E.g. imagine a project where development typically occurs through:
> 
> o: commit
> m: merge
> 
>    o---o-m--o-o-o--o----m <- project
>   /     /              /
> o-o-o-o-o--o-o-o--o-o-o <- main branch
> 
> The project merge back to main in one 'big' combined merge (collapsing 
> all of the commits on 'project' into one commit). This leads to 'impure 
> renames' being not uncommon. The desired end-result of merging back to 
> 'main' being to rebase 'project' as one commit against 'main', and merge 
> that single commit back, a la:
> 
>    o---o-m--o-o-o--o----m <- project
>   /     /              /
> o-o-o-o-o--o-o-o--o-o-o---m <- main branch
>                        \ /
>                         o <- project_collapsed
> 
> So that 'm' on 'main' is that one commit[1].
> 

I think you're misunderstanding the git meaning of rebase here. "git 
rebase" moves all commits since "project" forked from "main branch" to 
the tip of "main branch".

Other than that, this is the recommended workflow, and exactly how Linux 
and git both are managed (i.e. topic branches eventually merged into 
'master').

In your drawings, 'main branch' would be 'master' and 'project' would be 
any amount of topic-branches (or just one, if you like that better).

I'm not sure what you mean by 'project_collapsed' though. If I 
understand you correctly, each branch-head represents one 'collapse'. I 
suggest you clone the git repo and do

	$ gitk master
	$ gitk next
	$ gitk pu

gitk is great for visualizing what you've done and what the repo looks 
like. Use and abuse it frequently every time you're unsure what was you 
just did. It's the best way to quickly learn what happens, really.

If you just want to distribute snapshots I suggest you do take a look at 
git-tar-tree. Junio makes nice use of it in the git Makefile (the dist: 
target).


> The merits or demerits of such merging practice aside, what reason would 
> there be /against/ recording explicit rename information in the commit 
> object, so as to help browsers follow history (particularly impure 
> renames) better in a commit?
> 
> I.e. would there be resistance to adding meta-info rename headers commit 
> objects, and having diffcore and other tools to use those headers to 
> /augment/ their existing heuristics in detecting renames?
> 

Personally I think metadata is evil. Renames will still be auto-detected 
anyway, and with the distributed repo setup the only reason git 
shouldn't be able to detect a rename is if you rename a file and hack it 
up so it doesn't even come close to matching its origin (close in this 
case is 80% by default, I think). In those cases it isn't so much a 
rename as a rewrite. If you find the commit where the file was renamed 
it should be listed in that commit, like so:

	similarity index 92%
	rename from Documentation/git-log-script.txt
	rename to Documentation/git-log.txt

(this is gitk output from the git repo. Search for "Big tool rename")

IMO this is far better than having to tell git "I renamed this file to 
that", since it also detects code-copying with modifications, and it's 
usually quick enough to find those renames as well.

> Thanks!
> 
> 1. Git currently doesn't have 'porcelain' to do this, presumably there'd 
> be no objection to one?
> 

	$ git checkout master
	$ git pull . project

The dot means "pull from the local repo". "project" is the branch you 
want to merge into master. You can pull an arbitrary amount of branches 
in one go ("octopus" merge). The current tested limit is 12 (thanks, Len 
;) ).

If, for some reason, you want to combine lots of commits into a single 
mega-patch (like Linus does for each release of the kernel), you can do:

	$ git diff $(git merge-base main project) project > patch-file

Then you can apply patch-file to whatever branch you want and make the 
commit as if it was a single change-set. I'd recommend against it unless 
you're just toying around though. It's a bad idea to lie in a projects 
history.

Hope that helps.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: bug?: stgit creates (unneccessary?) conflicts when pulling
From: Catalin Marinas @ 2006-03-01 15:08 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: Karl Hasselström, git
In-Reply-To: <20060301145105.GB3313@spearce.org>

On 01/03/06, Shawn Pearce <spearce@spearce.org> wrote:
> [Side Note: I've suddenly stopped receiving mail from vger.
>  Even majordomo isn't replying to my pleas for help.  Arggh!
>  Yet all other incoming email seems to be fine.]

news.gmane.org

> True.  The constant reapplication does really slow it down.  So does
> grabbing the reverse patch and seeing if it applies backwards
> cleanly.  Neither operation is fast, and neither is really going
> to be fast.

I realised that, depending on the number of patches merged upstream,
using this option can make StGIT faster. That's because when pushing a
patch (without the --merged option), StGIT first tries a diff | apply
followed by a three-way merge (even slower) if the former method
fails. This means that for all the patches merged upstream, StGIT
tries both methods since diff | apply fails anyway. With the --merged
option, StGIT would only try the reverse-diff | apply and, if this
succeeds, it will skip the normal push methods.

--
Catalin

^ permalink raw reply


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