commit 14752f55064548cf20109b388ec6d1900420c7df from: Sergey Bronnikov date: Sun Jul 14 20:38:38 2019 UTC add git examples commit - 5d537aab2400af024f5a0066d68e5d9603a7df45 commit + 14752f55064548cf20109b388ec6d1900420c7df blob - /dev/null blob + 3896c253eb5f72146232f05b5c8cde92fee08342 (mode 644) --- /dev/null +++ libgit-notes.c @@ -0,0 +1,124 @@ +#include +#include + +#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(¬e, 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 +#include +#include +#include +#include +#include +#include + +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