Git development
 help / color / mirror / Atom feed
* Re: "tla missing -s" equivalent with git/cogito
From: Martin Langhoff @ 2006-01-18 19:07 UTC (permalink / raw)
  To: Petr Baudis; +Cc: luis, git
In-Reply-To: <20060118185542.GT28365@pasky.or.cz>

On 1/19/06, Petr Baudis <pasky@suse.cz> wrote:
> Now you want to merge the branch as a whole. Cherrypicking-aware VCS
> would just merge the patch2, but you are taking the whole diff:
...
> And you get a conflict instead of b\nc.

While I haven't tested your particular example, it looks to me like
git-cherry would identify it correctly. So far my experience has been
that git-cherry's strategy detects my cherry-picked patches pretty
well.

Why would it not work in your example? Patch 1 has clearly been
applied in both branches, and git-cherry would normally detect that
alright.

btw, when is cg-merge switching to use git-merge? :-p



martin

^ permalink raw reply

* Re: Joining Repositories
From: Ryan Anderson @ 2006-01-18 18:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Petr Baudis, Mathias Waack, git
In-Reply-To: <Pine.LNX.4.64.0601180813170.3240@g5.osdl.org>

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

Linus Torvalds wrote:
> 
> On Wed, 18 Jan 2006, Ryan Anderson wrote:
> 
>>Assuming both repositories are clean, no extraneous files, and without
>>testing, of course:
>>
>>In r1:
>>	mkdir r1
>>	# move everything into the subdirectory called r1.
>>	git mv $(ls -a | grep -v -e ^.git$ -e ^r1$) r1/
>>	git commit -a "Restructure directory"
>>
>>In r2:
>>	mkdir r2
>>	# move all files into r2/
>>	git mv $(ls -a | grep -v -e ^.git$ -e ^r2$) r2/
>>	git commit -a "Restructure directory"
>>
>>	git fetch ../r1/
>>	GIT_INDEX_FILE=.git/tmp-index git-read-tree FETCH_HEAD
>>	GIT_INDEX_FILE=.git/tmp-index git-checkout-cache -a -u
>>	git-update-cache --add -- $(GIT_INDEX_FILE=.git/tmp-index git-ls-files)
>>	cp .git/FETCH_HEAD .git/MERGE_HEAD
>>	git commit
>>
>>No history rewritten,
> 
> 
> Right.
> 
> 
>>merging with the old repositories should, at least theoretically, work, 
>>etc.
> 
> 
> No. This - and the history rewriting - both have a fundamental problem: it 
> becomes totally impossible to merge back any changes of the subprojects, 
> at least automatically. The renaming just ends up making pretty much any 
> merge a manual affair (git can _help_, but it's going to be a matter of 
> luck if it works or not - and it usually won't work very well, because 
> you'll probably end up having files that have the same name in the new and 
> the old repo, and eventually you'll just have tons of confusion).

What I meant was that an old repository can continue to be developed in,
and, in theory, the recursive merge should be able to merge those
changes into this new, joined, repository.



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

^ permalink raw reply

* Re: "tla missing -s" equivalent with git/cogito
From: Petr Baudis @ 2006-01-18 18:55 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: luis, git
In-Reply-To: <46a038f90601180956r69ba5dffl2106f697a6be4750@mail.gmail.com>

Dear diary, on Wed, Jan 18, 2006 at 06:56:38PM CET, I got a letter
where Martin Langhoff <martin.langhoff@gmail.com> said that...
> Andreas' response is good is you're into pure git. Let me add some
> cogito tricks ;-)
> 
> On 1/19/06, Belmar-Letelier <luis@itaapy.com> wrote:
> > arch-tla equivalent of
> >
> > $ cd project--luis--0.1
> > $ tla missing -sD paul@mail.com--public/project--paul--0.1
> 
>  $ cd project-luis
>  # only if have to do cg-branch-add the first time!
>  $ cg-branch-add paul http://server/git/project.git
>  $ cg-fetch paul
>  # show what paul has that we don't
>  $ cg-log -r master:paul
>  $ cg-diff -r master:paul

I usually do this as

	$ cg-log -m -r paul

which is shorter (and in some situations more accurately describes which
commits are actually going to get merged).

But I believe that Belmar-Letelier might be happier with git-cherry,
since he wants to do cherrypicking (and wrapping that in cg-log might
not be bad idea).

> > or I cherry pick only one of them (here patch-6) with
> >
> > $ tla replay  somefriend@mail.com--public/project--branchA--0.1--patch-6
> 
>   # export the patches paul has that we don't
>   $ mkdir .patchesfrompaul
>   $ git-format-patch --mbox --signoff -o .patchesfrompaul master paul
>   # review the contents of .patchesfrompaul and decide what patches you want
>   $ git-am -3 .patchesfrompaul/0006-fix-frob-invocation.txt

If you just want to pick one commit, it shouldn't be more difficult than

	$ cg-diff -p -r commitid | cg-patch
	$ cg-commit -c commitid

but I was actually thinking about wrapping this up to something like
cg-cherrypick or cg-pick. Perhaps I will just overload cg-patch, though
- I want to add support for autocommitting the patches there anyway.

> When you cherry pick patches, if the patch applies cleanly, the next
> time you do a merge from that branch it will be skipped automagically.
> If the patch needs serious editing, there's a good chance that git
> will try to apply it again.

