* Re: git "tag" objects implemented - and a re-done commit
From: Linus Torvalds @ 2005-04-25 22:39 UTC (permalink / raw)
To: Andreas Gal; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251505260.18901@ppc970.osdl.org>
On Mon, 25 Apr 2005, Linus Torvalds wrote:
>
> So I'll probably just push out my tags with my archives, and then people
> can verify them if they want to.
Ok, for the intrepid users, you can now test to see if you can pick them
out. fsck should make them totally obvious, and here's my public key in
case you also want to verify the things.
Of course, since I normally don't use pgp signing etc, it's entirely
possible that I've done something stupid, and I'm now sending you my
secret key and my full porn-collection.
Linus
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.4 (GNU/Linux)
mQGiBEJqZ4sRBADKttqQOCAxRzz5qGmo5QnSR5GTkSlPTm4lCuaVUon0qQPNrasr
cSBAOJ1MlXjhbRPrN3pAhI+taLgrWQ231zUNHxCTmWJZV3Yzxr8xJQGlfHlVOxXB
LI42tAfCjHOF7z8pPj6AGhtE2+fzq1U3mOlA/fUG4uYDOwIoPK+qgbM6SwCgulqs
DGlQKFFtFgW8HVnDftFmyZMD+wc0E9jRa9HJ3b1U3vY1jrxpoVw5QeeIZdSRnRFy
sknOHca5mlJvTidu1cs7xCuvpufw1VIVvgf4tPwXcTDEKthYEhoty+DFOqZ9R7pg
EMhjYbq+Q8yLT3OWQtUKV4B10FRYIWidnJ8y2CjLduTmB+cyj976oxEY/llLBbQM
yuDrBADDLw/3KZL5D75icA0l/uebQ6/73j8jcRoVu0gTqAdQBYL6Zv7Y0G7xHUCo
Eqgo+p2LXAeU9IoeA5/h8SNVDw4fYoqo6VQTkr+ydegHkjwlbrhOL/gxzlY1Pde1
TBi6+QCUssk0FCPMALt7M+OgFpSKx7pP2xSsDsMvvNNAmLl0JrQ0TGludXMgVG9y
dmFsZHMgKHRhZyBzaWduaW5nIGtleSkgPHRvcnZhbGRzQG9zZGwub3JnPoheBBMR
AgAeBQJCameLAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEBd2LEZ24hy7I84A
nROHRYes4RU8btdleR0TgwJG7jMvAKCF2CingjxaC4sTL7BkFfNacTkBYLkBDQRC
ameMEAQAlJiw0IBltu5ihEXE4mFYiWHuVAoeufVJ9fONv67y6fu3efJ10PJ7AQdG
Ufez+8yxkrahyIVC77NuQLDrRfvgmrJ8sbP8xb6QEbY1bnwLeuciTolGjL+kYi17
J74iG2cQDyimnLWJm5lNqeUOz3nTW429SyLCRhXpR1lUjijiVi8AAwcD/1f4VEql
u9HHTA4S+1aoOQV5guZCr6JbYdWkAZeeFRpFSXfCae6uO8DhpD7o/8kiK3O8qP1O
yjQF0bG26iLCm8MdJCO0WQ2xsVlwrrvnNPpgRgbirOgoxHM4ESq/YV+MqXo41Hm0
ilHRM7OIbmm7uvFSlUJmUasuJRsrhibilbvNiEkEGBECAAkFAkJqZ4wCGwwACgkQ
F3YsRnbiHLsolQCfRVImDkgijhPGmwyI7T19bWltXwsAniMi9gakkN+9DT8E5kli
e8uTEk8f
=PRrZ
-----END PGP PUBLIC KEY BLOCK-----
^ permalink raw reply
* Re: [PATCH] Add archive-tree, a cpio archive creator
From: Paul Dickson @ 2005-04-25 22:30 UTC (permalink / raw)
To: Rene Scharfe; +Cc: pasky, git
In-Reply-To: <20050424014346.GA23083@lsrfire.ath.cx>
On Sun, 24 Apr 2005 03:43:46 +0200, Rene Scharfe wrote:
> This patch adds archive-tree, a program to create a cpio archive of all
> files referenced by a given tree or commit object. Why cpio and not
> e.g., tar? The cpio format I chose (GNU cpio calls it "odc") is dead
> simple compared to any tar variant. I was simply being lazy. :-P
Use the "newc" format. The "odc" will generate a lot of errors on a
large filesystem (which I discovered this past weekend).
-Paul
^ permalink raw reply
* Re: unseeking?
From: Zack Brown @ 2005-04-25 22:28 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Petr Baudis, git
In-Reply-To: <Pine.LNX.4.21.0504251236400.30848-100000@iabervon.org>
On Mon, Apr 25, 2005 at 01:27:16PM -0400, Daniel Barkalow wrote:
> On Mon, 25 Apr 2005, Zack Brown wrote:
> > So moving on, I now have this mycogito tree. But I don't do any edits yet. I
> > just poke around for awhile, reading files. Finally I realize that there have
> > probably been updates to the upstream sources, and I want to pull those in
> > before I start my work. So, as I would do in the cogito directory, I give the
> > command
> >
> > git pull pasky; git pull linus
> >
> > this works fine. There are no new updates to be had, and git tells me my tree is
> > uptodate.
> >
> > so now I start work. I run aspell on the README file, and it catches some
> > typos. I fix them and save the file but don't yet commit it. Now mycogito
> > has some changes that I would ultimately like to push up to Pasky.
> >
> > Now I'm unclear what comes next. Do I just do a 'git diff' from the mycogito
> > directory and post the results to the git list?
>
> Now you commit in your directory. This gives you a new head for
> mycogito. You can then do "git patch pasky" (or something of the sort,
> check the help for the details)
OK, so it's actually:
git patch pasky:this
> to get a patch for the your changes. You
> can also do multiple commits and generate either a single patch or patches
> corresponding to each commit.
By replacing 'this' or 'pasky' in the above command with the appropriate
7de71a831508e51e0985cea173f3f7a7012c82b7 thingy, right?
So, I did 'git patch pasky:this', and got the following. Is this an appropriate
way to submit a patch? BTW, the 'truckload' fix I tried to change back by
editing the README again, and committing the change; but the git patch command
still shows the change.
spelling fixes
---
commit 8626d99da60a0cbb8e901df2da0f503959517bb8
tree a1c075cf00f03843de7200c2c341f1aeeb260a7f
parent 0d38182b234f5bb89e53ec31951e8d5d0ebdf69a
author <zbrown@tumblerings.org> 1114466199 -0700
committer <zbrown@tumblerings.org> 1114466199 -0700
Index: README
===================================================================
--- 7de71a831508e51e0985cea173f3f7a7012c82b7/README (mode:100644 sha1:bc52eb0f2e4fe17157635dca34a5073944153c15)
+++ a1c075cf00f03843de7200c2c341f1aeeb260a7f/README (mode:100644 sha1:140eefe0b740b2e7f4ee1644ec18f23855dc1af4)
@@ -9,7 +9,7 @@
dictionary of slang.
- "global information tracker": you're in a good mood, and it actually
works for you. Angels sing, and a light suddenly fills the room.
- - "goddamn idiotic truckload of sh*t": when it breaks
+ - "goddamn idiotic truck-load of sh*t": when it breaks
GIT comes in two layers. The bottom layer is merely an extremely fast and
flexible filesystem-based database designed to store directory trees with
@@ -245,7 +245,7 @@
In particular, since the blob is entirely defined by its data,
if two files in a directory tree (or in multiple different
versions of the repository) have the same contents, they will
- share the same blob object. The object is toally independent
+ share the same blob object. The object is totally independent
of it's location in the directory tree, and renaming a file does
not change the object that file is associated with in any way.
@@ -300,7 +300,7 @@
actually have any relationship with the result, for example.
Note on changesets: unlike real SCM's, changesets do not contain
- rename information or file mode chane information. All of that
+ rename information or file mode change information. All of that
is implicit in the trees involved (the result tree, and the
result trees of the parents), and describing that makes no sense
in this idiotic file manager.
@@ -468,7 +468,7 @@
changes in your working directory (ie "update-cache").
However, if you decide to jump to a new version, or check out
- somebody elses version, or just restore a previous tree, you'd
+ somebody else's version, or just restore a previous tree, you'd
populate your index file with read-tree, and then you need to
check out the result with
\f
!-------------------------------------------------------------flip-
undid a bogus fix
---
commit a2e1bea63e3ed44321f560b892660ea4613f74f6
tree c28936b6a10b436f7b6027e396bf340e54ecb48c
parent 8626d99da60a0cbb8e901df2da0f503959517bb8
author <zbrown@tumblerings.org> 1114467935 -0700
committer <zbrown@tumblerings.org> 1114467935 -0700
Index: README
===================================================================
--- a1c075cf00f03843de7200c2c341f1aeeb260a7f/README (mode:100644 sha1:140eefe0b740b2e7f4ee1644ec18f23855dc1af4)
+++ c28936b6a10b436f7b6027e396bf340e54ecb48c/README (mode:100644 sha1:0c1630a83614acb3a2e577da64797c1512bf0cf3)
@@ -9,7 +9,7 @@
dictionary of slang.
- "global information tracker": you're in a good mood, and it actually
works for you. Angels sing, and a light suddenly fills the room.
- - "goddamn idiotic truck-load of sh*t": when it breaks
+ - "goddamn idiotic truckload of sh*t": when it breaks
GIT comes in two layers. The bottom layer is merely an extremely fast and
flexible filesystem-based database designed to store directory trees with
\f
!-------------------------------------------------------------flip-
>
> > Suppose I want to keep working, changing more stuff in mycogito, but I
> > also want to make sure that mycogito tracks the upstream sources.
> >
> > git merge pasky; git merge linus
> >
> > and give that command to bring the upstream changes into mycogito?
>
> In general, you want to use "merge" when you've got local commits. You
> also want to commit before doing this, so that you have a known state
> for your version to revert to if you mess up merging.
>
> -Daniel
> *This .sig left intentionally blank*
>
--
Zack Brown
^ permalink raw reply
* Re: [PATCH] git-pasky spec file
From: Chris Wright @ 2005-04-25 22:21 UTC (permalink / raw)
To: Paul Dickson; +Cc: Chris Wright, pasky, git
In-Reply-To: <20050425142411.1849a5db.paul@permanentmail.com>
* Paul Dickson (paul@permanentmail.com) wrote:
> On Thu, 21 Apr 2005 19:48:34 -0700, Chris Wright wrote:
>
> > * Petr Baudis (pasky@ucw.cz) wrote:
> > > Dear diary, on Fri, Apr 22, 2005 at 03:55:21AM CEST, I got a letter
> > > where Chris Wright <chrisw@osdl.org> told me that...
> > > > Here's a simple spec file to do rpm builds. It's against the
> > > > latest Makefile (which has the s/BINDIR/bindir/ change). I've used
> > > > DESTDIR, although it's not clear it's meant to stay in the Makefile.
> > > > For now, there's no dynamic (git.spec.in, for example) update to the
> > > > Version, so it's set against 0.6.3 (expecting it to be forthcoming
> > > > shortly). It installs to /usr/local/bin, and expects the tarball to be
> > > > named git-pasky-0.6.3.tar.bz2. Creates a package named git, which seems
> > > > fine since Linus' isn't likely to be packaged directly. Enjoy.
> > >
> > > Thanks, applied. I'll gladly yet you maintain this file, but...
> >
> > No problem...
> >
> > > > --- /dev/null 1969-12-31 16:00:00.000000000 -0800
> > > > +++ git-pasky-0.6.3/git.spec 2005-04-21 18:42:18.000000000 -0700
> > > > @@ -0,0 +1,43 @@
> > > > +%install
> > > > +rm -rf $RPM_BUILD_ROOT
> > > > +make DESTDIR=$RPM_BUILD_ROOT/usr/local/ bindir=bin/ install
> > >
> > > I doubt this is actually what you want. I suppose you want
> > >
> > > make DESTDIR=$RPM_BUILD_ROOT prefix=/usr/local install
> >
> > Yup, that makes more sense. Feel free to update if you're so inclined.
>
> If you're building an RPM, it should go in /usr not /usr/local. /usr/local
> is for unmanaged (non-RPM) installs.
That's not quite the definition for FHS, but I don't mind putting into
/usr/bin. I had planned upon doing a /usr/bin/git and helpers in
another directory, but with new command name (ala cg-$cmd) then I think
they'll all just go in /usr/bin. Other opinions?
thanks,
-chris
^ permalink raw reply
* Re: [PATCH] multi item packed files
From: Chris Mason @ 2005-04-25 22:20 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Krzysztof Halasa, git
In-Reply-To: <200504221955.15422.mason@suse.com>
[-- Attachment #1: Type: text/plain, Size: 2897 bytes --]
On Friday 22 April 2005 19:55, Chris Mason wrote:
> On Friday 22 April 2005 16:32, Chris Mason wrote:
> > If I pack every 64k (uncompressed), the checkout-tree time goes down to
> > 3m14s. That's a very big difference considering how stupid my code is
> > .git was only 20% smaller with 64k chunks. I should be able to do
> > better...I'll do one more run.
>
> This run also packed tree files together (everything produced by write-tree
> went into a packed file), but not the commits. I estimate I could save
> about another 168m by packing the tree files and commits into the same file
> with the blobs, but this wouldn't make any of the times below faster.
>
> git - original (28k commits) packed
> FS size 2,675,408k 1,723,820k
> read-tree 24.45s 18.9s
> checkout-cache 4m30s 3m5s
> patch time 2h30m 1h55m
>
It was a rainy weekend, so I took a break from lawn care and hacked in some
simple changes to the packed file format. There's now a header listing the
sha1 for each subfile and the offset where to find it in the main file. Each
subfile is compressed individually so you don't have to decompress the whole
packed file to find one. commits were added into the packed files as well.
Some results were about what I expected:
FS size -- 1,614,376k
read-tree -- 18s
checkout-cache -- 2m35s (cold cache)
checkout-cache -- 18s (hot cache)
patch time -- 96m
vanilla git needs 56s to checkout with a hot cache. The hot cache numbers
weren't done before because I hadn't expected my patch to help at all. Even
though we both do things entirely from cache, vanilla git is much slower at
writing the checked out files back to the drive. I've made no optimizations
to that code, and the drive is only 30% full, so this seems to just be a bad
interaction with filesystem layout.
I also expected vanilla git to perform pretty well when there were no commits
in the tree. My test was to put a copy of 2.6.11 under git.
vanilla packed
update-cache (for all files) 2m1s 48s
checkout-cache (cold) 1m23s 28s
checkout-cache (hot) 12s 15s
The difference in hot cache checkout time is userland cpu time. It could be
avoided with smarter caching of the packed file header. Right now I'm
decompressing it over and over again for each checkout. Still, the
performance hit is pretty small because I try to limit the number of subfiles
that get packed together.
My current patch is attached for reference, it's against a git from late last
week. I wouldn't suggest using this for anything other than benchmarking,
and since I don't think I can get much better numbers easily, I'll stop
playing around with this for a while.
-chris
[-- Attachment #2: comp-tree-4.diff --]
[-- Type: text/x-diff, Size: 26388 bytes --]
diff -ur linus.back/cache.h linus/cache.h
--- linus.back/cache.h 2005-04-25 17:30:21.616654304 -0400
+++ linus/cache.h 2005-04-25 10:56:15.000000000 -0400
@@ -64,6 +64,16 @@
char name[0];
};
+struct packed_item {
+ /* lenght of compressed data */
+ unsigned long len;
+ struct packed_item *next;
+ /* sha1 of uncompressed data */
+ char sha1[20];
+ /* compressed data */
+ char *data;
+};
+
#define CE_NAMEMASK (0x0fff)
#define CE_STAGEMASK (0x3000)
#define CE_STAGESHIFT 12
@@ -117,7 +127,7 @@
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern void * map_sha1_file(const unsigned char *sha1, unsigned long *size);
-extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size);
+extern void * unpack_sha1_file(const unsigned char *sha1, void *map, unsigned long mapsize, char *type, unsigned long *size);
extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size);
extern int write_sha1_file(char *buf, unsigned len, unsigned char *return_sha1);
extern int check_sha1_signature(unsigned char *sha1, void *buf, unsigned long size, const char *type);
@@ -125,6 +135,9 @@
/* Convert to/from hex/sha1 representation */
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
+extern int pack_sha1_buffer(void *buf, unsigned long buf_len,
+ unsigned char *returnsha1, struct packed_item **);
+int write_packed_buffer(struct packed_item *head);
/* General helper functions */
extern void usage(const char *err);
@@ -137,4 +150,9 @@
unsigned long *size,
unsigned char *tree_sha1_ret);
+extern int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1, struct packed_item **head);
+
+#define MAXPARENT 16
+extern int commit_tree(char *tree_sha1_hex, unsigned char parent_sha1[MAXPARENT][20], int num_parents, struct packed_item **head);
+extern void check_valid_sha1_file(unsigned char *sha1, const char *expect);
#endif /* CACHE_H */
diff -ur linus.back/commit-tree.c linus/commit-tree.c
--- linus.back/commit-tree.c 2005-04-25 17:30:21.626652784 -0400
+++ linus/commit-tree.c 2005-04-25 10:58:15.000000000 -0400
@@ -4,360 +4,32 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
-
-#include <pwd.h>
-#include <time.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-
-#define BLOCKING (1ul << 14)
-#define ORIG_OFFSET (40)
-
-/*
- * Leave space at the beginning to insert the tag
- * once we know how big things are.
- *
- * FIXME! Share the code with "write-tree.c"
- */
-static void init_buffer(char **bufp, unsigned int *sizep)
-{
- char *buf = malloc(BLOCKING);
- memset(buf, 0, ORIG_OFFSET);
- *sizep = ORIG_OFFSET;
- *bufp = buf;
-}
-
-static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...)
-{
- char one_line[2048];
- va_list args;
- int len;
- unsigned long alloc, size, newsize;
- char *buf;
-
- va_start(args, fmt);
- len = vsnprintf(one_line, sizeof(one_line), fmt, args);
- va_end(args);
- size = *sizep;
- newsize = size + len;
- alloc = (size + 32767) & ~32767;
- buf = *bufp;
- if (newsize > alloc) {
- alloc = (newsize + 32767) & ~32767;
- buf = realloc(buf, alloc);
- *bufp = buf;
- }
- *sizep = newsize;
- memcpy(buf + size, one_line, len);
-}
-
-static int prepend_integer(char *buffer, unsigned val, int i)
-{
- buffer[--i] = '\0';
- do {
- buffer[--i] = '0' + (val % 10);
- val /= 10;
- } while (val);
- return i;
-}
-
-static void finish_buffer(char *tag, char **bufp, unsigned int *sizep)
-{
- int taglen;
- int offset;
- char *buf = *bufp;
- unsigned int size = *sizep;
-
- offset = prepend_integer(buf, size - ORIG_OFFSET, ORIG_OFFSET);
- taglen = strlen(tag);
- offset -= taglen;
- buf += offset;
- size -= offset;
- memcpy(buf, tag, taglen);
-
- *bufp = buf;
- *sizep = size;
-}
-
-static void remove_special(char *p)
-{
- char c;
- char *dst = p, *src = p;
-
- for (;;) {
- c = *src;
- src++;
- switch(c) {
- case '\n': case '<': case '>':
- continue;
- }
- *dst++ = c;
- if (!c)
- break;
- }
-
- /*
- * Go back, and remove crud from the end: some people
- * have commas etc in their gecos field
- */
- dst--;
- while (--dst >= p) {
- unsigned char c = *dst;
- switch (c) {
- case ',': case ';': case '.':
- *dst = 0;
- continue;
- }
- break;
- }
-}
-
-static const char *month_names[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static const char *weekday_names[] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-};
-
-
-static char *skipfws(char *str)
-{
- while (isspace(*str))
- str++;
- return str;
-}
-
-
-/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
- (i.e. English) day/month names, and it doesn't work correctly with %z. */
-static void parse_rfc2822_date(char *date, char *result, int maxlen)
-{
- struct tm tm;
- char *p;
- int i, offset;
- time_t then;
-
- memset(&tm, 0, sizeof(tm));
-
- /* Skip day-name */
- p = skipfws(date);
- if (!isdigit(*p)) {
- for (i=0; i<7; i++) {
- if (!strncmp(p,weekday_names[i],3) && p[3] == ',') {
- p = skipfws(p+4);
- goto day;
- }
- }
- return;
- }
-
- /* day */
- day:
- tm.tm_mday = strtoul(p, &p, 10);
-
- if (tm.tm_mday < 1 || tm.tm_mday > 31)
- return;
-
- if (!isspace(*p))
- return;
-
- p = skipfws(p);
-
- /* month */
-
- for (i=0; i<12; i++) {
- if (!strncmp(p, month_names[i], 3) && isspace(p[3])) {
- tm.tm_mon = i;
- p = skipfws(p+strlen(month_names[i]));
- goto year;
- }
- }
- return; /* Error -- bad month */
-
- /* year */
- year:
- tm.tm_year = strtoul(p, &p, 10);
-
- if (!tm.tm_year && !isspace(*p))
- return;
-
- if (tm.tm_year > 1900)
- tm.tm_year -= 1900;
-
- p=skipfws(p);
-
- /* hour */
- if (!isdigit(*p))
- return;
- tm.tm_hour = strtoul(p, &p, 10);
-
- if (!tm.tm_hour > 23)
- return;
-
- if (*p != ':')
- return; /* Error -- bad time */
- p++;
-
- /* minute */
- if (!isdigit(*p))
- return;
- tm.tm_min = strtoul(p, &p, 10);
-
- if (!tm.tm_min > 59)
- return;
-
- if (isspace(*p))
- goto zone;
-
- if (*p != ':')
- return; /* Error -- bad time */
- p++;
-
- /* second */
- if (!isdigit(*p))
- return;
- tm.tm_sec = strtoul(p, &p, 10);
-
- if (!tm.tm_sec > 59)
- return;
-
- if (!isspace(*p))
- return;
-
- zone:
- p = skipfws(p);
-
- if (*p == '-')
- offset = -60;
- else if (*p == '+')
- offset = 60;
- else
- return;
-
- if (!isdigit(p[1]) || !isdigit(p[2]) || !isdigit(p[3]) || !isdigit(p[4]))
- return;
-
- i = strtoul(p+1, NULL, 10);
- offset *= ((i % 100) + ((i / 100) * 60));
-
- if (*(skipfws(p + 5)))
- return;
-
- then = mktime(&tm); /* mktime appears to ignore the GMT offset, stupidly */
- if (then == -1)
- return;
-
- then -= offset;
-
- snprintf(result, maxlen, "%lu %5.5s", then, p);
-}
-
-static void check_valid(unsigned char *sha1, const char *expect)
-{
- void *buf;
- char type[20];
- unsigned long size;
-
- buf = read_sha1_file(sha1, type, &size);
- if (!buf || strcmp(type, expect))
- die("%s is not a valid '%s' object", sha1_to_hex(sha1), expect);
- free(buf);
-}
-
/*
* Having more than two parents is not strange at all, and this is
* how multi-way merges are represented.
*/
-#define MAXPARENT (16)
static char *commit_tree_usage = "commit-tree <sha1> [-p <sha1>]* < changelog";
int main(int argc, char **argv)
{
- int i, len;
+ int i;
int parents = 0;
unsigned char tree_sha1[20];
unsigned char parent_sha1[MAXPARENT][20];
- unsigned char commit_sha1[20];
- char *gecos, *realgecos, *commitgecos;
- char *email, *commitemail, realemail[1000];
- char date[20], realdate[20];
- char *audate;
- char comment[1000];
- struct passwd *pw;
- time_t now;
- struct tm *tm;
- char *buffer;
- unsigned int size;
if (argc < 2 || get_sha1_hex(argv[1], tree_sha1) < 0)
usage(commit_tree_usage);
- check_valid(tree_sha1, "tree");
+ check_valid_sha1_file(tree_sha1, "tree");
for (i = 2; i < argc; i += 2) {
char *a, *b;
a = argv[i]; b = argv[i+1];
if (!b || strcmp(a, "-p") || get_sha1_hex(b, parent_sha1[parents]))
usage(commit_tree_usage);
- check_valid(parent_sha1[parents], "commit");
+ check_valid_sha1_file(parent_sha1[parents], "commit");
parents++;
}
- if (!parents)
- fprintf(stderr, "Committing initial tree %s\n", argv[1]);
- pw = getpwuid(getuid());
- if (!pw)
- die("You don't exist. Go away!");
- realgecos = pw->pw_gecos;
- len = strlen(pw->pw_name);
- memcpy(realemail, pw->pw_name, len);
- realemail[len] = '@';
- gethostname(realemail+len+1, sizeof(realemail)-len-1);
- if (!strchr(realemail+len+1, '.')) {
- strcat(realemail, ".");
- getdomainname(realemail+strlen(realemail), sizeof(realemail)-strlen(realemail)-1);
- }
- time(&now);
- tm = localtime(&now);
-
- strftime(realdate, sizeof(realdate), "%s %z", tm);
- strcpy(date, realdate);
-
- commitgecos = getenv("COMMIT_AUTHOR_NAME") ? : realgecos;
- commitemail = getenv("COMMIT_AUTHOR_EMAIL") ? : realemail;
- gecos = getenv("AUTHOR_NAME") ? : realgecos;
- email = getenv("AUTHOR_EMAIL") ? : realemail;
- audate = getenv("AUTHOR_DATE");
- if (audate)
- parse_rfc2822_date(audate, date, sizeof(date));
-
- remove_special(gecos); remove_special(realgecos); remove_special(commitgecos);
- remove_special(email); remove_special(realemail); remove_special(commitemail);
-
- init_buffer(&buffer, &size);
- add_buffer(&buffer, &size, "tree %s\n", sha1_to_hex(tree_sha1));
-
- /*
- * NOTE! This ordering means that the same exact tree merged with a
- * different order of parents will be a _different_ changeset even
- * if everything else stays the same.
- */
- for (i = 0; i < parents; i++)
- add_buffer(&buffer, &size, "parent %s\n", sha1_to_hex(parent_sha1[i]));
-
- /* Person/date information */
- add_buffer(&buffer, &size, "author %s <%s> %s\n", gecos, email, date);
- add_buffer(&buffer, &size, "committer %s <%s> %s\n\n", commitgecos, commitemail, realdate);
-
- /* And add the comment */
- while (fgets(comment, sizeof(comment), stdin) != NULL)
- add_buffer(&buffer, &size, "%s", comment);
-
- finish_buffer("commit ", &buffer, &size);
-
- write_sha1_file(buffer, size, commit_sha1);
- printf("%s\n", sha1_to_hex(commit_sha1));
+ commit_tree(tree_sha1, parent_sha1, parents, NULL);
return 0;
}
diff -ur linus.back/fsck-cache.c linus/fsck-cache.c
--- linus.back/fsck-cache.c 2005-04-25 17:30:21.630652176 -0400
+++ linus/fsck-cache.c 2005-04-22 10:25:07.000000000 -0400
@@ -85,7 +85,7 @@
if (map) {
char type[100];
unsigned long size;
- void *buffer = unpack_sha1_file(map, mapsize, type, &size);
+ void *buffer = unpack_sha1_file(sha1, map, mapsize, type, &size);
if (!buffer)
return -1;
if (check_sha1_signature(sha1, buffer, size, type) < 0)
diff -ur linus.back/Makefile linus/Makefile
--- linus.back/Makefile 2005-04-25 17:30:21.631652024 -0400
+++ linus/Makefile 2005-04-25 10:03:53.000000000 -0400
@@ -23,7 +23,7 @@
install: $(PROG)
install $(PROG) $(HOME)/bin/
-LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o
+LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o lib-tree.o
LIB_FILE=libgit.a
LIB_H=cache.h object.h
@@ -71,6 +71,7 @@
show-diff.o: $(LIB_H)
show-files.o: $(LIB_H)
tree.o: $(LIB_H)
+lib-tree.o: $(LIB_H)
update-cache.o: $(LIB_H)
usage.o: $(LIB_H)
unpack-file.o: $(LIB_H)
diff -ur linus.back/sha1_file.c linus/sha1_file.c
--- linus.back/sha1_file.c 2005-04-25 17:30:21.633651720 -0400
+++ linus/sha1_file.c 2005-04-25 17:15:53.050696400 -0400
@@ -116,12 +116,14 @@
return map;
}
-void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size)
+void * unpack_sha1_file(const unsigned char *sha1, void *map,
+ unsigned long mapsize, char *type, unsigned long *size)
{
int ret, bytes;
z_stream stream;
char buffer[8192];
char *buf;
+ unsigned long offset;
/* Get the data stream */
memset(&stream, 0, sizeof(stream));
@@ -134,12 +136,12 @@
ret = inflate(&stream, 0);
if (sscanf(buffer, "%10s %lu", type, size) != 2)
return NULL;
-
bytes = strlen(buffer) + 1;
buf = malloc(*size);
- if (!buf)
+ if (!buf) {
+ perror("malloc");
return NULL;
-
+ }
memcpy(buf, buffer + bytes, stream.total_out - bytes);
bytes = stream.total_out - bytes;
if (bytes < *size && ret == Z_OK) {
@@ -149,6 +151,56 @@
/* nothing */;
}
inflateEnd(&stream);
+
+ /* we've found a packed object */
+ if (strcmp(type, "packed") == 0) {
+ char *p = buf;
+ unsigned long header_len = *size;
+ offset = stream.total_in;
+ if (!sha1)
+ return NULL;
+ while(p < buf + header_len) {
+ unsigned long item_len;
+ unsigned char sha1_hex[50];
+ unsigned char item_sha[20];
+ memcpy(item_sha, p, 20);
+ sscanf(p + 20, "%lu ", &item_len);
+ p += 20 + strlen(p + 20) + 1;
+ if (memcmp(item_sha, sha1, 20) == 0) {
+ /* Get the data stream */
+ free(buf);
+ memset(&stream, 0, sizeof(stream));
+ stream.next_in = map + offset;
+ stream.avail_in = mapsize - offset;
+ stream.next_out = buffer;
+ stream.avail_out = sizeof(buffer);
+
+ inflateInit(&stream);
+ ret = inflate(&stream, 0);
+ if (sscanf(buffer, "%10s %lu", type, size) != 2)
+ return NULL;
+ bytes = strlen(buffer) + 1;
+ buf = malloc(*size);
+ if (!buf) {
+ perror("malloc");
+ return NULL;
+ }
+ memcpy(buf, buffer + bytes,
+ stream.total_out - bytes);
+ bytes = stream.total_out - bytes;
+ if (bytes < *size && ret == Z_OK) {
+ stream.next_out = buf + bytes;
+ stream.avail_out = *size - bytes;
+ while (inflate(&stream, Z_FINISH) == Z_OK)
+ /* nothing */;
+ }
+ inflateEnd(&stream);
+ return buf;
+ }
+ offset += item_len;
+ }
+ return NULL;
+ }
return buf;
}
@@ -159,7 +211,7 @@
map = map_sha1_file(sha1, &mapsize);
if (map) {
- buf = unpack_sha1_file(map, mapsize, type, size);
+ buf = unpack_sha1_file(sha1, map, mapsize, type, size);
munmap(map, mapsize);
return buf;
}
@@ -305,3 +357,166 @@
close(fd);
return 0;
}
+
+int pack_sha1_buffer(void *buf, unsigned long buf_len,
+ unsigned char *returnsha1,
+ struct packed_item **packed_item)
+{
+ unsigned char sha1[20];
+ SHA_CTX c;
+ char *filename;
+ struct stat st;
+ char *compressed;
+ z_stream stream;
+ unsigned long size;
+ struct packed_item *item;
+
+ *packed_item = NULL;
+
+ /* Sha1.. */
+ SHA1_Init(&c);
+ SHA1_Update(&c, buf, buf_len);
+ SHA1_Final(sha1, &c);
+
+ if (returnsha1)
+ memcpy(returnsha1, sha1, 20);
+
+ filename = sha1_file_name(sha1);
+ if (stat(filename, &st) == 0)
+ return 0;
+
+ /* Set it up */
+ memset(&stream, 0, sizeof(stream));
+ deflateInit(&stream, Z_BEST_COMPRESSION);
+ size = deflateBound(&stream, buf_len);
+ compressed = malloc(size);
+
+ /*
+ * ASCII size + nul byte
+ */
+ stream.next_in = buf;
+ stream.avail_in = buf_len;
+ stream.next_out = compressed;
+ stream.avail_out = size;
+ /* Compress it */
+ while (deflate(&stream, Z_FINISH) == Z_OK)
+ /* nothing */;
+ deflateEnd(&stream);
+ size = stream.total_out;
+
+ item = malloc(sizeof(struct packed_item));
+ if (!item) {
+ free(compressed);
+ return -1;
+ }
+ memcpy(item->sha1, sha1, 20);
+ item->len = size;
+ item->next = NULL;
+ item->data = compressed;
+ *packed_item = item;
+ return 0;
+}
+
+static char *create_packed_header(struct packed_item *head, unsigned long *size)
+{
+ char *metadata = NULL;
+ int metadata_size = 0;
+ *size = 0;
+
+ while(head) {
+ char *p;
+ metadata = realloc(metadata, metadata_size + 220);
+ if (!metadata)
+ return NULL;
+ p = metadata+metadata_size;
+ memcpy(p, head->sha1, 20);
+ p += 20;
+ metadata_size += 1 + sprintf(p, "%lu ", head->len) + 20;
+ head = head->next;
+ }
+ *size = metadata_size;
+ return metadata;
+}
+
+int write_packed_buffer(struct packed_item *head)
+{
+ unsigned char sha1[20];
+ SHA_CTX c;
+ char *filename;
+ char *metadata = malloc(200);
+ char *header;
+ int metadata_size;
+ int fd;
+ int ret = 0;
+ unsigned long header_len;
+ struct packed_item *item;
+ char *compressed;
+ z_stream stream;
+ unsigned long size;
+ int nr = 0;
+
+ header = create_packed_header(head, &header_len);
+ metadata_size = 1+sprintf(metadata, "packed %lu", header_len);
+
+ SHA1_Init(&c);
+ SHA1_Update(&c, metadata, metadata_size);
+ SHA1_Update(&c, header, header_len);
+ item = head;
+ while(item) {
+ SHA1_Update(&c, item->data, item->len);
+ item = item->next;
+ nr++;
+ }
+ SHA1_Final(sha1, &c);
+
+ filename = strdup(sha1_file_name(sha1));
+ fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ if (fd < 0) {
+ /* add collision check! */
+ if (errno != EEXIST) {
+ ret = -errno;
+ }
+ goto out;
+ }
+ /* compress just the header info */
+ memset(&stream, 0, sizeof(stream));
+ deflateInit(&stream, Z_BEST_COMPRESSION);
+ size = deflateBound(&stream, header_len + metadata_size);
+ compressed = malloc(size);
+
+ stream.next_in = metadata;
+ stream.avail_in = metadata_size;
+ stream.next_out = compressed;
+ stream.avail_out = size;
+ while (deflate(&stream, 0) == Z_OK)
+ /* nothing */;
+ stream.next_in = header;
+ stream.avail_in = header_len;
+ while (deflate(&stream, Z_FINISH) == Z_OK)
+ /* nothing */;
+ deflateEnd(&stream);
+ size = stream.total_out;
+
+ write(fd, compressed, size);
+ free(compressed);
+
+ item = head;
+ while(item) {
+ char *item_file;
+ struct packed_item *next = item->next;
+ write(fd, item->data, item->len);
+ item_file = sha1_file_name(item->sha1);
+ if (link(filename, item_file) && errno != EEXIST) {
+ ret = -errno;
+ break;
+ }
+ free(item->data);
+ free(item);
+ item = next;
+ }
+out:
+ free(header);
+ free(metadata);
+ free(filename);
+ return ret;
+}
diff -ur linus.back/update-cache.c linus/update-cache.c
--- linus.back/update-cache.c 2005-04-25 17:30:21.635651416 -0400
+++ linus/update-cache.c 2005-04-25 14:24:14.000000000 -0400
@@ -12,57 +12,48 @@
* like "update-cache *" and suddenly having all the object
* files be revision controlled.
*/
-static int allow_add = 0, allow_remove = 0;
+static int allow_add = 0, allow_remove = 0, commit = 0;
-static int index_fd(unsigned char *sha1, int fd, struct stat *st)
+static int index_fd(unsigned char *sha1, int fd, struct stat *st, struct packed_item **head, struct packed_item **tail, unsigned long *packed_size)
{
- z_stream stream;
unsigned long size = st->st_size;
- int max_out_bytes = size + 200;
- void *out = malloc(max_out_bytes);
void *metadata = malloc(200);
int metadata_size;
void *in;
- SHA_CTX c;
+ char *copy;
+ int ret;
+ struct packed_item *new_item;
in = "";
if (size)
in = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
- if (!out || (int)(long)in == -1)
+ if (!metadata || (int)(long)in == -1)
return -1;
-
metadata_size = 1+sprintf(metadata, "blob %lu", size);
-
- SHA1_Init(&c);
- SHA1_Update(&c, metadata, metadata_size);
- SHA1_Update(&c, in, size);
- SHA1_Final(sha1, &c);
-
- memset(&stream, 0, sizeof(stream));
- deflateInit(&stream, Z_BEST_COMPRESSION);
-
- /*
- * ASCII size + nul byte
- */
- stream.next_in = metadata;
- stream.avail_in = metadata_size;
- stream.next_out = out;
- stream.avail_out = max_out_bytes;
- while (deflate(&stream, 0) == Z_OK)
- /* nothing */;
-
- /*
- * File content
- */
- stream.next_in = in;
- stream.avail_in = size;
- while (deflate(&stream, Z_FINISH) == Z_OK)
- /*nothing */;
-
- deflateEnd(&stream);
-
- return write_sha1_buffer(sha1, out, stream.total_out);
+ copy = malloc(metadata_size + size);
+ if (!copy)
+ return -1;
+ memcpy(copy, metadata, metadata_size);
+ memcpy(copy + metadata_size, in, size);
+ ret = pack_sha1_buffer(copy, metadata_size + size, sha1, &new_item);
+ if (new_item) {
+ if (*tail)
+ (*tail)->next = new_item;
+ *tail = new_item;
+ if (!*head)
+ *head = new_item;
+ *packed_size += new_item->len;
+ if (*packed_size > (512 * 1024)) {
+ write_packed_buffer(*head);
+ *head = NULL;
+ *tail = NULL;
+ *packed_size = 0;
+ }
+ }
+ munmap(in, size);
+ free(copy);
+ return ret;
}
/*
@@ -85,7 +76,7 @@
ce->ce_size = htonl(st->st_size);
}
-static int add_file_to_cache(char *path)
+static int add_file_to_cache(char *path, struct packed_item **packed_head, struct packed_item **packed_tail, unsigned long *packed_size)
{
int size, namelen;
struct cache_entry *ce;
@@ -113,7 +104,8 @@
ce->ce_mode = create_ce_mode(st.st_mode);
ce->ce_flags = htons(namelen);
- if (index_fd(ce->sha1, fd, &st) < 0)
+ if (index_fd(ce->sha1, fd, &st, packed_head,
+ packed_tail, packed_size) < 0)
return -1;
return add_cache_entry(ce, allow_add);
@@ -282,12 +274,30 @@
unlink(lockfile_name);
}
+static int path_comp(const void *p1, const void *p2)
+{
+ const char *s1 = *(char **)p1;
+ const char *s2 = *(char **)p2;
+ int len1 = strlen(s1);
+ int len2 = strlen(s2);
+ int ret;
+ ret = cache_name_compare(s1, len1, s2, len2);
+ return ret;
+}
+
int main(int argc, char **argv)
{
int i, newfd, entries;
int allow_options = 1;
static char lockfile[MAXPATHLEN+1];
const char *indexfile = get_index_file();
+ struct packed_item *packed_head = NULL;
+ struct packed_item *packed_tail = NULL;
+ unsigned long packed_size = 0;
+ char **paths = malloc(argc * sizeof(char *));
+ int num_paths = 0;
+ unsigned char parent_sha1[20];
+ int parents = 0;
snprintf(lockfile, sizeof(lockfile), "%s.lock", indexfile);
@@ -318,6 +328,17 @@
allow_remove = 1;
continue;
}
+ if (!strcmp(path, "--commit")) {
+ commit = 1;
+ continue;
+ }
+ if (!strcmp(path, "--parent")) {
+ if (i+1 >= argc || get_sha1_hex(argv[i+1], parent_sha1))
+ die("update-cache: --parent sha1");
+ parents = 1;
+ i+=1;
+ continue;
+ }
if (!strcmp(path, "--refresh")) {
refresh_cache();
continue;
@@ -334,8 +355,27 @@
fprintf(stderr, "Ignoring path %s\n", argv[i]);
continue;
}
- if (add_file_to_cache(path))
- die("Unable to add %s to database", path);
+ paths[num_paths++] = path;
+
+ }
+ // qsort(paths, num_paths, sizeof(char *), path_comp);
+ for(i = 0 ; i < num_paths ; i++) {
+ if (add_file_to_cache(paths[i], &packed_head, &packed_tail, &packed_size))
+ die("Unable to add %s to database", paths[i]);
+
+ }
+ if (commit) {
+ char tree_sha1[20];
+ if (write_tree(active_cache, active_nr, "", 0, tree_sha1, &packed_head) != active_nr)
+ die("write-tree failed");
+fprintf(stderr, "write_tree gave us %s\n", sha1_to_hex(tree_sha1));
+
+ if (commit_tree(tree_sha1, &parent_sha1, parents, &packed_head))
+ die("commit-tree failed");
+ }
+ if (packed_head) {
+ if (write_packed_buffer(packed_head))
+ die("write packed buffer failed");
}
if (write_cache(newfd, active_cache, active_nr) || rename(lockfile, indexfile))
die("Unable to write new cachefile");
diff -ur linus.back/write-tree.c linus/write-tree.c
--- linus.back/write-tree.c 2005-04-25 17:30:21.635651416 -0400
+++ linus/write-tree.c 2005-04-25 10:01:30.000000000 -0400
@@ -3,106 +3,15 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
-#include "cache.h"
-
-static int check_valid_sha1(unsigned char *sha1)
-{
- char *filename = sha1_file_name(sha1);
- int ret;
-
- /* If we were anal, we'd check that the sha1 of the contents actually matches */
- ret = access(filename, R_OK);
- if (ret)
- perror(filename);
- return ret;
-}
-
-static int prepend_integer(char *buffer, unsigned val, int i)
-{
- buffer[--i] = '\0';
- do {
- buffer[--i] = '0' + (val % 10);
- val /= 10;
- } while (val);
- return i;
-}
-
-#define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
-
-static int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1)
-{
- unsigned char subdir_sha1[20];
- unsigned long size, offset;
- char *buffer;
- int i, nr;
-
- /* Guess at some random initial size */
- size = 8192;
- buffer = malloc(size);
- offset = ORIG_OFFSET;
-
- nr = 0;
- do {
- struct cache_entry *ce = cachep[nr];
- const char *pathname = ce->name, *filename, *dirname;
- int pathlen = ce_namelen(ce), entrylen;
- unsigned char *sha1;
- unsigned int mode;
-
- /* Did we hit the end of the directory? Return how many we wrote */
- if (baselen >= pathlen || memcmp(base, pathname, baselen))
- break;
- sha1 = ce->sha1;
- mode = ntohl(ce->ce_mode);
-
- /* Do we have _further_ subdirectories? */
- filename = pathname + baselen;
- dirname = strchr(filename, '/');
- if (dirname) {
- int subdir_written;
-
- subdir_written = write_tree(cachep + nr, maxentries - nr, pathname, dirname-pathname+1, subdir_sha1);
- nr += subdir_written;
-
- /* Now we need to write out the directory entry into this tree.. */
- mode = S_IFDIR;
- pathlen = dirname - pathname;
-
- /* ..but the directory entry doesn't count towards the total count */
- nr--;
- sha1 = subdir_sha1;
- }
-
- if (check_valid_sha1(sha1) < 0)
- exit(1);
-
- entrylen = pathlen - baselen;
- if (offset + entrylen + 100 > size) {
- size = alloc_nr(offset + entrylen + 100);
- buffer = realloc(buffer, size);
- }
- offset += sprintf(buffer + offset, "%o %.*s", mode, entrylen, filename);
- buffer[offset++] = 0;
- memcpy(buffer + offset, sha1, 20);
- offset += 20;
- nr++;
- } while (nr < maxentries);
-
- i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
- i -= 5;
- memcpy(buffer+i, "tree ", 5);
-
- write_sha1_file(buffer + i, offset - i, returnsha1);
- free(buffer);
- return nr;
-}
+#include "cache.h"
int main(int argc, char **argv)
{
int i, unmerged;
int entries = read_cache();
unsigned char sha1[20];
+ struct packed_item *head = NULL;
if (entries <= 0)
die("write-tree: no cache contents to write");
@@ -123,8 +32,12 @@
die("write-tree: not able to write tree");
/* Ok, write it out */
- if (write_tree(active_cache, entries, "", 0, sha1) != entries)
+ if (write_tree(active_cache, entries, "", 0, sha1, &head) != entries)
die("write-tree: internal error");
+ if (head) {
+ if (write_packed_buffer(head))
+ die("write_packed_buffer failed");
+ }
printf("%s\n", sha1_to_hex(sha1));
return 0;
}
^ permalink raw reply
* Re: git "tag" objects implemented - and a re-done commit
From: Petr Baudis @ 2005-04-25 22:18 UTC (permalink / raw)
To: Linus Torvalds; +Cc: H. Peter Anvin, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251457510.18901@ppc970.osdl.org>
Dear diary, on Tue, Apr 26, 2005 at 12:05:17AM CEST, I got a letter
where Linus Torvalds <torvalds@osdl.org> told me that...
>
>
> On Mon, 25 Apr 2005, H. Peter Anvin wrote:
> >
> > It would be good if the tag object could permit junk lines before the
> > start of the header; in particular, the standard PGP/GPG signed message
> > format looks like:
>
> No, I've already explained why git doesn't parse arbitrary junk: I want
> git to have 100% repeatable behaviour. And that very much means that if
> git doesn't understand something, it just doesn't touch it or parse it.
>
> Here's my trivial script to generate tags in proper format. Go wild:
>
> #!/bin/sh
> ( echo -e "object $(cat .git/HEAD)\ntype commit\ntag $1\n"; cat ) > .tmp-tag
> rm -f .tmp-tag.asc
> gpg -bsa .tmp-tag && cat .tmp-tag.asc >> .tmp-tag
> git-mktag < .tmp-tag
> rm -f .tmp-tag*
>
> and it creates objects like this one:
>
>
> torvalds@ppc970:~/git> cat-file tag
> ba613c023dcd03e06158caee9c0337e6b6988854
> object ec4465adb38d21966acdc9510ff15c0fe4539468
> type commit
> tag test-release
> Testing tagging
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.4 (GNU/Linux)
>
> iD8DBQBCbVwSF3YsRnbiHLsRAliaAKCMlb6k6VAS7hxajwUtwRdzDZn9rACffVTb
> dRdDS6n+pjSAYbA6Lp11bQU=
> =JNiv
> -----END PGP SIGNATURE-----
Could we please at least maintain the newline between the "header" and data,
like in the commit objects?
Thanks,
--
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: git add / update-cache --add fails.
From: Chris Wedgwood @ 2005-04-25 22:09 UTC (permalink / raw)
To: Rhys Hardwick; +Cc: git
In-Reply-To: <200504252252.05957.rhys@rhyshardwick.co.uk>
On Mon, Apr 25, 2005 at 10:52:05PM +0100, Rhys Hardwick wrote:
> I have tried rebooting, and looking at a few sources, and nothing
> has helped. It's interesting noone else has had the same problem.
why would a reboot help?
^ permalink raw reply
* Re: git "tag" objects implemented - and a re-done commit
From: Linus Torvalds @ 2005-04-25 22:07 UTC (permalink / raw)
To: Andreas Gal; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251442480.12019@sam.ics.uci.edu>
On Mon, 25 Apr 2005, Andreas Gal wrote:
>
> Ok, if tags are standalone objects then I don't see how they get
> propagated.
You propagate them "by hand" (which eventually obviously means "with tools
to do so").
The thing is, you _shouldn't_ be interested in my tags unless I -tell- you
to be interested in them.
So I'll probably just push out my tags with my archives, and then people
can verify them if they want to.
Linus
^ permalink raw reply
* Re: git "tag" objects implemented - and a re-done commit
From: Linus Torvalds @ 2005-04-25 22:05 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Git Mailing List
In-Reply-To: <426D62C0.40104@zytor.com>
On Mon, 25 Apr 2005, H. Peter Anvin wrote:
>
> It would be good if the tag object could permit junk lines before the
> start of the header; in particular, the standard PGP/GPG signed message
> format looks like:
No, I've already explained why git doesn't parse arbitrary junk: I want
git to have 100% repeatable behaviour. And that very much means that if
git doesn't understand something, it just doesn't touch it or parse it.
Here's my trivial script to generate tags in proper format. Go wild:
#!/bin/sh
( echo -e "object $(cat .git/HEAD)\ntype commit\ntag $1\n"; cat ) > .tmp-tag
rm -f .tmp-tag.asc
gpg -bsa .tmp-tag && cat .tmp-tag.asc >> .tmp-tag
git-mktag < .tmp-tag
rm -f .tmp-tag*
and it creates objects like this one:
torvalds@ppc970:~/git> cat-file tag
ba613c023dcd03e06158caee9c0337e6b6988854
object ec4465adb38d21966acdc9510ff15c0fe4539468
type commit
tag test-release
Testing tagging
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQBCbVwSF3YsRnbiHLsRAliaAKCMlb6k6VAS7hxajwUtwRdzDZn9rACffVTb
dRdDS6n+pjSAYbA6Lp11bQU=
=JNiv
-----END PGP SIGNATURE-----
and then you just split it at the (last occurrence of) the
-----BEGIN PGP SIGNATURE-----
and you can do
torvalds@ppc970:~/git> gpg --verify tag.asc
gpg: Signature made Mon 25 Apr 2005 02:07:30 PM PDT using DSA key ID 76E21CBB
gpg: Good signature from "Linus Torvalds (tag signing key) <torvalds@osdl.org>"
to verify the dang thing.
And that way git never guesses anything at all, and you can use whatever
you want to sign the things.
Linus
^ permalink raw reply
* Re: git add / update-cache --add fails.
From: Rhys Hardwick @ 2005-04-25 21:52 UTC (permalink / raw)
To: git
In-Reply-To: <200504252226.00354.rhys@rhyshardwick.co.uk>
Sorry about previous email.
Just to clarify, the latest version of git to be merged with pasky is:
4e03aae5feb2e3fd2f543796ca3d3e8aa86c02dc
I have tried rebooting, and looking at a few sources, and nothing has helped.
It's interesting noone else has had the same problem.
Rhys
^ permalink raw reply
* Re: git add / update-cache --add fails.
From: Rhys Hardwick @ 2005-04-25 21:50 UTC (permalink / raw)
To: git
In-Reply-To: <200504252226.00354.rhys@rhyshardwick.co.uk>
To update - the last version of git to be merged with pasky is:
^ permalink raw reply
* Re: git "tag" objects implemented - and a re-done commit
From: Andreas Gal @ 2005-04-25 21:46 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251339020.18901@ppc970.osdl.org>
Ok, if tags are standalone objects then I don't see how they get
propagated. Right now all I need to do to pull a version from a remote
repository is to get the commit object and everything it depends on. Any tags
involved would not be pulled as there are no dependencies from the commit
object to the tag. Thats why I was asking whether they are part of any
tree or not.
So how do we want to do this? Maybe a file TAGS right next to HEAD that
lists all active tags in my tree by SHA1 hash? Or maybe make tags a linked
list, with all tags refering to some parent tag? That would give a nice
list to walk back to find older tags (again, we use something like TAG as
root).
Andreas
On Mon, 25 Apr 2005, Linus Torvalds wrote:
>
>
> On Mon, 25 Apr 2005, Andreas Gal wrote:
> >
> > Are tag objects referenced by trees (and thus limited in scope) or are
> > they stand-alone entities in the repository? The latter would be bad for
> > shared object storages.
>
> They are totally stand-alone, and I don't see why that would be bad for
> shared object storage.
>
> In fact, the whole point of them is that since they are named by the SHA1
> hash of the content, there are no shared object issues. Two different tags
> by two different developers will have different names, exactly the same
> way two different releases will have different names.
>
> And if two different developers tag exactly the same object with exactly
> the same tag-name and exactly the same signature, then they get the same
> tag object, and that's fine. They should.
>
> > Also, if I delete and recreate tags, will the old tag remain in the tree
> > or will the file in the object storage disapear?
>
> Tags in no way affect the entry they name. When you remove - or add - a
> tag object, nothing happens to anything else.
>
> Linus
> -
> 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: [FILE] GNU BIT
From: Petr Baudis @ 2005-04-25 21:46 UTC (permalink / raw)
To: Andreas Gal; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251430380.11722@sam.ics.uci.edu>
Dear diary, on Mon, Apr 25, 2005 at 11:33:12PM CEST, I got a letter
where Andreas Gal <gal@uci.edu> told me that...
> bit contains various pieces and snippets from Linus' and your scripts and
> thus automatically falls under GPL. Maybe I should have stated that
> somewhere explicitly, but its a 800 lines bash script for crying out loud.
I skimmed over it briefly and admitelly didn't find anything
*obviously* borrowed from my scripts, so I wanted to ask. It is worth
noting explicitly, I think.
> The "GNU" part was actually more like a joke. If you feel offended by it,
> I am happy to remove it. Are there any trademark issues involved in using
> "GNU"?
I was not offended, just confused. :-) I think it's better not to use
"GNU" in the name if it's not part of the GNU project.
--
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: git pull issues...
From: Dan Holmsand @ 2005-04-25 21:31 UTC (permalink / raw)
To: git
In-Reply-To: <118833cc05042514076221624d@mail.gmail.com>
Morten Welinder wrote:
> On 4/23/05, Petr Baudis <pasky@ucw.cz> wrote:
>
>>>1. Multiple rsync call might connect to different servers (with
>>>round-robin DNS). The effect
>>> will be interesting. One call, if possible, would be better.
>>
>>If you can do it without overwriting HEAD, please go ahead and send me
>>the patch. :-)
>
>
> This ought to work. It basically saves to a different directory while
> still ignoring
> all the files we have.
I was just looking at the same thing. Not saying this is better, or
anything, bit it has, perhaps, the slight advantage that downloaded
objects aren't thrown away, so that a pull can be safely resumed. Also,
it doesn't download anything from an url that doesn't contain ./HEAD,
./heads or ./objects. That might be a good thing if you accidentally try
to pull from, say, kernel.org/pub/...
/dan
Here goes:
Index: gitpull.sh
===================================================================
--- 7de71a831508e51e0985cea173f3f7a7012c82b7/gitpull.sh (mode:100755
sha1:6abc7f5c00fd3e082d0a34a238a53b67c38b8a7f)
+++ uncommitted/gitpull.sh (mode:100755)
@@ -18,7 +18,7 @@
[ "$name" ] || name=$(cat .git/tracking 2>/dev/null)
[ "$name" ] || die "where to pull from?"
uri=$(grep $(echo -e "^$name\t" | sed 's/\./\\./g') .git/remotes | cut
-f 2)
-[ "$uri" ] || die "unknown remote"
+[ "$uri" ] || die "unknown remote '$name'"
rembranch=master
if echo "$uri" | grep -q '#'; then
@@ -38,28 +38,39 @@
fi
-mkdir -p .git/heads
-rsyncerr=
-rsync $RSYNC_FLAGS -Lr "$uri/heads/$rembranch" ".git/heads/$name"
2>/dev/null || rsyncerr=1
-if [ "$rsyncerr" ] && [ "$rembranch" = "master" ]; then
- rsyncerr=
- rsync $RSYNC_FLAGS -Lr "$uri/HEAD" ".git/heads/$name" | grep -v
'^MOTD:' || rsyncerr=1
+mkdir -p .git/heads .git/objects .git/tags || die
+pulldir=$(mktemp -td gitpull.XXXXXX)
+[ -d "$pulldir" ] || die "failed to create temp dir"
+ln -s $(pwd)/.git/objects $(pwd)/.git/tags $pulldir || die
+mkdir $pulldir/heads || die
+
+echo pulling $uri
+
+rout=$pulldir/rsync_errors
+rsync $RSYNC_FLAGS -LKrv --whole-file --ignore-existing \
+ --include '/HEAD' --include '/heads/' --include '/tags/' \
+ --include '/objects/' --exclude='/*' \
+ "$uri/." $pulldir 2>$rout || {
+ cat $rout; die "failed to pull from $uri"
+ }
+
+if [ -f "$pulldir/heads/$rembranch" ]; then
+ cp "$pulldir/heads/$rembranch" ".git/heads/$name" || die
+elif [ master = "$rembranch" -a -f $pulldir/HEAD ]; then
+ cp $pulldir/HEAD ".git/heads/$name" || die
+else
+ echo "unable to get the head pointer of branch $rembranch" >&2
+ echo "is $uri a valid git repository?" >&2
+ die "pull failed"
fi
-[ "$rsyncerr" ] && die "unable to get the head pointer of branch
$rembranch"
-[ -d .git/objects ] || mkdir -p .git/objects
-# We already saw the MOTD, thank you very much.
-rsync $RSYNC_FLAGS --ignore-existing --whole-file \
- -v -Lr "$uri/objects/." ".git/objects/." | grep -v '^MOTD:' || die
"rsync error"
+# TODO: Check that at least the head commit exists.
-# FIXME: Warn about conflicting tag names?
-# XXX: We now throw stderr to /dev/null since not all repositories
-# may have tags/ and users were confused by the harmless errors.
-[ -d .git/tags ] || mkdir -p .git/tags
-rsync $RSYNC_FLAGS --ignore-existing \
- -v -Lr "$uri/tags/." ".git/tags/." 2>/dev/null | grep -v '^MOTD:' ||
die "rsync error"
+rm -rf $pulldir
+# FIXME: Warn about conflicting tag names?
+
new_head=$(cat ".git/heads/$name")
if [ ! "$orig_head" ]; then
^ permalink raw reply
* Re: git "tag" objects implemented - and a re-done commit
From: H. Peter Anvin @ 2005-04-25 21:36 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251213530.18901@ppc970.osdl.org>
Linus Torvalds wrote:
>
> Anyway, I decided that my original model for tags was the right one, with
> a trivial extension. Notably, if you want to tag a single file or a tree
> object, go wild. The tag object format is:
>
> object <sha1>
> type <type>
> tag <tag>
> .. free-form commentary and signature of this all ..
>
> and the "git-mktag" program verifies that the three first lines are valid
> before it accepts it and writes it as a git object.
>
> Right now the tags don't do anything, except fsck can verify them (not the
> signature - git doesn't even specify any particular format, and you may
> validly have unsigned tags in your tree), and will print out something
> like
>
> tagged commit e83c5163316f89bfbde7d9ab23ca2e25604af290 (v2.6.12-rc2)
>
> if you were to have such a tag-object in your object database (you don't,
> because I've not generated one, but hey..)
>
It would be good if the tag object could permit junk lines before the
start of the header; in particular, the standard PGP/GPG signed message
format looks like:
-----BEGIN PGP SIGNED MESSAGE-----
object aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
type commit
tag foo
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
iQEVAwUBQm1hyWx5eAAqlgcFAQEShgf+P/PNJu5h1uAVPp9+xSy8QtIIC/1Zpl6a
2Tp22Bw0hfXUNYoJ7O9TH35wttYbcx8ArXl6JhlMIEcV7rS48H/vmTJgtBwnhLSb
epDPbOriLbCl9E0XXPHqrlmQE07H0iZn2dmLyg2REmtdffi3hjSQIkvFSHy72kOe
Ho6H+s2hzs/u/ypkQ8Cl82Saqn/Drahj9ehdXLRQ5Nsslr71MhwRCD5M0x+0Uy0B
KPjBiyyx6g/qWzIRLZOdkdbSUdXjczlGnm2wwC6/RdBDjeagDBGafaiuNQH8W3sx
psfmqKgKZkCBFFlSvwJQAsRFgnVl2vYUAftRaxMnQlCG7COIjNAsdg==
=lsn0
-----END PGP SIGNATURE-----
As an alternative, the signature can be a separate object, since the
object SHA-1 itself acts as a verifier of its self-content; thus, all
that is really necessary is an authorized verifier.
-hpa
^ permalink raw reply
* [PATCH] Fix rfc2822 date parser
From: Edgar Toernig @ 2005-04-25 21:32 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
- Fix some broken tests like "if (!tm.tm_sec > 59)"
- Make seconds optional
- Allow trailing comments like (EDT)
- Stand-alone mktime without timezone correction
Ciao, ET.
diff -u git-0.6-orig/commit-tree.c git-0.6/commit-tree.c
--- git-0.6-orig/commit-tree.c Thu Apr 21 19:58:47 2005
+++ git-0.6/commit-tree.c Mon Apr 25 23:06:36 2005
@@ -113,6 +113,25 @@
}
}
+static time_t my_mktime(struct tm *tm)
+{
+ static const int mdays[] = {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+ };
+ int year = tm->tm_year - 70;
+ int month = tm->tm_mon;
+ int day = tm->tm_mday;
+
+ if (year < 0 || year > 129) /* algo only works for 1970-2099 */
+ return -1;
+ if (month < 0 || month > 11) /* array bounds */
+ return -1;
+ if (month < 2 || (year + 2) % 4)
+ day--;
+ return (year * 365 + (year + 1) / 4 + mdays[month] + day) * 24*60*60UL +
+ tm->tm_hour * 60*60 + tm->tm_min * 60 + tm->tm_sec;
+}
+
static const char *month_names[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
@@ -194,7 +213,7 @@
return;
tm.tm_hour = strtoul(p, &p, 10);
- if (!tm.tm_hour > 23)
+ if (tm.tm_hour > 23)
return;
if (*p != ':')
@@ -206,14 +225,11 @@
return;
tm.tm_min = strtoul(p, &p, 10);
- if (!tm.tm_min > 59)
+ if (tm.tm_min > 59)
return;
- if (isspace(*p))
- goto zone;
-
if (*p != ':')
- return; /* Error -- bad time */
+ goto zone;
p++;
/* second */
@@ -221,13 +237,13 @@
return;
tm.tm_sec = strtoul(p, &p, 10);
- if (!tm.tm_sec > 59)
+ if (tm.tm_sec > 59)
return;
+ zone:
if (!isspace(*p))
return;
- zone:
p = skipfws(p);
if (*p == '-')
@@ -243,10 +259,11 @@
i = strtoul(p+1, NULL, 10);
offset *= ((i % 100) + ((i / 100) * 60));
- if (*(skipfws(p + 5)))
+ p = skipfws(p + 5);
+ if (*p && *p != '(') /* trailing comment like (EDT) is ok */
return;
- then = mktime(&tm); /* mktime appears to ignore the GMT offset, stupidly */
+ then = my_mktime(&tm); /* mktime appears to ignore the GMT offset, stupidly */
if (then == -1)
return;
^ permalink raw reply
* Re: [FILE] GNU BIT
From: Andreas Gal @ 2005-04-25 21:33 UTC (permalink / raw)
To: Petr Baudis; +Cc: Git Mailing List
In-Reply-To: <20050425205226.GG13467@pasky.ji.cz>
bit contains various pieces and snippets from Linus' and your scripts and
thus automatically falls under GPL. Maybe I should have stated that
somewhere explicitly, but its a 800 lines bash script for crying out loud.
The "GNU" part was actually more like a joke. If you feel offended by it,
I am happy to remove it. Are there any trademark issues involved in using
"GNU"?
Andreas
PS: Unrelated note. There is a GNU GIT project (some graphical file
manager thing or so).
On Mon, 25 Apr 2005, Petr Baudis wrote:
> Dear diary, on Mon, Apr 25, 2005 at 08:24:24AM CEST, I got a letter
> where Andreas Gal <gal@uci.edu> told me that...
> > HELP
> >
> > Try "bit --help" to get some simple instructions how to use BIT. All
> > commands have builtin help as well. Try "bit commit --help". Not all
> > options are always implemented. Feel free to send me a patch.
>
> Do you intend to licence it as free software? Also, you call it "GNU
> BIT". Does that mean it is part of the GNU project?
>
> --
> Petr "Pasky" Baudis
> Stuff: http://pasky.or.cz/
> C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
>
^ permalink raw reply
* git add / update-cache --add fails.
From: Rhys Hardwick @ 2005-04-25 21:26 UTC (permalink / raw)
To: git
Hello people,
I get these errors when trying to add a new file to the directory. I pulled
the latest version today, and the day before yesterdays version had the same
problem (using git-pasky)
rhys@metatron:~/repo/learning.repo$ update-cache --add w1d4p1.c
fatal: Unable to add w1d4p1.c to database
rhys@metatron:~/repo/learning.repo$ git add w1d4p1.c
fatal: Unable to add w1d4p1.c to database
rhys@metatron:~/repo/learning.repo$
Any ideas?
Rhys
^ permalink raw reply
* Re: [PATCH] git-pasky spec file
From: Paul Dickson @ 2005-04-25 21:24 UTC (permalink / raw)
To: Chris Wright; +Cc: pasky, git
In-Reply-To: <20050422024834.GM493@shell0.pdx.osdl.net>
On Thu, 21 Apr 2005 19:48:34 -0700, Chris Wright wrote:
> * Petr Baudis (pasky@ucw.cz) wrote:
> > Dear diary, on Fri, Apr 22, 2005 at 03:55:21AM CEST, I got a letter
> > where Chris Wright <chrisw@osdl.org> told me that...
> > > Here's a simple spec file to do rpm builds. It's against the
> > > latest Makefile (which has the s/BINDIR/bindir/ change). I've used
> > > DESTDIR, although it's not clear it's meant to stay in the Makefile.
> > > For now, there's no dynamic (git.spec.in, for example) update to the
> > > Version, so it's set against 0.6.3 (expecting it to be forthcoming
> > > shortly). It installs to /usr/local/bin, and expects the tarball to be
> > > named git-pasky-0.6.3.tar.bz2. Creates a package named git, which seems
> > > fine since Linus' isn't likely to be packaged directly. Enjoy.
> >
> > Thanks, applied. I'll gladly yet you maintain this file, but...
>
> No problem...
>
> > > --- /dev/null 1969-12-31 16:00:00.000000000 -0800
> > > +++ git-pasky-0.6.3/git.spec 2005-04-21 18:42:18.000000000 -0700
> > > @@ -0,0 +1,43 @@
> > > +%install
> > > +rm -rf $RPM_BUILD_ROOT
> > > +make DESTDIR=$RPM_BUILD_ROOT/usr/local/ bindir=bin/ install
> >
> > I doubt this is actually what you want. I suppose you want
> >
> > make DESTDIR=$RPM_BUILD_ROOT prefix=/usr/local install
>
> Yup, that makes more sense. Feel free to update if you're so inclined.
If you're building an RPM, it should go in /usr not /usr/local. /usr/local
is for unmanaged (non-RPM) installs.
-Paul
^ permalink raw reply
* Re: git pull issues...
From: Morten Welinder @ 2005-04-25 21:07 UTC (permalink / raw)
To: Petr Baudis; +Cc: GIT Mailing List
In-Reply-To: <20050423220049.GC13222@pasky.ji.cz>
On 4/23/05, Petr Baudis <pasky@ucw.cz> wrote:
> > 1. Multiple rsync call might connect to different servers (with
> > round-robin DNS). The effect
> > will be interesting. One call, if possible, would be better.
>
> If you can do it without overwriting HEAD, please go ahead and send me
> the patch. :-)
This ought to work. It basically saves to a different directory while
still ignoring
all the files we have.
Morten
Index: gitpull.sh
===================================================================
--- 7de71a831508e51e0985cea173f3f7a7012c82b7/gitpull.sh (mode:100755
sha1:6abc7f5c00fd3e082d0a34a238a53b67c38b8a7f)
+++ uncommitted/gitpull.sh (mode:100775)
@@ -37,28 +37,32 @@
[ -s ".git/heads/$name" ] && orig_head=$(cat ".git/heads/$name")
fi
-
-mkdir -p .git/heads
-rsyncerr=
-rsync $RSYNC_FLAGS -Lr "$uri/heads/$rembranch" ".git/heads/$name"
2>/dev/null || rsyncerr=1
-if [ "$rsyncerr" ] && [ "$rembranch" = "master" ]; then
- rsyncerr=
- rsync $RSYNC_FLAGS -Lr "$uri/HEAD" ".git/heads/$name" | grep -v
'^MOTD:' || rsyncerr=1
+dotgit=dot-git
+test -d "$dotgit" && die "$dotgit already exists -- please clean up."
+mkdir -p "$dotgit" "$dotgit/objects" "$dotgit/tags" \
+ || die "failed to create $dotgit."
+
+(cd .git && find objects -type f -print0 && find tags -type f -print0) | \
+ rsync $RSYNC_FLAGS --from0 --exclude-from=- --whole-file -Lrv
"$uri/" "$dotgit" || \
+ { rm -rf "$dotgit"; die "rsync from $uri/ failed."; }
+
+# Move new files into place
+find "$dotgit/objects" -type f -print0 | \
+ perl -n0e 'chomp; $src=$_; s{^[^/]+/}{.git/}; rename $src, $_ or die
"failed to move $src into place: $!\n";'
+find "$dotgit/tags" -type f -print0 | \
+ perl -n0e 'chomp; $src=$_; s{^[^/]+/}{.git/}; rename $src, $_ or die
"failed to move $src into place: $!\n";'
+
+mkdir -p .git/heads || die "failed to create .git/heads"
+if [ -r "$dotgit/heads/$rembranch" ]; then
+ mv "$dotgit/heads/$rembranch" ".git/heads/$name"
+elif [ "$rembranch" = "master" -a -r "$dotgit/HEAD" ]; then
+ mv "$dotgit/HEAD" ".git/heads/$name"
+else
+ rm -rf "$dotgit"
+ die "unable to get the head pointer of branch $rembranch"
fi
-[ "$rsyncerr" ] && die "unable to get the head pointer of branch $rembranch"
-
-[ -d .git/objects ] || mkdir -p .git/objects
-# We already saw the MOTD, thank you very much.
-rsync $RSYNC_FLAGS --ignore-existing --whole-file \
- -v -Lr "$uri/objects/." ".git/objects/." | grep -v '^MOTD:' || die
"rsync error"
-
-# FIXME: Warn about conflicting tag names?
-# XXX: We now throw stderr to /dev/null since not all repositories
-# may have tags/ and users were confused by the harmless errors.
-[ -d .git/tags ] || mkdir -p .git/tags
-rsync $RSYNC_FLAGS --ignore-existing \
- -v -Lr "$uri/tags/." ".git/tags/." 2>/dev/null | grep -v '^MOTD:' ||
die "rsync error"
+rm -rf "$dotgit"
new_head=$(cat ".git/heads/$name")
^ permalink raw reply
* Re: [FILE] GNU BIT
From: Petr Baudis @ 2005-04-25 20:52 UTC (permalink / raw)
To: Andreas Gal; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504242308460.6454@sam.ics.uci.edu>
Dear diary, on Mon, Apr 25, 2005 at 08:24:24AM CEST, I got a letter
where Andreas Gal <gal@uci.edu> told me that...
> HELP
>
> Try "bit --help" to get some simple instructions how to use BIT. All
> commands have builtin help as well. Try "bit commit --help". Not all
> options are always implemented. Feel free to send me a patch.
Do you intend to licence it as free software? Also, you call it "GNU
BIT". Does that mean it is part of the GNU project?
--
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: [PATCH GIT 0.6] make use of register variables & size_t
From: Arjan van de Ven @ 2005-04-25 20:50 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Matthias-Christian Ott, git, Linux Kernel Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251147290.18901@ppc970.osdl.org>
On Mon, 2005-04-25 at 11:50 -0700, Linus Torvalds wrote:
>
> On Mon, 25 Apr 2005, Matthias-Christian Ott wrote:
> >
> > But this makes, like "register", direct use of processor registers (it
> > stores int arguments in eax, ebx, etc.).
>
> No. It make _unlike_ "register", direct use of processor registers.
>
> The "register" keyword does _not_ use processor registers. It's just
> syntactic fluff, and tells the compiler exactly one thing:
>
> - that the compiler should warn if you take the address of such a thing.
>
> In addition, the compiler may generate code that takes it into account,
> which most likely means _worse_ code than if it didn't take it into
> account.
afaik gcc just otherwise ignores it entirely.
^ permalink raw reply
* Re: git "tag" objects implemented - and a re-done commit
From: Linus Torvalds @ 2005-04-25 20:42 UTC (permalink / raw)
To: Andreas Gal; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251318290.11481@sam.ics.uci.edu>
On Mon, 25 Apr 2005, Andreas Gal wrote:
>
> Are tag objects referenced by trees (and thus limited in scope) or are
> they stand-alone entities in the repository? The latter would be bad for
> shared object storages.
They are totally stand-alone, and I don't see why that would be bad for
shared object storage.
In fact, the whole point of them is that since they are named by the SHA1
hash of the content, there are no shared object issues. Two different tags
by two different developers will have different names, exactly the same
way two different releases will have different names.
And if two different developers tag exactly the same object with exactly
the same tag-name and exactly the same signature, then they get the same
tag object, and that's fine. They should.
> Also, if I delete and recreate tags, will the old tag remain in the tree
> or will the file in the object storage disapear?
Tags in no way affect the entry they name. When you remove - or add - a
tag object, nothing happens to anything else.
Linus
^ permalink raw reply
* Re: git "tag" objects implemented - and a re-done commit
From: Andreas Gal @ 2005-04-25 20:23 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251213530.18901@ppc970.osdl.org>
Are tag objects referenced by trees (and thus limited in scope) or are
they stand-alone entities in the repository? The latter would be bad for
shared object storages. Also, if I delete and recreate tags, will the old
tag remain in the tree or will the file in the object storage disapear?
So far all objects were always persistent, which is a nice property to
have.
Andreas
On Mon, 25 Apr 2005, Linus Torvalds wrote:
>
> Ok, I just pushed out my "tag" object implementation, and due to some
> local braindamage over here, I ended up re-doing one commit, so if you
> happened to pull my 'git' tree at _just_ the right time, you will have a
> commit object named 06a02346f6a2e9ff113c189629ff7148f5141bb0 in your git
> repository, which is not exactly bogus, but which I ended up undoing.
>
> So if you've been pulling my git stuff, check your "git log" for whether
> you find that commit in your stuff. If you do, I guess it doesn't much
> matter (ie should all merge in cleanly), but if you want to match my tree,
> you should first undo it if it's your HEAD commit (by setting your HEAD to
> the _parent_ of that commit, and then running the git-prune-script thing).
>
> Anyway, I decided that my original model for tags was the right one, with
> a trivial extension. Notably, if you want to tag a single file or a tree
> object, go wild. The tag object format is:
>
> object <sha1>
> type <type>
> tag <tag>
> .. free-form commentary and signature of this all ..
>
> and the "git-mktag" program verifies that the three first lines are valid
> before it accepts it and writes it as a git object.
>
> Right now the tags don't do anything, except fsck can verify them (not the
> signature - git doesn't even specify any particular format, and you may
> validly have unsigned tags in your tree), and will print out something
> like
>
> tagged commit e83c5163316f89bfbde7d9ab23ca2e25604af290 (v2.6.12-rc2)
>
> if you were to have such a tag-object in your object database (you don't,
> because I've not generated one, but hey..)
>
> Linus
> -
> 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
* Git-aware darcs: gettable repo
From: Juliusz Chroboczek @ 2005-04-25 20:09 UTC (permalink / raw)
To: darcs-devel, Git Mailing List
Hi,
Just to let you know that, thanks to some friendly tagging by Ian Lynagh,
I've been able to set up a gettable Darcs repository of the Git-aware
version of Darcs.
http://www.pps.jussieu.fr/~jch/software/repos/darcs-git/
If you're on a Linux system with darcs, ghc 6.2, libz, libcurl and libssl,
you should be able to do
$ darcs get --partial http://www.pps.jussieu.fr/~jch/software/repos/darcs-git
$ cd darcs-git
$ make darcs
$ make Context.hs
$ make darcs
$ mv darcs ~/bin/darcs-git
$ cd ..
$ mkdir linux
$ cd linux
$ darcs-git initialize
$ darcs-git pull /usr/local/src/linux-2.6
and see the OOM killer in action.
Juliusz
^ 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