]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'kn/attr-from-tree'
authorJunio C Hamano <gitster@pobox.com>
Mon, 23 Jan 2023 21:39:50 +0000 (13:39 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 23 Jan 2023 21:39:51 +0000 (13:39 -0800)
"git check-attr" learned to take an optional tree-ish to read the
.gitattributes file from.

* kn/attr-from-tree:
  attr: add flag `--source` to work with tree-ish
  t0003: move setup for `--all` into new block

1  2 
attr.c
attr.h
pathspec.c
t/t0003-attributes.sh
ws.c

diff --cc attr.c
index 7783b87d8a965fd7ec80ec8745289978ae2d1753,9a1dcac470a16b10ef3f13dd71fd5344b19fd681..1053dfcd4b61b56e99df60e469ec4e757c80e860
--- 1/attr.c
--- 2/attr.c
+++ b/attr.c
@@@ -744,14 -731,61 +746,62 @@@ static struct attr_stack *read_attr_fro
        return res;
  }
  
- static struct attr_stack *read_attr_from_index(struct index_state *istate,
-                                              const char *path,
-                                              unsigned flags)
+ static struct attr_stack *read_attr_from_buf(char *buf, const char *path,
+                                            unsigned flags)
  {
        struct attr_stack *res;
-       char *buf, *sp;
+       char *sp;
        int lineno = 0;
+       if (!buf)
+               return NULL;
+       CALLOC_ARRAY(res, 1);
+       for (sp = buf; *sp;) {
+               char *ep;
+               int more;
+               ep = strchrnul(sp, '\n');
+               more = (*ep == '\n');
+               *ep = '\0';
+               handle_attr_line(res, sp, path, ++lineno, flags);
+               sp = ep + more;
+       }
+       free(buf);
+       return res;
+ }
+ static struct attr_stack *read_attr_from_blob(struct index_state *istate,
+                                             const struct object_id *tree_oid,
+                                             const char *path, unsigned flags)
+ {
+       struct object_id oid;
+       unsigned long sz;
+       enum object_type type;
+       void *buf;
+       unsigned short mode;
+       if (!tree_oid)
+               return NULL;
+       if (get_tree_entry(istate->repo, tree_oid, path, &oid, &mode))
+               return NULL;
+       buf = repo_read_object_file(istate->repo, &oid, &type, &sz);
+       if (!buf || type != OBJ_BLOB) {
+               free(buf);
+               return NULL;
+       }
+       return read_attr_from_buf(buf, path, flags);
+ }
+ static struct attr_stack *read_attr_from_index(struct index_state *istate,
+                                              const char *path, unsigned flags)
+ {
+       char *buf;
 +      unsigned long size;
  
        if (!istate)
                return NULL;
        if (!path_in_cone_mode_sparse_checkout(path, istate))
                return NULL;
  
 -      buf = read_blob_data_from_index(istate, path, NULL);
 +      buf = read_blob_data_from_index(istate, path, &size);
        if (!buf)
                return NULL;
 +      if (size >= ATTR_MAX_FILE_SIZE) {
 +              warning(_("ignoring overly large gitattributes blob '%s'"), path);
 +              return NULL;
 +      }
  
-       CALLOC_ARRAY(res, 1);
-       for (sp = buf; *sp; ) {
-               char *ep;
-               int more;
-               ep = strchrnul(sp, '\n');
-               more = (*ep == '\n');
-               *ep = '\0';
-               handle_attr_line(res, sp, path, ++lineno, flags);
-               sp = ep + more;
-       }
-       free(buf);
-       return res;
+       return read_attr_from_buf(buf, path, flags);
  }
  
  static struct attr_stack *read_attr(struct index_state *istate,
@@@ -1128,10 -1151,10 +1171,10 @@@ void git_check_attr(struct index_state 
  {
        int i;
  
-       collect_some_attrs(istate, path, check);
+       collect_some_attrs(istate, tree_oid, path, check);
  
        for (i = 0; i < check->nr; i++) {
 -              size_t n = check->items[i].attr->attr_nr;
 +              unsigned int n = check->items[i].attr->attr_nr;
                const char *value = check->all_attrs[n].value;
                if (value == ATTR__UNKNOWN)
                        value = ATTR__UNSET;
diff --cc attr.h
index 2f22dffadb32ad6f0b2b9a325e098b9bb0f199f7,fca6c30430462abefb456ff51313c5f2dfbd8f25..58a2bc1344f9f8f46cdede7317ee14f252973a51
--- 1/attr.h
--- 2/attr.h
+++ b/attr.h
   * - Free the `attr_check` struct by calling `attr_check_free()`.
   */
  
 +/**
 + * The maximum line length for a gitattributes file. If the line exceeds this
 + * length we will ignore it.
 + */
 +#define ATTR_MAX_LINE_LENGTH 2048
 +
 + /**
 +  * The maximum size of the giattributes file. If the file exceeds this size we
 +  * will ignore it.
 +  */
 +#define ATTR_MAX_FILE_SIZE (100 * 1024 * 1024)
 +
  struct index_state;
+ struct object_id;
  
  /**
   * An attribute is an opaque object that is identified by its name. Pass the
diff --cc pathspec.c
Simple merge
Simple merge
diff --cc ws.c
Simple merge