No, it will not be skipped automagically - GIT really does not properly
support merging  of branch you've cherrypicked before. It might work,
but that's just luck - very similar to the luck you might have when
re-merging branches in CVS using the original merge base.

Imagine having branch with two patches 1 and 2. There is a file X:

	a

Ppatch1:

	-a
	+b
	+c

Patch2:

	-b
	+a
	c

Resulting file:

	a
	c

Now, you've cherrypicked patch1, so your file is:

	b
	c

Now you want to merge the branch as a whole. Cherrypicking-aware VCS
would just merge the patch2, but you are taking the whole diff:

	a
	+c

And you get a conflict instead of b\nc.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us
what it's like to be the universe.  -- Douglas Adams

^ permalink raw reply

* Re: [PATCH] "sleep 1" sleeps too little on cygwin
From: Alex Riesen @ 2006-01-18 18:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7v4q41zd1t.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano, Wed, Jan 18, 2006 18:00:30 +0100:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > And where does the time lag (required for the test) come from now?
> 
> The point of the change is that it avoids to depend on the time
> lag.  The test is to make sure we catch dirty index; instead of
> timestamp difference it now uses i-num difference for that.
> 

this is probable unsafe too: not all systems export inodes
(the recent cygwin breakage comes to mind).

^ permalink raw reply

* Re: [QUESTION] What is a tag for?
From: Andreas Ericsson @ 2006-01-18 18:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfynlwg8n.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:
> Andreas Ericsson <ae@op5.se> writes:
> 
> 
>>I'd recommend not allowing un-annotated tags in your shared repo. I
>>sent a patch for the default update-hook sometime ago that disallows
>>this. Junio seemed happy about it so I don't understand why it hasn't
>>been pushed to the master branch yet.
> 
> 
> Most likely lost in the noise.  I probably have it in my mailbox
> but not applied in any of my private branches in my repository.
> 

I'll apply (and test) Linus suggestions of new refs and re-send it when 
I'm done watching King-Kong and stuffing my face with popcorn.

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

^ permalink raw reply

* Re: RFC: Subprojects
From: Junio C Hamano @ 2006-01-18 18:49 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0601181214150.25300@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> writes:

> I assume these get updated by checkout when you check out the commit with 
> them as bind lines?

I did not think of that when I wrote that message, but you are right.

> Ah, okay, so it's cheating for checkout, because checkout is supposed to 
> understand everything, but not cheating for other things.

Yeah; to put it another way, read-tree of the toplevel tree and
checking it out is equivalent to do the skelton read-tree
followed by --prefix read-tree of all the bound projects, so
checkout can optimize.

> ... I thought we 
> decided that the stuff that doesn't know about subprojects sees them as 
> opaque, rather than as their contents, so your toplevel git diff doesn't 
> show you a millions lines when you switch from linux-2.6.14 to 15.

It was discussed in the context of "gitlink" approach as a way
to keep things simple.  In the "bind" approach, I am doing
things a bit differently, and this "toplevel has everything" is
one big difference.

> I thought we decided that committing the superproject wouldn't
> commit the subprojects.

I see it as a policy.  We can forbid the modification of the
subproject part of the index (i.e. detect and refuse to commit
and/or do "git reset --mixed" only for the subproject part) so
that the commit outlined in the "bind" approach does not _have_
to make a new commit, if you want to work that way.  But if
somebody else wants to make a related set of changes to the
superproject and bound subprojects, we _could_ allow a commit
per subproject.

> Shouldn't "git read-tree --prefix=linux-2.6/ -u kernel" remove everything 
> else in the index in linux-2.6 itself, making the "git update-index 
> --force-remove" unnecessary?

I agree that "-u" should imply that.  The current "read-tree
--prefix=linux-2.6/" in proposed updates refuses if linux-2.6/
appears in the original index.

> I hope people will want to prepare their commits to the kernel subproject 
> as would be suitable for pushing to Linus, which would suggest that they'd 
> tend to do a commit in the kernel subproject embedded in their 
> superproject separately from doing the commit in the superproject, and 
> so the branch head would match the index but not the bind line when they 
> got to committing the superproject.

Yes, that is the workflow I outlined in the footnote part you
did not quote.  I think it is cleaner to do things that way: to
have a separate, kernel-only repository+worktree and do pure
kernel work there, and fetch into the superproject branch that
keeps track of the kernel subproject in that superproject.

Having more than one working tree with .git/, everything except
HEAD and index undef which are symlinked to one copy, like you
do, would be a natural way to work.

	embed/.git/HEAD -> refs/heads/master

	embed/linux-2.6/.git/HEAD -> refs/heads/kernel
	embed/linux-2.6/.git/refs -> ../.git/refs
	embed/linux-2.6/.git/objects -> ../.git/objects

Then, after hacking on the collective whole to make the whole
thing work in "embed" directory, you would:

	$ cd linux-2.6
        $ git commit

to make commit that can be sent Linus, at the same time updating
the "kernel" branch.  Then come back to the toplevel, tell git
that you updated the "kernel" branch so it does not complain
that the "bind" in the HEAD commit does not match "kernel" head,
and make a toplevel commit.

^ permalink raw reply

* Re: Joining Repositories
From: Linus Torvalds @ 2006-01-18 18:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqy9xx2r.fsf@assigned-by-dhcp.cox.net>



