Skip to content

Commit dd75d07

Browse files
committed
Merge branch 'jk/cached-textconv'
* jk/cached-textconv: diff: avoid useless filespec population diff: cache textconv output textconv: refactor calls to run_textconv introduce notes-cache interface make commit_tree a library function
2 parents 3ecaa3b + b337398 commit dd75d07

File tree

14 files changed

+403
-118
lines changed

14 files changed

+403
-118
lines changed

Documentation/gitattributes.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,26 @@ because it quickly conveys the changes you have made), you
414414
should generate it separately and send it as a comment _in
415415
addition to_ the usual binary diff that you might send.
416416

417+
Because text conversion can be slow, especially when doing a
418+
large number of them with `git log -p`, git provides a mechanism
419+
to cache the output and use it in future diffs. To enable
420+
caching, set the "cachetextconv" variable in your diff driver's
421+
config. For example:
422+
423+
------------------------
424+
[diff "jpg"]
425+
textconv = exif
426+
cachetextconv = true
427+
------------------------
428+
429+
This will cache the result of running "exif" on each blob
430+
indefinitely. If you change the textconv config variable for a
431+
diff driver, git will automatically invalidate the cache entries
432+
and re-run the textconv filter. If you want to invalidate the
433+
cache manually (e.g., because your version of "exif" was updated
434+
and now produces better output), you can remove the cache
435+
manually with `git update-ref -d refs/notes/textconv/jpg` (where
436+
"jpg" is the name of the diff driver, as in the example above).
417437

418438
Performing a three-way merge
419439
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ LIB_H += log-tree.h
486486
LIB_H += mailmap.h
487487
LIB_H += merge-recursive.h
488488
LIB_H += notes.h
489+
LIB_H += notes-cache.h
489490
LIB_H += object.h
490491
LIB_H += pack.h
491492
LIB_H += pack-refs.h
@@ -575,6 +576,7 @@ LIB_OBJS += merge-file.o
575576
LIB_OBJS += merge-recursive.o
576577
LIB_OBJS += name-hash.o
577578
LIB_OBJS += notes.o
579+
LIB_OBJS += notes-cache.o
578580
LIB_OBJS += object.o
579581
LIB_OBJS += pack-check.o
580582
LIB_OBJS += pack-refs.o

builtin.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ extern const char *help_unknown_cmd(const char *cmd);
1616
extern void prune_packed_objects(int);
1717
extern int fmt_merge_msg(int merge_summary, struct strbuf *in,
1818
struct strbuf *out);
19-
extern int commit_tree(const char *msg, unsigned char *tree,
20-
struct commit_list *parents, unsigned char *ret,
21-
const char *author);
2219
extern int commit_notes(struct notes_tree *t, const char *msg);
2320

2421
struct notes_rewrite_cfg {

builtin/commit-tree.c

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,6 @@
99
#include "builtin.h"
1010
#include "utf8.h"
1111

12-
/*
13-
* FIXME! Share the code with "write-tree.c"
14-
*/
15-
static void check_valid(unsigned char *sha1, enum object_type expect)
16-
{
17-
enum object_type type = sha1_object_info(sha1, NULL);
18-
if (type < 0)
19-
die("%s is not a valid object", sha1_to_hex(sha1));
20-
if (type != expect)
21-
die("%s is not a valid '%s' object", sha1_to_hex(sha1),
22-
typename(expect));
23-
}
24-
2512
static const char commit_tree_usage[] = "git commit-tree <sha1> [-p <sha1>]* < changelog";
2613

2714
static void new_parent(struct commit *parent, struct commit_list **parents_p)
@@ -38,61 +25,6 @@ static void new_parent(struct commit *parent, struct commit_list **parents_p)
3825
commit_list_insert(parent, parents_p);
3926
}
4027

