Skip to content

Commit

Permalink
Introduce commit notes
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
dscho authored and gitster committed Dec 21, 2008
1 parent 5832d1a commit 879ef24
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "utf8.h"
#include "diff.h"
#include "revision.h"
#include "notes.h"

int save_commit_buffer = 1;

Expand Down
5 changes: 5 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
68 changes: 68 additions & 0 deletions notes.c
Original file line number Diff line number Diff line change
@@ -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);
}
7 changes: 7 additions & 0 deletions notes.h
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions pretty.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "string-list.h"
#include "mailmap.h"
#include "log-tree.h"
#include "notes.h"

static char *user_format;

Expand Down Expand Up @@ -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);
}

0 comments on commit 879ef24

Please sign in to comment.