From: Junio C Hamano Date: Thu, 18 Aug 2011 00:36:22 +0000 (-0700) Subject: Merge branch 'mh/check-attr-relative' X-Git-Tag: v1.7.7-rc0~23 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/324b6b1678a3c1c6179f53fccf4e5fe2cef43240?ds=inline;hp=-c Merge branch 'mh/check-attr-relative' * mh/check-attr-relative: (29 commits) test-path-utils: Add subcommand "prefix_path" test-path-utils: Add subcommand "absolute_path" git-check-attr: Normalize paths git-check-attr: Demonstrate problems with relative paths git-check-attr: Demonstrate problems with unnormalized paths git-check-attr: test that no output is written to stderr Rename git_checkattr() to git_check_attr() git-check-attr: Fix command-line handling to match docs git-check-attr: Drive two tests using the same raw data git-check-attr: Add an --all option to show all attributes git-check-attr: Error out if no pathnames are specified git-check-attr: Process command-line args more systematically git-check-attr: Handle each error separately git-check-attr: Extract a function error_with_usage() git-check-attr: Introduce a new variable git-check-attr: Extract a function output_attr() Allow querying all attributes on a file Remove redundant check Remove redundant call to bootstrap_attr_stack() Extract a function collect_all_attrs() ... --- 324b6b1678a3c1c6179f53fccf4e5fe2cef43240 diff --combined Documentation/gitattributes.txt index 2bbe76b5d8,3d8643437e..25e46aeb7a --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@@ -79,7 -79,7 +79,7 @@@ Attributes for all users on a system sh `$(prefix)/etc/gitattributes` file. Sometimes you would need to override an setting of an attribute -for a path to `unspecified` state. This can be done by listing +for a path to `Unspecified` state. This can be done by listing the name of the attribute prefixed with an exclamation point `!`. @@@ -868,7 -868,7 +868,7 @@@ If this attribute is not set or has an (See linkgit:git-config[1]). -USING ATTRIBUTE MACROS +USING MACRO ATTRIBUTES ---------------------- You do not want any end-of-line conversions applied to, nor textual diffs @@@ -879,27 -879,24 +879,27 @@@ produced for, any binary file you track ------------ but that may become cumbersome, when you have many attributes. Using -attribute macros, you can specify groups of attributes set or unset at -the same time. The system knows a built-in attribute macro, `binary`: +macro attributes, you can define an attribute that, when set, also +sets or unsets a number of other attributes at the same time. The +system knows a built-in macro attribute, `binary`: ------------ *.jpg binary ------------ -which is equivalent to the above. Note that the attribute macros can only -be "Set" (see the above example that sets "binary" macro as if it were an -ordinary attribute --- setting it in turn unsets "text" and "diff"). +Setting the "binary" attribute also unsets the "text" and "diff" +attributes as above. Note that macro attributes can only be "Set", +though setting one might have the effect of setting or unsetting other +attributes or even returning other attributes to the "Unspecified" +state. -DEFINING ATTRIBUTE MACROS +DEFINING MACRO ATTRIBUTES ------------------------- -Custom attribute macros can be defined only in the `.gitattributes` file -at the toplevel (i.e. not in any subdirectory). The built-in attribute -macro "binary" is equivalent to: +Custom macro attributes can be defined only in the `.gitattributes` +file at the toplevel (i.e. not in any subdirectory). The built-in +macro attribute "binary" is equivalent to: ------------ [attr]binary -diff -text @@@ -955,6 -952,9 +955,9 @@@ frotz unspecifie ---------------------------------------------------------------- + SEE ALSO + -------- + linkgit:git-check-attr[1]. GIT --- diff --combined builtin/pack-objects.c index 27f24d3aaf,ac8bed8aa1..a9c67c18ba --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@@ -51,8 -51,6 +51,8 @@@ struct object_entry * objects against. */ unsigned char no_try_delta; + unsigned char tagged; /* near the very tip of refs */ + unsigned char filled; /* assigned write-order */ }; /* @@@ -98,7 -96,6 +98,7 @@@ static unsigned long window_memory_limi */ static int *object_ix; static int object_ix_hashsz; +static struct object_entry *locate_object_entry(const unsigned char *sha1); /* * stats @@@ -203,7 -200,6 +203,7 @@@ static void copy_pack_data(struct sha1f } } +/* Return 0 if we will bust the pack-size limit */ static unsigned long write_object(struct sha1file *f, struct object_entry *entry, off_t write_offset) @@@ -438,134 -434,6 +438,134 @@@ static int write_one(struct sha1file *f return 1; } +static int mark_tagged(const char *path, const unsigned char *sha1, int flag, + void *cb_data) +{ + unsigned char peeled[20]; + struct object_entry *entry = locate_object_entry(sha1); + + if (entry) + entry->tagged = 1; + if (!peel_ref(path, peeled)) { + entry = locate_object_entry(peeled); + if (entry) + entry->tagged = 1; + } + return 0; +} + +static void add_to_write_order(struct object_entry **wo, + int *endp, + struct object_entry *e) +{ + if (e->filled) + return; + wo[(*endp)++] = e; + e->filled = 1; +} + +static void add_descendants_to_write_order(struct object_entry **wo, + int *endp, + struct object_entry *e) +{ + struct object_entry *child; + + for (child = e->delta_child; child; child = child->delta_sibling) + add_to_write_order(wo, endp, child); + for (child = e->delta_child; child; child = child->delta_sibling) + add_descendants_to_write_order(wo, endp, child); +} + +static void add_family_to_write_order(struct object_entry **wo, + int *endp, + struct object_entry *e) +{ + struct object_entry *root; + + for (root = e; root->delta; root = root->delta) + ; /* nothing */ + add_to_write_order(wo, endp, root); + add_descendants_to_write_order(wo, endp, root); +} + +static struct object_entry **compute_write_order(void) +{ + int i, wo_end; + + struct object_entry **wo = xmalloc(nr_objects * sizeof(*wo)); + + for (i = 0; i < nr_objects; i++) { + objects[i].tagged = 0; + objects[i].filled = 0; + objects[i].delta_child = NULL; + objects[i].delta_sibling = NULL; + } + + /* + * Fully connect delta_child/delta_sibling network. + * Make sure delta_sibling is sorted in the original + * recency order. + */ + for (i = nr_objects - 1; 0 <= i; i--) { + struct object_entry *e = &objects[i]; + if (!e->delta) + continue; + /* Mark me as the first child */ + e->delta_sibling = e->delta->delta_child; + e->delta->delta_child = e; + } + + /* + * Mark objects that are at the tip of tags. + */ + for_each_tag_ref(mark_tagged, NULL); + + /* + * Give the commits in the original recency order until + * we see a tagged tip. + */ + for (i = wo_end = 0; i < nr_objects; i++) { + if (objects[i].tagged) + break; + add_to_write_order(wo, &wo_end, &objects[i]); + } + + /* + * Then fill all the tagged tips. + */ + for (; i < nr_objects; i++) { + if (objects[i].tagged) + add_to_write_order(wo, &wo_end, &objects[i]); + } + + /* + * And then all remaining commits and tags. + */ + for (i = 0; i < nr_objects; i++) { + if (objects[i].type != OBJ_COMMIT && + objects[i].type != OBJ_TAG) + continue; + add_to_write_order(wo, &wo_end, &objects[i]); + } + + /* + * And then all the trees. + */ + for (i = 0; i < nr_objects; i++) { + if (objects[i].type != OBJ_TREE) + continue; + add_to_write_order(wo, &wo_end, &objects[i]); + } + + /* + * Finally all the rest in really tight order + */ + for (i = 0; i < nr_objects; i++) + add_family_to_write_order(wo, &wo_end, &objects[i]); + + return wo; +} + static void write_pack_file(void) { uint32_t i = 0, j; @@@ -574,12 -442,10 +574,12 @@@ struct pack_header hdr; uint32_t nr_remaining = nr_result; time_t last_mtime = 0; + struct object_entry **write_order; if (progress > pack_to_stdout) progress_state = start_progress("Writing objects", nr_result); written_list = xmalloc(nr_objects * sizeof(*written_list)); + write_order = compute_write_order(); do { unsigned char sha1[20]; @@@ -603,8 -469,7 +603,8 @@@ offset = sizeof(hdr); nr_written = 0; for (; i < nr_objects; i++) { - if (!write_one(f, objects + i, &offset)) + struct object_entry *e = write_order[i]; + if (!write_one(f, e, &offset)) break; display_progress(progress_state, written); } @@@ -681,7 -546,6 +681,7 @@@ } while (nr_remaining && i < nr_objects); free(written_list); + free(write_order); stop_progress(&progress_state); if (written != nr_result) die("wrote %"PRIu32" objects while expecting %"PRIu32, @@@ -770,7 -634,7 +770,7 @@@ static int no_try_delta(const char *pat struct git_attr_check check[1]; setup_delta_attr_check(check); - if (git_checkattr(path, ARRAY_SIZE(check), check)) + if (git_check_attr(path, ARRAY_SIZE(check), check)) return 0; if (ATTR_FALSE(check->value)) return 1;