#include "common.h"
#include "git2.h"
static void oid_parsing(git_oid *out);
static void object_database(git_repository *repo, git_oid *oid);
static void commit_writing(git_repository *repo);
static void commit_parsing(git_repository *repo);
static void tag_parsing(git_repository *repo);
static void tree_parsing(git_repository *repo);
static void blob_parsing(git_repository *repo);
static void revwalking(git_repository *repo);
static void index_walking(git_repository *repo);
static void reference_listing(git_repository *repo);
static void config_files(const char *repo_path, git_repository *repo);
static void check_error(int error_code, const char *action)
{
const git_error *error = git_error_last();
if (!error_code)
return;
printf("Error %d %s - %s\n", error_code, action,
(error && error->message) ? error->message : "???");
exit(1);
}
int lg2_general(git_repository *repo, int argc, char** argv)
{
int error;
git_oid oid;
char *repo_path;
git_libgit2_init();
repo_path = (argc > 1) ? argv[1] : "/opt/libgit2-test/.git";
error = git_repository_open(&repo, repo_path);
check_error(error, "opening repository");
oid_parsing(&oid);
object_database(repo, &oid);
commit_writing(repo);
commit_parsing(repo);
tag_parsing(repo);
tree_parsing(repo);
blob_parsing(repo);
revwalking(repo);
index_walking(repo);
reference_listing(repo);
config_files(repo_path, repo);
git_repository_free(repo);
return 0;
}
static void oid_parsing(git_oid *oid)
{
char out[GIT_OID_HEXSZ+1];
char hex[] = "4a202b346bb0fb0db7eff3cffeb3c70babbd2045";
printf("*Hex to Raw*\n");
git_oid_fromstr(oid, hex);
printf("\n*Raw to Hex*\n");
out[GIT_OID_HEXSZ] = '\0';
git_oid_fmt(out, oid);
git_oid_fmt(out, oid);
printf("SHA hex string: %s\n", out);
}
static void object_database(git_repository *repo, git_oid *oid)
{
char oid_hex[GIT_OID_HEXSZ+1] = { 0 };
const unsigned char *data;
const char *str_type;
int error;
git_odb_object *obj;
git_odb *odb;
git_object_t otype;
git_repository_odb(&odb, repo);
printf("\n*Raw Object Read*\n");
error = git_odb_read(&obj, odb, oid);
check_error(error, "finding object in repository");
data = (const unsigned char *)git_odb_object_data(obj);
otype = git_odb_object_type(obj);
str_type = git_object_type2string(otype);
printf("object length and type: %d, %s\nobject data: %s\n",
(int)git_odb_object_size(obj),
str_type, data);
git_odb_object_free(obj);
printf("\n*Raw Object Write*\n");
git_odb_write(oid, odb, "test data", sizeof("test data") - 1, GIT_OBJECT_BLOB);
git_oid_fmt(oid_hex, oid);
printf("Written Object: %s\n", oid_hex);
git_odb_free(odb);
}
static void commit_writing(git_repository *repo)
{
git_oid tree_id, parent_id, commit_id;
git_tree *tree;
git_commit *parent;
git_signature *author, *committer;
char oid_hex[GIT_OID_HEXSZ+1] = { 0 };
printf("\n*Commit Writing*\n");
git_signature_new(&author,
"Scott Chacon", "schacon@gmail.com", 123456789, 60);
git_signature_new(&committer,
"Scott A Chacon", "scott@github.com", 987654321, 90);
git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1");
git_tree_lookup(&tree, repo, &tree_id);
git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
git_commit_lookup(&parent, repo, &parent_id);
git_commit_create_v(
&commit_id,
repo,
NULL,
author,
committer,
NULL,
"example commit",
tree,
1, parent);
git_oid_fmt(oid_hex, &commit_id);
printf("New Commit: %s\n", oid_hex);
git_tree_free(tree);
git_commit_free(parent);
git_signature_free(author);
git_signature_free(committer);
}
static void commit_parsing(git_repository *repo)
{
const git_signature *author, *cmtter;
git_commit *commit, *parent;
git_oid oid;
char oid_hex[GIT_OID_HEXSZ+1];
const char *message;
unsigned int parents, p;
int error;
time_t time;
printf("\n*Commit Parsing*\n");
git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479");
error = git_commit_lookup(&commit, repo, &oid);
check_error(error, "looking up commit");
message = git_commit_message(commit);
author = git_commit_author(commit);
cmtter = git_commit_committer(commit);
time = git_commit_time(commit);
printf("Author: %s (%s)\nCommitter: %s (%s)\nDate: %s\nMessage: %s\n",
author->name, author->email,
cmtter->name, cmtter->email,
ctime(&time), message);
parents = git_commit_parentcount(commit);
for (p = 0;p < parents;p++) {
memset(oid_hex, 0, sizeof(oid_hex));
git_commit_parent(&parent, commit, p);
git_oid_fmt(oid_hex, git_commit_id(parent));
printf("Parent: %s\n", oid_hex);
git_commit_free(parent);
}
git_commit_free(commit);
}
static void tag_parsing(git_repository *repo)
{
git_commit *commit;
git_object_t type;
git_tag *tag;
git_oid oid;
const char *name, *message;
int error;
printf("\n*Tag Parsing*\n");
git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
error = git_tag_lookup(&tag, repo, &oid);
check_error(error, "looking up tag");
git_tag_target((git_object **)&commit, tag);
name = git_tag_name(tag);
type = git_tag_target_type(tag);
message = git_tag_message(tag);
printf("Tag Name: %s\nTag Type: %s\nTag Message: %s\n",
name, git_object_type2string(type), message);
git_commit_free(commit);
git_tag_free(tag);
}
static void tree_parsing(git_repository *repo)
{
const git_tree_entry *entry;
size_t cnt;
git_object *obj;
git_tree *tree;
git_oid oid;
printf("\n*Tree Parsing*\n");
git_oid_fromstr(&oid, "f60079018b664e4e79329a7ef9559c8d9e0378d1");
git_tree_lookup(&tree, repo, &oid);
cnt = git_tree_entrycount(tree);
printf("tree entries: %d\n", (int) cnt);
entry = git_tree_entry_byindex(tree, 0);
printf("Entry name: %s\n", git_tree_entry_name(entry));
entry = git_tree_entry_byname(tree, "README");
git_tree_entry_name(entry);
git_tree_entry_to_object(&obj, repo, entry);
git_object_free(obj);
git_tree_free(tree);
}
static void blob_parsing(git_repository *repo)
{
git_blob *blob;
git_oid oid;
printf("\n*Blob Parsing*\n");
git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08");
git_blob_lookup(&blob, repo, &oid);
printf("Blob Size: %ld\n", (long)git_blob_rawsize(blob));
git_blob_rawcontent(blob);
git_blob_free(blob);
}
static void revwalking(git_repository *repo)
{
const git_signature *cauth;
const char *cmsg;
int error;
git_revwalk *walk;
git_commit *wcommit;
git_oid oid;
printf("\n*Revwalking*\n");
git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
git_revwalk_new(&walk, repo);
git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
git_revwalk_push(walk, &oid);
while ((git_revwalk_next(&oid, walk)) == 0) {
error = git_commit_lookup(&wcommit, repo, &oid);
check_error(error, "looking up commit during revwalk");
cmsg = git_commit_message(wcommit);
cauth = git_commit_author(wcommit);
printf("%s (%s)\n", cmsg, cauth->email);
git_commit_free(wcommit);
}
git_revwalk_free(walk);
}
static void index_walking(git_repository *repo)
{
git_index *index;
size_t i, ecount;
printf("\n*Index Walking*\n");
git_repository_index(&index, repo);
ecount = git_index_entrycount(index);
for (i = 0; i < ecount; ++i) {
const git_index_entry *e = git_index_get_byindex(index, i);
printf("path: %s\n", e->path);
printf("mtime: %d\n", (int)e->mtime.seconds);
printf("fs: %d\n", (int)e->file_size);
}
git_index_free(index);
}
static void reference_listing(git_repository *repo)
{
git_strarray ref_list;
unsigned i;
printf("\n*Reference Listing*\n");
git_reference_list(&ref_list, repo);
for (i = 0; i < ref_list.count; ++i) {
git_reference *ref;
char oid_hex[GIT_OID_HEXSZ+1] = GIT_OID_HEX_ZERO;
const char *refname;
refname = ref_list.strings[i];
git_reference_lookup(&ref, repo, refname);
switch (git_reference_type(ref)) {
case GIT_REFERENCE_DIRECT:
git_oid_fmt(oid_hex, git_reference_target(ref));
printf("%s [%s]\n", refname, oid_hex);
break;
case GIT_REFERENCE_SYMBOLIC:
printf("%s => %s\n", refname, git_reference_symbolic_target(ref));
break;
default:
fprintf(stderr, "Unexpected reference type\n");
exit(1);
}
git_reference_free(ref);
}
git_strarray_free(&ref_list);
}
static void config_files(const char *repo_path, git_repository* repo)
{
const char *email;
char config_path[256];
int32_t autocorrect;
git_config *cfg;
git_config *snap_cfg;
int error_code;
printf("\n*Config Listing*\n");
sprintf(config_path, "%s/config", repo_path);
check_error(git_config_open_ondisk(&cfg, config_path), "opening config");
if (git_config_get_int32(&autocorrect, cfg, "help.autocorrect") == 0)
printf("Autocorrect: %d\n", autocorrect);
check_error(git_repository_config_snapshot(&snap_cfg, repo), "config snapshot");
git_config_get_string(&email, snap_cfg, "user.email");
printf("Email: %s\n", email);
error_code = git_config_get_int32(&autocorrect, cfg, "help.autocorrect");
switch (error_code)
{
case 0:
printf("Autocorrect: %d\n", autocorrect);
break;
case GIT_ENOTFOUND:
printf("Autocorrect: Undefined\n");
break;
default:
check_error(error_code, "get_int32 failed");
}
git_config_free(cfg);
check_error(git_repository_config_snapshot(&snap_cfg, repo), "config snapshot");
error_code = git_config_get_string(&email, snap_cfg, "user.email");
switch (error_code)
{
case 0:
printf("Email: %s\n", email);
break;
case GIT_ENOTFOUND:
printf("Email: Undefined\n");
break;
default:
check_error(error_code, "get_string failed");
}
git_config_free(snap_cfg);
}