41-
static const char commit_utf8_warn[] =
42-
"Warning: commit message does not conform to UTF-8.\n"
43-
"You may want to amend it after fixing the message, or set the config\n"
44-
"variable i18n.commitencoding to the encoding your project uses.\n";
45-
46-
int commit_tree(const char *msg, unsigned char *tree,
47-
struct commit_list *parents, unsigned char *ret,
48-
const char *author)
49-
{
50-
int result;
51-
int encoding_is_utf8;
52-
struct strbuf buffer;
53-
54-
check_valid(tree, OBJ_TREE);
55-
56-
/* Not having i18n.commitencoding is the same as having utf-8 */
57-
encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
58-
59-
strbuf_init(&buffer, 8192); /* should avoid reallocs for the headers */
60-
strbuf_addf(&buffer, "tree %s\n", sha1_to_hex(tree));
61-
62-
/*
63-
* NOTE! This ordering means that the same exact tree merged with a
64-
* different order of parents will be a _different_ changeset even
65-
* if everything else stays the same.
66-
*/
67-
while (parents) {
68-
struct commit_list *next = parents->next;
69-
strbuf_addf(&buffer, "parent %s\n",
70-
sha1_to_hex(parents->item->object.sha1));
71-
free(parents);
72-
parents = next;
73-
}
74-
75-
/* Person/date information */
76-
if (!author)
77-
author = git_author_info(IDENT_ERROR_ON_NO_NAME);
78-
strbuf_addf(&buffer, "author %s\n", author);
79-
strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME));
80-
if (!encoding_is_utf8)
81-
strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
82-
strbuf_addch(&buffer, '\n');
83-
84-
/* And add the comment */
85-
strbuf_addstr(&buffer, msg);
86-
87-
/* And check the encoding */
88-
if (encoding_is_utf8 && !is_utf8(buffer.buf))
89-
fprintf(stderr, commit_utf8_warn);
90-
91-
result = write_sha1_file(buffer.buf, buffer.len, commit_type, ret);
92-
strbuf_release(&buffer);
93-
return result;
94-
}
95-
9628
int cmd_commit_tree(int argc, const char **argv, const char *prefix)
9729
{
9830
int i;
@@ -117,7 +49,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
11749

11850
if (get_sha1(b, sha1))
11951
die("Not a valid object name %s", b);
120-
check_valid(sha1, OBJ_COMMIT);
52+
assert_sha1_type(sha1, OBJ_COMMIT);
12153
new_parent(lookup_commit(sha1), &parents);
12254
}
12355

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,8 @@ extern int has_loose_object_nonlocal(const unsigned char *sha1);
718718

719719
extern int has_pack_index(const unsigned char *sha1);
720720

721+
extern void assert_sha1_type(const unsigned char *sha1, enum object_type expect);
722+
721723
extern const signed char hexval_table[256];
722724
static inline unsigned int hexval(unsigned char c)
723725
{

commit.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,3 +790,58 @@ struct commit_list *reduce_heads(struct commit_list *heads)
790790
free(other);
791791
return result;
792792
}
793+
794+
static const char commit_utf8_warn[] =
795+
"Warning: commit message does not conform to UTF-8.\n"
796+
"You may want to amend it after fixing the message, or set the config\n"
797+
"variable i18n.commitencoding to the encoding your project uses.\n";
798+
799+
int commit_tree(const char *msg, unsigned char *tree,
800+
struct commit_list *parents, unsigned char *ret,
801+
const char *author)
802+
{
803+
int result;
804+
int encoding_is_utf8;
805+
struct strbuf buffer;
806+
807+
assert_sha1_type(tree, OBJ_TREE);
808+
809+
/* Not having i18n.commitencoding is the same as having utf-8 */
810+
encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
811+
812+
strbuf_init(&buffer, 8192); /* should avoid reallocs for the headers */
813+
strbuf_addf(&buffer, "tree %s\n", sha1_to_hex(tree));
814+
815+
/*
816+
* NOTE! This ordering means that the same exact tree merged with a
817+
* different order of parents will be a _different_ changeset even
818+
* if everything else stays the same.
819+
*/
820+
while (parents) {
821+
struct commit_list *next = parents->next;
822+
strbuf_addf(&buffer, "parent %s\n",
823+
sha1_to_hex(parents->item->object.sha1));
824+
free(parents);
825+
parents = next;
826+
}
827+
828+
/* Person/date information */
829+
if (!author)
830+
author = git_author_info(IDENT_ERROR_ON_NO_NAME);
831+
strbuf_addf(&buffer, "author %s\n", author);
832+
strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME));
833+
if (!encoding_is_utf8)
834+
strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
835+
strbuf_addch(&buffer, '\n');
836+
837+
/* And add the comment */
838+
strbuf_addstr(&buffer, msg);
839+
840+
/* And check the encoding */
841+
if (encoding_is_utf8 && !is_utf8(buffer.buf))
842+
fprintf(stderr, commit_utf8_warn);
843+
844+
result = write_sha1_file(buffer.buf, buffer.len, commit_type, ret);
845+
strbuf_release(&buffer);
846+
return result;
847+
}

commit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,8 @@ static inline int single_parent(struct commit *commit)
163163

164164
struct commit_list *reduce_heads(struct commit_list *heads);
165165

166+
extern int commit_tree(const char *msg, unsigned char *tree,
167+
struct commit_list *parents, unsigned char *ret,
168+
const char *author);
169+
166170
#endif /* COMMIT_H */

0 commit comments

Comments
 (0)