On Wed, 18 Jan 2006, Junio C Hamano wrote:
> 
> Tracking history across renames is something we have only half
> of the needed support.  We can notice rename points but there is
> no way to tell our usability tools to automatically follow it.
> IOW "whatchanged r1/hello.c" will stop at the point the
> original project renamed hello.c

Note that "whatchanged" really really _really_ must not follow renames.

Why? The whole _point_ of whatchanged is that it takes a path limiter. A 
path limiter is much more useful (to me) that following files. A path 
limiter works even when the file doesn't _currently_ exist, and you don't 
know what happened to it. A path limiter also fundamentally works for 
directories and for multiple files.

If you want "git annotate", then do a "git annotate". Don't change what 
"git whatchanged" does. The "pathname only" behaviour is in my opinion THE 
MOST SINGLE BIGGEST FEATURE of git.

I _much_ more often use a directory to "git-whatchanged" than I look at an 
individual file. Maybe other people don't do that, because they don't tend 
to look at the "big picture", or because they are stuck in the "single 
file only" mentality, but trust me, especially for maintaining big things, 
the "track directories" is a lot more important than single-file tracking. 

A _LOT_ more.

I realize that this is heresy to people who are used to "annotate" and 
want to follow not the path, but the "conceptual inode", but the thing is, 
paths really really are a lot more important to a maintainer. Following an 
individual file is a secondary issue.

Now, the fact that we still don't have an efficient "git annotate" is not 
because we don't have the capability. It _should_ be perfectly easy to do 
(and efficient) by just parsing the output of

	git-rev-list HEAD -- <filename>

and when you see a "delete" event, you'd look if it was really a rename.

I think qgit does this, but we don't have the textual version in core git.

So the reason core git tracks PATHNAMES and not files is:

 - it's fundamentally a much more powerful operation

 - it's possible (and not that much harder) to track renames efficiently 
   using it anyway, so you can emulate the "track file" behaviour using 
   "track pathname", but you can NOT emulate it the other way around.

In other words, tracking pathnames is really _fundamentally_ a more 
powerful operation.

Git does this right. It is - together with multiple branches - the thing 
that makes git work better than BK did for me.

> > suggest just something like
> >
> > 	git clone oldrepo r1
> > 	cd r1
> > 	git checkout -b join-branch
> > 	cd ..
> > 	git add r1/.git/refs/heads/join-branch
> > 	git commit -m "Join repo 'oldrepo' at 'r1'"
> >
> > which should actually work except for the fact that we don't like the 
> > ".git" component even as part of a sub-component (ie small hack to git 
> > required to make it not ignore that path).
> 
> Sorry you lost me with this.  The "join-branch" is a file with
> commit object name in it, so is this "recording the revision of
> the other project this particular version of the project is
> linked to" idea?

Yes. It also means that if you update the other project (commit, pull, 
whatever), "git diff" in the top level will do the right thing: it won't 
be readable, but you'll always have the SHA1 visible, and you can "commit" 
the fact that you updated the sub-project in the top project. It's 
basically a poor mans "gitlink".

		Linus

^ permalink raw reply

* Re: [QUESTION] What is a tag for?
From: Junio C Hamano @ 2006-01-18 18:19 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: git
In-Reply-To: <43CE19F2.6000709@op5.se>

Andreas Ericsson <ae@op5.se> writes:

> I'd recommend not allowing un-annotated tags in your shared repo. I
> sent a patch for the default update-hook sometime ago that disallows
> this. Junio seemed happy about it so I don't understand why it hasn't
> been pushed to the master branch yet.

Most likely lost in the noise.  I probably have it in my mailbox
but not applied in any of my private branches in my repository.

^ permalink raw reply

* Re: RFC: Subprojects
From: Daniel Barkalow @ 2006-01-18 18:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Josef Weidendorfer, git
In-Reply-To: <7vpsmq2tyb.fsf@assigned-by-dhcp.cox.net>

On Tue, 17 Jan 2006, Junio C Hamano wrote:

> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > Incidentally, I don't think we'd want "gitlink" objects with the "gitlink" 
> > approach; we'd want trees to contain commit objects for subprojects. The 
> > "gitlink" thing that corresponds to ".git/HEAD" isn't an object, it's a 
> > tree entry, which, like ".git/HEAD" (or, more appropriately, 
> > ".git/refs/heads/something") maps a name to the hash of a commit object.
> 
> > Hmm... maybe libification should go ahead of subprojects. If access to the 
> > index weren't so often open-coded, it would just be a matter of having 
> > these entries in the data structure, but not actually returned by any 
> > current call, and it would be just like they were in some other structure. 
> 
> And libification has been waiting for the core to settle ;-) We
> have to start somewhere.

Well, we could do a pass at cleaning, organizing, and documenting the 
internals, which is sort of the start to each of them.

> > Side issue here: this implies that the kernel objects are in the 
> > superproject's repository, or at least accessible from it. So prune has to 
> > not remove them. So, if you've committed changes to a subproject but not 
> > yet committed the fact that you want to use the changed subproject into 
> > the superproject, fsck-objects has to find them somewhere.
> 
> Yes.  I was planning to have "$GIT_DIR/bind" that says:
> 
> 	master kernel=linux-2.6/ gcc=gcc-4.0/
> 
> meaning:
> 
> 	The project kept track by "master" branch binds the
> 	project kept track by "kernel" branch as its subproject
> 	at its linux-2.6/ subdirectory.
> 
> or something like that, so when you make a commit, you update
> those other branches as needed.  You already raised that issue
> at the end of your message, and I will explain how I think that
> can/should be done as a response to that part later.

