Skip to content

Commit

Permalink
Merge branch 'tr/notes-display'
Browse files Browse the repository at this point in the history
* tr/notes-display:
  git-notes(1): add a section about the meaning of history
  notes: track whether notes_trees were changed at all
  notes: add shorthand --ref to override GIT_NOTES_REF
  commit --amend: copy notes to the new commit
  rebase: support automatic notes copying
  notes: implement helpers needed for note copying during rewrite
  notes: implement 'git notes copy --stdin'
  rebase -i: invoke post-rewrite hook
  rebase: invoke post-rewrite hook
  commit --amend: invoke post-rewrite hook
  Documentation: document post-rewrite hook
  Support showing notes from more than one notes tree
  test-lib: unset GIT_NOTES_REF to stop it from influencing tests

Conflicts:
	git-am.sh
	refs.c
  • Loading branch information
Junio C Hamano committed Mar 24, 2010
2 parents b6a7a06 + 66d6819 commit a86ed83
Show file tree
Hide file tree
Showing 25 changed files with 1,366 additions and 33 deletions.
53 changes: 51 additions & 2 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -519,10 +519,12 @@ check that makes sure that existing object files will not get overwritten.
core.notesRef::
When showing commit messages, also show notes which are stored in
the given ref. This ref is expected to contain files named
after the full SHA-1 of the commit they annotate.
after the full SHA-1 of the commit they annotate. The ref
must be fully qualified.
+
If such a file exists in the given ref, the referenced blob is read, and
appended to the commit message, separated by a "Notes:" line. If the
appended to the commit message, separated by a "Notes (<refname>):"
line (shortened to "Notes:" in the case of "refs/notes/commits"). If the
given ref itself does not exist, it is not an error, but means that no
notes should be printed.
+
Expand Down Expand Up @@ -1334,6 +1336,53 @@ mergetool.keepTemporaries::
mergetool.prompt::
Prompt before each invocation of the merge resolution program.

notes.displayRef::
The (fully qualified) refname from which to show notes when
showing commit messages. The value of this variable can be set
to a glob, in which case notes from all matching refs will be
shown. You may also specify this configuration variable
several times. A warning will be issued for refs that do not
exist, but a glob that does not match any refs is silently
ignored.
+
This setting can be overridden with the `GIT_NOTES_DISPLAY_REF`
environment variable, which must be a colon separated list of refs or
globs.
+
The effective value of "core.notesRef" (possibly overridden by
GIT_NOTES_REF) is also implicitly added to the list of refs to be
displayed.

notes.rewrite.<command>::
When rewriting commits with <command> (currently `amend` or
`rebase`) and this variable is set to `true`, git
automatically copies your notes from the original to the
rewritten commit. Defaults to `true`, but see
"notes.rewriteRef" below.
+
This setting can be overridden with the `GIT_NOTES_REWRITE_REF`
environment variable, which must be a colon separated list of refs or
globs.

notes.rewriteMode::
When copying notes during a rewrite (see the
"notes.rewrite.<command>" option), determines what to do if
the target commit already has a note. Must be one of
`overwrite`, `concatenate`, or `ignore`. Defaults to
`concatenate`.
+
This setting can be overridden with the `GIT_NOTES_REWRITE_MODE`
environment variable.

notes.rewriteRef::
When copying notes during a rewrite, specifies the (fully
qualified) ref whose notes should be copied. The ref may be a
glob, in which case notes in all matching refs will be copied.
You may also specify this configuration several times.
+
Does not have a default value; you must configure this variable to
enable note rewriting.

