@matheusbsbs / matheus-bagliano / commits / a97a74686d
Fork 0

Introduce commit notes

Commit notes are blobs which are shown together with the commit message. These blobs are taken from the notes ref, which you can configure by the config variable core.notesRef, which in turn can be overridden by the environment variable GIT_NOTES_REF. The notes ref is a branch which contains "files" whose names are the names of the corresponding commits (i.e. the SHA-1). The rationale for putting this information into a ref is this: we want to be able to fetch and possibly union-merge the notes, maybe even look at the date when a note was introduced, and we want to store them efficiently together with the other objects. This patch has been improved by the following contributions: - Thomas Rast: fix core.notesRef documentation - Tor Arne Vestbø: fix printing of multi-line notes - Alex Riesen: Using char array instead of char pointer costs less BSS - Johan Herland: Plug leak when msg is good, but msglen or type causes return Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Tor Arne Vestbø <tavestbo@trolltech.com> Signed-off-by: Johan Herland <johan@herland.net> Signed-off-by: Junio C Hamano <gitster@pobox.com> get_commit_notes(): Plug memory leak when 'if' triggers, but not because of read_sha1_file() failure

Johannes Schindelin committed Oct 9, 2009 at 12:21 UTC a97a74686d70a318cd802003498054cc1e8b0ae2
9 files changed +108
Documentation/config.txt
+13
@@ -454,6 +454,19 @@ On some file system/operating system combinations, this is unreliable.
454 Set this config setting to 'rename' there; However, This will remove the
455 check that makes sure that existing object files will not get overwritten.
456
457 +core.notesRef::
458 + When showing commit messages, also show notes which are stored in
459 + the given ref. This ref is expected to contain files named
460 + after the full SHA-1 of the commit they annotate.
461 ++
462 +If such a file exists in the given ref, the referenced blob is read, and
463 +appended to the commit message, separated by a "Notes:" line. If the
464 +given ref itself does not exist, it is not an error, but means that no
465 +notes should be printed.
466 ++
467 +This setting defaults to "refs/notes/commits", and can be overridden by
468 +the `GIT_NOTES_REF` environment variable.
469 +
470 add.ignore-errors::
471 Tells 'git-add' to continue adding files when some files cannot be
472 added due to indexing errors. Equivalent to the '--ignore-errors'
Makefile
+2
@@ -432,6 +432,7 @@ LIB_H += ll-merge.h
432 LIB_H += log-tree.h
433 LIB_H += mailmap.h
434 LIB_H += merge-recursive.h
435 +LIB_H += notes.h
436 LIB_H += object.h
437 LIB_H += pack.h
438 LIB_H += pack-refs.h
@@ -516,6 +517,7 @@ LIB_OBJS += match-trees.o
517 LIB_OBJS += merge-file.o
518 LIB_OBJS += merge-recursive.o
519 LIB_OBJS += name-hash.o
520 +LIB_OBJS += notes.o
521 LIB_OBJS += object.o
522 LIB_OBJS += pack-check.o
523 LIB_OBJS += pack-refs.o
cache.h
+4
@@ -372,6 +372,8 @@ static inline enum object_type object_type(unsigned int mode)
372 #define GITATTRIBUTES_FILE ".gitattributes"
373 #define INFOATTRIBUTES_FILE "info/attributes"
374 #define ATTRIBUTE_MACRO_PREFIX "[attr]"
375 +#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF"
376 +#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"
377
378 extern int is_bare_repository_cfg;
379 extern int is_bare_repository(void);
@@ -567,6 +569,8 @@ enum object_creation_mode {
569
570 extern enum object_creation_mode object_creation_mode;
571
572 +extern char *notes_ref_name;
573 +
574 extern int grafts_replace_parents;
575
576 #define GIT_REPO_VERSION 0
commit.c
+1
@@ -5,6 +5,7 @@
5 #include "utf8.h"
6 #include "diff.h"
7 #include "revision.h"
8 +#include "notes.h"
9
10 int save_commit_buffer = 1;
11
config.c
+5
@@ -467,6 +467,11 @@ static int git_default_core_config(const char *var, const char *value)
467 return 0;
468 }
469
470 + if (!strcmp(var, "core.notesref")) {
471 + notes_ref_name = xstrdup(value);
472 + return 0;
473 + }
474 +
475 if (!strcmp(var, "core.pager"))
476 return git_config_string(&pager_program, var, value);
477
environment.c
+1
@@ -49,6 +49,7 @@ enum push_default_type push_default = PUSH_DEFAULT_MATCHING;
49 #define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
50 #endif
51 enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
52 +char *notes_ref_name;
53 int grafts_replace_parents = 1;
54
55 /* Parallel index stat data preload? */
notes.c new
+70
@@ -0,0 +1,70 @@
1 +#include "cache.h"
2 +#include "commit.h"
3 +#include "notes.h"
4 +#include "refs.h"
5 +#include "utf8.h"
6 +#include "strbuf.h"
7 +
8 +static int initialized;
9 +
10 +void get_commit_notes(const struct commit *commit, struct strbuf *sb,
11 + const char *output_encoding)
12 +{
13 + static const char utf8[] = "utf-8";
14 + struct strbuf name = STRBUF_INIT;
15 + unsigned char sha1[20];
16 + char *msg, *msg_p;
17 + unsigned long linelen, msglen;
18 + enum object_type type;
19 +
20 + if (!initialized) {
21 + const char *env = getenv(GIT_NOTES_REF_ENVIRONMENT);
22 + if (env)
23 + notes_ref_name = getenv(GIT_NOTES_REF_ENVIRONMENT);
24 + else if (!notes_ref_name)
25 + notes_ref_name = GIT_NOTES_DEFAULT_REF;
26 + if (notes_ref_name && read_ref(notes_ref_name, sha1))
27 + notes_ref_name = NULL;
28 + initialized = 1;
29 + }
30 +
31 + if (!notes_ref_name)
32 + return;
33 +
34 + strbuf_addf(&name, "%s:%s", notes_ref_name,
35 + sha1_to_hex(commit->object.sha1));
36 + if (get_sha1(name.buf, sha1))
37 + return;
38 +
39 + if (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen ||
40 + type != OBJ_BLOB) {
41 + free(msg);
42 + return;
43 + }
44 +
45 + if (output_encoding && *output_encoding &&
46 + strcmp(utf8, output_encoding)) {
47 + char *reencoded = reencode_string(msg, output_encoding, utf8);
48 + if (reencoded) {
49 + free(msg);
50 + msg = reencoded;
51 + msglen = strlen(msg);
52 + }
53 + }
54 +
55 + /* we will end the annotation by a newline anyway */
56 + if (msglen && msg[msglen - 1] == '\n')
57 + msglen--;
58 +
59 + strbuf_addstr(sb, "\nNotes:\n");
60 +
61 + for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
62 + linelen = strchrnul(msg_p, '\n') - msg_p;
63 +
64 + strbuf_addstr(sb, " ");
65 + strbuf_add(sb, msg_p, linelen);
66 + strbuf_addch(sb, '\n');
67 + }
68 +
69 + free(msg);
70 +}
notes.h new
+7
@@ -0,0 +1,7 @@
1 +#ifndef NOTES_H
2 +#define NOTES_H
3 +
4 +void get_commit_notes(const struct commit *commit, struct strbuf *sb,
5 + const char *output_encoding);
6 +
7 +#endif
pretty.c
+5
@@ -6,6 +6,7 @@
6 #include "string-list.h"
7 #include "mailmap.h"
8 #include "log-tree.h"
9 +#include "notes.h"
10 #include "color.h"
11
12 static char *user_format;
@@ -975,5 +976,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
976 */
977 if (fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
978 strbuf_addch(sb, '\n');
979 +
980 + if (fmt != CMIT_FMT_ONELINE)
981 + get_commit_notes(commit, sb, encoding);
982 +
983 free(reencoded);
984 }