Okay, so you're using additional branch heads in the superproject to track 
the current state of the subprojects. That makes sense, although I think 
it would confuse people less if they were held separately. IIRC, 
refs/subprojects/kernel/heads/master is a perfectly good ref name these 
days, so that might be a good idea. That would also mean that 
refs/tags/v2.6.14 and refs/tags/v2.7.2.3 wouldn't get confused (being 
linux and gcc tags, respectively), because they'd be under the appropriate 
subprojects.

I assume these get updated by checkout when you check out the commit with 
them as bind lines?

> >> Reading such a commit is easy:
> >> 
> >> 	$ git-read-tree $tree ;# ;-)
> >> 
> >> But that is cheating.  
> >
> > This is for backwards compatibility, I assume?
> 
> This is done more for not having to touch *anything* that does
> "index vs working file", "tree vs index" and "tree vs working
> file via index".  It also is the easiest way to keep the "a
> commit object name can be used in place of the tree object name
> of the tree it contains" invariant.  Also I suspect this
> organization might help recursive subprojects, but if it is the
> case, that is just a byproduct, not a design goal.

Ah, okay, so it's cheating for checkout, because checkout is supposed to 
understand everything, but not cheating for other things. I thought we 
decided that the stuff that doesn't know about subprojects sees them as 
opaque, rather than as their contents, so your toplevel git diff doesn't 
show you a millions lines when you switch from linux-2.6.14 to 15.

> >> When you have such an index, writing out various trees are:
> >> 
> >> 	$ git-write-tree ;# $tree
> >> 	$ git-write-tree --prefix=linux-2.6/ ;# $linuxsub^{tree}
> >> 	$ git-write-tree --prefix=gcc-4.0/ ;# $gccsub^{tree}
> >> 	$ git-write-tree \
> >>           --bound=linux-2.6/ --bound=gcc-4.0/ ;# $primarysub^{tree}
> >
> > The hard thing here is getting the commits for the trees. The bind lines 
> > need commits, which means either identifying that we already have the 
> > correct commit object, because we didn't change anything in the 
> > subproject, or generating a new commit object with some message and the 
> > right parent. And we want to use commit objects, not tree objects, in the 
> > bind lines, so that, once we track a problem to the change of which commit 
> > is bound, we can treat the subproject as a project and debug it with 
> > bisect, rather than just having one tree that works and one that doesn't.
> 
> Your wording "get the commit" is a bit misleading.  Even when
> the tree for a subproject happens to match a commit in the
> subproject in a distant past, we would not want to use it unless
> the user explicitly asked for it.  IOW, we do not actively go
> and look for a commit.

We don't search the history for just any commit, but we have to look 
somewhere...

> Our subproject tree either matches the subproject branch head,
> in which case we just reuse it, or we make a new commit on top
> of that ourselves.

I hadn't realized that the subprojects had branch heads. It makes much 
more sense that you'd expect to be able to just write out bind lines if 
you've got that information.

I thought we decided that committing the superproject wouldn't commit the 
subprojects. If this is what we decided, then the subproject tree is 
required to match the branch head, because we must have committed the 
subproject already (which is good, because otherwise the user will get 
confused about which commit message to write when).

> Let's say my project breaks with the latest kernel, and I
> suspect that it would work with v2.6.13 sources.  To test that
> theory, I could:
> 
>         $ git branch -f kernel v2.6.13 ;# rewind
> 
> 	$ git ls-files linux-2.6/ |
>           xargs git update-index --force-remove
>         $ git read-tree --prefix=linux-2.6/ -u kernel
> 
> to construct such a tree.  Maybe the latter two-command sequence
> "ls-files & read-tree --prefix" sequence deserves to become a
> command, "git update-subproject kernel" [*1*].

Shouldn't "git read-tree --prefix=linux-2.6/ -u kernel" remove everything 
else in the index in linux-2.6 itself, making the "git update-index 
--force-remove" unnecessary?

> The result may work as-is, or I may need to do some further
> futzing in linux-2.6/ directory before the result works.  Once
> the result starts working, I'd want to make a commit:
> 
>  - I compare the result of write-tree for linux-2.6/ portion and
>    the tree object name contained in the head commit of the
>    "kernel" branch.  If they match, then the current "kernel"
>    branch head commit is what I'll place on the "bind" line in
>    my commit; I do not have to make a new commit in the "kernel"
>    subproject in this case.
> 
>  - If the tree object does not match the "kernel" head, that
>    means I have tweaked the kernel part further, on top of
>    v2.6.13.  So I make a commit for the kernel subproject (whose
>    parent is obviously v2.6.13), update the kernel branch head
>    with that commit, and then record that tip-of-the-tree commit
>    for the subproject on the "bind" line in my commit for the
>    toplevel.

Equivalently, you make a commit for the kernel subproject, update the 
branch head, and start over; the first case should apply now.