pack.window::
The size of the window used by linkgit:git-pack-objects[1] when no
window size is given on the command line. Defaults to 10.
Expand Down
46 changes: 40 additions & 6 deletions Documentation/git-notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SYNOPSIS
[verse]
'git notes' [list [<object>]]
'git notes' add [-f] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' copy [-f] <from-object> <to-object>
'git notes' copy [-f] ( --stdin | <from-object> <to-object> )
'git notes' append [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' edit [<object>]
'git notes' show [<object>]
Expand All @@ -27,12 +27,17 @@ A typical use of notes is to extend a commit message without having
to change the commit itself. Such commit notes can be shown by `git log`
along with the original commit message. To discern these notes from the
message stored in the commit object, the notes are indented like the
message, after an unindented line saying "Notes:".
message, after an unindented line saying "Notes (<refname>):" (or
"Notes:" for the default setting).

To disable notes, you have to set the config variable core.notesRef to
the empty string. Alternatively, you can set it to a different ref,
something like "refs/notes/bugzilla". This setting can be overridden
by the environment variable "GIT_NOTES_REF".
This command always manipulates the notes specified in "core.notesRef"
(see linkgit:git-config[1]), which can be overridden by GIT_NOTES_REF.
To change which notes are shown by 'git-log', see the
"notes.displayRef" configuration.

See the description of "notes.rewrite.<command>" in
linkgit:git-config[1] for a way of carrying your notes across commands
that rewrite commits.


SUBCOMMANDS
Expand All @@ -55,6 +60,16 @@ copy::
object has none (use -f to overwrite existing notes to the
second object). This subcommand is equivalent to:
`git notes add [-f] -C $(git notes list <from-object>) <to-object>`
+
In `\--stdin` mode, take lines in the format
+
----------
<from-object> SP <to-object> [ SP <rest> ] LF
----------
+
on standard input, and copy the notes from each <from-object> to its
corresponding <to-object>. (The optional `<rest>` is ignored so that
the command can read the input given to the `post-rewrite` hook.)

append::
Append to the notes of an existing object (defaults to HEAD).
Expand Down Expand Up @@ -101,6 +116,25 @@ OPTIONS
Like '-C', but with '-c' the editor is invoked, so that
the user can further edit the note message.

--ref <ref>::
Manipulate the notes tree in <ref>. This overrides both
GIT_NOTES_REF and the "core.notesRef" configuration. The ref
is taken to be in `refs/notes/` if it is not qualified.


NOTES
-----

Every notes change creates a new commit at the specified notes ref.
You can therefore inspect the history of the notes by invoking, e.g.,
`git log -p notes/commits`.

Currently the commit message only records which operation triggered
the update, and the commit authorship is determined according to the
usual rules (see linkgit:git-commit[1]). These details may change in
the future.


Author
------
Written by Johannes Schindelin <johannes.schindelin@gmx.de> and
Expand Down
38 changes: 38 additions & 0 deletions Documentation/githooks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,44 @@ This hook is invoked by 'git gc --auto'. It takes no parameter, and
exiting with non-zero status from this script causes the 'git gc --auto'
to abort.

post-rewrite
~~~~~~~~~~~~

This hook is invoked by commands that rewrite commits (`git commit
--amend`, 'git-rebase'; currently 'git-filter-branch' does 'not' call
it!). Its first argument denotes the command it was invoked by:
currently one of `amend` or `rebase`. Further command-dependent
arguments may be passed in the future.

The hook receives a list of the rewritten commits on stdin, in the
format

<old-sha1> SP <new-sha1> [ SP <extra-info> ] LF

The 'extra-info' is again command-dependent. If it is empty, the
preceding SP is also omitted. Currently, no commands pass any
'extra-info'.

The hook always runs after the automatic note copying (see
"notes.rewrite.<command>" in linkgit:git-config.txt) has happened, and
thus has access to these notes.

The following command-specific comments apply:

rebase::
For the 'squash' and 'fixup' operation, all commits that were
squashed are listed as being rewritten to the squashed commit.
This means that there will be several lines sharing the same
'new-sha1'.
+
The commits are guaranteed to be listed in the order that they were
processed by rebase.

There is no default 'post-rewrite' hook, but see the
`post-receive-copy-notes` script in `contrib/hooks` for an example
that copies your git-notes to the rewritten commits.


GIT
---
Part of the linkgit:git[1] suite
11 changes: 10 additions & 1 deletion Documentation/pretty-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,18 @@ people using 80-column terminals.
defaults to UTF-8.

--no-notes::
--show-notes::
--show-notes[=<ref>]::
Show the notes (see linkgit:git-notes[1]) that annotate the
commit, when showing the commit log message. This is the default
for `git log`, `git show` and `git whatchanged` commands when
there is no `--pretty`, `--format` nor `--oneline` option is
given on the command line.
+
With an optional argument, add this ref to the list of notes. The ref
is taken to be in `refs/notes/` if it is not qualified.

--[no-]standard-notes::
Enable or disable populating the notes ref list from the
'core.notesRef' and 'notes.displayRef' variables (or
corresponding environment overrides). Enabled by default.
See linkgit:git-config[1].
17 changes: 17 additions & 0 deletions builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ extern int commit_tree(const char *msg, unsigned char *tree,
struct commit_list *parents, unsigned char *ret,
const char *author);
extern int commit_notes(struct notes_tree *t, const char *msg);

struct notes_rewrite_cfg {
struct notes_tree **trees;
const char *cmd;
int enabled;
combine_notes_fn *combine;
struct string_list *refs;
int refs_from_env;
int mode_from_env;
};

combine_notes_fn *parse_combine_notes_fn(const char *v);
struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd);
int copy_note_for_rewrite(struct notes_rewrite_cfg *c,
const unsigned char *from_obj, const unsigned char *to_obj);
void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c);

