diff options
-rw-r--r-- | Documentation/config.txt | 15 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | cache.h | 3 | ||||
-rw-r--r-- | commit.c | 1 | ||||
-rw-r--r-- | config.c | 5 | ||||
-rw-r--r-- | environment.c | 1 | ||||
-rw-r--r-- | notes.c | 68 | ||||
-rw-r--r-- | notes.h | 7 | ||||
-rw-r--r-- | pretty.c | 5 |
9 files changed, 107 insertions, 0 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt index 21ea16590b..b35a32abe1 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -422,6 +422,21 @@ relatively high IO latencies. With this set to 'true', git will do the index comparison to the filesystem data in parallel, allowing overlapping IO's. +core.notesRef:: + When showing commit messages, also show notes which are stored in + the given ref. This ref is expected to contain paths of the form + ??/*, where the directory name consists of the first two + characters of the commit name, and the base name consists of + the remaining 38 characters. ++ +If such a path exists in the given ref, the referenced blob is read, and +appended to the commit message, separated by a "Notes:" line. If the +given ref itself does not exist, it is not an error, but means that no +notes should be print. ++ +This setting defaults to "refs/notes/commits", and can be overridden by +the `GIT_NOTES_REF` environment variable. + alias.*:: Command aliases for the linkgit:git[1] command wrapper - e.g. after defining "alias.last = cat-file commit HEAD", the invocation @@ -370,6 +370,7 @@ LIB_H += ll-merge.h LIB_H += log-tree.h LIB_H += mailmap.h LIB_H += merge-recursive.h +LIB_H += notes.h LIB_H += object.h LIB_H += pack.h LIB_H += pack-refs.h @@ -451,6 +452,7 @@ LIB_OBJS += match-trees.o LIB_OBJS += merge-file.o LIB_OBJS += merge-recursive.o LIB_OBJS += name-hash.o +LIB_OBJS += notes.o LIB_OBJS += object.o LIB_OBJS += pack-check.o LIB_OBJS += pack-refs.o @@ -367,6 +367,8 @@ static inline enum object_type object_type(unsigned int mode) #define GITATTRIBUTES_FILE ".gitattributes" #define INFOATTRIBUTES_FILE "info/attributes" #define ATTRIBUTE_MACRO_PREFIX "[attr]" +#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF" +#define GIT_NOTES_DEFAULT_REF "refs/notes/commits" extern int is_bare_repository_cfg; extern int is_bare_repository(void); @@ -538,6 +540,7 @@ enum rebase_setup_type { extern enum branch_track git_branch_track; extern enum rebase_setup_type autorebase; +extern char *notes_ref_name; #define GIT_REPO_VERSION 0 extern int repository_format_version; @@ -5,6 +5,7 @@ #include "utf8.h" #include "diff.h" #include "revision.h" +#include "notes.h" int save_commit_buffer = 1; @@ -469,6 +469,11 @@ static int git_default_core_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.notesref")) { + notes_ref_name = xstrdup(value); + return 0; + } + if (!strcmp(var, "core.pager")) return git_config_string(&pager_program, var, value); diff --git a/environment.c b/environment.c index e278bce0ea..0edae21e74 100644 --- a/environment.c +++ b/environment.c @@ -45,6 +45,7 @@ enum rebase_setup_type autorebase = AUTOREBASE_NEVER; /* Parallel index stat data preload? */ int core_preload_index = 0; +char *notes_ref_name; /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; diff --git a/notes.c b/notes.c new file mode 100644 index 0000000000..91ec77f3f0 --- /dev/null +++ b/notes.c @@ -0,0 +1,68 @@ +#include "cache.h" +#include "commit.h" +#include "notes.h" +#include "refs.h" +#include "utf8.h" +#include "strbuf.h" + +static int initialized; + +void get_commit_notes(const struct commit *commit, struct strbuf *sb, + const char *output_encoding) +{ + static const char *utf8 = "utf-8"; + struct strbuf name = STRBUF_INIT; + const char *hex; + unsigned char sha1[20]; + char *msg; + unsigned long msgoffset, msglen; + enum object_type type; + + if (!initialized) { + const char *env = getenv(GIT_NOTES_REF_ENVIRONMENT); + if (env) + notes_ref_name = getenv(GIT_NOTES_REF_ENVIRONMENT); + else if (!notes_ref_name) + notes_ref_name = GIT_NOTES_DEFAULT_REF; + if (notes_ref_name && read_ref(notes_ref_name, sha1)) + notes_ref_name = NULL; + initialized = 1; + } + + if (!notes_ref_name) + return; + + strbuf_addf(&name, "%s:%s", notes_ref_name, + sha1_to_hex(commit->object.sha1)); + if (get_sha1(name.buf, sha1)) + return; + + if (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen || + type != OBJ_BLOB) + return; + + if (output_encoding && *output_encoding && + strcmp(utf8, output_encoding)) { + char *reencoded = reencode_string(msg, output_encoding, utf8); + if (reencoded) { + free(msg); + msg = reencoded; + msglen = strlen(msg); + } + } + + /* we will end the annotation by a newline anyway */ + if (msglen && msg[msglen - 1] == '\n') + msglen--; + + strbuf_addstr(sb, "\nNotes:\n"); + + for (msgoffset = 0; msgoffset < msglen;) { + int linelen = strchrnul(msg, '\n') - msg; + + strbuf_addstr(sb, " "); + strbuf_add(sb, msg + msgoffset, linelen); + msgoffset += linelen; + } + free(msg); +} diff --git a/notes.h b/notes.h new file mode 100644 index 0000000000..79d21b65f5 --- /dev/null +++ b/notes.h @@ -0,0 +1,7 @@ +#ifndef NOTES_H +#define NOTES_H + +void get_commit_notes(const struct commit *commit, struct strbuf *sb, + const char *output_encoding); + +#endif @@ -6,6 +6,7 @@ #include "string-list.h" #include "mailmap.h" #include "log-tree.h" +#include "notes.h" static char *user_format; @@ -881,5 +882,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, */ if (fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); + + if (fmt != CMIT_FMT_ONELINE) + get_commit_notes(commit, sb, encoding); + free(reencoded); } |