Merge branch 'yl/build'
authorJunio C Hamano <junkio@cox.net>
Mon, 19 Jun 2006 04:18:49 +0000 (21:18 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 19 Jun 2006 04:18:49 +0000 (21:18 -0700)
* yl/build:
auto-detect changed prefix and/or changed build flags

15 files changed:
Documentation/git-tar-tree.txt
Makefile
builtin-init-db.c
builtin-log.c
builtin-tar-tree.c
cache.h
environment.c
fsck-objects.c
object-refs.c [new file with mode: 0644]
object.c
object.h
path.c
ppc/sha1.c
setup.c
t/annotate-tests.sh
index 831537b6ffe5c53b8b1955fe7b4f8bac9a3df60d..f2675c41933fc4f824f871cc9185a6a1bf010d2b 100644 (file)
@@ -39,19 +39,24 @@ OPTIONS
 
 Examples
 --------
-git tar-tree HEAD | (cd /var/tmp/ && mkdir junk && tar Cxf junk -)::
+git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)::
 
        Create a tar archive that contains the contents of the
        latest commit on the current branch, and extracts it in
        `/var/tmp/junk` directory.
 
-git tar-tree v2.6.17 linux-2.6.17 | gzip >linux-2.6.17.tar.gz
+git tar-tree v1.4.0 git-1.4.0 | gzip >git-1.4.0.tar.gz::
 
-       Create a tarball for v2.6.17 release.
+       Create a tarball for v1.4.0 release.
 
-git tar-tree --remote=example.com:git.git v0.99 >git-0.99.tar
+git tar-tree v1.4.0{caret}\{tree\} git-1.4.0 | gzip >git-1.4.0.tar.gz::
 
-       Get a tarball v0.99 from example.com.
+       Create a tarball for v1.4.0 release, but without a
+       global extended pax header.
+
+git tar-tree --remote=example.com:git.git v1.4.0 >git-1.4.0.tar::
+
+       Get a tarball v1.4.0 from example.com.
 
 Author
 ------
index ec91181c090eaaa8f2cbbccdb6f0c280b8bc2ee9..ea8cd283e2407cc0f16b2e7a3fa1421f3193e142 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -212,7 +212,7 @@ LIB_OBJS = \
        blob.o commit.o connect.o csum-file.o cache-tree.o base85.o \
        date.o diff-delta.o entry.o exec_cmd.o ident.o lockfile.o \
        object.o pack-check.o patch-delta.o path.o pkt-line.o \
-       quote.o read-cache.o refs.o run-command.o dir.o \
+       quote.o read-cache.o refs.o run-command.o dir.o object-refs.o \
        server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
        tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
        fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
@@ -679,7 +679,7 @@ git.spec: git.spec.in
 
 GIT_TARNAME=git-$(GIT_VERSION)
 dist: git.spec git-tar-tree
-       ./git-tar-tree HEAD $(GIT_TARNAME) > $(GIT_TARNAME).tar
+       ./git-tar-tree HEAD^{tree} $(GIT_TARNAME) > $(GIT_TARNAME).tar
        @mkdir -p $(GIT_TARNAME)
        @cp git.spec $(GIT_TARNAME)
        @echo $(GIT_VERSION) > $(GIT_TARNAME)/version
index 6a24e9bcab4a7b364b69f9ccf2ae822c40873895..7fdd2fa9f9f7fb2801c6e1fc398f78b414a269e1 100644 (file)
@@ -263,7 +263,9 @@ int cmd_init_db(int argc, const char **argv, char **envp)
                if (!strncmp(arg, "--template=", 11))
                        template_dir = arg+11;
                else if (!strcmp(arg, "--shared"))
-                       shared_repository = 1;
+                       shared_repository = PERM_GROUP;
+               else if (!strncmp(arg, "--shared=", 9))
+                       shared_repository = git_config_perm("arg", arg+9);
                else
                        die(init_db_usage);
        }
@@ -301,8 +303,15 @@ int cmd_init_db(int argc, const char **argv, char **envp)
        strcpy(path+len, "/info");
        safe_create_dir(path, 1);
 
