Commit Diff


commit - 5d537aab2400af024f5a0066d68e5d9603a7df45
commit + 14752f55064548cf20109b388ec6d1900420c7df
blob - /dev/null
blob + 3896c253eb5f72146232f05b5c8cde92fee08342 (mode 644)
--- /dev/null
+++ libgit-notes.c
@@ -0,0 +1,124 @@
+#include <git2.h>
+#include <stdio.h>
+
+#define GIT_REPO "."
+#define DEFAULT_NOTES_REF "refs/notes/commits"
+
+/**
+ * gcc notes.c -o notes -L/usr/local/lib -lgit2 -I/usr/local/include
+ * https://github.com/libgit2/libgit2/tree/master/tests/notes
+ */
+
+static int note_list_cb(
+	const git_oid *blob_id, const git_oid *annotated_obj_id, void *payload)
+{
+	printf("note_list_cb\n");
+	git_repository *repo = (git_repository*)payload;
+	git_note *git_note;
+	int rc = 0;
+	const char *note_msg;
+	rc = git_note_read(&git_note, repo, DEFAULT_NOTES_REF, blob_id);
+	if (rc != 0) {
+		const git_error *e = giterr_last();
+		printf("Error %d/%d: %s\n", rc, e->klass, e->message);
+		exit(rc);
+	}
+	note_msg = git_note_message(git_note);
+	printf("%s\n", note_msg);
+	/*
+	const git_signature *signature = NULL;
+	signature = git_note_author(git_note);
+	if (signature != NULL) {
+		printf("author %s\n", signature->name);
+	}
+	*/
+
+	return 0;
+}
+
+struct payload {
+	git_repository *repo;
+	const char *notes_ref;
+};
+
+int main (int argc, char** argv)
+{
+	if (!(git_repository_open_ext(
+        NULL, GIT_REPO, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL) == 0)) {
+        exit(-1);
+	}
+	printf("%s is a GIT repository\n", GIT_REPO);
+	git_libgit2_init();
+	git_repository *repo = NULL;
+	int rc = 0;
+	rc = git_repository_open(&repo, GIT_REPO);
+	if (rc < 0) {
+		const git_error *e = giterr_last();
+		printf("Error %d/%d: %s\n", rc, e->klass, e->message);
+		exit(rc);
+	}
+
+	git_oid *annotated_id, *note_id;
+
+/*
+	git_note_iterator *iter;
+	rc = git_note_iterator_new(&iter, repo, NULL);
+	// rc = git_note_iterator_new(&iter, repo, "refs/notes/commits");
+	if (rc < 0) {
+		const git_error *e = giterr_last();
+		printf("Error git_note_iterator_new() %d/%d: %s\n", rc, e->klass, e->message);
+		exit(rc);
+	}
+	printf("iterator\n");
+	rc = 0;
+	while(rc != GIT_ITEROVER) {
+		rc = git_note_next(note_id, annotated_id, iter);
+		if (rc == GIT_ITEROVER) {
+			break;
+		}
+		if (rc < 0) {
+			const git_error *e = giterr_last();
+			printf("Error git_note_next() %d/%d: %s\n", rc, e->klass, e->message);
+			continue;
+		}
+		printf("XXX\n");
+		const char *note_msg;
+		git_note *git_note;
+		git_note_read(&git_note, repo, "refs/notes/commits", note_id);
+		note_msg = git_note_message(git_note);
+		printf("%s\n", note_msg);
+	}
+	git_note_iterator_free(iter);
+*/
+
+	/*
+	git_note_iterator *iter;
+	git_note *note;
+	git_commit *notes_commit;
+	const char* note_message;
+	int i, err;
+
+	git_note_commit_iterator_new(&iter, notes_commit);
+	for (i = 0; (err = git_note_next(note_id, annotated_id, iter)) >= 0; ++i) {
+		git_note_commit_read(&note, repo, notes_commit, annotated_id);
+		note_message = git_note_message(note);
+		git_note_free(note);
+	}
+	git_note_iterator_free(iter);
+	git_commit_free(notes_commit);
+	*/
+
+	/*
+	git_buf *notes_ref;
+	rc = git_note_default_ref(notes_ref, repo);
+	if (rc != 0) {
+		const git_error *e = giterr_last();
+		printf("Error git_note_next() %d/%d: %s\n", rc, e->klass, e->message);
+		exit(rc);
+	}
+	printf("%s\n", (const char*)notes_ref);
+	*/
+
+	git_note_foreach(repo, DEFAULT_NOTES_REF, note_list_cb, repo);
+	git_libgit2_shutdown();
+}
blob - /dev/null
blob + 67d62d88ea944adeefcc9f000fa8112f0b359252 (mode 644)
--- /dev/null
+++ parse_git_index.c
@@ -0,0 +1,142 @@
+/**
+ * Parser of .git/index file
+ * 
+ * This C program parses .git/index file (only format version 2).
+ * It works just like "git ls-files --stage".
+ * 
+ * Usage:
+ *   gcc -g -Wall -O0 -std=c99 -lz -o parse_git_index parse_git_index.c
+ *   ./parse_git_index  /path/to/.git/index
+ * 
+ * Spec of index format:  https://github.com/git/git/blame/v2.12.0/Documentation/technical/index-format.txt
+ * Original implementation: https://github.com/git/git/blame/v2.12.0/read-cache.c#L1568-L1629
+ *
+ * This file is licensed under the GPL v2, or a later version at the discretion of Linus.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+struct cache_entry {
+    unsigned int ce_ctime_sec;
+    unsigned int ce_ctime_nsec;
+    unsigned int ce_mtime_sec;
+    unsigned int ce_mtime_nsec;
+    unsigned int ce_dev;
+    unsigned int ce_ino;
+    unsigned int ce_mode;
+    unsigned int ce_uid;
+    unsigned int ce_gid;
+    unsigned int ce_size;
+    unsigned char sha1[21];
+    char namelen;
+    char name[1];
+};
+
+struct index_header {
+    char dirc[4];
+    unsigned int version;
+    unsigned int entries;
+};
+
+static inline unsigned int default_swab32(unsigned int val)
+{
+	return (((val & 0xff000000) >> 24) |
+		((val & 0x00ff0000) >>  8) |
+		((val & 0x0000ff00) <<  8) |
+		((val & 0x000000ff) << 24));
+}
+
+static inline unsigned int bswap32(unsigned int x)
+{
+	unsigned int result;
+	if (__builtin_constant_p(x))
+		result = default_swab32(x);
+	else
+		__asm__("bswap %0" : "=r" (result) : "0" (x));
+	return result;
+}
+
+char *sha1_to_hex(const unsigned char *sha1)
+{
+    static int bufno;
+    static char hexbuffer[4][50];
+    static const char hex[] = "0123456789abcdef";
+    char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
+    int i;
+
+    for (i = 0; i < 20; i++) {
+	unsigned int val = *sha1++;
+	*buf++ = hex[val >> 4];
+	*buf++ = hex[val & 0xf];
+    }
+    *buf = '\0';
+
+    return buffer;
+}
+
+int calc_padding(int n)
+{
+    int floor;
+    int ret, target;
+
+    floor = (int)((n -2) / 8);
+    target = (floor + 1) * 8 + 2;
+    ret = target - n;
+
+    return ret;
+}
+
+int main(int argc, char **argv)
+{
+    char *index_file;
+    struct stat st;
+    int fd;
+    void *map;
+    struct index_header *hdr;
+    struct cache_entry *ce;
+    char *p_next_entry;
+    int count_entries;
+    int i;
+
+    if (argc != 2) {
+	fprintf(stderr, "Usage:prog .git/index\n");
+	exit(1);
+    }
+
+    index_file = argv[1];
+    if (stat(index_file, &st) == -1) {
+	fprintf(stderr, "unable to stat '%s'\n", index_file);
+	exit(1);
+    }
+
+    if ((fd = open(index_file, O_RDONLY)) == -1) {
+	fprintf(stderr, "unable to open file '%s'\n", index_file);
+	exit(1);
+    }
+
+    map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+
+    hdr = map;
+    ce = (struct cache_entry *)(hdr + 1);
+
+    count_entries = bswap32(hdr->entries);
+
+    for (i=0; i < count_entries; i++) {
+	printf("%o %s 0\t%s\n",
+	       bswap32(ce->ce_mode),
+	       sha1_to_hex(ce->sha1),
+	       ce->name
+	    );
+
+	p_next_entry = ce->name + ce->namelen + calc_padding(ce->namelen);
+	ce = (struct cache_entry *)p_next_entry;
+    }
+
+    close(fd);
+    return 0;
+}
\ No newline at end of file