extern int check_pager_config(const char *cmd);

extern int cmd_add(int argc, const char **argv, const char *prefix);
Expand Down
45 changes: 45 additions & 0 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static char *edit_message, *use_message;
static char *author_name, *author_email, *author_date;
static int all, edit_flag, also, interactive, only, amend, signoff;
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
static int no_post_rewrite;
static char *untracked_files_arg, *force_date;
/*
* The default commit message cleanup mode will remove the lines
Expand Down Expand Up @@ -137,6 +138,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN('z', "null", &null_termination,
"terminate entries with NUL"),
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
/* end commit contents options */
Expand Down Expand Up @@ -1160,6 +1162,40 @@ static int git_commit_config(const char *k, const char *v, void *cb)
return git_status_config(k, v, s);
}

static const char post_rewrite_hook[] = "hooks/post-rewrite";

static int run_rewrite_hook(const unsigned char *oldsha1,
const unsigned char *newsha1)
{
/* oldsha1 SP newsha1 LF NUL */
static char buf[2*40 + 3];
struct child_process proc;
const char *argv[3];
int code;
size_t n;

if (access(git_path(post_rewrite_hook), X_OK) < 0)
return 0;

argv[0] = git_path(post_rewrite_hook);
argv[1] = "amend";
argv[2] = NULL;

memset(&proc, 0, sizeof(proc));
proc.argv = argv;
proc.in = -1;
proc.stdout_to_stderr = 1;

code = start_command(&proc);
if (code)
return code;
n = snprintf(buf, sizeof(buf), "%s %s\n",
sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
write_in_full(proc.in, buf, n);
close(proc.in);
return finish_command(&proc);
}

int cmd_commit(int argc, const char **argv, const char *prefix)
{
struct strbuf sb = STRBUF_INIT;
Expand Down Expand Up @@ -1303,6 +1339,15 @@ int cmd_commit(int argc, const char **argv, const char *prefix)

rerere(0);
run_hook(get_index_file(), "post-commit", NULL);
if (amend && !no_post_rewrite) {
struct notes_rewrite_cfg *cfg;
cfg = init_copy_notes_for_rewrite("amend");
if (cfg) {
copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
finish_copy_notes_for_rewrite(cfg);
}
run_rewrite_hook(head_sha1, commit_sha1);
}
if (!quiet)
print_summary(prefix, commit_sha1);

Expand Down
5 changes: 5 additions & 0 deletions builtin/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,

if (!rev->show_notes_given && !rev->pretty_given)
rev->show_notes = 1;
if (rev->show_notes)
init_display_notes(&rev->notes_opt);

if (rev->diffopt.pickaxe || rev->diffopt.filter)
rev->always_show_header = 0;
Expand Down Expand Up @@ -1105,6 +1107,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
DIFF_OPT_SET(&rev.diffopt, BINARY);

if (rev.show_notes)
init_display_notes(&rev.notes_opt);

if (!use_stdout)
output_directory = set_outdir(prefix, output_directory);

Expand Down
Loading

0 comments on commit a86ed83

Please sign in to comment.