* [PATCH 1/2] Add a generic "object decorator" interface, and make object refs use it
@ 2007-04-16 23:03 Linus Torvalds
2007-04-16 23:05 ` [PATCH 2/2] Add support for "commit name decorations" to log family of commands Linus Torvalds
0 siblings, 1 reply; 2+ messages in thread
From: Linus Torvalds @ 2007-04-16 23:03 UTC (permalink / raw
To: Junio C Hamano, Theodore Ts'o, Git Mailing List
This allows you to add an arbitrary "decoration" of your choice to any
object. It's a space- and time-efficient way to add information to
arbitrary objects, especially if most objects probably do not have the
decoration.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
This shouldn't change any behaviour, just re-implements the object-refs
hashing as a new generic "decorator".
Makefile | 4 +-
decorate.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
decorate.h | 18 +++++++++++
object-refs.c | 69 ++++---------------------------------------
object.h | 1 -
5 files changed, 116 insertions(+), 65 deletions(-)
create mode 100644 decorate.c
create mode 100644 decorate.h
diff --git a/Makefile b/Makefile
index b8e6030..251fc31 100644
--- a/Makefile
+++ b/Makefile
@@ -283,7 +283,7 @@ LIB_H = \
diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
- utf8.h reflog-walk.h patch-ids.h
+ utf8.h reflog-walk.h patch-ids.h decorate.h
DIFF_OBJS = \
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@ -305,7 +305,7 @@ LIB_OBJS = \
write_or_die.o trace.o list-objects.o grep.o match-trees.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
- convert.o
+ convert.o decorate.o
BUILTIN_OBJS = \
builtin-add.o \
diff --git a/decorate.c b/decorate.c
new file mode 100644
index 0000000..721bcd1
--- /dev/null
+++ b/decorate.c
@@ -0,0 +1,89 @@
+/*
+ * decorate.c - decorate a git object with some arbitrary
+ * data.
+ */
+#include "cache.h"
+#include "object.h"
+#include "decorate.h"
+
+static unsigned int hash_obj(struct object *obj, unsigned int n)
+{
+ unsigned int hash = *(unsigned int *)obj->sha1;
+ return hash % n;
+}
+
+static void *insert_decoration(struct decoration *n, struct object *base, void *decoration)
+{
+ int size = n->size;
+ struct object_decoration *hash = n->hash;
+ int j = hash_obj(base, size);
+
+ while (hash[j].base) {
+ if (hash[j].base == base) {
+ void *old = hash[j].decoration;
+ hash[j].decoration = decoration;
+ return old;
+ }
+ j++;
+ if (++j >= size)
+ j = 0;
+ }
+ hash[j].base = base;
+ hash[j].decoration = decoration;
+ n->nr++;
+ return NULL;
+}
+
+static void grow_decoration(struct decoration *n)
+{
+ int i;
+ int old_size = n->size;
+ struct object_decoration *old_hash;
+
+ old_size = n->size;
+ old_hash = n->hash;
+
+ n->size = (old_size + 1000) * 3 / 2;
+ n->hash = xcalloc(n->size, sizeof(struct object_decoration));
+ n->nr = 0;
+
+ for (i = 0; i < old_size; i++) {
+ struct object *base = old_hash[i].base;
+ void *decoration = old_hash[i].decoration;
+
+ if (!base)
+ continue;
+ insert_decoration(n, base, decoration);
+ }
+ free(old_hash);
+}
+
+/* Add a decoration pointer, return any old one */
+void *add_decoration(struct decoration *n, struct object *obj, void *decoration)
+{
+ int nr = n->nr + 1;
+
+ if (nr > n->size * 2 / 3)
+ grow_decoration(n);
+ return insert_decoration(n, obj, decoration);
+}
+
+/* Lookup a decoration pointer */
+void *lookup_decoration(struct decoration *n, struct object *obj)
+{
+ int j;
+
+ /* nothing to lookup */
+ if (!n->size)
+ return NULL;
+ j = hash_obj(obj, n->size);
+ for (;;) {
+ struct object_decoration *ref = n->hash + j;
+ if (ref->base == obj)
+ return ref->decoration;
+ if (!ref->base)
+ return NULL;
+ if (++j == n->size)
+ j = 0;
+ }
+}
diff --git a/decorate.h b/decorate.h
new file mode 100644
index 0000000..1fa4ad9
--- /dev/null
+++ b/decorate.h
@@ -0,0 +1,18 @@
+#ifndef DECORATE_H
+#define DECORATE_H
+
+struct object_decoration {
+ struct object *base;
+ void *decoration;
+};
+
+struct decoration {
+ const char *name;
+ unsigned int size, nr;
+ struct object_decoration *hash;
+};
+
+extern void *add_decoration(struct decoration *n, struct object *obj, void *decoration);
+extern void *lookup_decoration(struct decoration *n, struct object *obj);
+
+#endif
diff --git a/object-refs.c b/object-refs.c
index 98ea100..022e8d8 100644
--- a/object-refs.c
+++ b/object-refs.c
@@ -1,75 +1,20 @@
#include "cache.h"
#include "object.h"
+#include "decorate.h"
int track_object_refs = 0;
-static unsigned int refs_hash_size, nr_object_refs;
-static struct object_refs **refs_hash;
+static struct decoration ref_decorate;
-static unsigned int hash_obj(struct object *obj, unsigned int n)
+struct object_refs *lookup_object_refs(struct object *base)
{
- unsigned int hash = *(unsigned int *)obj->sha1;
- return hash % n;
+ return lookup_decoration(&ref_decorate, base);
}
-static void insert_ref_hash(struct object_refs *ref, struct object_refs **hash, unsigned int size)
+static void add_object_refs(struct object *obj, struct object_refs *refs)
{
- int j = hash_obj(ref->base, size);
-
- while (hash[j]) {
- j++;
- if (j >= size)
- j = 0;
- }
- hash[j] = ref;
-}
-
-static void grow_refs_hash(void)
-{
- int i;
- int new_hash_size = (refs_hash_size + 1000) * 3 / 2;
- struct object_refs **new_hash;
-
- new_hash = xcalloc(new_hash_size, sizeof(struct object_refs *));
- for (i = 0; i < refs_hash_size; i++) {
- struct object_refs *ref = refs_hash[i];
- if (!ref)
- continue;
- insert_ref_hash(ref, new_hash, new_hash_size);
- }
- free(refs_hash);
- refs_hash = new_hash;
- refs_hash_size = new_hash_size;
-}
-
-static void add_object_refs(struct object *obj, struct object_refs *ref)
-{
- int nr = nr_object_refs + 1;
-
- if (nr > refs_hash_size * 2 / 3)
- grow_refs_hash();
- ref->base = obj;
- insert_ref_hash(ref, refs_hash, refs_hash_size);
- nr_object_refs = nr;
-}
-
-struct object_refs *lookup_object_refs(struct object *obj)
-{
- struct object_refs *ref;
- int j;
-
- /* nothing to lookup */
- if (!refs_hash_size)
- return NULL;
- j = hash_obj(obj, refs_hash_size);
- while ((ref = refs_hash[j]) != NULL) {
- if (ref->base == obj)
- break;
- j++;
- if (j >= refs_hash_size)
- j = 0;
- }
- return ref;
+ if (add_decoration(&ref_decorate, obj, refs))
+ die("object %s tried to add refs twice!", sha1_to_hex(obj->sha1));
}
struct object_refs *alloc_object_refs(unsigned count)
diff --git a/object.h b/object.h
index bdbf0fa..bdbbc18 100644
--- a/object.h
+++ b/object.h
@@ -8,7 +8,6 @@ struct object_list {
struct object_refs {
unsigned count;
- struct object *base;
struct object *ref[FLEX_ARRAY]; /* more */
};
--
1.5.1.1.107.g7a15
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 2/2] Add support for "commit name decorations" to log family of commands
2007-04-16 23:03 [PATCH 1/2] Add a generic "object decorator" interface, and make object refs use it Linus Torvalds
@ 2007-04-16 23:05 ` Linus Torvalds
0 siblings, 0 replies; 2+ messages in thread
From: Linus Torvalds @ 2007-04-16 23:05 UTC (permalink / raw
To: Junio C Hamano, Theodore Ts'o, Git Mailing List
This adds "--decorate" as a log option, which prints out the ref names
of any commits that are shown.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
I'm not married to the exact format, but if people prefer some other
setup it should be easy to change. The code is fairly simple and obvious.
builtin-log.c | 34 ++++++++++++++++++++++++++++++++--
commit.h | 8 ++++++++
log-tree.c | 21 +++++++++++++++++++++
3 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/builtin-log.c b/builtin-log.c
index 4699494..38bf52f 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -13,16 +13,43 @@
#include "tag.h"
#include "reflog-walk.h"
#include "patch-ids.h"
+#include "refs.h"
static int default_show_root = 1;
/* this is in builtin-diff.c */
void add_head(struct rev_info *revs);
+static void add_name_decoration(const char *prefix, const char *name, struct object *obj)
+{
+ int plen = strlen(prefix);
+ int nlen = strlen(name);
+ struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + plen + nlen);
+ memcpy(res->name, prefix, plen);
+ memcpy(res->name + plen, name, nlen + 1);
+ res->next = add_decoration(&name_decoration, obj, res);
+}
+
+static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+{
+ struct object *obj = parse_object(sha1);
+ if (!obj)
+ return 0;
+ add_name_decoration("", refname, obj);
+ while (obj->type == OBJ_TAG) {
+ obj = ((struct tag *)obj)->tagged;
+ if (!obj)
+ break;
+ add_name_decoration("tag: ", refname, obj);
+ }
+ return 0;
+}
+
static void cmd_log_init(int argc, const char **argv, const char *prefix,
struct rev_info *rev)
{
int i;
+ int decorate = 0;
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
@@ -39,8 +66,11 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
git_log_output_encoding = xstrdup(arg);
else
git_log_output_encoding = "";
- }
- else
+ } else if (!strcmp(arg, "--decorate")) {
+ if (!decorate)
+ for_each_ref(add_ref_decoration, NULL);
+ decorate = 1;
+ } else
die("unrecognized argument: %s", arg);
}
}
diff --git a/commit.h b/commit.h
index 83507a0..59de17e 100644
--- a/commit.h
+++ b/commit.h
@@ -3,6 +3,7 @@
#include "object.h"
#include "tree.h"
+#include "decorate.h"
struct commit_list {
struct commit *item;
@@ -21,6 +22,13 @@ struct commit {
extern int save_commit_buffer;
extern const char *commit_type;
+/* While we can decorate any object with a name, it's only used for commits.. */
+extern struct decoration name_decoration;
+struct name_decoration {
+ struct name_decoration *next;
+ char name[1];
+};
+
struct commit *lookup_commit(const unsigned char *sha1);
struct commit *lookup_commit_reference(const unsigned char *sha1);
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
diff --git a/log-tree.c b/log-tree.c
index dad5513..300b733 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -4,6 +4,8 @@
#include "log-tree.h"
#include "reflog-walk.h"
+struct decoration name_decoration = { "object names" };
+
static void show_parents(struct commit *commit, int abbrev)
{
struct commit_list *p;
@@ -13,6 +15,23 @@ static void show_parents(struct commit *commit, int abbrev)
}
}
+static void show_decorations(struct commit *commit)
+{
+ const char *prefix;
+ struct name_decoration *decoration;
+
+ decoration = lookup_decoration(&name_decoration, &commit->object);
+ if (!decoration)
+ return;
+ prefix = " (";
+ while (decoration) {
+ printf("%s%s", prefix, decoration->name);
+ prefix = ", ";
+ decoration = decoration->next;
+ }
+ putchar(')');
+}
+
/*
* Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches
* Signed-off-by: and Acked-by: lines.
@@ -136,6 +155,7 @@ void show_log(struct rev_info *opt, const char *sep)
fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
if (opt->parents)
show_parents(commit, abbrev_commit);
+ show_decorations(commit);
putchar(opt->diffopt.line_termination);
return;
}
@@ -240,6 +260,7 @@ void show_log(struct rev_info *opt, const char *sep)
printf(" (from %s)",
diff_unique_abbrev(parent->object.sha1,
abbrev_commit));
+ show_decorations(commit);
printf("%s",
diff_get_color(opt->diffopt.color_diff, DIFF_RESET));
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
--
1.5.1.1.107.g7a15
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-04-16 23:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-16 23:03 [PATCH 1/2] Add a generic "object decorator" interface, and make object refs use it Linus Torvalds
2007-04-16 23:05 ` [PATCH 2/2] Add support for "commit name decorations" to log family of commands Linus Torvalds
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).