-       if (shared_repository)
-               git_config_set("core.sharedrepository", "true");
+       if (shared_repository) {
+               char buf[10];
+               /* We do not spell "group" and such, so that
+                * the configuration can be read by older version
+                * of git.
+                */
+               sprintf(buf, "%d", shared_repository);
+               git_config_set("core.sharedrepository", buf);
+       }
 
        return 0;
 }
index 6afa66ce02bee9a0de4403e1bfb0eedb70c087df..9187fd337ba767384abab26224b95610aa531807 100644 (file)
@@ -220,8 +220,11 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
                }
                else if (!strcmp(argv[i], "--signoff") ||
                         !strcmp(argv[i], "-s")) {
-                       const char *committer = git_committer_info(1);
-                       const char *endpos = strchr(committer, '>');
+                       const char *committer;
+                       const char *endpos;
+                       setup_ident();
+                       committer = git_committer_info(1);
+                       endpos = strchr(committer, '>');
                        if (!endpos)
                                die("bogos committer info %s\n", committer);
                        add_signoff = xmalloc(endpos - committer + 2);
index f6310b9032374d6fd262b807d85987465887cdbf..39a61b629367df9dd274acf5fa310b45dd06f126 100644 (file)
@@ -22,8 +22,10 @@ static unsigned long offset;
 static time_t archive_time;
 
 /* tries hard to write, either succeeds or dies in the attempt */
-static void reliable_write(void *buf, unsigned long size)
+static void reliable_write(const void *data, unsigned long size)
 {
+       const char *buf = data;
+
        while (size > 0) {
                long ret = xwrite(1, buf, size);
                if (ret < 0) {
@@ -47,37 +49,13 @@ static void write_if_needed(void)
        }
 }
 
-/* acquire the next record from the buffer; user must call write_if_needed() */
-static char *get_record(void)
-{
-       char *p = block + offset;
-       memset(p, 0, RECORDSIZE);
-       offset += RECORDSIZE;
-       return p;
-}
-
-/*
- * The end of tar archives is marked by 1024 nul bytes and after that
- * follows the rest of the block (if any).
- */
-static void write_trailer(void)
-{
-       get_record();
-       write_if_needed();
-       get_record();
-       write_if_needed();
-       while (offset) {
-               get_record();
-               write_if_needed();
-       }
-}
-
 /*
  * queues up writes, so that all our write(2) calls write exactly one
  * full block; pads writes to RECORDSIZE
  */
-static void write_blocked(void *buf, unsigned long size)
+static void write_blocked(const void *data, unsigned long size)
 {
+       const char *buf = data;
        unsigned long tail;
 
        if (offset) {
@@ -107,6 +85,21 @@ static void write_blocked(void *buf, unsigned long size)
        write_if_needed();
 }
 
+/*
+ * The end of tar archives is marked by 2*512 nul bytes and after that
+ * follows the rest of the block (if any).
+ */
+static void write_trailer(void)
+{
+       int tail = BLOCKSIZE - offset;
+       memset(block + offset, 0, tail);
+       reliable_write(block, BLOCKSIZE);
+       if (tail < 2 * RECORDSIZE) {
+               memset(block, 0, offset);
+               reliable_write(block, BLOCKSIZE);
+       }
+}
+
 static void strbuf_append_string(struct strbuf *sb, const char *s)
 {
        int slen = strlen(s);
diff --git a/cache.h b/cache.h
index f630cf4bfa92e45600a83d2c3bac05a855deb847..7fcb6d406aa258315f6f2bbba128baee60f59838 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -208,6 +208,12 @@ extern const unsigned char null_sha1[20];
 
 int git_mkstemp(char *path, size_t n, const char *template);
 
+enum sharedrepo {
+       PERM_UMASK = 0,
+       PERM_GROUP,
+       PERM_EVERYBODY
+};
+int git_config_perm(const char *var, const char *value);
 int adjust_shared_perm(const char *path);
 int safe_create_leading_directories(char *path);
 size_t safe_strncpy(char *, const char *, size_t);
index 2e79eab18d322b61e783f45758fdbdc5210de13c..3de8eb3b2a2359a9f8a9f702076292f1e1429df3 100644 (file)
@@ -18,7 +18,7 @@ int log_all_ref_updates = 0;
 int warn_ambiguous_refs = 1;
 int repository_format_version = 0;
 char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
-int shared_repository = 0;
+int shared_repository = PERM_UMASK;
 const char *apply_default_whitespace = NULL;
 
 static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
index 2b1aab488f2b8d64fa799adf427b6eeca35ac757..769bb2a6a75f34192cfd7d6f99ea8f6efbfdce7e 100644 (file)
@@ -64,6 +64,7 @@ static void check_connectivity(void)
 
        /* Look up all the requirements, warn about missing objects.. */
        for (i = 0; i < obj_allocs; i++) {
+               const struct object_refs *refs;
                struct object *obj = objs[i];
 
                if (!obj)
@@ -78,8 +79,8 @@ static void check_connectivity(void)
                        continue;
                }
 
-               if (obj->refs) {
-                       const struct object_refs *refs = obj->refs;
+               refs = lookup_object_refs(obj);
+               if (refs) {
                        unsigned j;
                        for (j = 0; j < refs->count; j++) {
                                struct object *ref = refs->ref[j];
diff --git a/object-refs.c b/object-refs.c
new file mode 100644 (file)
index 0000000..8afa227
--- /dev/null
@@ -0,0 +1,142 @@
+#include "cache.h"
+#include "object.h"
+
+int track_object_refs = 0;
+
+static unsigned int refs_hash_size, nr_object_refs;
+static struct object_refs **refs_hash;
+
+static unsigned int hash_obj(struct object *obj, unsigned int n)
+{
+       unsigned int hash = *(unsigned int *)obj->sha1;
+       return hash % n;
+}
+
+static void grow_refs_hash(void)
+{
+       int i;
+       int new_hash_size = (refs_hash_size + 1000) * 3 / 2;
+       struct object_refs **new_hash;
+
+       new_hash = calloc(new_hash_size, sizeof(struct object_refs *));
+       for (i = 0; i < refs_hash_size; i++) {
+               int j;
+               struct object_refs *ref = refs_hash[i];
+               if (!ref)
+                       continue;
+               j = hash_obj(ref->base, new_hash_size);
+               new_hash[j] = ref;
+       }
+       free(refs_hash);
+       refs_hash = new_hash;
+       refs_hash_size = new_hash_size;
+}
+
+static void insert_ref_hash(struct object_refs *ref)
+{
+       int j = hash_obj(ref->base, refs_hash_size);
+
+       while (refs_hash[j]) {
+               j++;
+               if (j >= refs_hash_size)
+                       j = 0;
+       }
+       refs_hash[j] = ref;
+}
+
+static void add_object_refs(struct object *obj, struct object_refs *ref)
+{
+       int nr = nr_object_refs + 1;
+
+       if (nr > refs_hash_size * 2 / 3)
+               grow_refs_hash();
+       ref->base = obj;
+       insert_ref_hash(ref);
+       nr_object_refs = nr;
+}
+
+struct object_refs *lookup_object_refs(struct object *obj)
+{
+       int j = hash_obj(obj, refs_hash_size);
+       struct object_refs *ref;
+
+       while ((ref = refs_hash[j]) != NULL) {
+               if (ref->base == obj)
+                       break;
+               j++;
+               if (j >= refs_hash_size)
+                       j = 0;
+       }
+       return ref;
+}
+
+struct object_refs *alloc_object_refs(unsigned count)
+{
+       struct object_refs *refs;
+       size_t size = sizeof(*refs) + count*sizeof(struct object *);
+
+       refs = xcalloc(1, size);
+       refs->count = count;
+       return refs;
+}
+
+static int compare_object_pointers(const void *a, const void *b)
+{
+       const struct object * const *pa = a;
+       const struct object * const *pb = b;
+       if (*pa == *pb)
+               return 0;
+       else if (*pa < *pb)
+               return -1;
+       else
+               return 1;
+}
+
+void set_object_refs(struct object *obj, struct object_refs *refs)
+{
+       unsigned int i, j;
+
+       /* Do not install empty list of references */
+       if (refs->count < 1) {
+               free(refs);
+               return;
+       }
+
+       /* Sort the list and filter out duplicates */
+       qsort(refs->ref, refs->count, sizeof(refs->ref[0]),
+             compare_object_pointers);
+       for (i = j = 1; i < refs->count; i++) {
+               if (refs->ref[i] != refs->ref[i - 1])
+                       refs->ref[j++] = refs->ref[i];
+       }
+       if (j < refs->count) {
+               /* Duplicates were found - reallocate list */
+               size_t size = sizeof(*refs) + j*sizeof(struct object *);
+               refs->count = j;
+               refs = xrealloc(refs, size);
+       }
+
+       for (i = 0; i < refs->count; i++)
+               refs->ref[i]->used = 1;
+       add_object_refs(obj, refs);
+}
+
+void mark_reachable(struct object *obj, unsigned int mask)
+{
+       const struct object_refs *refs;
+
+       if (!track_object_refs)
+               die("cannot do reachability with object refs turned off");
+       /* If we've been here already, don't bother */
+       if (obj->flags & mask)
+               return;
+       obj->flags |= mask;
+       refs = lookup_object_refs(obj);
+       if (refs) {
+               unsigned i;
+               for (i = 0; i < refs->count; i++)
+                       mark_reachable(refs->ref[i], mask);
+       }
+}
+
+
index 0f70890a4582fec845fb9399b3dc9f388c6538fc..e26e319ccd22e5c9e9125e58f9ed32620afd66b1 100644 (file)
--- a/object.c
+++ b/object.c
@@ -13,8 +13,6 @@ const char *type_names[] = {
        "none", "blob", "tree", "commit", "bad"
 };
 
-int track_object_refs = 0;
-
 static int hashtable_index(const unsigned char *sha1)
 {
        unsigned int i;
@@ -55,7 +53,6 @@ void created_object(const unsigned char *sha1, struct object *obj)
        obj->parsed = 0;
        memcpy(obj->sha1, sha1, 20);
        obj->type = TYPE_NONE;
-       obj->refs = NULL;
        obj->used = 0;
 
        if (obj_allocs - 1 <= nr_objs * 2) {
@@ -84,73 +81,6 @@ void created_object(const unsigned char *sha1, struct object *obj)
        nr_objs++;
 }
 
-struct object_refs *alloc_object_refs(unsigned count)
-{
-       struct object_refs *refs;
-       size_t size = sizeof(*refs) + count*sizeof(struct object *);
-
-       refs = xcalloc(1, size);
-       refs->count = count;
-       return refs;
-}
-
-static int compare_object_pointers(const void *a, const void *b)
-{
-       const struct object * const *pa = a;
-       const struct object * const *pb = b;
-       if (*pa == *pb)
-               return 0;
-       else if (*pa < *pb)
-               return -1;
-       else
-               return 1;
-}
-
-void set_object_refs(struct object *obj, struct object_refs *refs)
-{
-       unsigned int i, j;
-
-       /* Do not install empty list of references */
-       if (refs->count < 1) {
-               free(refs);
-               return;
-       }
-
-       /* Sort the list and filter out duplicates */
-       qsort(refs->ref, refs->count, sizeof(refs->ref[0]),
-             compare_object_pointers);
-       for (i = j = 1; i < refs->count; i++) {
-               if (refs->ref[i] != refs->ref[i - 1])
-                       refs->ref[j++] = refs->ref[i];
-       }
-       if (j < refs->count) {
-               /* Duplicates were found - reallocate list */
-               size_t size = sizeof(*refs) + j*sizeof(struct object *);
-               refs->count = j;
-               refs = xrealloc(refs, size);
-       }
-
-       for (i = 0; i < refs->count; i++)
-               refs->ref[i]->used = 1;
-       obj->refs = refs;
-}
-
-void mark_reachable(struct object *obj, unsigned int mask)
-{
-       if (!track_object_refs)
-               die("cannot do reachability with object refs turned off");
-       /* If we've been here already, don't bother */
-       if (obj->flags & mask)
-               return;
-       obj->flags |= mask;
-       if (obj->refs) {
-               const struct object_refs *refs = obj->refs;
-               unsigned i;
-               for (i = 0; i < refs->count; i++)
-                       mark_reachable(refs->ref[i], mask);
-       }
-}
-
 struct object *lookup_object_type(const unsigned char *sha1, const char *type)
 {
        if (!type) {
index f4ee2e55ba7853e3b49cbca7409c89b71d4b848f..c537b4b72acabc8b2425ca9bb50c890e730aa788 100644 (file)
--- a/object.h
+++ b/object.h
@@ -9,6 +9,7 @@ struct object_list {
 
 struct object_refs {
        unsigned count;
+       struct object *base;
        struct object *ref[FLEX_ARRAY]; /* more */
 };
 
@@ -28,7 +29,6 @@ struct object {
        unsigned type : TYPE_BITS;
        unsigned flags : FLAG_BITS;
        unsigned char sha1[20];
-       struct object_refs *refs;
 };
 
 extern int track_object_refs;
@@ -41,6 +41,8 @@ static inline const char *typename(unsigned int type)
        return type_names[type > TYPE_TAG ? TYPE_BAD : type];
 }
 
+extern struct object_refs *lookup_object_refs(struct object *);
+
 /** Internal only **/
 struct object *lookup_object(const unsigned char *sha1);
 
diff --git a/path.c b/path.c
index 194e0b553f7a5c4fd99b348228112b308c5419b6..36972fd6df63b3c4eebdcf89238df8ade60d53c3 100644 (file)
--- a/path.c
+++ b/path.c
@@ -267,11 +267,21 @@ int adjust_shared_perm(const char *path)
                return -1;
        mode = st.st_mode;
        if (mode & S_IRUSR)
-               mode |= S_IRGRP;
+               mode |= (shared_repository == PERM_GROUP
+                        ? S_IRGRP
+                        : (shared_repository == PERM_EVERYBODY
+                           ? (S_IRGRP|S_IROTH)
+                           : 0));
+
        if (mode & S_IWUSR)
                mode |= S_IWGRP;
+
        if (mode & S_IXUSR)
-               mode |= S_IXGRP;
+               mode |= (shared_repository == PERM_GROUP
+                        ? S_IXGRP
+                        : (shared_repository == PERM_EVERYBODY
+                           ? (S_IXGRP|S_IXOTH)
+                           : 0));
        if (S_ISDIR(mode))
                mode |= S_ISGID;
        if (chmod(path, mode) < 0)
index 5ba4fc5259b063dab6417c142938d987ee894fc0..0820398b004dd8af93a25e7fa26be60cf4dda410 100644 (file)
@@ -30,7 +30,7 @@ int SHA1_Update(SHA_CTX *c, const void *ptr, unsigned long n)
        unsigned long nb;
        const unsigned char *p = ptr;
 
-       c->len += n << 3;
+       c->len += (uint64_t) n << 3;
        while (n != 0) {
                if (c->cnt || n < 64) {
                        nb = 64 - c->cnt;
diff --git a/setup.c b/setup.c
index fe7f8846962d1c656d258384dbfa466031e28896..4612f110ee0beaeada3cb31ce7d47ad7175eec9c 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -219,12 +219,27 @@ const char *setup_git_directory_gently(int *nongit_ok)
        return cwd + offset;
 }
 
+int git_config_perm(const char *var, const char *value)
+{
+       if (value) {
+               if (!strcmp(value, "umask"))
+                       return PERM_UMASK;
+               if (!strcmp(value, "group"))
+                       return PERM_GROUP;
+               if (!strcmp(value, "all") ||
+                   !strcmp(value, "world") ||
+                   !strcmp(value, "everybody"))
+                       return PERM_EVERYBODY;
+       }
+       return git_config_bool(var, value);
+}
+
 int check_repository_format_version(const char *var, const char *value)
 {
        if (strcmp(var, "core.repositoryformatversion") == 0)
                repository_format_version = git_config_int(var, value);
        else if (strcmp(var, "core.sharedrepository") == 0)
-               shared_repository = git_config_bool(var, value);
+               shared_repository = git_config_perm(var, value);
        return 0;
 }
 
index 114938c3ff18fadb130e6809fc14e89cfe3f36f2..c04f0e1540794c3d4d950c158beee249ba98b726 100644 (file)
@@ -111,9 +111,7 @@ test_expect_success \
 
 test_expect_success \
     'some edit' \
-    'mv file file1 &&
-     sed -e 1d -e "5s/3A/99/" file1 >file &&
-     rm -f file1 &&
+    'perl -pi -e "s/^1A.*\n$//; s/^3A/99/" file &&
     GIT_AUTHOR_NAME="D" git commit -a -m "edit"'
 
 test_expect_success \