> Or let's say my project builds with the latest kernel (IOW, I
> did not do the branch -f kernel in the above), and I made some
> custom tweaks in the kernel area.  The above precedure would
> result in a new commit on top of the latest kernel, update the
> "kernel" branch head, and make a commit for the toplevel that
> records the updated "kernel" branch head on its "bind" line.
> 
> Note that the above procedure did not use the commit object name
> recorded on the "bind" line at all in either case.  From the
> mechanism point of view, it is the right thing to do.  From the
> usability point of view, however, we may want to take notice
> that "bind" line commit and the bound branch head do not match,
> and remind/warn the user about it.  If the reason why they are
> different is because the user rewound the bound branch to use a
> known working version, or made fixes in the subproject and
> pulled the result into the bound branch (in which case there is
> no funny rewinding involved), then this warning is
> extraneous. But in the normal case of keep reusing the same
> vintage of subprojects (and maybe making necessary adjustments
> to subprojects while working on the main project), the commit
> object on the "bind" line of the HEAD commit and bound branch
> head should match.

I hope people will want to prepare their commits to the kernel subproject 
as would be suitable for pushing to Linus, which would suggest that they'd 
tend to do a commit in the kernel subproject embedded in their 
superproject separately from doing the commit in the superproject, and 
so the branch head would match the index but not the bind line when they 
got to committing the superproject.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: "tla missing -s" equivalent with git/cogito
From: Martin Langhoff @ 2006-01-18 18:06 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Andreas Ericsson, git
In-Reply-To: <7vlkxdwhs6.fsf@assigned-by-dhcp.cox.net>

On 1/19/06, Junio C Hamano <junkio@cox.net> wrote:
> Arch star-merge is not an octopus.  They have different "merge
> strategy" just like we have more than one.  No, I do not
> remember the details of how they do it.

In Arch, star-merge is roughly equivalent to git-merge. When I was an
Arch user, I could go out and take a walk under the stars while it
tried to work its magic on my 10K file tree -- so the name was quite
fitting ;-)

The main difference with git is that it has explicit rename tracking
and explicit "patches already applied" tracking. We detect those
things at merge time, and in my projects it has so far worked better
than tla's explicit tracking of things -- but only when I merge with
git-merge. One of these days I'll convince Pasky to use git-merge for
cg-merge's internals.

cheers,


martin

^ permalink raw reply

* Re: Joining Repositories
From: Linus Torvalds @ 2006-01-18 18:03 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Ryan Anderson, Mathias Waack, git
In-Reply-To: <20060118170536.GS28365@pasky.or.cz>



On Wed, 18 Jan 2006, Petr Baudis wrote:
> 
> Well, the recursive merge strategy is at least advertised to be able to
> merge across renames (as long as they are autodetected).

Yes. It can. However, the git merge approach fundamentally expects that 
the merged trees _converge_. 

So what happens is that if two trees continue to be developed as separate 
trees, and the merges never converge (ie they happen just one way, with 
the other way seldom or never merging back), the merge strategy will get 
increasingly bad.

That's pretty unavoidable, btw. I can pretty much guarantee that nobody 
else will really do it any better, although any particular strategy will 
always handle one particular case perfectly (*).

			Linus

(*) I think merging is like scheduling: you can always find a perfect 
scheduling algorithm _after_the_fact_ when you know the load, but finding 
one that works for all loads inevitably means that some cases won't work 
well. You also find scheduling getting an inordinate amount of time in CS 
literature, while in real life it's one of the least important problems of 
a kernel.

^ permalink raw reply

* Re: "tla missing -s" equivalent with git/cogito
From: Martin Langhoff @ 2006-01-18 17:56 UTC (permalink / raw)
  To: luis; +Cc: git
In-Reply-To: <43CE5666.90502@itaapy.com>

Andreas' response is good is you're into pure git. Let me add some
cogito tricks ;-)

On 1/19/06, Belmar-Letelier <luis@itaapy.com> wrote:
> arch-tla equivalent of
>
> $ cd project--luis--0.1
> $ tla missing -sD paul@mail.com--public/project--paul--0.1

 $ cd project-luis
 # only if have to do cg-branch-add the first time!
 $ cg-branch-add paul http://server/git/project.git
 $ cg-fetch paul
 # show what paul has that we don't
 $ cg-log -r master:paul
 $ cg-diff -r master:paul
 # show what we have that paul doesn't
 $ cg-log -r paul:master
 $ cg-diff -r master:paul

You can also do

 $ cg-diff -r master:paul

> so I get the information like what are the interesting patch to get
>
> and then I take all of them with
>
> $ tla star-merge -t paul@mail.com--public/project--paul--0.1

 # if you've done cg-fetch paul and reviewed it what you're about to
merge, just do
 cg-merge paul

 # otherwise, for a shortcut of cg-fetch <branch> && cg-merge <branch> do
 $ cg-update paul

> or I cherry pick only one of them (here patch-6) with
>
> $ tla replay  somefriend@mail.com--public/project--branchA--0.1--patch-6

  # export the patches paul has that we don't
  $ mkdir .patchesfrompaul
  $ git-format-patch --mbox --signoff -o .patchesfrompaul master paul
  # review the contents of .patchesfrompaul and decide what patches you want
  $ git-am -3 .patchesfrompaul/0006-fix-frob-invocation.txt

Note that git does not track patch application _explicitly_ like Arch
does, it tracks them only indirectly. Merges (tla star-merge type of
merges) are recorded explicitly. This work surprisingly well. If you
do a cg-update, cg-merge or git-merge, git will keep a good record of
what points of the history have been merged.

