summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b0032d1)
raw | patch | inline | side by side (parent: b0032d1)
author | Johan Herland <johan@herland.net> | |
Sat, 13 Feb 2010 21:28:27 +0000 (22:28 +0100) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sun, 14 Feb 2010 03:36:14 +0000 (19:36 -0800) |
When an object is made unreachable by Git, any notes that annotate that object
are not automagically made unreachable, since all notes are always trivially
reachable from a notes ref. In order to remove notes for non-existing objects,
we therefore need to add functionality for traversing the notes tree and
explicitly removing references to notes that annotate non-reachable objects.
Thus the notes objects themselves also become unreachable, and are removed
by a later garbage collect.
prune_notes() performs this traversal (by using for_each_note() internally),
and removes the notes in question from the notes tree.
Note that the effect of prune_notes() is not persistent unless a subsequent
call to write_notes_tree() is made.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
are not automagically made unreachable, since all notes are always trivially
reachable from a notes ref. In order to remove notes for non-existing objects,
we therefore need to add functionality for traversing the notes tree and
explicitly removing references to notes that annotate non-reachable objects.
Thus the notes objects themselves also become unreachable, and are removed
by a later garbage collect.
prune_notes() performs this traversal (by using for_each_note() internally),
and removes the notes in question from the notes tree.
Note that the effect of prune_notes() is not persistent unless a subsequent
call to write_notes_tree() is made.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
notes.c | patch | blob | history | |
notes.h | patch | blob | history |
index d432517587ce451b39cb8f636815366005b7a303..3ba3e6de17a562f309e6d8c64d609768fd740110 100644 (file)
--- a/notes.c
+++ b/notes.c
write_each_note_helper(d->root, note_path, mode, note_sha1);
}
+struct note_delete_list {
+ struct note_delete_list *next;
+ const unsigned char *sha1;
+};
+
+static int prune_notes_helper(const unsigned char *object_sha1,
+ const unsigned char *note_sha1, char *note_path,
+ void *cb_data)
+{
+ struct note_delete_list **l = (struct note_delete_list **) cb_data;
+ struct note_delete_list *n;
+
+ if (has_sha1_file(object_sha1))
+ return 0; /* nothing to do for this note */
+
+ /* failed to find object => prune this note */
+ n = (struct note_delete_list *) xmalloc(sizeof(*n));
+ n->next = *l;
+ n->sha1 = object_sha1;
+ *l = n;
+ return 0;
+}
+
int combine_notes_concatenate(unsigned char *cur_sha1,
const unsigned char *new_sha1)
{
return ret;
}
+void prune_notes(struct notes_tree *t)
+{
+ struct note_delete_list *l = NULL;
+
+ if (!t)
+ t = &default_notes_tree;
+ assert(t->initialized);
+
+ for_each_note(t, 0, prune_notes_helper, &l);
+
+ while (l) {
+ remove_note(t, l->sha1);
+ l = l->next;
+ }
+}
+
void free_notes(struct notes_tree *t)
{
if (!t)
index f98578f91f7f26fbc8d1cf2aae01837143f8262f..bad03ccab776d837751803623394667bfd1c7d11 100644 (file)
--- a/notes.h
+++ b/notes.h
*/
int write_notes_tree(struct notes_tree *t, unsigned char *result);
+/*
+ * Remove all notes annotating non-existing objects from the given notes tree
+ *
+ * All notes in the given notes_tree that are associated with objects that no
+ * longer exist in the database, are removed from the notes tree.
+ *
+ * IMPORTANT: The changes made by prune_notes() to the given notes_tree
+ * structure are not persistent until a subsequent call to write_notes_tree()
+ * returns zero.
+ */
+void prune_notes(struct notes_tree *t);
+
/*
* Free (and de-initialize) the given notes_tree structure
*