Skip to content

Commit

Permalink
Compare buffers in diff example
Browse files Browse the repository at this point in the history
  • Loading branch information
albfan committed Jun 18, 2019
1 parent 89f36f1 commit 93de380
Showing 1 changed file with 128 additions and 30 deletions.
158 changes: 128 additions & 30 deletions examples/diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/

#include "common.h"
#include "buffer.h"

/**
* This example demonstrates the use of the libgit2 diff APIs to
Expand All @@ -25,6 +26,12 @@
* how to do renaming detection and patch formatting.
*/

#ifndef READ_SIZE
#define READ_SIZE 256
#endif

char git_buf__initbuf[1];

static const char *colors[] = {
"\033[m", /* reset */
"\033[1m", /* bold */
Expand Down Expand Up @@ -52,6 +59,7 @@ struct opts {
git_diff_options diffopts;
git_diff_find_options findopts;
int color;
int no_index;
int cache;
int output;
git_diff_format_t format;
Expand All @@ -67,13 +75,70 @@ static int color_printer(
const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*);
static void diff_print_stats(git_diff *diff, struct opts *o);

/*
* Read a file path
*
* path: a file path (char*)
*
* returns char* with the contents of the file (must be freed) or NULL if
* file does not exist or memory allocation failed
*/
char* read_file(const char* path) {
FILE* file;
char* result;
size_t pos = 0;
size_t capacity = READ_SIZE;
char ch;

file = fopen(path, "r");

if (!file) {
return NULL;
}

result = malloc(sizeof(char) * READ_SIZE + 1);

if (result == NULL) {
return NULL;
}

while ((ch = getc(file)) != EOF) {
result[pos++] = ch;

if(pos >= capacity) {
capacity += READ_SIZE;

result = realloc(result, sizeof(char) * capacity + 1);

if(result == NULL) {
return NULL;
}
}
}

fclose(file);

result = realloc(result, sizeof(char) * pos);

if(result == NULL)
return NULL;

result[pos] = '\0';

return result;
}

int lg2_diff(git_repository *repo, int argc, char *argv[])
{
git_tree *t1 = NULL, *t2 = NULL;
git_diff *diff;
git_patch *patch = NULL;
char* file1_str = NULL;
char* file2_str = NULL;

struct opts o = {
GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT,
-1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "."
-1, -1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "."
};

parse_opts(&o, argc, argv);
Expand All @@ -86,49 +151,80 @@ int lg2_diff(git_repository *repo, int argc, char *argv[])
* * <sha1>
* * --cached
* * --nocache (don't use index data in diff at all)
* * --no-index <file1> <file2>
* * nothing
*
* Currently ranged arguments like <sha1>..<sha2> and <sha1>...<sha2>
* are not supported in this example
*/

if (o.treeish1)
treeish_to_tree(&t1, repo, o.treeish1);
if (o.treeish2)
treeish_to_tree(&t2, repo, o.treeish2);
if (o.no_index >= 0) {
if (o.treeish1 && o.treeish2) {
file1_str = read_file(o.treeish1);
if (file1_str == NULL) {
usage("file cannot be readed", o.treeish1);
}
file2_str = read_file(o.treeish2);
if (file2_str == NULL) {
usage("file cannot be readed", o.treeish2);
}
} else {
usage("two files should be provided as arguments", NULL);
}
}

if (t1 && t2)
if (file1_str && file2_str) {
git_buf buf = GIT_BUF_INIT;
check_lg2(
git_diff_tree_to_tree(&diff, repo, t1, t2, &o.diffopts),
"diff trees", NULL);
else if (o.cache != CACHE_NORMAL) {
if (!t1)
treeish_to_tree(&t1, repo, "HEAD");

if (o.cache == CACHE_NONE)
git_patch_from_buffers(&patch, file1_str, strlen(file1_str), o.treeish1, file2_str, strlen(file2_str), o.treeish2, &o.diffopts),
"patch buffers", NULL);
check_lg2(
git_patch_to_buf(&buf, patch),
"patch to buf", NULL);
check_lg2(
git_diff_from_buffer(&diff, buf.ptr, buf.size),
"diff from patch", NULL);
free(file1_str);
free(file2_str);
} else {
if (o.treeish1)
treeish_to_tree(&t1, repo, o.treeish1);
if (o.treeish2)
treeish_to_tree(&t2, repo, o.treeish2);

if (t1 && t2)
check_lg2(
git_diff_tree_to_workdir(&diff, repo, t1, &o.diffopts),
git_diff_tree_to_tree(&diff, repo, t1, t2, &o.diffopts),
"diff trees", NULL);
else if (o.cache != CACHE_NORMAL) {
if (!t1)
treeish_to_tree(&t1, repo, "HEAD");

if (o.cache == CACHE_NONE)
check_lg2(
git_diff_tree_to_workdir(&diff, repo, t1, &o.diffopts),
"diff tree to working directory", NULL);
else
check_lg2(
git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts),
"diff tree to index", NULL);
}
else if (t1)
check_lg2(
git_diff_tree_to_workdir_with_index(&diff, repo, t1, &o.diffopts),
"diff tree to working directory", NULL);
else
check_lg2(
git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts),
"diff tree to index", NULL);
}
else if (t1)
check_lg2(
git_diff_tree_to_workdir_with_index(&diff, repo, t1, &o.diffopts),
"diff tree to working directory", NULL);
else
check_lg2(
git_diff_index_to_workdir(&diff, repo, NULL, &o.diffopts),
"diff index to working directory", NULL);
git_diff_index_to_workdir(&diff, repo, NULL, &o.diffopts),
"diff index to working directory", NULL);

/** Apply rename and copy detection if requested. */
/** Apply rename and copy detection if requested. */

if ((o.findopts.flags & GIT_DIFF_FIND_ALL) != 0)
check_lg2(
git_diff_find_similar(diff, &o.findopts),
"finding renames and copies", NULL);
if ((o.findopts.flags & GIT_DIFF_FIND_ALL) != 0)
check_lg2(
git_diff_find_similar(diff, &o.findopts),
"finding renames and copies", NULL);
}

/** Generate simple output using libgit2 display helper. */

Expand Down Expand Up @@ -238,6 +334,8 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
o->format = GIT_DIFF_FORMAT_RAW;
o->diffopts.id_abbrev = 40;
}
else if (!strcmp(a, "--no-index"))
o->no_index = 0;
else if (!strcmp(a, "--color"))
o->color = 0;
else if (!strcmp(a, "--no-color"))
Expand Down

0 comments on commit 93de380

Please sign in to comment.