When you cherry pick patches, if the patch applies cleanly, the next
time you do a merge from that branch it will be skipped automagically.
If the patch needs serious editing, there's a good chance that git
will try to apply it again.

cheers.


martin

^ permalink raw reply

* Re: [QUESTION] about .git/info/grafts file
From: Franck @ 2006-01-18 17:47 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <cda58cb80601170932o6f955469y@mail.gmail.com>

Hi,

Could anybody shed some light there ? It would be very nice.

Thanks
                  Franck

2006/1/17, Franck <vagabon.xyz@gmail.com>:
> Hi,
>
> I'm wondering why the "grafts" files is not involved during
> push/pull/clone operations ?
>
> Another question regarding grafting use case. Let's say I have my
> origin branch looks like:
>
>                origin ---0---1---<snip>---300 000---300 001---300 002
>
> Let's say that the 300 000th commit is where I started my work by using:
>
>                $ git-checkout -b master <300 000 shaid>
>
> I do some work on master branch and get the following
>
>                                                  a---b---c---d master
>                                                 /
>                origin ---0---1---...---300,000---300,001---300,002
>
> Now, I would like to make my own public repository based on my work
> but before pushing master branch in that repo I would like to get rid
> of all unused commits [0 299,999]. Indeed each of these commits do not
> have useful history for my work. So I used grafts things to have:
>
>                               a---b---c---d master
>                              /
>                origin 300,000---300,001---300,002
>
> But now if I ask to git for:
>
>                $ git-merge-base master origin
>                # nothing
>
> So git failed to found the common commit object which should be 300,000. Why ?
>
> In other the hand, if I use grafting to get:
>
>                                                a---b---c---d master
>                                               /
>                origin 2999,999---300,000---300,001---300,002
>
>               $ git-merge-base master origin
>               2dcaaf2decd31ac9a21d616604c0a7c1fa65d5a4
>
> So now git found the common commit. Can anybody explain me why ?
>
> Do you think it's a good usage of git ? Or should I do otherwise to
> setup my public repository ?
>
> Thanks
> --
>                Franck
>

^ permalink raw reply

* Re: "tla missing -s" equivalent with git/cogito
From: Junio C Hamano @ 2006-01-18 17:46 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: git
In-Reply-To: <43CE75F0.4060009@op5.se>

Andreas Ericsson <ae@op5.se> writes:

> The "pull" above will do the merging nessecary. You can merge several
> branches at once if you like (known as "doing an octopus" in
> gittish. I imagine that's a star-merge in arch).

Arch star-merge is not an octopus.  They have different "merge
strategy" just like we have more than one.  No, I do not
remember the details of how they do it.

^ permalink raw reply

* Re: Joining Repositories
From: Junio C Hamano @ 2006-01-18 17:33 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060118170536.GS28365@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

> Well, the recursive merge strategy is at least advertised to be able to
> merge across renames (as long as they are autodetected). Not that I
> would have any practical experiences with it and I don't know how smart
> is it done (if it just runs rename detection between the merge base and
> current head, yes, that might not give very good results in this case).

If I understand and remember the code correctly, it is based on
rename detection between two heads.  When the versions have
diverged greatly beyond recognition, obviously this would not
work well.

^ permalink raw reply

* Re: Joining Repositories
From: Junio C Hamano @ 2006-01-18 17:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0601180813170.3240@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> On Wed, 18 Jan 2006, Ryan Anderson wrote:
>>
>> Assuming both repositories are clean, no extraneous files, and without
>> testing, of course:
>>
>> ... "coolest merge ever" recipe here ... 
>> 
>> No history rewritten,
>
> Right.

>> merging with the old repositories should, at least theoretically, work, 
>> etc.
>
> No. This - and the history rewriting - both have a fundamental problem: it 
> becomes totally impossible to merge back any changes of the subprojects, 
> at least automatically.

Right.

> In the "gitk" case, we could actually continue to merge stuff after a 
> join, but that was largaly because there was no renaming. That's a very 
> special case, and it also became impossible to merge back.

Correct.

> Now, let's see what Junio comes up with,...

Well, since the reason the original RFI came was "somehow we
forgot these things are together but ended up having to and need
a way to rectify the situation", in this particular case,
merging back the changes to subprojects (which is very awkward
if not impossible after a "coolest merge ever") is a non issue.

Tracking history across renames is something we have only half
of the needed support.  We can notice rename points but there is
no way to tell our usability tools to automatically follow it.
IOW "whatchanged r1/hello.c" will stop at the point the
original project renamed hello.c to r1/hello.c in preparation
for the coolest merge and you have to restart whatchanged at
that commit with "whatchanged $that_commit hello.c" to go
further back; but that is true when no project merge is involved
so it may be an issue but it is not a new issue.

So for this case, I think the "coolest merge" is the right thing
to do.

> suggest just something like
>
> 	git clone oldrepo r1
> 	cd r1
> 	git checkout -b join-branch
> 	cd ..
> 	git add r1/.git/refs/heads/join-branch
> 	git commit -m "Join repo 'oldrepo' at 'r1'"
>
> which should actually work except for the fact that we don't like the 
> ".git" component even as part of a sub-component (ie small hack to git 
> required to make it not ignore that path).

Sorry you lost me with this.  The "join-branch" is a file with
commit object name in it, so is this "recording the revision of
the other project this particular version of the project is
linked to" idea?

^ permalink raw reply

* Re: "git cat" and "git ls"
From: Junio C Hamano @ 2006-01-18 17:14 UTC (permalink / raw)
  To: Santi Béjar; +Cc: git
In-Reply-To: <87irsh6087.fsf@gmail.com>

Santi Béjar <sbejar@gmail.com> writes:

>         following the "git diff" wrapper I've done two new wrappers:
>
> git cat: USAGE='<tag|commit|blob> | [<ent>|-1|-2|-3] -- <file>'
> git ls: USAGE='[<ent>] [--] <path>'

Not interested; sorry.

The only thing I find lacking from the current set of tools is a
way to prettyprint an annotated tag to make its date human
readable.

^ permalink raw reply

* Re: "tla missing -s" equivalent with git/cogito
From: Andreas Ericsson @ 2006-01-18 17:08 UTC (permalink / raw)
  To: luis; +Cc: git
In-Reply-To: <43CE5666.90502@itaapy.com>

Belmar-Letelier wrote:
> Hello,
> 
> Could someone say me how we do in cogito or git the
> 
> arch-tla equivalent of
> 
> $ cd project--luis--0.1
> $ tla missing -sD paul@mail.com--public/project--paul--0.1
> 
> so I get the information like what are the interesting patch to get
> 
> and then I take all of them with
> 
> $ tla star-merge -t paul@mail.com--public/project--paul--0.1
> 
> or I cherry pick only one of them (here patch-6) with
> 
> $ tla replay  somefriend@mail.com--public/project--branchA--0.1--patch-6
> 

Not that I'm even half aware of how arch does this, but if the two repos 
are cloned from the same one (which they seem to be), you could just do

	$ git checkout -b paul
	$ git pull <path-to-pauls-repo> <branch-from-pauls-repo>

The "pull" above will do the merging nessecary. You can merge several 
branches at once if you like (known as "doing an octopus" in gittish. I 
imagine that's a star-merge in arch).

Then, if you want to cherry-pick commits from Paul's repo to your 
master-branch, you do

	$ git checkout master
	$ git cherry-pick -r paul~3

to replay the commit 3 steps below the tip of Paul's latest commit in 
the branch you just pulled from.

If you want to import all of them into your own master branch you can do

	$ git checkout master
	$ git pull . paul


You can also do

	$ cd pauls-repo
	$ git format-patch --mbox -k HEAD~10 -o /your/repo
	$ cd /your/repo
	$ git am -k 00*.txt

but that has the feel of doing things the wrong way around (exporting 
from a repo to import to another should be done by a fetch or, if you 
want to merge them into whatever branch you're currently on, a pull).


Two things worth noting:
* git repositories are damn near indestructible, so long as you don't 
run "git prune" while mucking around doing very strange things or suffer 
hardware failure. Don't be afraid to experiment.

* gitk is your friend for finding out where you are in the repo and what 
actually happens when you merge, reset, revert, rebase, commit, pull, 
fetch, branch, tag or does something else entirely. Use it. You'll be 
glad you did.

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

^ permalink raw reply

* Re: RFC: Subprojects
From: Junio C Hamano @ 2006-01-18 17:06 UTC (permalink / raw)
  To: Alexander Litvinov; +Cc: git
In-Reply-To: <200601181747.15609.lan@ac-sw.com>

Alexander Litvinov <lan@ac-sw.com> writes:

>> I started this "bind" design as a thought experiment, but I
>> started to like it more and more.
>>
>
> Is there a version of git with this to try it ?

	http://article.gmane.org/gmane.comp.version-control.git/14760

As I warned there, it still has quite rough edges, so do not use
it on your production repositories.

^ permalink raw reply

* Re: Joining Repositories
From: Petr Baudis @ 2006-01-18 17:05 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ryan Anderson, Mathias Waack, git
In-Reply-To: <Pine.LNX.4.64.0601180813170.3240@g5.osdl.org>

Dear diary, on Wed, Jan 18, 2006 at 05:23:03PM CET, I got a letter
where Linus Torvalds <torvalds@osdl.org> said that...
> On Wed, 18 Jan 2006, Ryan Anderson wrote:
> > merging with the old repositories should, at least theoretically, work, 
> > etc.
> 
> No. This - and the history rewriting - both have a fundamental problem: it 
> becomes totally impossible to merge back any changes of the subprojects, 
> at least automatically. The renaming just ends up making pretty much any 
> merge a manual affair (git can _help_, but it's going to be a matter of 
> luck if it works or not - and it usually won't work very well, because 
> you'll probably end up having files that have the same name in the new and 
> the old repo, and eventually you'll just have tons of confusion).

Well, the recursive merge strategy is at least advertised to be able to
merge across renames (as long as they are autodetected). Not that I
would have any practical experiences with it and I don't know how smart
is it done (if it just runs rename detection between the merge base and
current head, yes, that might not give very good results in this case).

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us
what it's like to be the universe.  -- Douglas Adams

^ permalink raw reply

* Re: [PATCH] "sleep 1" sleeps too little on cygwin
From: Junio C Hamano @ 2006-01-18 17:00 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Alex Riesen, git
In-Reply-To: <Pine.LNX.4.63.0601181233460.8678@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> And where does the time lag (required for the test) come from now?

The point of the change is that it avoids to depend on the time
lag.  The test is to make sure we catch dirty index; instead of
timestamp difference it now uses i-num difference for that.

^ permalink raw reply

* Re: [PATCH] "sleep 1" sleeps too little on cygwin
From: Junio C Hamano @ 2006-01-18 16:55 UTC (permalink / raw)
  To: Alex Riesen; +Cc: git
In-Reply-To: <81b0412b0601180550k4df9b89fwf73af7966095ffc7@mail.gmail.com>

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

> On 1/18/06, Junio C Hamano <junkio@cox.net> wrote:
>> Instead of depending on $SECONDS (isn't it a bashism?), how
>> about doing something like this?
>
> Probably not, even QNX6 ksh has it, and being the most broken shell
> I ever met, I'd consider $SECONDS safe 8-)

When I have to answer these questions myself, I mostly do so by
checking http://www.opengroup.org/onlinepubs/009695399/.

^ permalink raw reply

* Re: Joining Repositories
From: H. Peter Anvin @ 2006-01-18 16:38 UTC (permalink / raw)
  To: Mathias Waack; +Cc: git
In-Reply-To: <200601181325.59832.Mathias.Waack@rantzau.de>

Mathias Waack wrote:
> Hello everybody, 
> 
> we're using git with cogito as a frontend. For some reasons I forgot we have 
> some repositories which belong to the same project. To simplify the whole 
> thing I would like to join these repositories. It mainly means to move some 
> directories. So lets say I have: 
> 
> 	/r1/.git
> 	/r2/.git
> 
> and what I would like to have is
> 
> 	/r/.git
> 	   r1
>            r2
> 
> Of course the history should remain (otherwise it would be to easy). 
> 
> How should I do this?
> 

Rename the files in each repository independently (with a checkin), then 
merge the repositories.

Git *should* track across the rename, as long as it's "obvious".

	-hpa

^ permalink raw reply

* Re: Joining Repositories
From: Linus Torvalds @ 2006-01-18 16:23 UTC (permalink / raw)
  To: Ryan Anderson; +Cc: Petr Baudis, Mathias Waack, git
In-Reply-To: <20060118140917.GA15438@mythryan2.michonline.com>



On Wed, 18 Jan 2006, Ryan Anderson wrote:
>
> Assuming both repositories are clean, no extraneous files, and without
> testing, of course:
> 
> In r1:
> 	mkdir r1
> 	# move everything into the subdirectory called r1.
> 	git mv $(ls -a | grep -v -e ^.git$ -e ^r1$) r1/
> 	git commit -a "Restructure directory"
> 
> In r2:
> 	mkdir r2
> 	# move all files into r2/
> 	git mv $(ls -a | grep -v -e ^.git$ -e ^r2$) r2/
> 	git commit -a "Restructure directory"
> 
> 	git fetch ../r1/
> 	GIT_INDEX_FILE=.git/tmp-index git-read-tree FETCH_HEAD
> 	GIT_INDEX_FILE=.git/tmp-index git-checkout-cache -a -u
> 	git-update-cache --add -- $(GIT_INDEX_FILE=.git/tmp-index git-ls-files)
> 	cp .git/FETCH_HEAD .git/MERGE_HEAD
> 	git commit
> 
> No history rewritten,

Right.

> merging with the old repositories should, at least theoretically, work, 
> etc.

No. This - and the history rewriting - both have a fundamental problem: it 
becomes totally impossible to merge back any changes of the subprojects, 
at least automatically. The renaming just ends up making pretty much any 
merge a manual affair (git can _help_, but it's going to be a matter of 
luck if it works or not - and it usually won't work very well, because 
you'll probably end up having files that have the same name in the new and 
the old repo, and eventually you'll just have tons of confusion).

So it works only if you want to _really_ join the projects (like in the 
"git tools" case), and never touch the old one again but it sucks 
otherwise.

In the "gitk" case, we could actually continue to merge stuff after a 
join, but that was largaly because there was no renaming. That's a very 
special case, and it also became impossible to merge back.

Now, let's see what Junio comes up with, but in the meantime, I'd almost 
suggest just something like

	git clone oldrepo r1
	cd r1
	git checkout -b join-branch
	cd ..
	git add r1/.git/refs/heads/join-branch
	git commit -m "Join repo 'oldrepo' at 'r1'"

which should actually work except for the fact that we don't like the 
".git" component even as part of a sub-component (ie small hack to git 
required to make it not ignore that path).

		Linus

^ permalink raw reply

* Re: New ref generates 8MB mail message
From: Linus Torvalds @ 2006-01-18 16:12 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: git
In-Reply-To: <20060118140907.GV19769@parisc-linux.org>



On Wed, 18 Jan 2006, Matthew Wilcox wrote:
> 
> Based on the idea that a new branch is probably a branch off master, and
> if it isn't, then at least sending a log vs master is better than a log
> vs the beginning of time, I propose this patch:

Actually, since the update hook _should_ be called before the ref has 
actually been updated, it's probably much better to instead of this:

> -	git-rev-list --pretty "$3"
> +	git-rev-list --pretty "$3" ^master

do something like this:

	git-rev-list --pretty "$3" $(git-rev-parse --not --all)

which basically says: show any commits that are in the new ref, but are 
not in _any_ other ref.

Untested, of course.

		Linus

^ 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