* [Patch] ls-tree enhancements
From: Junio C Hamano @ 2005-04-15 2:21 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Petr Baudis, git
In-Reply-To: <Pine.LNX.4.58.0504141133260.7211@ppc970.osdl.org>
This adds '-r' (recursive) option and '-z' (NUL terminated)
option to ls-tree. I need it so that the merge-trees (formerly
known as git-merge.perl) script does not need to create any
temporary dircache while merging. It used to use show-files on
a temporary dircache to get the list of files in the ancestor
tree, and also used the dircache to store the result of its
automerge. I probably still need it for the latter reason, but
with this patch not for the former reason anymore.
It is relative to bb95843a5a0f397270819462812735ee29796fb4
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
ls-tree.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 90 insertions(+), 18 deletions(-)
--- ,,Linus/ls-tree.c 2005-04-14 19:08:17.000000000 -0700
+++ ,,Siam/ls-tree.c 2005-04-14 19:11:23.000000000 -0700
@@ -5,45 +5,117 @@
*/
#include "cache.h"
-static int list(unsigned char *sha1)
+int line_termination = '\n';
+int recursive = 0;
+
+struct path_prefix {
+ struct path_prefix *prev;
+ const char *name;
+};
+
+static void print_path_prefix(struct path_prefix *prefix)
{
- void *buffer;
- unsigned long size;
- char type[20];
+ if (prefix) {
+ if (prefix->prev)
+ print_path_prefix(prefix->prev);
+ fputs(prefix->name, stdout);
+ putchar('/');
+ }
+}
+
+static void list_recursive(void *buffer,
+ unsigned char *type,
+ unsigned long size,
+ struct path_prefix *prefix)
+{
+ struct path_prefix this_prefix;
+ this_prefix.prev = prefix;
- buffer = read_sha1_file(sha1, type, &size);
- if (!buffer)
- die("unable to read sha1 file");
if (strcmp(type, "tree"))
die("expected a 'tree' node");
+
while (size) {
- int len = strlen(buffer)+1;
- unsigned char *sha1 = buffer + len;
- char *path = strchr(buffer, ' ')+1;
+ int namelen = strlen(buffer)+1;
+ void *eltbuf;
+ char elttype[20];
+ unsigned long eltsize;
+ unsigned char *sha1 = buffer + namelen;
+ char *path = strchr(buffer, ' ') + 1;
unsigned int mode;
- unsigned char *type;
- if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
+ if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
die("corrupt 'tree' file");
buffer = sha1 + 20;
- size -= len + 20;
+ size -= namelen + 20;
+
/* XXX: We do some ugly mode heuristics here.
* It seems not worth it to read each file just to get this
- * and the file size. -- pasky@ucw.cz */
- type = S_ISDIR(mode) ? "tree" : "blob";
- printf("%03o\t%s\t%s\t%s\n", mode, type, sha1_to_hex(sha1), path);
+ * and the file size. -- pasky@ucw.cz
+ * ... that is, when we are not recursive -- junkio@cox.net
+ */
+ eltbuf = (recursive ? read_sha1_file(sha1, elttype, &eltsize) :
+ NULL);
+ if (! eltbuf) {
+ if (recursive)
+ error("cannot read %s", sha1_to_hex(sha1));
+ type = S_ISDIR(mode) ? "tree" : "blob";
+ }
+ else
+ type = elttype;
+
+ printf("%03o\t%s\t%s\t", mode, type, sha1_to_hex(sha1));
+ print_path_prefix(prefix);
+ fputs(path, stdout);
+ putchar(line_termination);
+
+ if (eltbuf && !strcmp(type, "tree")) {
+ this_prefix.name = path;
+ list_recursive(eltbuf, elttype, eltsize, &this_prefix);
+ }
+ free(eltbuf);
}
+}
+
+static int list(unsigned char *sha1)
+{
+ void *buffer;
+ unsigned long size;
+ char type[20];
+
+ buffer = read_sha1_file(sha1, type, &size);
+ if (!buffer)
+ die("unable to read sha1 file");
+ list_recursive(buffer, type, size, NULL);
return 0;
}
+static void _usage(void)
+{
+ usage("ls-tree [-r] [-z] <key>");
+}
+
int main(int argc, char **argv)
{
unsigned char sha1[20];
+ while (1 < argc && argv[1][0] == '-') {
+ switch (argv[1][1]) {
+ case 'z':
+ line_termination = 0;
+ break;
+ case 'r':
+ recursive = 1;
+ break;
+ default:
+ _usage();
+ }
+ argc--; argv++;
+ }
+
if (argc != 2)
- usage("ls-tree <key>");
+ _usage();
if (get_sha1_hex(argv[1], sha1) < 0)
- usage("ls-tree <key>");
+ _usage();
sha1_file_directory = getenv(DB_ENVIRONMENT);
if (!sha1_file_directory)
sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
^ permalink raw reply
* Re: Merge with git-pasky II.
From: Christopher Li @ 2005-04-14 22:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Petr Baudis, Linus Torvalds, git
In-Reply-To: <7v7jj4q2j2.fsf@assigned-by-dhcp.cox.net>
On Thu, Apr 14, 2005 at 05:58:25PM -0700, Junio C Hamano wrote:
>
> I do like, however, the idea of separating the step of doing any
> checkout/merge etc. and actually doing them. So the command set
> of parse-your-output needs to be defined. Based on what I have
> done so far, it would consist of the following:
>
> - Result is this object $SHA1 with mode $mode at $path (takes
> one of the trees); you can do update-cache --cacheinfo (if
> you want to muck with dircache) or cat-file blob (if you want
> to get the file) or both.
Is that SHA1 for tree or the file object? If it is tree it don't
need the $mode any more. If it is file you might need to emit
entry for it's parent directory, including the modes of directory.
>
> - Result is to delete $path.
>
> - Result is a merge between object $SHA1-1 and $SHA1-2 with
> mode $mode-1 or $mode-2 at $path.
>
> Would this be a good enough command set?
And of course error/command for the files that unable to perform
auto merge. including information of both revisions. That needs
to be defined as well.
Chris
^ permalink raw reply
* Re: Git archive now available
From: Darren Williams @ 2005-04-15 1:39 UTC (permalink / raw)
To: David S. Miller; +Cc: Darren Williams, git, linux-kernel
In-Reply-To: <20050414170338.77c4397e.davem@davemloft.net>
Hi David
On Thu, 14 Apr 2005, David S. Miller wrote:
> On Fri, 15 Apr 2005 10:01:47 +1000
> Darren Williams <dsw@gelato.unsw.edu.au> wrote:
>
> > Thanks to the team at Gelato@UNSW we now have a
> > no so complete Git archive at
> > http://www.gelato.unsw.edu.au/archives/git/
> >
> > If somebody could send me a complete Git mbox I will
> > update the archive with it.
>
> I just had to unsubscribe git@lemon.gelato.unsw.edu.au
> because it was bouncing with errors like "hypermail: ...
> this archive looks non-empty but there it no gdbm file"
>
> So don't get too excited about your archive just yet :-)
Sorry permissions problem should be OK now:)
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--------------------------------------------------
Darren Williams <dsw AT gelato.unsw.edu.au>
Gelato@UNSW <www.gelato.unsw.edu.au>
--------------------------------------------------
^ permalink raw reply
* Re: Yet another base64 patch
From: H. Peter Anvin @ 2005-04-15 1:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: bert hubert, Christopher Li, git
In-Reply-To: <Pine.LNX.4.58.0504141743360.7211@ppc970.osdl.org>
Linus Torvalds wrote:
>
> On Thu, 14 Apr 2005, bert hubert wrote:
>
>>It is too easy to get into a O(N^2) situation. Git may be able to deal with
>>it but you may hurt yourself when making backups, or if you ever want to
>>share your tree (possibly with yourself) over the network.
>
>
> Even something as simple as "ls -l" has been known to have O(n**2)
> behaviour for big directories.
>
Ultimately the question is: do we care about old (broken) filesystems?
-hpa
^ permalink raw reply
* Question about git process model
From: Barry Silverman @ 2005-04-15 1:07 UTC (permalink / raw)
To: 'Junio C Hamano'
Cc: 'Petr Baudis', 'Linus Torvalds', git
In-Reply-To: <7vfyxtose8.fsf@assigned-by-dhcp.cox.net>
JH->Junio Hamano, LT->Linus Torvalds
JH>>I just have this fuzzy feeling that, when doing this merge:
A-1 --- A-2 --- A-3
/ \
Common Ancestor Merge Result
\ /
B-1 --- B-2 --- B-3
JH>>looking at diff(Common Ancestor, A-1), diff(Common Ancestor,
JH>>B-1), diff(A-1, A-2), ... might give you richer context than
JH>>just merging 3-way using Common Ancestor, A-3, and B-3 to derive
JH>>the Merge Result. It might not. I honestly do not know.
In the distributed git model, with lots of parallel development, and
lots of merging - Is it important at the "business process" level that
intermediate history (and content) be present for any forks off the
mainline (in particular, forks maintained by someone else)?
Git has the property that it is NOT delta based. In Junio's example
above, if branch A were your mainline, and branch B were imported
changes from elsewhere, Is it necessary to have B1, B2 available to you,
when all that was required for you to merge successfully was B3?
Which leads me to....
LT>>In particular, if you ever find yourself wanting to graft together
two LT>>different commit histories, that almost certainly is what you'd
want to LT>>do. Somebody might have arrived at the exact same tree some
other way, LT>>starting with a 2.6.12 tar.ball or something, and I think
we should at LT>>least support the notion of saying "these two totally
unrelated commits LT>>actually have the same base tree, so let's merge
them in "space" (ie LT>>data) even if we can't really sanely join them
in "time" (ie "commits").
So in the case of only merging B3 - we would write into the commit
record of
Merge-Result, that it was parented by A1, and another new commit record
-> B3-Prime.
B3-Prime is space-wise identical to B3, but "time-wise" different.
B3-Prime would be different than B3 because it would necessarily not
have the same SHA1 as B3. Why? B3 has B2 as a parent, B3-Prime has the
Common Ancestor as a parent - thus the Commit record is different, and
so is the SHA1.
We would need a facility to recognize that B3 and B3-Prime were
space-wise the same, (and maybe have the SHA for B3 kept in somewhere in
the SCM portion of B3-Prime's commit record???)
Linus, is that what you were saying?
^ permalink raw reply
* Re: Yet another base64 patch
From: H. Peter Anvin @ 2005-04-15 1:06 UTC (permalink / raw)
To: Linus Torvalds; +Cc: bert hubert, Christopher Li, git
In-Reply-To: <Pine.LNX.4.58.0504141743360.7211@ppc970.osdl.org>
Linus Torvalds wrote:
>
> Even something as simple as "ls -l" has been known to have O(n**2)
> behaviour for big directories.
>
For filesystems with linear directories, sure. For sane filesystems, it
should have O(n log n).
-hpa
^ permalink raw reply
* Re: Merge with git-pasky II.
From: Junio C Hamano @ 2005-04-15 0:58 UTC (permalink / raw)
To: Petr Baudis; +Cc: Linus Torvalds, git
In-Reply-To: <20050414233159.GX22699@pasky.ji.cz>
>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:
>> I think the above would result in what SCM person would call
>> "merge upstream/sidestream changes into my working directory".
PB> And that's exactly what I'm doing now with git merge. ;-) In fact,
PB> ideally the whole change in my scripts when your script is finished
PB> would be replacing
PB> checkout-cache `diff-tree` # symbolic
PB> git diff $base $merged | git apply
PB> with
PB> merge-tree.pl -b $base $(tree-id) $merged | parse-your-output
In the above I presume by $merged you mean the tree ID (or
commit ID) the user's working directory is based upon? Well,
merge-trees (Linus has a single directory merge-tree already)
looks at tree IDs (or commit IDs); it would never involve
working files in random state that is not recorded as part of a
tree (committed or not). Given that constraints I am not sure
how well that would pan out. I have to think about this a bit.
I do like, however, the idea of separating the step of doing any
checkout/merge etc. and actually doing them. So the command set
of parse-your-output needs to be defined. Based on what I have
done so far, it would consist of the following:
- Result is this object $SHA1 with mode $mode at $path (takes
one of the trees); you can do update-cache --cacheinfo (if
you want to muck with dircache) or cat-file blob (if you want
to get the file) or both.
- Result is to delete $path.
- Result is a merge between object $SHA1-1 and $SHA1-2 with
mode $mode-1 or $mode-2 at $path.
Would this be a good enough command set?
PB> Doesn't Emacs have something equivalent to ./.vimrc? I've also seen
PB> those funny -*- strings.
The former is global per user (that is me including other Perl
files I work outside of git context), which is exactly what I
said is unacceptable to me. The latter is per file (applying to
everybody else who touch the file), so if it is short and sweet
I should use one.
^ permalink raw reply
* Re: Yet another base64 patch
From: Linus Torvalds @ 2005-04-15 0:44 UTC (permalink / raw)
To: bert hubert; +Cc: H. Peter Anvin, Christopher Li, git
In-Reply-To: <20050414214756.GA31249@outpost.ds9a.nl>
On Thu, 14 Apr 2005, bert hubert wrote:
>
> It is too easy to get into a O(N^2) situation. Git may be able to deal with
> it but you may hurt yourself when making backups, or if you ever want to
> share your tree (possibly with yourself) over the network.
Even something as simple as "ls -l" has been known to have O(n**2)
behaviour for big directories.
Linus
^ permalink raw reply
* Re: Merge with git-pasky II.
From: Linus Torvalds @ 2005-04-15 0:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Petr Baudis, git
In-Reply-To: <7v7jj5qgdz.fsf@assigned-by-dhcp.cox.net>
On Thu, 14 Apr 2005, Junio C Hamano wrote:
>
> You say "merge these two trees" above (I take it that you mean
> "merge these two trees, taking account of this tree as their
> common ancestor", so actually you are dealing with three trees),
Yes. We're definitely talking three trees.
> and I am tending to agree with the notion of merging trees not
> commits. However you might get richer context and more sensible
> resulting merge if you say "merge these two commits". Since
> commit chaining is part of the fundamental git object model you
> may as well use it.
Yes and no. There are real advantages to using the commit state to just
figure out the trees, and then at least have the _option_ to do the merge
at a pure tree object.
In particular, if you ever find yourself wanting to graft together two
different commit histories, that almost certainly is what you'd want to
do. Somebody might have arrived at the exact same tree some other way,
starting with a 2.6.12 tar.ball or something, and I think we should at
least support the notion of saying "these two totally unrelated commits
actually have the same base tree, so let's merge them in "space" (ie data)
even if we can't really sanely join them in "time" (ie "commits").
I dunno.
And it's also a question of sanity. The fact is, we know how to make tree
merges unambiguous, by just totally ignoring the history between them. Ie
we know how to merge data. I am pretty damn sure that _nobody_ knows how
to merge "data over time". Maybe BK does. I'm pretty sure it actually
takes the "over time" into account. But My goal is to get something that
works, and something that is reliable because it is simple and it has
simple rules.
As you say:
> This however opens up another set of can of worms---it would
> involve not just three trees but all the trees in the commit
> chain in between.
Exactly. I seriously believe that the model is _broken_, simply because
it gets too complicated. At some point it boils down to "keep it simple,
stupid".
> That's when you start wondering if it would
> be better to add renames in the git object model, which is the
> topic of another thread. I have not formed an opinion on that
> one myself yet.
I've not even been convinved that renames are worth it. Nobody has really
given a good reason why.
There are two reasons for renames I can think of:
- space efficiency in delta-based trees. This is a total non-issue for
git, and trying to explicitly track renames is going to cause _more_
space to be wasted rather than less.
- "annotate". Something git doesn't really handle anyway, and it has
little to do with renames. You can fake an annotate, but let's face it,
it's _always_ going to be depending on interpreting a diff. In fact,
that ends up how traditional SCM's do it too - they don't really
annotate lines, they just interpret the diff.
I think you might as well interpret the whole object thing. Git _does_
tell you how the objects changed, and I actually believe that a diff
that works in between objects (ie can show "these lines moved from this
file X to tjhat file Y") is a _hell_ of a lot more powerful than
"rename" is.
So I'd seriously suggest that instead of worryign about renames, people
think about global diffs that aren't per-file. Git is good at limiting
the changes to a set of objects, and it should be entirely possible to
think of diffs as ways of moving lines _between_ objects and not just
within objects. It's quite common to move a function from one file to
another - certainly more so than renaming the whole file.
In other words, I really believe renames are just a meaningless special
case of a much more interesting problem. Which is just one reason why
I'm not at all interested in bothering with them other than as a "data
moved" thing, which git already handles very well indeed.
So there,
Linus
^ permalink raw reply
* Re: Git archive now available
From: David S. Miller @ 2005-04-15 0:03 UTC (permalink / raw)
To: Darren Williams; +Cc: git, linux-kernel
In-Reply-To: <20050415000147.GA1480@cse.unsw.EDU.AU>
On Fri, 15 Apr 2005 10:01:47 +1000
Darren Williams <dsw@gelato.unsw.edu.au> wrote:
> Thanks to the team at Gelato@UNSW we now have a
> no so complete Git archive at
> http://www.gelato.unsw.edu.au/archives/git/
>
> If somebody could send me a complete Git mbox I will
> update the archive with it.
I just had to unsubscribe git@lemon.gelato.unsw.edu.au
because it was bouncing with errors like "hypermail: ...
this archive looks non-empty but there it no gdbm file"
So don't get too excited about your archive just yet :-)
^ permalink raw reply
* Re: [PATCH] Git pasky include commit-id in Makefile
From: Darren Williams @ 2005-04-15 0:04 UTC (permalink / raw)
To: Martin Schlemmer; +Cc: Git Mailing List, Petr Baudis
In-Reply-To: <1113518245.23299.107.camel@nosferatu.lan>
Hi Martin
On Fri, 15 Apr 2005, Martin Schlemmer wrote:
> On Fri, 2005-04-15 at 00:10 +1000, Darren Williams wrote:
> > Currently the commit-id script is not install with
> > make install, this patches includes it in the SCRIPT
> > target. This patch is against git-pasky-0.4
> >
>
> Hmm, this is still not fixed ...
OK hopefully we can now have people look at the archives
http://www.gelato.unsw.edu.au/archives/git/
- dsw
>
> > Signed-off-by Darren Williams <dsw@gelato.unsw.edu.au>
> >
> > COPYING: fe2a4177a760fd110e78788734f167bd633be8de
> > Makefile: ca50293c4f211452d999b81f122e99babb9f2987
> > --- Makefile
> > +++ Makefile 2005-04-14 23:52:35.701915203 +1000
> > @@ -19,7 +19,7 @@
> > SCRIPT= parent-id tree-id git gitXnormid.sh gitadd.sh gitaddremote.sh \
> > gitcommit.sh gitdiff-do gitdiff.sh gitlog.sh gitls.sh gitlsobj.sh \
> > gitmerge.sh gitpull.sh gitrm.sh gittag.sh gittrack.sh gitexport.sh \
> > - gitapply.sh gitcancel.sh gitlntree.sh
> > + gitapply.sh gitcancel.sh gitlntree.sh commit-id
> >
> > GEN_SCRIPT= gitversion.sh
> >
> > README: ded1a3b20e9bbe1f40e487ba5f9361719a1b6b85
> > VERSION: c27bd67cd632cc15dd520fbfbf807d482efa2dcf
> > cache.h: 4d382549041d3281f8d44aa2e52f9f8ec47dd420
> > cat-file.c: 45be1badaa8517d4e3a69e0bf1cac2e90191e475
> > check-files.c: 927b0b9aca742183fc8e7ccd73d73d8d5427e98f
> > checkout-cache.c: f06871cdbc1b18ea93bdf4e17126aeb4cca1373e
> > commit-id: 65c81756c8f10d513d073ecbd741a3244663c4c9
> > commit-tree.c: 12196c79f31d004dff0df1f50dda67d8204f5568
> > diff-tree.c: 7dcc9eb7782fa176e27f1677b161ce78ac1d2070
> > fsck-cache.c: 9c900fe458cecd2bdb4c4571a584115b5cf24f22
> > git: 2c557dcf2032325acc265b577ee104e605fdaede
> > gitXnormid.sh: a5d7a9f4a6e8d4860f35f69500965c2a493d80de
> > gitadd.sh: 3ed93ea0fcb995673ba9ee1982e0e7abdbe35982
> > gitaddremote.sh: bf1f28823da5b5270aa8fa05b321faa514a57a11
> > gitapply.sh: d0e3c46e2ce1ee74e1a87ee6137955fa9b35c27b
> > gitcancel.sh: ec58f7444a42cd3cbaae919fc68c70a3866420c0
> > gitcommit.sh: 3629f67bbd3f171d091552814908b67af7537f4d
> > gitdiff-do: d6174abceab34d22010c36a8453a6c3f3f184fe0
> > gitdiff.sh: 5e47c4779d73c3f2f39f6be714c0145175933197
> > gitexport.sh: dad00bf251b38ce522c593ea9631f842d8ccc934
> > gitlntree.sh: 17c4966ea64aeced96ae4f1b00f3775c1904b0f1
> > gitlog.sh: 177c6d12dd9fa4b4920b08451ffe4badde544a39
> > gitls.sh: b6f15d82f16c1e9982c5031f3be22eb5430273af
> > gitlsobj.sh: 128461d3de6a42cfaaa989fc6401bebdfa885b3f
> > gitmerge.sh: 23e4a3ff342c6005928ceea598a2f52de6fb9817
> > gitpull.sh: 0883898dda579e3fa44944b7b1d909257f6dc63e
> > gitrm.sh: 5c18c38a890c9fd9ad2b866ee7b529539d2f3f8f
> > gittag.sh: c8cb31385d5a9622e95a4e0b2d6a4198038a659c
> > gittrack.sh: 03d6db1fb3a70605ef249c632c04e542457f0808
> > init-db.c: aa00fbb1b95624f6c30090a17354c9c08a6ac596
> > ls-tree.c: 3e2a6c7d183a42e41f1073dfec6794e8f8a5e75c
> > parent-id: 1801c6fe426592832e7250f8b760fb9d2e65220f
> > read-cache.c: 7a6ae8b9b489f6b67c82e065dedd5716a6bfc0ef
> > read-tree.c: eb548148aa6d212f05c2c622ffbe62a06cd072f9
> > rev-tree.c: 395b0b3bfadb0537ae0c62744b25ead4b487f3f6
> > show-diff.c: a531ca4078525d1c8dcf84aae0bfa89fed6e5d96
> > show-files.c: a9fa6767a418f870a34b39379f417bf37b17ee18
> > tree-id: cb70e2c508a18107abe305633612ed702aa3ee4f
> > update-cache.c: 62d0a6c41560d40863c44599355af10d9e089312
> > write-tree.c: 1534477c91169ebddcf953e3f4d2872495477f6b
> >
> > ---------------------------------------------------
> > Darren Williams <dsw AT gelato.unsw.edu.au>
> > Gelato@UNSW <www.gelato.unsw.edu.au>
> > --------------------------------------------------
> > -
> > To unsubscribe from this list: send the line "unsubscribe git" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> --
> Martin Schlemmer
>
--------------------------------------------------
Darren Williams <dsw AT gelato.unsw.edu.au>
Gelato@UNSW <www.gelato.unsw.edu.au>
--------------------------------------------------
^ permalink raw reply
* Git archive now available
From: Darren Williams @ 2005-04-15 0:01 UTC (permalink / raw)
To: Git Mailing List, LKML
Hi All
Thanks to the team at Gelato@UNSW we now have a
no so complete Git archive at
http://www.gelato.unsw.edu.au/archives/git/
If somebody could send me a complete Git mbox I will
update the archive with it.
- dsw
--------------------------------------------------
Darren Williams <dsw AT gelato.unsw.edu.au>
Gelato@UNSW <www.gelato.unsw.edu.au>
--------------------------------------------------
^ permalink raw reply
* Re: Re: Merge with git-pasky II.
From: Christopher Li @ 2005-04-14 20:50 UTC (permalink / raw)
To: Petr Baudis; +Cc: Junio C Hamano, Linus Torvalds, git
In-Reply-To: <20050414203717.GE25468@64m.dyndns.org>
BTW, I am not competing with Junio script. If that is the way
we all agree on. It is should be very easy for Junio to fix his
perl script. right?
Chris
On Thu, Apr 14, 2005 at 04:37:17PM -0400, Christopher Li wrote:
> Is that some thing you want to see? Maybe clean up the error printing.
>
>
> Chris
>
> --- /dev/null 2003-01-30 05:24:37.000000000 -0500
> +++ merge.py 2005-04-14 16:34:39.000000000 -0400
> @@ -0,0 +1,76 @@
> +#!/usr/bin/env python
> +
> +import re
> +import sys
> +import os
> +from pprint import pprint
> +
> +def get_tree(commit):
> + data = os.popen("cat-file commit %s"%commit).read()
> + return re.findall(r"(?m)^tree (\w+)", data)[0]
> +
> +PREFIX = 0
> +PATH = -1
> +SHA = -2
> +ORIGSHA = -3
> +
> +def get_difftree(old, new):
> + lines = os.popen("diff-tree %s %s"%(old, new)).read().split("\x00")
> + patterns = (r"(\*)(\d+)->(\d+)\s(\w+)\s(\w+)->(\w+)\s(.*)",
> + r"([+-])(\d+)\s(\w+)\s(\w+)\s(.*)")
> + res = {}
> + for l in lines:
> + if not l: continue
> + for p in patterns:
> + m = re.findall(p, l)
> + if m:
> + m = m[0]
> + res[m[-1]] = m
> + break
> + else:
> + raise "difftree: unknow line", l
> + return res
> +
> +def analyze(diff1, diff2):
> + diff1only = [ diff1[k] for k in diff1 if k not in diff2 ]
> + diff2only = [ diff2[k] for k in diff2 if k not in diff1 ]
> + both = [ (diff1[k],diff2[k]) for k in diff2 if k in diff1 ]
> +
> + action(diff1only)
> + action(diff2only)
> + action_two(both)
> +
> +def action(diffs):
> + for act in diffs:
> + if act[PREFIX] == "*":
> + print "modify", act[PATH], act[SHA]
> + elif act[PREFIX] == '-':
> + print "remove", act[PATH], act[SHA]
> + elif act[PREFIX] == '+':
> + print "add", act[PATH], act[SHA]
> + else:
> + raise "unknow action"
> +
> +def action_two(diffs):
> + for act1, act2 in diffs:
> + if len(act1) == len(act2): # same kind type
> + if act1[PREFIX] == act2[PREFIX]:
> + if act1[SHA] == act2[SHA] or act1[PREFIX] == '-':
> + return action(act1)
> + if act1[PREFIX]=='*':
> + print "do_merge", act1[PATH], act1[ORIGSHA], act1[SHA], act2[SHA]
> + return
> + print "unable to handle", act[PATH]
> + print "one side wants", act1[PREFIX]
> + print "the other side wants", act2[PREFIX]
> +
> +
> +args = sys.argv[1:]
> +if len(args)!=3:
> + print "Usage merge.py <common> <rev1> <rev2>"
> +trees = map(get_tree, args)
> +print "checkout-tree", trees[0]
> +diff1 = get_difftree(trees[0], trees[1])
> +diff2 = get_difftree(trees[0], trees[2])
> +analyze(diff1, diff2)
> +
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: trying to figure out this git thing - some questions
From: tony.luck @ 2005-04-14 23:52 UTC (permalink / raw)
To: Ehud Shabtai; +Cc: git
In-Reply-To: <68b6a2bc05041412025f1cb7c9@mail.gmail.com>
>I'm trying to understand how it works and I'll appreciate if someone could help.
>1. git uses object abstraction for the different types and so
>everything is in one directory (objects). From what I've seen in the
>implementation, the different kind of objects are not of the same type
>(there aren't any operations which work on two different types) and
>thus in each step when an object is used its type is verified.
>What's the benefit of having them all in the same tree? An alternative
>would be to separate the different object types into different
>directories which trivially allows getting a list of all commits, or
>trees or blobs.
If all the commits were in ".git/objects/commits/xx/xxxxx", etc. then every
time git opened a file the kernel would have one extra level of directory
to walk to get to the file ... so opens would be fractionally slower. There
is no normal-use upside to this overhead. While it would be easier to find
all the blobs if they were kept separate from the trees and commits, there
isn't any time that we'd ever want to scan through just the blobs. Git never
goes searching through a directory opening files to see what they are
(exception: fsck-cache does scan all objects).
>2. A commit can have more than one parent. Can anyone draw an example
>of such a case? When do we get a commit graph which is not linear?
When a merge happens. E.g. I take a snapshot of Linus' tree when a file
is at version 1.2. We both make a couple of changes before I ask him to
pull from my tree:
1.1 -> 1.2 -> 1.3 -> 1.4 -> 1.5
\ /
1.2.1 -> 1.2.2 ---/
The changeset to create 1.5 has two parents ... the changeset that Linus made
to create 1.4, and the changeset that I made to create 1.2.2
>3. How does git handle binary files? I guess it doesn't really care if
>it's binary or text, but how would the diff and merge scripts handle
>them?
Yes, git doesn't care. Diff is somewhat smart about noticing that its
input files aren't text:
$ diff /bin/cat /bin/ls
Binary files /bin/cat and /bin/ls differ
But in general this will be an issue for the SCM layer if there are binary
files checked into the tree.
-Tony
^ permalink raw reply
* Re: Re: Re: [patch pasky] update gitcancel.sh to handle modes as well
From: Petr Baudis @ 2005-04-14 23:49 UTC (permalink / raw)
To: Martin Schlemmer; +Cc: GIT Mailing Lists
In-Reply-To: <1113521946.23299.143.camel@nosferatu.lan>
Dear diary, on Fri, Apr 15, 2005 at 01:39:06AM CEST, I got a letter
where Martin Schlemmer <azarah@nosferatu.za.org> told me that...
> On Fri, 2005-04-15 at 01:15 +0200, Petr Baudis wrote:
> > Dear diary, on Fri, Apr 15, 2005 at 01:04:50AM CEST, I got a letter
> > where Martin Schlemmer <azarah@nosferatu.za.org> told me that...
> > > Rather use checkout-cache to sync our tree, as should do the right thing
> > > instead of diffing (cancel imply just blow away everything).
> > >
> > > Signed-off-by: Martin Schlemmer <azarah@nosferatu.za.org>
> > >
> > > gitcancel.sh: 839b3c58f20f6eb8412f499a891e007e2e67d114
> > > --- 839b3c58f20f6eb8412f499a891e007e2e67d114/gitcancel.sh
> > > +++ uncommitted/gitcancel.sh
> > > @@ -10,9 +10,8 @@
> > > #
> > > # Takes no arguments. Takes the evil changes from the tree.
> > >
> > > -# FIXME: Does not revert mode changes!
> > >
> > > -show-diff | patch -p0 -R
> > > rm -f .git/add-queue .git/rm-queue
> > > +checkout-cache -q -f -a
> > >
> > > update-cache --refresh
> >
>
> PS, shouldn't we add a read-tree $(tree-id) before the checkout-cache?
A correct tree should be in the index. And if for any completely weird
and smelly reason it isn't, I'm pondering if we should back that out and
always reread-tree (takes some time, but do you do git cancel all the
time?), or rather comply to it and adjust to the loaded tree, whichever
it is.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ permalink raw reply
* Re: Re: Merge with git-pasky II.
From: Christopher Li @ 2005-04-14 20:37 UTC (permalink / raw)
To: Petr Baudis; +Cc: Junio C Hamano, Linus Torvalds, git
In-Reply-To: <20050414203013.GD25468@64m.dyndns.org>
Is that some thing you want to see? Maybe clean up the error printing.
Chris
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ merge.py 2005-04-14 16:34:39.000000000 -0400
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+import re
+import sys
+import os
+from pprint import pprint
+
+def get_tree(commit):
+ data = os.popen("cat-file commit %s"%commit).read()
+ return re.findall(r"(?m)^tree (\w+)", data)[0]
+
+PREFIX = 0
+PATH = -1
+SHA = -2
+ORIGSHA = -3
+
+def get_difftree(old, new):
+ lines = os.popen("diff-tree %s %s"%(old, new)).read().split("\x00")
+ patterns = (r"(\*)(\d+)->(\d+)\s(\w+)\s(\w+)->(\w+)\s(.*)",
+ r"([+-])(\d+)\s(\w+)\s(\w+)\s(.*)")
+ res = {}
+ for l in lines:
+ if not l: continue
+ for p in patterns:
+ m = re.findall(p, l)
+ if m:
+ m = m[0]
+ res[m[-1]] = m
+ break
+ else:
+ raise "difftree: unknow line", l
+ return res
+
+def analyze(diff1, diff2):
+ diff1only = [ diff1[k] for k in diff1 if k not in diff2 ]
+ diff2only = [ diff2[k] for k in diff2 if k not in diff1 ]
+ both = [ (diff1[k],diff2[k]) for k in diff2 if k in diff1 ]
+
+ action(diff1only)
+ action(diff2only)
+ action_two(both)
+
+def action(diffs):
+ for act in diffs:
+ if act[PREFIX] == "*":
+ print "modify", act[PATH], act[SHA]
+ elif act[PREFIX] == '-':
+ print "remove", act[PATH], act[SHA]
+ elif act[PREFIX] == '+':
+ print "add", act[PATH], act[SHA]
+ else:
+ raise "unknow action"
+
+def action_two(diffs):
+ for act1, act2 in diffs:
+ if len(act1) == len(act2): # same kind type
+ if act1[PREFIX] == act2[PREFIX]:
+ if act1[SHA] == act2[SHA] or act1[PREFIX] == '-':
+ return action(act1)
+ if act1[PREFIX]=='*':
+ print "do_merge", act1[PATH], act1[ORIGSHA], act1[SHA], act2[SHA]
+ return
+ print "unable to handle", act[PATH]
+ print "one side wants", act1[PREFIX]
+ print "the other side wants", act2[PREFIX]
+
+
+args = sys.argv[1:]
+if len(args)!=3:
+ print "Usage merge.py <common> <rev1> <rev2>"
+trees = map(get_tree, args)
+print "checkout-tree", trees[0]
+diff1 = get_difftree(trees[0], trees[1])
+diff2 = get_difftree(trees[0], trees[2])
+analyze(diff1, diff2)
+
^ permalink raw reply
* Re: Re: Merge with git-pasky II.
From: Christopher Li @ 2005-04-14 20:30 UTC (permalink / raw)
To: Petr Baudis; +Cc: Junio C Hamano, Linus Torvalds, git
In-Reply-To: <20050414233159.GX22699@pasky.ji.cz>
On Fri, Apr 15, 2005 at 01:31:59AM +0200, Petr Baudis wrote:
> > I am just trying to follow my understanding of what Linus
> > wanted. One of the guiding principle is to do as much things as
> > in dircache without ever checking things out or touching working
> > files unnecessarily.
>
> I'm just arguing that instead of directly touching the directory cache,
> you should just list what would you do there - and you already do this,
That is exactly what I suggest in the previous email. And my python script
does exactly that ;-)
Chris
^ permalink raw reply
* Re: Re: [patch pasky] update gitcancel.sh to handle modes as well
From: Martin Schlemmer @ 2005-04-14 23:39 UTC (permalink / raw)
To: Petr Baudis; +Cc: GIT Mailing Lists
In-Reply-To: <20050414231558.GW22699@pasky.ji.cz>
[-- Attachment #1: Type: text/plain, Size: 969 bytes --]
On Fri, 2005-04-15 at 01:15 +0200, Petr Baudis wrote:
> Dear diary, on Fri, Apr 15, 2005 at 01:04:50AM CEST, I got a letter
> where Martin Schlemmer <azarah@nosferatu.za.org> told me that...
> > Rather use checkout-cache to sync our tree, as should do the right thing
> > instead of diffing (cancel imply just blow away everything).
> >
> > Signed-off-by: Martin Schlemmer <azarah@nosferatu.za.org>
> >
> > gitcancel.sh: 839b3c58f20f6eb8412f499a891e007e2e67d114
> > --- 839b3c58f20f6eb8412f499a891e007e2e67d114/gitcancel.sh
> > +++ uncommitted/gitcancel.sh
> > @@ -10,9 +10,8 @@
> > #
> > # Takes no arguments. Takes the evil changes from the tree.
> >
> > -# FIXME: Does not revert mode changes!
> >
> > -show-diff | patch -p0 -R
> > rm -f .git/add-queue .git/rm-queue
> > +checkout-cache -q -f -a
> >
> > update-cache --refresh
>
PS, shouldn't we add a read-tree $(tree-id) before the checkout-cache?
--
Martin Schlemmer
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Merge with git-pasky II.
From: Christopher Li @ 2005-04-14 20:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Petr Baudis, Linus Torvalds, git
In-Reply-To: <7vmzs1osv1.fsf@assigned-by-dhcp.cox.net>
Hi Junio,
I think if the merge tree belong to plumbing, you can do
even less in the merge.perl. You can just print out the
instruction for the upper level SCM what to to without
actually doing it yourself.
So you don't have to do touch anything in the tree.
That is the way I use in my previous python script.
You just print out some easy to modify
e.g. in my python script it prints: (BTW, poor choice of print out name)
check out tree 253290af8b9ebc8565dd8de4cda24d0432a92b57
modify pre-process.c 7684c115a87e41a9226ce79478101c746cf22c34
3way-merge check.c dcb970cc1c5a83284dc5986abf07b6da76a8758c f77bfe119c19d928879091e0e3ee6debe3f1e1bf d315b43b025350d0107568a4d42cc2494d38621d
Your merge tree can do the smae.
Then the supper level SCM can easily follow instruction.
Save your effort and make no assumption what SCM module is.
Chris
On Thu, Apr 14, 2005 at 04:12:34PM -0700, Junio C Hamano wrote:
> >>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:
>
> I think you are contradicting yourself for saying the above
> after agreeing with me that the script should just work on trees
> not commits. My understanding is that the tools is just to
> merge two related trees relative to another ancestor tree,
> nothing more. Especially, it should not care what is in the
> working directory---that is SCM person's business.
>
> I am just trying to follow my understanding of what Linus
> wanted. One of the guiding principle is to do as much things as
> in dircache without ever checking things out or touching working
> files unnecessarily.
>
> PB> This will give the tool maximal flexibility.
>
> I suspect it would force me to have a working directory
> populated with files, just to do a merge.
>
> PB> I'm all for an -o, and I don't mind ,, - I just don't want it uselessly
> PB> long. I hope "git~merge~$$" was a joke... :-)
>
> Which part do you object to? PID part? or tilde? Would
> git~merge do, perhaps? It probably would not matter to you
> because as an SCM you would always give an explicit --output
> parameter to the script anyway.
>
> PB> By the way, what about indentation with tabs? If you have a
> PB> strong opinion about this, I don't insist - but if you
> PB> really don't mind/care either way, it'd be great to use tabs
> PB> as in the rest of the git code.
>
> I do not have a strong opinion, but it is more trouble for me
> only because I am lazy and am used to the indentation my Emacs
> gives me. I write code other than git, so changing Perl-mode
> indentation setting globally for all .pl files is not an option
> for me. I'll see what I can do when I have time.
>
> PB> Is there a fundamental reason why the directory cache
> PB> contains the ancestor instead of the destination branch?
>
> Because you are thinking as an SCM person where there are
> distinction between tree-A and tree-B, two heads being merged.
> There is no "destination branch" nor "source branch" in what I
> am doing. It is a merge of two equals derived from the same
> ancestor.
>
> PB> I think the script actually does not fundamentally depend on it. My main
> PB> motivation is that the user can then trivially see what is he actually
> PB> going to commit to his destination branch, which would be bought for
> PB> free by that.
>
> And again the user is *not* commiting to his "destination
> branch". At the level I am working at, the merge result should
> be commited with two -p parameters to commit-tree --- tree-A and
> tree-B, both being equal parents from the POV of git object
> storage.
>
> PB> And this is another thing I dislike a lot. I'd like merge-tree.pl to
> PB> leave my directory cache alone, thank you very much. You know, I see
> PB> what goes to the directory cache as actually part of the policy part.
>
> Remember I am not touching *your* dircache. It is a dircache in
> the temporary merge area, specifically set up to help you review
> the merge.
>
> Can't the SCM driver do things along this line, perhaps?
>
> - You have your working files and your dircache. They may not
> match because you have uncommitted changes to your
> environment. You want to merge with Linus head. You know
> its SHA1 (call it COMMIT-Linus). Your SCM knows which commit
> you started with (call it COMMIT-Current).
>
> - First you merge the tree associated with COMMIT-Current. Use
> it and COMMIT-Linus to find the common ancestor to use.
>
> - Now use the tree SHA of COMMIT-Current, tree SHA1 of
> COMMIT-Linus, and tree SHA1 of the common ancestor commit to
> drive git-merge.perl (to be renamed ;-). You will get a
> temporary directory. Have your user examine what is in
> there, and fix the merge and have them tell you they are
> happy.
>
> - You go to that temporary directory, do write-tree and
> commit-tree with -p parameter of COMMIT-Linus and
> COMMIT-Current. This will result in a new commit. Call that
> COMMIT-Merge.
>
> - You, as an SCM, should know what your user have done in the
> working directory relative to COMMIT-Current. Especially you
> should know the set of paths involved in that change. Go in
> to the temporary area, checkout-cache those files if you have
> not done so. Apply the changes you have there. Optionally
> have the user examine the changes and have him confirm. Lift
> those files into the user's working directory.
>
> - Do your bookkeeping like "echo COMMIT-Merge >.git/Head", to
> make the user's working files based on COMMIT-Merge, and run
> read-tree using the COMMIT-Merge in the user's working
> directory. At this point, show-diff output should show what
> the changes your user have had made if he had started working
> based on COMMIT-Merge instead of starting from
> COMMIT-Current.
>
> I think the above would result in what SCM person would call
> "merge upstream/sidestream changes into my working directory".
>
^ permalink raw reply
* Re: Re: Merge with git-pasky II.
From: Petr Baudis @ 2005-04-14 23:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7vmzs1osv1.fsf@assigned-by-dhcp.cox.net>
Dear diary, on Fri, Apr 15, 2005 at 01:12:34AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> >>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:
>
> PB> What I would like your script to do is therefore just do the
> PB> merge in a given already prepared (including built index)
> PB> directory, with a passed base. The base should be determined
> PB> by a separate tool (I already saw some patches); most future
> PB> "science" will probably go to a clever selection of this
> PB> base, anyway.
>
> I think you are contradicting yourself for saying the above
> after agreeing with me that the script should just work on trees
> not commits. My understanding is that the tools is just to
> merge two related trees relative to another ancestor tree,
> nothing more. Especially, it should not care what is in the
> working directory---that is SCM person's business.
Yes. Isn't this exactly what I'm saying?
I'm arguing for doing less in my paragraph, you are arguing for doing
less in your paragraph, and we even seem to agree on the direction in
which we should do less.
> I am just trying to follow my understanding of what Linus
> wanted. One of the guiding principle is to do as much things as
> in dircache without ever checking things out or touching working
> files unnecessarily.
I'm just arguing that instead of directly touching the directory cache,
you should just list what would you do there - and you already do this,
I think. So I'd be happy with a switch which would just do that and not
touch the directory cache. I'll parse your output and do the right thing
for me.
> PB> This will give the tool maximal flexibility.
>
> I suspect it would force me to have a working directory
> populated with files, just to do a merge.
Why would that be so?
> PB> I'm all for an -o, and I don't mind ,, - I just don't want it uselessly
> PB> long. I hope "git~merge~$$" was a joke... :-)
>
> Which part do you object to? PID part? or tilde? Would
> git~merge do, perhaps? It probably would not matter to you
> because as an SCM you would always give an explicit --output
> parameter to the script anyway.
Yes. I'll just override it with ,,merge, I think. So, do whatever you
want. ;-))
> PB> By the way, what about indentation with tabs? If you have a
> PB> strong opinion about this, I don't insist - but if you
> PB> really don't mind/care either way, it'd be great to use tabs
> PB> as in the rest of the git code.
>
> I do not have a strong opinion, but it is more trouble for me
> only because I am lazy and am used to the indentation my Emacs
> gives me. I write code other than git, so changing Perl-mode
> indentation setting globally for all .pl files is not an option
> for me. I'll see what I can do when I have time.
Doesn't Emacs have something equivalent to ./.vimrc? I've also seen
those funny -*- strings.
Well, if it would mean a lot of trouble for you, just forget about it.
> PB> Is there a fundamental reason why the directory cache
> PB> contains the ancestor instead of the destination branch?
>
> Because you are thinking as an SCM person where there are
> distinction between tree-A and tree-B, two heads being merged.
> There is no "destination branch" nor "source branch" in what I
> am doing. It is a merge of two equals derived from the same
> ancestor.
That's a valid point of view too.
Actually, when you would have a mode in which you would not write to the
directory cache, do you need to read from it? You could do just direct
cat-files like for the other trees, and it would be even faster. Then,
you could do without a directory cache altogether in this mode.
> PB> And this is another thing I dislike a lot. I'd like merge-tree.pl to
> PB> leave my directory cache alone, thank you very much. You know, I see
> PB> what goes to the directory cache as actually part of the policy part.
>
> Remember I am not touching *your* dircache. It is a dircache in
> the temporary merge area, specifically set up to help you review
> the merge.
Yes, but I want to have a control over its dircache too. :-) That is
because I want the user to be able to use the regular git commands like
"git diff" there.
> Can't the SCM driver do things along this line, perhaps?
>
> - You have your working files and your dircache. They may not
> match because you have uncommitted changes to your
> environment. You want to merge with Linus head. You know
> its SHA1 (call it COMMIT-Linus). Your SCM knows which commit
> you started with (call it COMMIT-Current).
>
> - First you merge the tree associated with COMMIT-Current. Use
> it and COMMIT-Linus to find the common ancestor to use.
>
> - Now use the tree SHA of COMMIT-Current, tree SHA1 of
> COMMIT-Linus, and tree SHA1 of the common ancestor commit to
> drive git-merge.perl (to be renamed ;-). You will get a
> temporary directory. Have your user examine what is in
> there, and fix the merge and have them tell you they are
> happy.
>
> - You go to that temporary directory, do write-tree and
> commit-tree with -p parameter of COMMIT-Linus and
> COMMIT-Current. This will result in a new commit. Call that
> COMMIT-Merge.
>
> - You, as an SCM, should know what your user have done in the
> working directory relative to COMMIT-Current. Especially you
> should know the set of paths involved in that change. Go in
> to the temporary area, checkout-cache those files if you have
> not done so. Apply the changes you have there. Optionally
> have the user examine the changes and have him confirm. Lift
> those files into the user's working directory.
>
> - Do your bookkeeping like "echo COMMIT-Merge >.git/Head", to
> make the user's working files based on COMMIT-Merge, and run
> read-tree using the COMMIT-Merge in the user's working
> directory. At this point, show-diff output should show what
> the changes your user have had made if he had started working
> based on COMMIT-Merge instead of starting from
> COMMIT-Current.
>
> I think the above would result in what SCM person would call
> "merge upstream/sidestream changes into my working directory".
And that's exactly what I'm doing now with git merge. ;-) In fact,
ideally the whole change in my scripts when your script is finished
would be replacing
checkout-cache `diff-tree` # symbolic
git diff $base $merged | git apply
with
merge-tree.pl -b $base $(tree-id) $merged | parse-your-output
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ permalink raw reply
* Re: Live Merging from remote repositories
From: Junio C Hamano @ 2005-04-14 23:22 UTC (permalink / raw)
To: Barry Silverman; +Cc: Petr Baudis, Junio C Hamano, Linus Torvalds, git
In-Reply-To: <IGEMLBGAECDFPIKMIMLCCEELCHAA.barry@disus.com>
>>>>> "BS" == Barry Silverman <barry@disus.com> writes:
I have not thought about remote issues at all, other than the
distribution mechanism vaguely outlined in my previous mail (not
cc'ed to git list but I would not mind if you reproduced it here
if somebody asked), so I am not qualified to comment on that
part of your message.
BS> The way Junio has done it, no intermediate trees or commits
BS> are used...
BS> Is this a bug or a feature?
I would call that a feature in that there is no need to look at
intermediate state. I also might call that a misfeature in that
it may have resulted in a better merge if it looked at
intermediate state.
I just have this fuzzy feeling that, when doing this merge:
A-1 --- A-2 --- A-3
/ \
Common Ancestor Merge Result
\ /
B-1 --- B-2 --- B-3
looking at diff(Common Ancestor, A-1), diff(Common Ancestor,
B-1), diff(A-1, A-2), ... might give you richer context than
just merging 3-way using Common Ancestor, A-3, and B-3 to derive
the Merge Result. It might not. I honestly do not know.
BTW, Pasky, the above paragraph is my answer to your question in
the other message <20050414202016.GC22699@pasky.ji.cz>:
> But one different thing to note here.
>
> You say "merge these two trees" above (I take it that you mean
> "merge these two trees, taking account of this tree as their
> common ancestor", so actually you are dealing with three trees),
> and I am tending to agree with the notion of merging trees not
> commits. However you might get richer context and more sensible
> resulting merge if you say "merge these two commits". Since
> commit chaining is part of the fundamental git object model you
> may as well use it.
Pasky> Could you be more particular on the richer context etc?
^ permalink raw reply
* Re: Remove need to untrack before tracking new branch
From: Martin Schlemmer @ 2005-04-14 23:25 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <1113520175.23299.134.camel@nosferatu.lan>
[-- Attachment #1: Type: text/plain, Size: 2551 bytes --]
On Fri, 2005-04-15 at 01:09 +0200, Martin Schlemmer wrote:
> On Fri, 2005-04-15 at 01:00 +0200, Petr Baudis wrote:
> > Dear diary, on Fri, Apr 15, 2005 at 01:01:27AM CEST, I got a letter
> > where Martin Schlemmer <azarah@nosferatu.za.org> told me that...
> > > On Fri, 2005-04-15 at 00:42 +0200, Petr Baudis wrote:
> > > > Dear diary, on Thu, Apr 14, 2005 at 11:40:09AM CEST, I got a letter
> > > > where Martin Schlemmer <azarah@nosferatu.za.org> told me that...
> > > > > > > - snprintf(cmd, sizeof(cmd), "diff -L %s -u -N - %s", name, name);
> > > > > > > + for (n = 0; n < 20; n++)
> > > > > > > + snprintf(&(sha1[n*2]), 3, "%02x", ce->sha1[n]);
> > > > > > > + snprintf(cmd, sizeof(cmd), "diff -L %s/%s -L uncommitted/%s -u -N - %s",
> > > > > > > + sha1, ce->name, ce->name, ce->name);
> > > > > >
> > > > > > The "directory" sha1 is the sha1 of the tree, not of the particular
> > > > > > file - that one is in the "attributes" list (parentheses after the
> > > > > > filename), together with mode.
> > > > > >
> > > > >
> > > > > Does it really matter? It is more just to get the patch prefix right,
> > > > > and I did it as it went nicely with the printed:
> > > > >
> > > > > ----
> > > > > show-diff.c: a531ca4078525d1c8dcf84aae0bfa89fed6e5d96
> > > > > ----
> > > > >
> > > > > for example ...
> > > >
> > > > Yes, it matters, and I don't care how nicely it wents with what you
> > > > print before.
> > > >
> > >
> > > hah ;p
> > >
> > > > Either print there some nonsense which is clear not to be a tree ID, or
> > > > (much more preferably) print the real tree ID there. If some tool ever
> > > > uses it (e.g. to help resolve conflicts, perhaps even actually doing a
> > > > real merge based on the patch), you just confused it.
> > > >
> > >
> > > Ok, understood. Do you think it will be scripted? If not I guess we
> > > can just do labels like:
> > >
> > > --- committed/
> > > +++ uncommitted/
> > >
> > > ?
> >
> > Heh. Well, of course this could do. But is there any technical reason
> > why not just carry the sha1 id of the tree around and stuff it there?
> >
>
> Not at all. Just wanted to know if anybody saw the possible use before
> adding possible cruft that could be done shorter - will do a patch
> shortly.
>
Ho hum - none of the lowlevel tools know or work with the tree-id, and I
am not too sure if Linus will like adding something to get it ... any
ideas?
--
Martin Schlemmer
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* git for beginners
From: tony.luck @ 2005-04-14 23:19 UTC (permalink / raw)
To: git
If the mechanics of git still have you stumped, then here are a couple of
examples of using the really low level tools to do some basic operations.
In real life you would have higher level wrappers around these tools so
that you don't have to remember to update .git/HEAD with the new SHA1 after
you do a commit ... but knowing what the low-level tools do may help you
understand what is going on.
-Tony
$ # How to create your own project from scratch
$ mkdir tmp
$ cd tmp
$ # Create initial empty git filesystem
$ init-db
defaulting to private storage area
$ # Look around ... lots of directories, but no files yet
$ ls -l .git
total 4
drwxr-xr-x 258 aegl aegl 4096 Apr 14 14:54 objects
$ ls .git/objects/
00 09 12 1b 24 2d 36 3f 48 51 5a 63 6c 75 7e 87 90 99 a2 ab b4 bd c6 cf d8 e1 ea f3 fc
01 0a 13 1c 25 2e 37 40 49 52 5b 64 6d 76 7f 88 91 9a a3 ac b5 be c7 d0 d9 e2 eb f4 fd
02 0b 14 1d 26 2f 38 41 4a 53 5c 65 6e 77 80 89 92 9b a4 ad b6 bf c8 d1 da e3 ec f5 fe
03 0c 15 1e 27 30 39 42 4b 54 5d 66 6f 78 81 8a 93 9c a5 ae b7 c0 c9 d2 db e4 ed f6 ff
04 0d 16 1f 28 31 3a 43 4c 55 5e 67 70 79 82 8b 94 9d a6 af b8 c1 ca d3 dc e5 ee f7
05 0e 17 20 29 32 3b 44 4d 56 5f 68 71 7a 83 8c 95 9e a7 b0 b9 c2 cb d4 dd e6 ef f8
06 0f 18 21 2a 33 3c 45 4e 57 60 69 72 7b 84 8d 96 9f a8 b1 ba c3 cc d5 de e7 f0 f9
07 10 19 22 2b 34 3d 46 4f 58 61 6a 73 7c 85 8e 97 a0 a9 b2 bb c4 cd d6 df e8 f1 fa
08 11 1a 23 2c 35 3e 47 50 59 62 6b 74 7d 86 8f 98 a1 aa b3 bc c5 ce d7 e0 e9 f2 fb
$ find . -type f
$
$ # create some files ready to check in ... use a subdirectory just to show
$ # how subdirs work
$ mkdir src
$ cat > src/hello.c
#include <stdio.h>
main()
{
printf("Hello, world!\n");
}
$ cat > Makefile
hello: src/hello.c
cc -o hello -O src/hello.c
$ # Now add these two files to the cache, ready for checkin (use the
$ # "--add" option because these files are new)
$ update-cache --add Makefile src/hello.c
$ # save a tree listing these files
$ write-tree
eab75ce51622aa312bb0b03572d43769f420c347
$ # commit the change. We tell it the SHA1 of the tree we just made
$ commit-tree eab75ce51622aa312bb0b03572d43769f420c347
Committing initial tree eab75ce51622aa312bb0b03572d43769f420c347
First revision of the hello system.
0107d57e748b2f01601adb6749a03aed7b3f5a84
$ # Save the SHA1 for that changeset ... we need it later
$ echo 0107d57e748b2f01601adb6749a03aed7b3f5a84 > .git/HEAD
$
$ # Take a look at the changeset
$ cat-file commit 0107d57e748b2f01601adb6749a03aed7b3f5a84
tree eab75ce51622aa312bb0b03572d43769f420c347
author Tony Luck <aegl@example.com> Thu Apr 14 14:57:27 2005
committer Tony Luck <aegl@example.com> Thu Apr 14 14:57:27 2005
First revision of the hello system.
$ # And dig into the tree we saved
$ ls-tree eab75ce51622aa312bb0b03572d43769f420c347
100664 blob 3a7a1c51dbc62797d6c903203de44cc6a734c05c Makefile
40000 tree ba103f91defa4b3885b826d6630a055f27800398 src
$ # see that git automatically made a tree for the "src" subdir, look at it
$ ls-tree ba103f91defa4b3885b826d6630a055f27800398
100664 blob 522fff361ad5c07351479ea8504b7c370d189524 hello.c
$ # This blob is our src/hello.c file
$ cat-file blob 522fff361ad5c07351479ea8504b7c370d189524
#include <stdio.h>
main()
{
printf("Hello, world!\n");
}
$ # Look at all the files we have now, a blob for each file, a
$ # pair of tree objects for the directory and subdir, and a lone
$ # changeset.
$ find .git -type f
.git/index
.git/objects/01/07d57e748b2f01601adb6749a03aed7b3f5a84
.git/objects/ba/103f91defa4b3885b826d6630a055f27800398
.git/objects/ea/b75ce51622aa312bb0b03572d43769f420c347
.git/objects/52/2fff361ad5c07351479ea8504b7c370d189524
.git/objects/3a/7a1c51dbc62797d6c903203de44cc6a734c05c
.git/HEAD
$ # Now make a change
$ ed src/hello.c
59
$i
return 0;
.
w
70
q
$ # We need to tell .git/index which file(s) are going to be
$ # in this changeset. Don't need "--add" option because we are
$ # changing a file that already exists
$ update-cache src/hello.c
$ # Now we can write a new tree incorporating the change
$ write-tree
8f5ba0203e31204c5c052d995a5b4449226bcfb5
$ # and finally create a changeset ... this time we tell commit that
$ # the parent of this change is the previous change
$ commit-tree 8f5ba0203e31204c5c052d995a5b4449226bcfb5 -p `cat .git/HEAD`
Fix hello program to return successful exit code.
5403689e0c29607f57da8f751d4ba40637134e87
$ # save the new changeset in .git/HEAD
$ echo 5403689e0c29607f57da8f751d4ba40637134e87 > .git/HEAD
$ # walk the tree from HEAD to the new version of hello.c
$ cat-file commit 5403689e0c29607f57da8f751d4ba40637134e87
tree 8f5ba0203e31204c5c052d995a5b4449226bcfb5
parent 0107d57e748b2f01601adb6749a03aed7b3f5a84
author Tony Luck <aegl@example.com> Thu Apr 14 15:00:34 2005
committer Tony Luck <aegl@example.com> Thu Apr 14 15:00:34 2005
Fix hello program to return successful exit code.
$ ls-tree 8f5ba0203e31204c5c052d995a5b4449226bcfb5
100664 blob 3a7a1c51dbc62797d6c903203de44cc6a734c05c Makefile
40000 tree 77dc2cb94930017f62b55b9706cbadda8c90f650 src
$ ls-tree 77dc2cb94930017f62b55b9706cbadda8c90f650
100664 blob 8a6a2a7261742c6f69adaa8c876045e721ffff22 hello.c
$ cat-file blob 8a6a2a7261742c6f69adaa8c876045e721ffff22
#include <stdio.h>
main()
{
printf("Hello, world!\n");
return 0;
}
$
$ # Now an example of getting started with a pre-existing project
$ # download www.kernel.org/pub/linux/kernel/people/torvalds/sparse.git
$ # then ...
$ ls -l sparse.git
total 8
-rw-rw-r-- 1 aegl aegl 41 Apr 14 14:50 HEAD
drwxr-xr-x 258 aegl aegl 4096 Apr 12 21:33 objects
$ # set up environment so that git sees these objects when we are elsewhere
$ export SHA1_FILE_DIRECTORY=`pwd`/sparse.git/objects
$ # make a directory to work in
$ mkdir sparse
$ cd sparse
$ # Still need a local .git for the cache file
$ mkdir .git
$ # Now look at the most recent commit, to find the topmost tree
$ cat-file commit `cat ../sparse.git/HEAD`
tree 67607f05a66e36b2f038c77cfb61350d2110f7e8
parent 9c59995fef9b52386e5f7242f44720a7aca287d7
author Christopher Li <sparse@chrisli.org> Sat Apr 2 09:30:09 PST 2005
committer Linus Torvalds <torvalds@ppc970.osdl.org> Thu Apr 7 20:06:31 2005
[PATCH] static declear
This patch add static declare to make sparse happy of checking itself.
$ # load up that tree into our cache (.git/index)
$ read-tree 67607f05a66e36b2f038c77cfb61350d2110f7e8
$ # and checkout all the files
$ checkout-cache -a
$ # quick as a flash, our directory is full of files
$ ls
allocate.c compat-linux.c example.c inline.c memops.c scope.c symbol.h tokenize.c
allocate.h compat-mingw.c expand.c lib.c obfuscate.c scope.h target.c validation
bitmap.h compat-solaris.c expression.c lib.h parse.c show-parse.c target.h
cgcc compile.c expression.h LICENSE parse.h simplify.c test-lexing.c
check.c compile.h FAQ linearize.c pre-process.c sort.c test-linearize.c
compat compile-i386.c flow.c linearize.h ptrlist.c storage.c test-parsing.c
compat-cygwin.c cse.c flow.h liveness.c ptrlist.h storage.h test-sort.c
compat.h evaluate.c ident-list.h Makefile README symbol.c token.h
$
^ permalink raw reply
* Re: Naming the SCM (was Re: Handling renames.)
From: Peter Williams @ 2005-04-14 23:17 UTC (permalink / raw)
To: Steven Cole
Cc: Andrew Timberlake-Newell, git, 'Zach Welch',
'Linus Torvalds'
In-Reply-To: <200504141442.17235.elenstev@mesatop.com>
Steven Cole wrote:
> On Thursday 14 April 2005 01:40 pm, Andrew Timberlake-Newell wrote:
>
>>Zach Welch pontificated:
>>
>>>I imagine quite a few folks expect something not entirely unlike an SCM
>>>to emerge from these current efforts. Moreover, Petr's 'git' scripts
>>>wrap your "filesystem" plumbing to that very end.
>>>
>>>To avoid confusion, I think it would be better to distinguish the two
>>>layers, perhaps by calling the low-level plumbing... 'gitfs', of course.
>>
>>Or perhaps to come up with a name (or at least nickname) for the SCM.
>>
>>GitMaster?
>>
>
>
> Cogito. "Git inside" can be the first slogan.
>
> Differentiating the SCM built on top of git from git itself is probably worthwhile
> to avoid confusion. Other SCMs may be developed later, built on git, and these
> can come up with their own clever names.
And the logo could be a dove which, as everybody knows, coos.
Peter
--
Peter Williams pwil3058@bigpond.net.au
"Learning, n. The kind of ignorance distinguishing the studious."
-- Ambrose Bierce
^ permalink raw reply
* Re: Reorganize common code
From: Petr Baudis @ 2005-04-14 23:13 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: git, torvalds
In-Reply-To: <Pine.LNX.4.21.0504131755550.30848-100000@iabervon.org>
Dear diary, on Thu, Apr 14, 2005 at 12:00:25AM CEST, I got a letter
where Daniel Barkalow <barkalow@iabervon.org> told me that...
> This splits read-cache.c into util.c, cache.c, and objects.c, based on
> what the code is used for; similarly, cache.h becomes util.h, cache.h, and
> objects.h. For simplicity, cache.h includes the other two to give the
> previous overall behavior.
>
> Signed-Off-By: Daniel Barkalow <barkalow@iabervon.org>
FYI, given the scale of this change, I'm waiting for Linus to either ack
it, pick it himself or reject it.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ 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