* Re: RFC: Subprojects
From: Junio C Hamano @ 2006-01-18 3:49 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Josef Weidendorfer, git
In-Reply-To: <7vpsmq2tyb.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> Daniel Barkalow <barkalow@iabervon.org> writes:
>
>>> 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.
I started this "bind" design as a thought experiment, but I
started to like it more and more.
One interesting outcome of keeping the whole tree in the index
and the tree object recorded in the commit object of the
toplevel project is that a merge in the toplevel project "just
works".
To preserve our sanity, let's say we refuse to merge two commits
that have different sets of subprojects. That is, they must
have the "bind" lines for the same set of subdirectories. The
commits bound at these subdirectories do not need to match.
Before starting a merge, we require that the index is in sync
with the tree object recorded in the top commit, just like we do
for a normal merge[*1*]. Then we use the current merge
machinery that does not know anything about "bind" to perform
the merge, using the merge base of the toplevel project and
usual three-way merge. From the mechanism point of view, there
is no need to look at commits on "bind" line of either side to
come up with the resulting tree.
We could notice that the commit bound at linux-2.6/ subdirectory
of one side is v2.6.15 and the other side is v2.6.16-rc1, and
because one is a fast-forward of the other, choose to pick the
tree associated with v2.6.16-rc1 commit without actually doing
the 3-way resolve of linux-2.6/ subtree part, but that is purely
a performance optimization [*2*].
When writing out the merge result as a commit, we would create
(this is the fun part) a commit for linux-2.6/ part that has two
parents: the commits bound to linux-2.6/ tree from the two
toplevel commits being merged are the parents of such a
subproject commit. And the resulting toplevel merge commit
would have that commit object name on its "bind" line.
Obviously, when the bound subproject head of one side is a
fast-forwad of the other, we do not create such a merge commit
for the subproject; instead, we just record the one that is
ahead on the "bind" line of the resulting toplevel merge commit.
[Footnote]
*1* As a side effect, this also ensures the index is in sync
with the bound commits of the subprojects. As an additional
requirement, we may want to enforce that the bound commits must
match the branch heads that keep track of subprojects.
*2* Of course, from the usability, safety and confusion
avoidance point of view, it _might_ make sense to require that
bound commits are in such fast-forward relationship. But that
is a policy issue; at the mechanism level, there is no need to
impose such a requirement.
^ permalink raw reply
* Re: RFC: Subprojects
From: Junio C Hamano @ 2006-01-18 1:41 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Josef Weidendorfer, git
In-Reply-To: <Pine.LNX.4.64.0601171150050.25300@iabervon.org>
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.
> Actually, it should be easy to have them in the index file but not in the
> main index data structure, by skipping over them in the for loop near the
> end of read_cache()....
Yeah, I guess I was vaguely thinking along those lines while I
was driving to work this morning. I appreciate your spelling it
out to make things clearer.
> 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.
>> 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.
>> 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.
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.
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*].
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.
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.
[Footnote]
*1* One could also do a forward development on the kernel branch
in a separate working tree and fetch from there. For example,
if our example "superproject" is in embed/ directory, and there
is a linux/ directory next to it to house a kernel repository,
we could:
$ cd ../linux/
$ edit && compile && test
$ git commit -m 'Fix for upstream, not just for embed'
to make an upstream fix, and then:
$ cd ../embed/
$ git fetch ../linux/ master:kernel
to update the "kernel" subproject branch head. In such a case:
$ git update-subproject kernel
would bring the subproject working tree and index up to date
with respect to the updated kernel branch.
^ permalink raw reply
* Re: [PATCH] "sleep 1" sleeps too little on cygwin
From: Junio C Hamano @ 2006-01-18 1:41 UTC (permalink / raw)
To: Alex Riesen; +Cc: git
In-Reply-To: <81b0412b0601170325y60094b4w693ac37490c67410@mail.gmail.com>
Alex Riesen <raa.lkml@gmail.com> writes:
> Probably another one windows quirk, or just the moon phases,
> but I have to make damn sure it sleeps long enough.
IIRC, DOS file timestamps have 2 seconds granularity, so
sleeping for one second might not be enough to begin with. Also
I run my cygwin test on sufficiently slow machine, so that may
explain why I have not notice the problem ;-).
Instead of depending on $SECONDS (isn't it a bashism?), how
about doing something like this?
---
diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh
index e3ebf38..9a5fa38 100755
--- a/t/t4011-diff-symlink.sh
+++ b/t/t4011-diff-symlink.sh
@@ -23,6 +23,7 @@ EOF
test_expect_success \
'diff new symlink' \
'ln -s xyzzy frotz &&
+ touch -t 199901010000 frotz &&
git-update-index &&
tree=$(git-write-tree) &&
git-update-index --add frotz &&
@@ -58,8 +59,8 @@ EOF
test_expect_success \
'diff identical, but newly created symlink' \
- 'sleep 1 &&
- ln -s xyzzy frotz &&
+ 'ln -s xyzzy frotz &&
+ touch -t 200201010000 frotz &&
git-diff-index -M -p $tree > current &&
compare_diff_patch current expected'
^ permalink raw reply related
* Re: [QUESTION] What is a tag for?
From: Junio C Hamano @ 2006-01-18 1:41 UTC (permalink / raw)
To: Alex Bennee; +Cc: git
In-Reply-To: <1137538344.9104.34.camel@malory>
Alex Bennee <kernel-hacker@bennee.com> writes:
> ... I'm not brave enough to sit on the very bleeding edge and
> build what ever happens to be at the "HEAD" of the tree. However when a
> kernel releases I'd like to build *that* kernel.
Then maybe its time to change your e-mail address from
kernel-hacker to kernel-builder? ;-) ;-) ;-)
> I keep thinking of tags like labels in the old convetional SCM case. Is
> this correct?
Correct.
Tags are just labels. So you can think of them as a shorthand
that lets you easily communicate a set of selected well-known
versions with others (either people, or git tools). Instead of
saying 2664b25051f7ab96b22b199aa2f..., you can say v2.6.16-rc1.
All of the things I demonstrate below, you can substitute v2.6.X
with their commit object names and things work the same way. It
is more convenient and human friendly to use tags.
Except one thing: signed tags can be verified, if you have GPG
public key of the signer (in this case Linus), with "git
verify-tag".
<offtopic>
Does anybody know where to obtain the public key to verify
v2.6.16-rc1 tag?
</offtopic>
> So what do I do with them now? Are they only for branch points?
That is one of the things often done. To build on top of
v2.6.16-rc1:
$ git checkout -b myhack v2.6.16-rc1
$ hack hack hack
$ git commit -s -m 'Add support for frotz videocard.
This adds frotz videocard support. Blah Blah Blah...'
You could also use them to see what happened during a given
timeframe. For example:
$ git log v2.6.14..v2.6.15 | git shortlog
would list you all the changes between these two releases, for
example.
If you know something used to work at a given version, say
v2.6.15, and now it does not work, you can use it as good/bad
input for the bisection bug hunting:
$ git bisect good v2.6.15 && git bisect bad master
> Is the
> only way to know I'm building 2.6.16-rc1 to branch from it as described
> in git-branch, even if I'm not planning on doing any development?
I do not quite understand. Immediately after the above example
checkout, before or after doing the hackhack and commit, git
branch would probably say:
$ git branch
origin
master
* myhack
Immediately after the example checkout, "git describe myhack"
would answer v2.6.16-rc1. OTOH, after the hackhack and commit,
it would answer v2.6.16-rc1-gXXXXXXXX where XXXX part is an
abbreviated commit object name of the commit you have at the tip
of myhack branch.
To see what you did in the branch, the tag, if you remember
where you forked from, can be used this way:
$ git whatchanged -p v2.6.16-rc1..myhack
However, the above is equivalent to saying this:
$ git whatchanged -p master..myhack
So in that sense tag is not that useful for the purpose of
getting list of commits (or, more precicely, naming a
development track).
It is useful to name a specific version:
$ git diff v2.6.16-rc1 myhack
compares two versions; it is not equivalent to "git diff master myhack".
> Is this part of the concept that branches are cheap and you should feel
> free to create and throw them away at will?
That depends on what you exactly mean by "this", but all of the
above are quite cheap. If the "myhack" practice turned out to
be useless, you can just:
$ git checkout master
$ git branch -D myhack
to come back to the tip of the mainline and delete your side branch.
^ permalink raw reply
* Re: StGIT: "stg new" vs "stg new --force"
From: Pavel Roskin @ 2006-01-17 23:16 UTC (permalink / raw)
To: Yann Dirson; +Cc: Catalin Marinas, git, Charles Lever
In-Reply-To: <20060117215752.GH32585@nowhere.earth>
On Tue, 2006-01-17 at 22:57 +0100, Yann Dirson wrote:
> I commonly also feel the need to "stg refresh" only part of the
> current changes. Allowing to limit the files to be impacted by a
> refresh could be a good addition.
Absolutely.
> It would even be useful sometimes to dispatch changes to a single file
> into several patches. When they are distinct enough to be in
> different diff hunks, it is pretty easy to split an existing patch,
> but it could also be useful to only refresh a patch with specific diff
> hunks. A possibility would be to add a filterdiff-like "-#<n>" flag,
> in addition to the above-suggested "refresh <file>" (and possibly only
> allow to specify a single file together with this flag).
I think if would be better to improve "stg fold" to work on arbitrary
patches. This way, you prepare the patch in the editor (which would not
be harder than finding hunk numbers) and fold it into the patch of your
choice. stg should check that the stack remains valid, possibly doing
trivial adjustments to the higher patches. The current tree should not
be impacted.
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: [QUESTION] What is a tag for?
From: Petr Baudis @ 2006-01-17 23:05 UTC (permalink / raw)
To: Alex Bennee; +Cc: git
In-Reply-To: <1137538344.9104.34.camel@malory>
Hi,
Dear diary, on Tue, Jan 17, 2006 at 11:52:24PM CET, I got a letter
where Alex Bennee <kernel-hacker@bennee.com> said that...
> So I want to track Linus's 2.6 git tree as well as do a little small
> time hacking. I'm not brave enough to sit on the very bleeding edge and
> build what ever happens to be at the "HEAD" of the tree. However when a
> kernel releases I'd like to build *that* kernel.
>
> I keep thinking of tags like labels in the old convetional SCM case. Is
> this correct? I can see once I've done my update (fetch/cogito what
> ever) that these tags apear in my local tree:
>
> 22:42 alex@malory [linux-2.6] >cat .git/refs/tags/v2.6.16-rc1
> f3bcf72eb85aba88a7bd0a6116dd0b5418590dbe
>
> So what do I do with them now? Are they only for branch points? Is the
> only way to know I'm building 2.6.16-rc1 to branch from it as described
> in git-branch, even if I'm not planning on doing any development?
the simplest thing to do in Cogito if you just want to follow tags
around is to cg-fetch periodically (that will get the changes to your
local database, but will not check them out), and cg-seek around to
whatever tag you want:
$ cg-fetch
$ cg-seek v2.6.16-rc1
$ cg-fetch
... no new tag ...
$ cg-fetch
... still no new tag ...
$ cg-fetch
... Linus, are you sleeping? ...
$ cg-fetch
$ cg-seek v2.6.16-rc2
...
--
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
* [QUESTION] What is a tag for?
From: Alex Bennee @ 2006-01-17 22:52 UTC (permalink / raw)
To: git
Hi,
So I want to track Linus's 2.6 git tree as well as do a little small
time hacking. I'm not brave enough to sit on the very bleeding edge and
build what ever happens to be at the "HEAD" of the tree. However when a
kernel releases I'd like to build *that* kernel.
I keep thinking of tags like labels in the old convetional SCM case. Is
this correct? I can see once I've done my update (fetch/cogito what
ever) that these tags apear in my local tree:
22:42 alex@malory [linux-2.6] >cat .git/refs/tags/v2.6.16-rc1
f3bcf72eb85aba88a7bd0a6116dd0b5418590dbe
So what do I do with them now? Are they only for branch points? Is the
only way to know I'm building 2.6.16-rc1 to branch from it as described
in git-branch, even if I'm not planning on doing any development?
Is this part of the concept that branches are cheap and you should feel
free to create and throw them away at will?
I look forward to your elucidation and the ah! moment that finally gets
my head around git ;-)
Cheers,
--
Alex, homepage: http://www.bennee.com/~alex/
Zoe: "So.. Trap?" Mal: "Trap." Zoe: "We goin' in?" Mal: "Ain't nothin'
but a few hours out." Wash: "But, remember the part where it's a trap?"
^ permalink raw reply
* Re: StGIT: "stg new" vs "stg new --force"
From: Yann Dirson @ 2006-01-17 21:57 UTC (permalink / raw)
To: Pavel Roskin; +Cc: Catalin Marinas, git, Charles Lever
In-Reply-To: <1137517300.20556.26.camel@dv>
On Tue, Jan 17, 2006 at 12:01:40PM -0500, Pavel Roskin wrote:
> Hello, Catalin!
>
> On Mon, 2006-01-16 at 08:18 +0000, Catalin Marinas wrote:
> > On 13/01/06, Pavel Roskin <proski@gnu.org> wrote:
> > > 1) "stg new --force" becomes "stg new" and "stg new" becomes "stg new
> > > --empty", i.e. empty files can only be created with the "--empty"
> > > switch.
> > > 2) "stg new --force" becomes "stg record" or something.
> > > 3) "stg new --force" becomes "stg new --record" or something.
> > > 4) "stg new" works both with and without modified files.
> >
> > Regarding (1), the newly created patch is empty anyway, you would need
> > to run 'refresh' to add the modified patches to it ('stg series -e'
> > would show the empty patches prefixed with a 0).
>
> I was going to suggest that would be logical to run "stg refresh"
> implicitly if "stg new" is used on modified files. But then I realized
> that it would be even better if future versions of StGIT allowed to
> refresh (i.e. add changes to) patches other that the current one. In
> this case, indeed, you don't want the newly created patch to suck in all
> the changes in the local repository.
I commonly also feel the need to "stg refresh" only part of the
current changes. Allowing to limit the files to be impacted by a
refresh could be a good addition.
It would even be useful sometimes to dispatch changes to a single file
into several patches. When they are distinct enough to be in
different diff hunks, it is pretty easy to split an existing patch,
but it could also be useful to only refresh a patch with specific diff
hunks. A possibility would be to add a filterdiff-like "-#<n>" flag,
in addition to the above-suggested "refresh <file>" (and possibly only
allow to specify a single file together with this flag).
Best regards,
--
Yann Dirson <ydirson@altern.org> |
Debian-related: <dirson@debian.org> | Support Debian GNU/Linux:
| Freedom, Power, Stability, Gratis
http://ydirson.free.fr/ | Check <http://www.debian.org/>
^ permalink raw reply
* Re: git-diff-files and fakeroot
From: Sam Ravnborg @ 2006-01-17 18:10 UTC (permalink / raw)
To: Ryan Anderson; +Cc: Kyle Moffett, Junio C Hamano, git, linux-kernel
In-Reply-To: <43CC89F0.7060109@michonline.com>
On Tue, Jan 17, 2006 at 01:08:48AM -0500, Ryan Anderson wrote:
>
> I think I might take your suggestion, and fix up the builddeb script to
> do the "run as root" part itself, rather than needing to do it outside.
> It would make it possible to just run "make oldconfig deb-pkg" which
> would make things a little bit simpler.
If we do something it must be consistent for all *-pkg targets.
So fixing up builddeb is not enough, we must fix it for rpm etc also.
Not that I have looked into what is needed, but we shall not have
inconsistent behavious between the different *-pkg targets.
Sam
^ permalink raw reply
* Re: RFC: Subprojects
From: Daniel Barkalow @ 2006-01-17 17:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Josef Weidendorfer, git
In-Reply-To: <7vfynnfkc8.fsf@assigned-by-dhcp.cox.net>
On Mon, 16 Jan 2006, Junio C Hamano wrote:
> Daniel Barkalow <barkalow@iabervon.org> writes:
>
> > So why not use the "bind" approach for the "index vs working tree" part,
> > but write out "gitlink"-style tree objects?
>
> I said "index vs working tree" as a mere example, and never said
> "gitlink" is easier (or at least as easy as "bind") for "tree
> object vs index" or "tree object vs working tree through index".
> In fact I suspect those parts also need to be changed fairly
> heavily, and to be honest, I am not very much looking forward to
> investigating the details.
I suspect that it's just as easy, except that you get confronted
immediately with the issues that you haven't dealt with in the bind
approach (mentioned below). If you had parse_tree_buffer() just ignore
them, and had write-tree take a list of bind lines, that would match the
status of your "bind" implementation, I think (except for the part you say
is cheating).
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.
> > In any case, I think it would be good to track where the subprojects are
> > in some core state, and probably the right solution is to have special
> > index entries for them, in addition to having their contents in the index.
>
> Actually, the "special entry" was what I found out to be quite a
> pain, if you mean to have "linux-2.6/" in the index and have it
> used in some meaningful way. Further hacking and prototyping
> _might_ convince me otherwise, but I am not so optimistic at
> this moment.
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.
Actually, it should be easy to have them in the index file but not in the
main index data structure, by skipping over them in the for loop near the
end of read_cache(). Put them in a separate structure, and write them back
to the file in write_cache(), and have a different method entirely for
changing them, and they shouldn't affect the normal use of the index.
> > I'm not seeing a clear way to get from commit objects with "bind" lines to
> > an index with the appropriate things read and back otherwise.
>
> Here again I am thinking aloud, remembering the earlier example
> of an embedded linux project that ships with linux-2.6 and
> gcc-4.0, along with its own README and Makefile at the toplevel
> and src/ for its own sources. The tools at the tip of "pu"
> should be able to let you do the following:
>
> $ git cat-file commit $such_toplevel_commit
> tree $tree
> parent $parent
> bind $primarysub /
> bind $linuxsub linux-2.6/
> bind $gccsub gcc-4.0/
> author A U Thor <author@example.com> 1137392543 -0800
> commmitter A U Thor <author@example.com> 1137392543 -0800
>
> An example.
>
> where $tree is the object name of the whole tree (no "gitlink"
> object), $primarysub and $linuxsub are the object names of
> commit objects for the primary subproject (which sits at the
> rootlevel) and another subproject (which sits at linux-2.6/
> subdirectory).
>
> To make sure there is no misunderstanding:
>
> * "git-ls-tree $tree" would show the object name of
> $linuxsub^{tree} at path "linux-2.6/" because
> "tree" line of a commit describes the whole tree,
> including subprojects.
>
> * "git-ls-tree $primarysub" would show README,
> Makefile and src/ directories but not linux-2.6/ nor
> gcc-4.0/.
>
> * "git-ls-tree $linuxsub" would show COPYING, Makefile
> etc., not linux-2.6/COPYING.
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.
> Reading such a commit is easy:
>
> $ git-read-tree $tree ;# ;-)
>
> But that is cheating.
This is for backwards compatibility, I assume?
> Constructing such an index can be done by:
>
> $ git-read-tree $primarysub
> $ git-read-tree --prefix=linux-2.6/ $linuxsub
> $ git-read-tree --prefix=gcc-4.0/ $gccsub
>
> 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 decision to use what --prefix and --bound and what tree(s)
> to write out must come from somewhere, and as you say it would
> be nice if we _could_ stick them in the index as "special
> entries", but for the purpose of prototyping I am assuming I
> keep that somewhere in $GIT_DIR/ (the "mtab" in the previous
> message. Maybe "$GIT_DIR/bind" is a good name?).
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.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: RFC: Subprojects
From: Linus Torvalds @ 2006-01-17 17:38 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Petr Baudis, Junio C Hamano, Josef Weidendorfer, git
In-Reply-To: <Pine.LNX.4.64.0601171122270.25300@iabervon.org>
On Tue, 17 Jan 2006, Daniel Barkalow wrote:
>
> Think from a debugging standpoint. You know that the main project worked
> with a particular commit of the superproject.
Yes, there are real advantages to being able to tag a very specific
version of a tree.
You can do it manually (ie tag the versions of everything used), but
there's a real convenience to being able to say "I want the tree to look
exactly as it looked for our internal test-release that we shipped as a
pre-view to customer so-and-so".
You can do it with ad-hoc build rules inside a company, but the likelihood
that they don't work all the time is pretty high. Somebody forgot to
follow the right procedure, and had updated a sub-tree without marking it,
and now you can't reproduce the problem that a customer has with a debug
build, because you have no way to reproduce the exact binary...
It's why people tag every file for huge trees under CVS for a release, and
accept why building a release may take hours. It's crazy, yes, but there
are other projects than just the BSD's that have that "World" mentality,
where they want every single program under _one_ umbrella, so that they
can tag them all together.
Me, I think it's crazy engineering ("if you can't reproduce it with
individual projects, you're not doing programming, you're doing Voodoo"),
but it's something that some organizations simply require.
Now, it might be enough with a cogito approach of ".git/subprojects", and
just _version-control_ it in the top-level project, but then you'd need to
make sure that all the tools automatically update the version when they do
a "pull" or a "commit" on a subproject. But then it almost boils down to
"gitlink"s after all.
Linus
^ permalink raw reply
* Re: RFC: Subprojects
From: Craig Schlenter @ 2006-01-17 17:33 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0601171122270.25300@iabervon.org>
Hi
For reference, here is what subversion does:
http://svnbook.red-bean.com/nightly/en/svn.advanced.externals.html
--Craig
^ permalink raw reply
* [QUESTION] about .git/info/grafts file
From: Franck @ 2006-01-17 17:32 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <cda58cb80601170928r252a6e34y@mail.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: StGIT: "stg new" vs "stg new --force"
From: Pavel Roskin @ 2006-01-17 17:01 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git, Charles Lever
In-Reply-To: <b0943d9e0601160018x206faf9ck@mail.gmail.com>
Hello, Catalin!
On Mon, 2006-01-16 at 08:18 +0000, Catalin Marinas wrote:
> On 13/01/06, Pavel Roskin <proski@gnu.org> wrote:
> > 1) "stg new --force" becomes "stg new" and "stg new" becomes "stg new
> > --empty", i.e. empty files can only be created with the "--empty"
> > switch.
> > 2) "stg new --force" becomes "stg record" or something.
> > 3) "stg new --force" becomes "stg new --record" or something.
> > 4) "stg new" works both with and without modified files.
>
> Regarding (1), the newly created patch is empty anyway, you would need
> to run 'refresh' to add the modified patches to it ('stg series -e'
> would show the empty patches prefixed with a 0).
I was going to suggest that would be logical to run "stg refresh"
implicitly if "stg new" is used on modified files. But then I realized
that it would be even better if future versions of StGIT allowed to
refresh (i.e. add changes to) patches other that the current one. In
this case, indeed, you don't want the newly created patch to suck in all
the changes in the local repository.
> Anyway, I would also prefer option 4. If there are no objections, I'll
> modify StGIT accordingly. It would also be useful to have a wiki page
> about StGIT vs. Quilt to show the main differences.
That would be great!
I'm trying to make StGIT my primary development tool, and I think it has
a great potential the could be realized if StGIT is freed from the need
to emulate older tools.
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: RFC: Subprojects
From: Daniel Barkalow @ 2006-01-17 16:45 UTC (permalink / raw)
To: Petr Baudis; +Cc: Junio C Hamano, Josef Weidendorfer, git
In-Reply-To: <20060117140937.GI28365@pasky.or.cz>
On Tue, 17 Jan 2006, Petr Baudis wrote:
> I perhaps missed this in the thread, but is it really so useful to bind
> the subprojects to specific commits? If you care about reproducing
> specific configuration, all you have to do is tag and seek recursively -
> and even having a separate tiny git branch tracking just a single file
> listing the commit ids of subprojects seems more elegant to me than just
> forcing the specific commit ids. In the general case, I think it most
> usually goes "this project#branch, the latest commit you can get", so
> I'm not really convinced that you are optimizing for the right case at
> all.
Think from a debugging standpoint. You know that the main project worked
with a particular commit of the superproject. The bug you've found is
related to the behavior of one of the subprojects in the the context of
your superproject, but you don't know this. In order to reproduce the
working version and search for the change that broken things, you need to
be able to identify which commits of subprojects were used in each commit
of the superproject; these are almost certainly not the latest commits on
any branch of the subproject. And if you're going to want to debug things
later, no commit of the superproject can just say to use the latest in the
subproject. You don't know what you make a commit whether it will turn out
to be a configuration that you'll want to recreate later.
Now it may be useful to have a tool to update all of the subprojects to
the latest versions, similar in end-user usage to pulling repositories,
but you still need to generate new commits when you do this, rather than
reinterpreting the old commits with new content, so that you keep the
history immutable. You also want to know when you've done this, so that
you don't clone a tree that's working fine and build it only to find that
the clone has fetched a new kernel version with different behavior without
letting you know that anything has changed.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: [kernel.org users] [RFC] "clone --naked"?
From: Andreas Ericsson @ 2006-01-17 15:54 UTC (permalink / raw)
To: Ulrich Windl; +Cc: Junio C Hamano, git
In-Reply-To: <43CCFDEA.2997.15EA2FA@Ulrich.Windl.rkdvmks1.ngate.uni-regensburg.de>
Ulrich Windl wrote:
> On 17 Jan 2006 at 0:17, Junio C Hamano wrote:
>
>
>>"Ulrich Windl" <ulrich.windl@rz.uni-regensburg.de> writes:
>>
>>
>>>... My original intention was that I
>>>thought them to be little descriptive regarding their
>>>function. You seem to have "--bare" and "--naked". Hard to
>>>guess what they really do.
>>
>>True. "A repository without an associated working tree". I do
>
>
> --rmo --repository-metadata-only?
> --sdf --sans-data-files?
> --rwwt (Repository Without Working Tree)?
> --qdr (Quick-and-Dirty Repository)?
>
I like --bare (Barely A REpository, BAre REpository).
Oh well.
--
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: Petr Baudis @ 2006-01-17 14:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Daniel Barkalow, Josef Weidendorfer, git
In-Reply-To: <7vfynnfkc8.fsf@assigned-by-dhcp.cox.net>
Dear diary, on Tue, Jan 17, 2006 at 07:18:47AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Here again I am thinking aloud, remembering the earlier example
> of an embedded linux project that ships with linux-2.6 and
> gcc-4.0, along with its own README and Makefile at the toplevel
> and src/ for its own sources. The tools at the tip of "pu"
> should be able to let you do the following:
>
> $ git cat-file commit $such_toplevel_commit
> tree $tree
> parent $parent
> bind $primarysub /
> bind $linuxsub linux-2.6/
> bind $gccsub gcc-4.0/
> author A U Thor <author@example.com> 1137392543 -0800
> commmitter A U Thor <author@example.com> 1137392543 -0800
>
> An example.
>
> where $tree is the object name of the whole tree (no "gitlink"
> object), $primarysub and $linuxsub are the object names of
> commit objects for the primary subproject (which sits at the
> rootlevel) and another subproject (which sits at linux-2.6/
> subdirectory).
I perhaps missed this in the thread, but is it really so useful to bind
the subprojects to specific commits? If you care about reproducing
specific configuration, all you have to do is tag and seek recursively -
and even having a separate tiny git branch tracking just a single file
listing the commit ids of subprojects seems more elegant to me than just
forcing the specific commit ids. In the general case, I think it most
usually goes "this project#branch, the latest commit you can get", so
I'm not really convinced that you are optimizing for the right case at
all.
--
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: [kernel.org users] [RFC] "clone --naked"?
From: Ulrich Windl @ 2006-01-17 13:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1wz7clps.fsf@assigned-by-dhcp.cox.net>
On 17 Jan 2006 at 0:17, Junio C Hamano wrote:
> "Ulrich Windl" <ulrich.windl@rz.uni-regensburg.de> writes:
>
> > ... My original intention was that I
> > thought them to be little descriptive regarding their
> > function. You seem to have "--bare" and "--naked". Hard to
> > guess what they really do.
>
> True. "A repository without an associated working tree". I do
--rmo --repository-metadata-only?
--sdf --sans-data-files?
--rwwt (Repository Without Working Tree)?
--qdr (Quick-and-Dirty Repository)?
...
I think you have your own ideas...
Ulrich
> not know a short and sweet phrase to describe that (well, except
> "bare" and "naked", which I kind of already got used to).
>
> Whatever word we choose to describe that, it should go to the
> glossary document.
>
^ permalink raw reply
* [PATCH] "sleep 1" sleeps too little on cygwin
From: Alex Riesen @ 2006-01-17 11:25 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
[-- Attachment #1: Type: text/plain, Size: 115 bytes --]
Probably another one windows quirk, or just the moon phases,
but I have to make damn sure it sleeps long enough.
[-- Attachment #2: cygwin-sleeps-too-little.patch --]
[-- Type: text/x-patch, Size: 530 bytes --]
diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh
index e3ebf38..8c5b614 100755
--- a/t/t4011-diff-symlink.sh
+++ b/t/t4011-diff-symlink.sh
@@ -56,10 +56,11 @@ cat > expected << EOF
diff --git a/frotz b/frotz
EOF
+secs="$SECONDS"
+while [ "$SECONDS" = "$secs" ]; do sleep 1; done
test_expect_success \
'diff identical, but newly created symlink' \
- 'sleep 1 &&
- ln -s xyzzy frotz &&
+ 'ln -s xyzzy frotz &&
git-diff-index -M -p $tree > current &&
compare_diff_patch current expected'
^ permalink raw reply related
* Re: Cancelling certain commits
From: Andreas Ericsson @ 2006-01-17 10:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Bahadir Balban, git
In-Reply-To: <7vvewjlowk.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> Andreas Ericsson <ae@op5.se> writes:
>
>># make sure "git status" doesn't show any changes
>>
>>$ git branch anchor # to make a safe point to reset to if things go bad
>>$ git reset --hard HEAD~7 # undo commits 3 - 10
>># replay commits 4, 5, 6, 8, 9
>>$ for i in 6 5 4 2 1; do git cherry-pick -r anchor~$i || break; done
>># replay commit 10
>>$ git cherry-pick -r anchor
>
>
> I think "6 5 4 2 1 0" would be sweeter. rev~0 == rev
>
Didn't know that. The day isn't a complete loss already. :)
>
>>..., and never *ever*
>>do
>>
>>$ git prune
>>
>>on a repo where you're juggling loose commits like this (although that
>>should actually be safe when you create 'anchor' as a branch rather
>>than as a tag, which Junio usually recommends).
>
>
> Sorry, I do not understand this part. tags and branch heads are
> used in the same way to determine what objects to protect from
> "prune", so I thought there was no difference from the safety
> point of view between the anchor being a branch or a tag.
>
You're right. That's weird though, because I distinctly remember being
bitten by this when I was very new to git. OTOH, I probably did
something stupid that broke the repo before, and my girlfriend provided
plenty distraction so I didn't do the pruning and the reset'ing on the
same day.
Would a tag with the same name in a central repo overwrite a local one
when "git fetch --tags" is used? I think I did this over http, but I'm
not sure. I know I had to clean up un-annotated tags that got pushed by
accident after I had restored the lost commits though, so this could be
a cause (there was an 'anchor' tag in the shared repo as well).
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: git rebase behaviour changed?
From: Junio C Hamano @ 2006-01-17 8:56 UTC (permalink / raw)
To: Martin Langhoff; +Cc: Mike McCormack, git
In-Reply-To: <7vvewjb5xz.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> You are right. We will lose #1 and #2, (although the "already
> up to date" might catch some cases) and this _is_ dangerous. I
> need to do something about this soon.
Actually, I think we are OK; I do not think we would lose any
commits. git-format-patch (actually, git-cherry called from
there) does the right thing. It does not use the merge base
done in git-rebase in any way.
In any case, we _do_ need an explanation and error-out upon
finding a merge, as we discussed. If somebody really wants to
rebase a merge, he can do that by hand, as Mike easily
demonstrated.
^ permalink raw reply
* Re: git rebase behaviour changed?
From: Junio C Hamano @ 2006-01-17 8:43 UTC (permalink / raw)
To: Martin Langhoff; +Cc: Mike McCormack, git
In-Reply-To: <46a038f90601170033y334d111fjed277fc787a2e523@mail.gmail.com>
Martin Langhoff <martin.langhoff@gmail.com> writes:
> GIT won't literally lose them, someone could run git-fsck and fish
> out the dangling heads from the repo, and after a bit of spelunking
> recover them, but it's suddenly a really tricky operation.
"git-lost-found".
You are right. We will lose #1 and #2, (although the "already
up to date" might catch some cases) and this _is_ dangerous. I
need to do something about this soon.
Thanks for the discussion.
[Footnote]
*1* ... or #1 and #3 --- sorry, my "one of them picked up by
upstream" scenario description was inconsistent in the previous
message.
^ permalink raw reply
* Re: git rebase behaviour changed?
From: Martin Langhoff @ 2006-01-17 8:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Mike McCormack, git
In-Reply-To: <7v8xtfclyx.fsf@assigned-by-dhcp.cox.net>
On 1/17/06, Junio C Hamano <junkio@cox.net> wrote:
> Sorry I am always slow but I am a bit slower than I usually am
> tonight, and do not understand this part without an
> illustration:
My fault. I did have a few bits of paper here on my lap, but gmail's
textbox sucks at ascii art...
>
> master 1---2---3---4---5---A
> / /
> origin 0---6---7---B
>
>
> A = master head
> B = origin head == merge base
>
> rev-list B..A = 1 2 3 4 5
> rev-list A..B = 6 7
Yep, exacly the example I was thinking about.
(...)
> Among the first list of commit, there is #4 which is a merge.
> So we reject. Is that what you meant?
Exactly. We refuse to reset the head and begin the rebase operation,
because it looks like operator error.
> By the way, the longer I think about this, the more I agree with
> the conclusion of the earlier thread: "if you rebase, do not
> merge; if you merge, do not rebase". It is really about picking
> the right workflow.
Definitely. But errors and misunderstandings are frequent, and people
who haven't thought the process through or aren't that familiar with
the internals are very likely to try it.
Refusing to rebase, with a good error msg gives the user a chance to
evaluate what to do with the commits. Right now, if I read the
situation right, there's a good chance commits 1,2 and 3 will be
"lost" once the rebase is complete.
GIT won't literally lose them, someone could run git-fsck and fish
out the dangling heads from the repo, and after a bit of spelunking
recover them, but it's suddenly a really tricky operation.
cheers,
martin
^ permalink raw reply
* Re: [kernel.org users] [RFC] "clone --naked"?
From: Junio C Hamano @ 2006-01-17 8:17 UTC (permalink / raw)
To: Ulrich Windl; +Cc: git
In-Reply-To: <43CCB1D3.10309.35645D@Ulrich.Windl.rkdvmks1.ngate.uni-regensburg.de>
"Ulrich Windl" <ulrich.windl@rz.uni-regensburg.de> writes:
> ... My original intention was that I
> thought them to be little descriptive regarding their
> function. You seem to have "--bare" and "--naked". Hard to
> guess what they really do.
True. "A repository without an associated working tree". I do
not know a short and sweet phrase to describe that (well, except
"bare" and "naked", which I kind of already got used to).
Whatever word we choose to describe that, it should go to the
glossary document.
^ permalink raw reply
* Re: git rebase behaviour changed?
From: Junio C Hamano @ 2006-01-17 8:11 UTC (permalink / raw)
To: Martin Langhoff; +Cc: Mike McCormack, git
In-Reply-To: <46a038f90601162252y7e2d9227p4eb4091b653d5c6d@mail.gmail.com>
Martin Langhoff <martin.langhoff@gmail.com> writes:
> Now, I have realised that a simple mistake (merging from origin in you
> scenario) would lead git-rebase to discard earlier patches during the
> rebase. If you had a single commit *after* the merge, git-rebase would
> have rebased that single patch, and dropped earlier patches.
It may not necessarily be a mistake.
> git-rebase should refuse to run in the above scenario. Is there a
> straightforward way to ask if the merge base is "shared"?
>
> <thinking>
>...
> </thinking>
Sorry I am always slow but I am a bit slower than I usually am
tonight, and do not understand this part without an
illustration:
master 1---2---3---4---5---A
/ /
origin 0---6---7---B
A = master head
B = origin head == merge base
rev-list B..A = 1 2 3 4 5
rev-list A..B = 6 7
The first rev-list is "what we have but they do not". They are
the candidates to be fed upstream. The latter is "what they
have but we do not". Potentially some of them are commit that
represent patches we submitted earlier upstream.
Among the first list of commit, there is #4 which is a merge.
So we reject. Is that what you meant? Which makes sense in
this picture (but I am a bit tired and maybe this may not apply
in a different picture).
By the way, the longer I think about this, the more I agree with
the conclusion of the earlier thread: "if you rebase, do not
merge; if you merge, do not rebase". It is really about picking
the right workflow.
Let's say you submitted #1, #2, #3 earlier, and #3 was accepted
upstream and came back as #7, and let's further assume that we
are lucky enough that patch-id gives the same answer for
"diff-tree #2" and "diff-tree #7". So the set of commits left
are #1, #3, and #5 (#4 is just a merge so we will not re-apply).
Now, what is the shape of the final "rebased" ancestry graph we
would want?
master 1'--3'--5'--A'
/
origin 0---6---7---B
If this is what we want, why did we make #4 merge in the first
place, I wonder. If the workflow is based on rebase [*1*],
instead of making a merge at #4, the developer *should* have
done fetch and rebase, not merge:
master 1---2---3
/
origin 0---6---7---B
==>
master 1'--3'
/
origin 0---6---7---B
This would have been easier to manage at the point we discovered
#6, #7, and #B, than creating #4 merge only to discard it later.
And #5 and #A can be built on top of #3'.
master 1'--3'--5---A
/
origin 0---6---7---B
[Footnote]
*1* That is certainly easier to manage for an individual
developer than a merge based workflow. I know it because I
operated that way for a long time back when Linus was managing
git)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox