Exemplo n.º 1
0
std::vector<std::string> Commit::getAffectedFiles() const {
  git_tree* tree = nullptr;
  git_tree* tree2 = nullptr;
  int error = git_commit_tree(&tree, get());
  throw_on_error(error);
  
  try {
    error = git_commit_tree(&tree2, parent(0).get());
  } catch (GitException e) {
    tree2 = nullptr; // probably initial commit
  }
  git_diff* diff = nullptr;
  git_diff_tree_to_tree(&diff, getRepo(), tree2, tree, 0);  
 
  std::vector<std::string> ret;
  git_diff_foreach(diff,
  [](const git_diff_delta* entry, float progress, void* payload) {
    std::string str = entry->old_file.path;
    ((std::vector<std::string>*)payload)->push_back(str);
    return 0;
  }, nullptr, nullptr, &ret);
  git_tree_free(tree);
  git_tree_free(tree2);
  git_diff_free(diff);
  return ret; 
}
Exemplo n.º 2
0
static int rebase_next_inmemory(
	git_rebase_operation **out,
	git_rebase *rebase)
{
	git_commit *current_commit = NULL, *parent_commit = NULL;
	git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
	git_rebase_operation *operation;
	git_index *index = NULL;
	unsigned int parent_count;
	int error;

	*out = NULL;

	operation = git_array_get(rebase->operations, rebase->current);

	if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
		(error = git_commit_tree(&current_tree, current_commit)) < 0)
		goto done;

	if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
		giterr_set(GITERR_REBASE, "Cannot rebase a merge commit");
		error = -1;
		goto done;
	} else if (parent_count) {
		if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
			(error = git_commit_tree(&parent_tree, parent_commit)) < 0)
			goto done;
	}

	if ((error = git_commit_tree(&head_tree, rebase->last_commit)) < 0 ||
		(error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0)
		goto done;

	if (!rebase->index) {
		rebase->index = index;
		index = NULL;
	} else {
		if ((error = git_index_read_index(rebase->index, index)) < 0)
			goto done;
	}

	*out = operation;

done:
	git_commit_free(current_commit);
	git_commit_free(parent_commit);
	git_tree_free(current_tree);
	git_tree_free(head_tree);
	git_tree_free(parent_tree);
	git_index_free(index);

	return error;
}
Exemplo n.º 3
0
Arquivo: merge.c Projeto: mikeando/agb
void test_core_merge__initialize(void) {
	//TODO: Change this path and IDs - can use the code in
	//      utils/src/get_commit_info to get the tree ids.
	git_repository_open(&repo, REPODIR);

	head_commit = commit_from_ref("branch_a");
	branch_commit = commit_from_ref("branch_b");
	base_commit = commit_from_ref("a_b_merge_base");

	git_commit_tree((git_tree**)&head_tree, head_commit);
	git_commit_tree((git_tree**)&branch_tree, branch_commit);
	git_commit_tree((git_tree**)&base_tree, base_commit);
}
Exemplo n.º 4
0
void test_patch(
	const char *one,
	const char *two,
	const git_diff_options *opts,
	const char *expected)
{
	git_oid id_one, id_two;
	git_index *index = NULL;
	git_commit *commit_one, *commit_two = NULL;
	git_tree *tree_one, *tree_two;
	git_diff *diff;
	git_patch *patch;
	git_buf actual = GIT_BUF_INIT;

	cl_git_pass(git_oid_fromstr(&id_one, one));
	cl_git_pass(git_commit_lookup(&commit_one, repo, &id_one));
	cl_git_pass(git_commit_tree(&tree_one, commit_one));

	if (two) {
		cl_git_pass(git_oid_fromstr(&id_two, two));
		cl_git_pass(git_commit_lookup(&commit_two, repo, &id_two));
		cl_git_pass(git_commit_tree(&tree_two, commit_two));
	} else {
		cl_git_pass(git_repository_index(&index, repo));
		cl_git_pass(git_index_write_tree(&id_two, index));
		cl_git_pass(git_tree_lookup(&tree_two, repo, &id_two));
	}

	cl_git_pass(git_diff_tree_to_tree(&diff, repo, tree_one, tree_two, opts));

	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
	cl_git_pass(git_patch_to_buf(&actual, patch));

	cl_assert_equal_s(expected, actual.ptr);

	git_buf_clear(&actual);
	cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual));

	cl_assert_equal_s(expected, actual.ptr);

	git_buf_dispose(&actual);
	git_patch_free(patch);
	git_diff_free(diff);
	git_tree_free(tree_one);
	git_tree_free(tree_two);
	git_commit_free(commit_one);
	git_commit_free(commit_two);
	git_index_free(index);
}
Exemplo n.º 5
0
void Commit::buildTree()
{
    git_tree *gitTree;
    gitTest(git_commit_tree (&gitTree, commit));

    commitTree = new Tree (repo, gitTree);
}
Exemplo n.º 6
0
// ReadTree is/must only be executed on an empty list
int CGitHeadFileList::ReadTree()
{
	CAutoWriteLock lock(m_SharedMutex);
	ATLASSERT(empty());

	CAutoRepository repository(m_Gitdir);
	CAutoCommit commit;
	CAutoTree tree;
	bool ret = repository;
	ret = ret && !git_commit_lookup(commit.GetPointer(), repository, (const git_oid*)m_Head.m_hash);
	ret = ret && !git_commit_tree(tree.GetPointer(), commit);
	try
	{
		ret = ret && !ReadTreeRecursive(*repository, tree, "", CGitHeadFileList::CallBack, this);
	}
	catch (const std::bad_alloc& ex)
	{
		CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Catched exception inside ReadTreeRecursive: %s\n", ex.what());
		return -1;
	}
	if (!ret)
	{
		clear();
		m_LastModifyTimeHead = 0;
		return -1;
	}

	std::sort(this->begin(), this->end(), SortTree);
	m_TreeHash = git_commit_id(commit)->id;

	return 0;
}
Exemplo n.º 7
0
PyObject *
Commit_tree__get__(Commit *commit)
{
    git_tree *tree;
    Tree *py_tree;
    int err;

    err = git_commit_tree(&tree, commit->commit);
    if (err == GIT_ENOTFOUND) {
        char tree_id[GIT_OID_HEXSZ + 1] = { 0 };
        git_oid_fmt(tree_id, git_commit_tree_id(commit->commit));
        return PyErr_Format(GitError, "Unable to read tree %s", tree_id);
    }

    if (err < 0)
        return Error_set(err);

    py_tree = PyObject_New(Tree, &TreeType);
    if (py_tree) {
        Py_INCREF(commit->repo);
        py_tree->repo = commit->repo;
        py_tree->tree = (git_tree*)tree;
    }
    return (PyObject*)py_tree;
}
Exemplo n.º 8
0
static void execute_test(void)
{
	git_oid oid, check;
	git_commit *commit;
	git_tree *tree;
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;

	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/branch1"));
	cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
	cl_git_pass(git_commit_tree(&tree, commit));

	opts.checkout_strategy = GIT_CHECKOUT_SAFE;

	cl_git_pass(git_checkout_tree(g_repo, (git_object *)tree, &opts));

	git_tree_free(tree);
	git_commit_free(commit);

	/* Verify that the lenna.jpg file was checked out correctly */
	cl_git_pass(git_oid_fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1"));
	cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJ_BLOB));
	cl_assert(git_oid_equal(&oid, &check));

	/* Verify that the text file was checked out correctly */
	cl_git_pass(git_oid_fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a"));
	cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJ_BLOB));
	cl_assert(git_oid_equal(&oid, &check));
}
Exemplo n.º 9
0
Arquivo: git.c Projeto: ileitch/meanie
static int mne_git_get_tag_tree(git_tree **tag_tree, git_reference **tag_ref, const char *ref_name) {
  int err = git_reference_lookup(tag_ref, repo, ref_name);
  mne_check_error("git_reference_lookup()", err, __FILE__, __LINE__);

  const git_oid *tag_oid = git_reference_oid(*tag_ref);
  assert(tag_oid != NULL);

  git_tag *tag;
  err = git_tag_lookup(&tag, repo, tag_oid);
  const git_oid *tag_commit_oid;

  if (err == GIT_ENOTFOUND) {
    /* Not a tag, must be a commit. */
    tag_commit_oid = tag_oid;
  } else {
    err = mne_git_get_tag_commit_oid(&tag_commit_oid, tag);
    git_tag_free(tag);
    if (err != GIT_OK)
      return err;
  }

  git_commit *tag_commit;
  err = git_commit_lookup(&tag_commit, repo, tag_commit_oid);
  mne_check_error("git_commit_lookup()", err, __FILE__, __LINE__);

  err = git_commit_tree(tag_tree, tag_commit);
  mne_check_error("git_commit_tree()", err, __FILE__, __LINE__);

  git_commit_free(tag_commit);

  return MNE_GIT_OK;
}
Exemplo n.º 10
0
void test_diff_binary__empty_for_no_diff(void)
{
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_oid id;
	git_commit *commit;
	git_tree *tree;
	git_diff *diff;
	git_buf actual = GIT_BUF_INIT;

	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
	opts.id_abbrev = GIT_OID_HEXSZ;

	repo = cl_git_sandbox_init("renames");

	cl_git_pass(git_oid_fromstr(&id, "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13"));
	cl_git_pass(git_commit_lookup(&commit, repo, &id));
	cl_git_pass(git_commit_tree(&tree, commit));

	cl_git_pass(git_diff_tree_to_tree(&diff, repo, tree, tree, &opts));
	cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual));

	cl_assert_equal_s("", actual.ptr);

	git_buf_dispose(&actual);
	git_diff_free(diff);
	git_commit_free(commit);
	git_tree_free(tree);
}
Exemplo n.º 11
0
int git_cherry_pick_commit(
    git_index **out,
    git_repository *repo,
    git_commit *cherry_pick_commit,
    git_commit *our_commit,
    unsigned int mainline,
    const git_merge_options *merge_opts)
{
    git_commit *parent_commit = NULL;
    git_tree *parent_tree = NULL, *our_tree = NULL, *cherry_pick_tree = NULL;
    int parent = 0, error = 0;

    assert(out && repo && cherry_pick_commit && our_commit);

    if (git_commit_parentcount(cherry_pick_commit) > 1) {
        if (!mainline)
            return cherry_pick_seterr(cherry_pick_commit,
                                      "Mainline branch is not specified but %s is a merge commit");

        parent = mainline;
    } else {
        if (mainline)
            return cherry_pick_seterr(cherry_pick_commit,
                                      "Mainline branch specified but %s is not a merge commit");

        parent = git_commit_parentcount(cherry_pick_commit);
    }

    if (parent &&
            ((error = git_commit_parent(&parent_commit, cherry_pick_commit, (parent - 1))) < 0 ||
             (error = git_commit_tree(&parent_tree, parent_commit)) < 0))
        goto done;

    if ((error = git_commit_tree(&cherry_pick_tree, cherry_pick_commit)) < 0 ||
            (error = git_commit_tree(&our_tree, our_commit)) < 0)
        goto done;

    error = git_merge_trees(out, repo, parent_tree, our_tree, cherry_pick_tree, merge_opts);

done:
    git_tree_free(parent_tree);
    git_tree_free(our_tree);
    git_tree_free(cherry_pick_tree);
    git_commit_free(parent_commit);

    return error;
}
Exemplo n.º 12
0
Diff::Diff(const Commit& comm, const Commit& comm2) {
  git_tree *commit_tree = nullptr, *parent_tree = nullptr;
  int error = 0;
  error = git_commit_tree(&commit_tree, comm.get());
  throw_on_error(error);
  error = git_commit_tree(&parent_tree, comm2.get());
  throw_on_error(error);

  git_diff *d = nullptr;
  error = git_diff_tree_to_tree(
            &d, comm.getRepo(), commit_tree, parent_tree, nullptr);
  throw_on_error(error);
  // TODO: Make this exception safe
  git_tree_free(commit_tree);
  git_tree_free(parent_tree);
  diff = std::shared_ptr<git_diff>(d, git_diff_free);
}
Exemplo n.º 13
0
Arquivo: git.c Projeto: entropia/tuerd
static int read_file_git(const char *repo_path, const char *name, void **out, size_t *outlen) {
    int ret, retcode = -1;

    git_repository *repo;
    ret = git_repository_open_bare(&repo, repo_path);
    if(check_lg2(ret, "opening repo"))
        goto out;

    git_object *master;
    ret = git_revparse_single(&master, repo, "master");
    if(check_lg2(ret, "getting master branch"))
        goto out_repo;

    if(git_object_type(master) != GIT_OBJ_COMMIT) {
        debug("master is not a commit");
        goto out_master;
    }

    git_tree *tree;
    ret = git_commit_tree(&tree, (git_commit*)master);
    if(check_lg2(ret, "getting tree from commit"))
        goto out_master;

    const git_tree_entry *entry = git_tree_entry_byname(tree, name);
    if(!entry) {
        debug("entry %s not found", name);
        goto out_tree;
    }

    if(git_tree_entry_type(entry) != GIT_OBJ_BLOB) {
        debug("entry is not a blob");
        goto out_tree;
    }

    git_object *file;
    ret = git_tree_entry_to_object(&file, repo, entry);
    if(check_lg2(ret, "getting file from tree entry"))
        goto out_tree;

    const void *data = git_blob_rawcontent((git_blob*)file);
    *outlen = git_blob_rawsize((git_blob*)file);

    *out = malloc(*outlen);
    memcpy(*out, data, *outlen);

    retcode = 0;

    git_object_free(file);
out_tree:
    git_tree_free(tree);
out_master:
    git_object_free(master);
out_repo:
    git_repository_free(repo);
out:
    return retcode;
}
Exemplo n.º 14
0
static VALUE rb_git_commit_tree_GET(VALUE self)
{
    git_commit *commit;
    const git_tree *tree;
    Data_Get_Struct(self, git_commit, commit);

    tree = git_commit_tree(commit);
    return tree ? rugged_object_c2rb((git_object *)tree) : Qnil;
}
Exemplo n.º 15
0
int merge_trees_from_branches(
	git_index **index, git_repository *repo,
	const char *ours_name, const char *theirs_name,
	git_merge_tree_opts *opts)
{
	git_commit *our_commit, *their_commit, *ancestor_commit = NULL;
	git_tree *our_tree, *their_tree, *ancestor_tree = NULL;
	git_oid our_oid, their_oid, ancestor_oid;
	git_buf branch_buf = GIT_BUF_INIT;
	int error;

	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name);
	cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr));
	cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid));

	git_buf_clear(&branch_buf);
	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name);
	cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr));
	cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid));

	error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit));

	if (error != GIT_ENOTFOUND) {
		cl_git_pass(error);

		cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid));
		cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit));
	}

	cl_git_pass(git_commit_tree(&our_tree, our_commit));
	cl_git_pass(git_commit_tree(&their_tree, their_commit));

	cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts));

	git_buf_free(&branch_buf);
	git_tree_free(our_tree);
	git_tree_free(their_tree);
	git_tree_free(ancestor_tree);
	git_commit_free(our_commit);
	git_commit_free(their_commit);
	git_commit_free(ancestor_commit);

	return 0;
}
Exemplo n.º 16
0
static VALUE rb_git_commit_tree_GET(VALUE self)
{
	git_commit *commit;
	const git_tree *tree;
	VALUE owner;

	RUGGED_OBJ_UNWRAP(self, git_commit, commit);
	RUGGED_OBJ_OWNER(self, owner);

	tree = git_commit_tree(commit);
	return tree ? rugged_object_new(owner, (git_object *)tree) : Qnil;
}
Exemplo n.º 17
0
void test_apply_both__generated_diff(void)
{
	git_oid a_oid, b_oid;
	git_commit *a_commit, *b_commit;
	git_tree *a_tree, *b_tree;
	git_diff *diff;
	git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;

	struct merge_index_entry both_expected[] = {
		{ 0100644, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", 0, "asparagus.txt" },
		{ 0100644, "68f6182f4c85d39e1309d97c7e456156dc9c0096", 0, "beef.txt" },
		{ 0100644, "4b7c5650008b2e747fe1809eeb5a1dde0e80850a", 0, "bouilli.txt" },
		{ 0100644, "c4e6cca3ec6ae0148ed231f97257df8c311e015f", 0, "gravy.txt" },
		{ 0100644, "68af1fc7407fd9addf1701a87eb1c95c7494c598", 0, "oyster.txt" },
		{ 0100644, "a7b066537e6be7109abfe4ff97b675d4e077da20", 0, "veal.txt" },
	};
	size_t both_expected_cnt = sizeof(both_expected) /
		sizeof(struct merge_index_entry);

	git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707");
	git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f");
	cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
	cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid));

	cl_git_pass(git_commit_tree(&a_tree, a_commit));
	cl_git_pass(git_commit_tree(&b_tree, b_commit));

	cl_git_pass(git_diff_tree_to_tree(&diff, repo, a_tree, b_tree, &diff_opts));
	cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));

	validate_apply_index(repo, both_expected, both_expected_cnt);
	validate_apply_workdir(repo, both_expected, both_expected_cnt);

	git_diff_free(diff);
	git_tree_free(a_tree);
	git_tree_free(b_tree);
	git_commit_free(a_commit);
	git_commit_free(b_commit);
}
Exemplo n.º 18
0
Arquivo: stash.c Projeto: aep/libgit2
static int build_untracked_tree(
	git_tree **tree_out,
	git_index *index,
	git_commit *i_commit,
	uint32_t flags)
{
	git_tree *i_tree = NULL;
	git_diff_list *diff = NULL;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	struct cb_data data = {0};
	int error;

	git_index_clear(index);

	data.index = index;

	if (flags & GIT_STASH_INCLUDE_UNTRACKED) {
		opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED |
			GIT_DIFF_RECURSE_UNTRACKED_DIRS;
		data.include_untracked = true;
	}

	if (flags & GIT_STASH_INCLUDE_IGNORED) {
		opts.flags |= GIT_DIFF_INCLUDE_IGNORED;
		data.include_ignored = true;
	}

	if ((error = git_commit_tree(&i_tree, i_commit)) < 0)
		goto cleanup;

	if ((error = git_diff_tree_to_workdir(
			&diff, git_index_owner(index), i_tree, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_foreach(
			diff, update_index_cb, NULL, NULL, &data)) < 0)
	{
		if (error == GIT_EUSER)
			error = data.error;
		goto cleanup;
	}

	error = build_tree_from_index(tree_out, index);

cleanup:
	git_diff_list_free(diff);
	git_tree_free(i_tree);
	return error;
}
Exemplo n.º 19
0
// ReadTree is/must only be executed on an empty list
int CGitHeadFileList::ReadTree()
{
    CAutoWriteLock lock(&m_SharedMutex);
    CStringA gitdir = CUnicodeUtils::GetMulti(m_Gitdir, CP_UTF8);
    git_repository *repository = NULL;
    git_commit *commit = NULL;
    git_tree * tree = NULL;
    int ret = 0;
    ATLASSERT(this->empty());
    do
    {
        ret = git_repository_open(&repository, gitdir);
        if(ret)
            break;
        ret = git_commit_lookup(&commit, repository, (const git_oid*)m_Head.m_hash);
        if(ret)
            break;

        ret = git_commit_tree(&tree, commit);
        if(ret)
            break;

        ret = ReadTreeRecursive(*repository, tree,"", CGitHeadFileList::CallBack,this);
        if(ret)
            break;

        std::sort(this->begin(), this->end(), SortTree);
        this->m_TreeHash = (char*)(git_commit_id(commit)->id);

    } while(0);

    if (tree)
        git_tree_free(tree);

    if (commit)
        git_commit_free(commit);

    if (repository)
        git_repository_free(repository);

    if (ret)
    {
        clear();
        m_LastModifyTimeHead = 0;
    }

    return ret;

}
Exemplo n.º 20
0
/*
 *  call-seq:
 *    commit.tree -> tree
 *
 *  Return the tree pointed at by this +commit+. The tree is
 *  returned as a +Rugged::Tree+ object.
 *
 *    commit.tree #=> #<Rugged::Tree:0x10882c680>
 */
static VALUE rb_git_commit_tree_GET(VALUE self)
{
	git_commit *commit;
	git_tree *tree;
	VALUE owner;
	int error;

	Data_Get_Struct(self, git_commit, commit);
	owner = rugged_owner(self);

	error = git_commit_tree(&tree, commit);
	rugged_exception_check(error);

	return rugged_object_new(owner, (git_object *)tree);
}
Exemplo n.º 21
0
/* Helper to find how many files in a commit changed from its nth parent. */
static int match_with_parent(git_commit *commit, int i, git_diff_options *opts)
{
	git_commit *parent;
	git_tree *a, *b;
	git_diff *diff;
	int ndeltas;

	check_lg2(
		git_commit_parent(&parent, commit, (size_t)i), "Get parent", NULL);
	check_lg2(git_commit_tree(&a, parent), "Tree for parent", NULL);
	check_lg2(git_commit_tree(&b, commit), "Tree for commit", NULL);
	check_lg2(
		git_diff_tree_to_tree(&diff, git_commit_owner(commit), a, b, opts),
		"Checking diff between parent and commit", NULL);

	ndeltas = (int)git_diff_num_deltas(diff);

        git_diff_free(diff);
        git_tree_free(a);
        git_tree_free(b);
        git_commit_free(parent);

        return ndeltas > 0;
}
Exemplo n.º 22
0
Arquivo: commit.c Projeto: jwes/luagi
int luagi_commit_tree( lua_State *L )
{
   git_commit** commit = checkcommit( L );
   git_tree** tree = (git_tree**) lua_newuserdata( L, sizeof( git_tree* ) );
   int ret = git_commit_tree( tree, *commit);
   if( ret != 0 )
   {
      lua_pushnil( L );
      lua_pushfstring( L, "can't find tree %d", ret );
      return 2;
   }

   ltk_setmetatable( L, LUAGI_TREE_FUNCS );
   return 1;
}
Exemplo n.º 23
0
/* Helper to get the latest commit of the specified file */
int git_show_last_commit(char *filename)
{
        git_oid oid;
        git_commit *commit = NULL;

        /* Set up pathspec. */
        git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
        diffopts.pathspec.strings = &filename;
        diffopts.pathspec.count = 1;

        /* Use the revwalker to traverse the history. */
        check_lg2(git_revwalk_push_ref(s.walker, s.ref),
                        "Could not find repository reference", NULL);

        for (; !git_revwalk_next(&oid, s.walker); git_commit_free(commit)) {
                check_lg2(git_commit_lookup(&commit, s.repo, &oid),
                                "Failed to look up commit", NULL);

                int parents = (int)git_commit_parentcount(commit);
                int unmatched = parents;
                if (parents == 0) {
                        git_tree *tree;
                        git_pathspec *ps;
                        check_lg2(git_commit_tree(&tree, commit), "Get tree", NULL);
                        check_lg2(git_pathspec_new(&ps, &diffopts.pathspec),
                                        "Building pathspec", NULL);
                        if (git_pathspec_match_tree(
                                                NULL, tree, GIT_PATHSPEC_NO_MATCH_ERROR, ps) != 0)
                                unmatched = 1;
                        git_pathspec_free(ps);
                        git_tree_free(tree);
                } else {
                        int i;
                        for (i = 0; i < parents; ++i) {
                                if (match_with_parent(commit, i, &diffopts))
                                        unmatched--;
                        }
                }
                if (unmatched > 0)
                        continue;

                print_commit(commit);
                git_commit_free(commit);
                break;
        }
        git_revwalk_reset(s.walker);
        return 0;
}
Exemplo n.º 24
0
static void fill_index_wth_head_entries(git_repository *repo, git_index *index)
{
	git_oid oid;
	git_commit *commit;
	git_tree *tree;

	cl_git_pass(git_reference_name_to_oid(&oid, repo, "HEAD"));
	cl_git_pass(git_commit_lookup(&commit, repo, &oid));
	cl_git_pass(git_commit_tree(&tree, commit));

	cl_git_pass(git_index_read_tree(index, tree));
	cl_git_pass(git_index_write(index));

	git_tree_free(tree);
	git_commit_free(commit);
}
Exemplo n.º 25
0
/**
 * Get the tree pointed to by a commit
 *
 * @param commit S4 class git_commit or git_stash
 * @return S4 class git_tree
 */
SEXP git2r_commit_tree(SEXP commit)
{
    int err;
    SEXP result = R_NilValue;
    SEXP repo;
    git_commit *commit_obj = NULL;
    git_repository *repository = NULL;
    git_tree *tree = NULL;

    if (git2r_arg_check_commit(commit))
        git2r_error(git2r_err_commit_arg, __func__, "commit");

    repo = GET_SLOT(commit, Rf_install("repo"));
    repository = git2r_repository_open(repo);
    if (!repository)
        git2r_error(git2r_err_invalid_repository, __func__, NULL);

    err = git2r_commit_lookup(&commit_obj, repository, commit);
    if (GIT_OK != err)
        goto cleanup;

    err = git_commit_tree(&tree, commit_obj);
    if (GIT_OK != err)
        goto cleanup;

    PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tree")));
    git2r_tree_init((git_tree*)tree, repo, result);

cleanup:
    if (commit_obj)
        git_commit_free(commit_obj);

    if (tree)
        git_tree_free(tree);

    if (repository)
        git_repository_free(repository);

    if (R_NilValue != result)
        UNPROTECT(1);

    if (GIT_OK != err)
        git2r_error(git2r_err_from_libgit2, __func__, giterr_last()->message);

    return result;
}
Exemplo n.º 26
0
Arquivo: stash.c Projeto: aep/libgit2
static int build_workdir_tree(
	git_tree **tree_out,
	git_index *index,
	git_commit *b_commit)
{
	git_repository *repo = git_index_owner(index);
	git_tree *b_tree = NULL;
	git_diff_list *diff = NULL, *diff2 = NULL;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	struct cb_data data = {0};
	int error;

	if ((error = git_commit_tree(&b_tree, b_commit)) < 0)
		goto cleanup;

	if ((error = git_diff_tree_to_index(&diff, repo, b_tree, NULL, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_index_to_workdir(&diff2, repo, NULL, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_merge(diff, diff2)) < 0)
		goto cleanup;

	data.index = index;
	data.include_changed = true;

	if ((error = git_diff_foreach(
			diff, update_index_cb, NULL, NULL, &data)) < 0)
	{
		if (error == GIT_EUSER)
			error = data.error;
		goto cleanup;
	}


	if ((error = build_tree_from_index(tree_out, index)) < 0)
		goto cleanup;

cleanup:
	git_diff_list_free(diff);
	git_diff_list_free(diff2);
	git_tree_free(b_tree);

	return error;
}
Exemplo n.º 27
0
/*
 *  call-seq:
 *    index.diff([options]) -> diff
 *    index.diff(diffable[, options]) -> diff
 *
 *  The first form returns a diff between the index and the current working
 *  directory.
 *
 *  The second form returns a diff between the index and the given diffable object.
 *  +diffable+ can either be a +Rugged::Commit+ or a +Rugged::Tree+.
 *
 *  The index will be used as the "old file" side of the diff, while the working
 *  directory or the +diffable+ will be used for the "new file" side.
 *
 *  The following options can be passed in the +options+ Hash:
 *
 *  :paths ::
 *    An array of paths / fnmatch patterns to constrain the diff to a specific
 *    set of files. Also see +:disable_pathspec_match+.
 *
 *  :max_size ::
 *    An integer specifying the maximum byte size of a file before a it will
 *    be treated as binary. The default value is 512MB.
 *
 *  :context_lines ::
 *    The number of unchanged lines that define the boundary of a hunk (and
 *    to display before and after the actual changes). The default is 3.
 *
 *  :interhunk_lines ::
 *    The maximum number of unchanged lines between hunk boundaries before the hunks
 *    will be merged into a one. The default is 0.
 *
 *  :reverse ::
 *    If true, the sides of the diff will be reversed.
 *
 *  :force_text ::
 *    If true, all files will be treated as text, disabling binary attributes & detection.
 *
 *  :ignore_whitespace ::
 *    If true, all whitespace will be ignored.
 *
 *  :ignore_whitespace_change ::
 *    If true, changes in amount of whitespace will be ignored.
 *
 *  :ignore_whitespace_eol ::
 *    If true, whitespace at end of line will be ignored.
 *
 *  :ignore_submodules ::
 *    if true, submodules will be excluded from the diff completely.
 *
 *  :patience ::
 *    If true, the "patience diff" algorithm will be used (currenlty unimplemented).
 *
 *  :include_ignored ::
 *    If true, ignored files will be included in the diff.
 *
 *  :include_untracked ::
 *   If true, untracked files will be included in the diff.
 *
 *  :include_unmodified ::
 *    If true, unmodified files will be included in the diff.
 *
 *  :recurse_untracked_dirs ::
 *    Even if +:include_untracked+ is true, untracked directories will only be
 *    marked with a single entry in the diff. If this flag is set to true,
 *    all files under ignored directories will be included in the diff, too.
 *
 *  :disable_pathspec_match ::
 *    If true, the given +:paths+ will be applied as exact matches, instead of
 *    as fnmatch patterns.
 *
 *  :deltas_are_icase ::
 *    If true, filename comparisons will be made with case-insensitivity.
 *
 *  :include_untracked_content ::
 *    if true, untracked content will be contained in the the diff patch text.
 *
 *  :skip_binary_check ::
 *    If true, diff deltas will be generated without spending time on binary
 *    detection. This is useful to improve performance in cases where the actual
 *    file content difference is not needed.
 *
 *  :include_typechange ::
 *    If true, type changes for files will not be interpreted as deletion of
 *    the "old file" and addition of the "new file", but will generate
 *    typechange records.
 *
 *  :include_typechange_trees ::
 *    Even if +:include_typechange+ is true, blob -> tree changes will still
 *    usually be handled as a deletion of the blob. If this flag is set to true,
 *    blob -> tree changes will be marked as typechanges.
 *
 *  :ignore_filemode ::
 *    If true, file mode changes will be ignored.
 *
 *  :recurse_ignored_dirs ::
 *    Even if +:include_ignored+ is true, ignored directories will only be
 *    marked with a single entry in the diff. If this flag is set to true,
 *    all files under ignored directories will be included in the diff, too.
 */
static VALUE rb_git_index_diff(int argc, VALUE *argv, VALUE self)
{
	git_index *index;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_repository *repo;
	git_diff *diff = NULL;
	VALUE owner, rb_other, rb_options;
	int error;

	rb_scan_args(argc, argv, "01:", &rb_other, &rb_options);
	rugged_parse_diff_options(&opts, rb_options);

	Data_Get_Struct(self, git_index, index);
	owner = rugged_owner(self);
	Data_Get_Struct(owner, git_repository, repo);

	if (NIL_P(rb_other)) {
		error = git_diff_index_to_workdir(&diff, repo, index, &opts);
	} else {
		// Need to flip the reverse option, so that the index is by default
		// the "old file" side of the diff.
		opts.flags ^= GIT_DIFF_REVERSE;

		if (rb_obj_is_kind_of(rb_other, rb_cRuggedCommit)) {
			git_tree *other_tree;
			git_commit *commit;
			Data_Get_Struct(rb_other, git_commit, commit);
			error = git_commit_tree(&other_tree, commit);

			if (!error)
				error = git_diff_tree_to_index(&diff, repo, other_tree, index, &opts);
		} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedTree)) {
			git_tree *other_tree;
			Data_Get_Struct(rb_other, git_tree, other_tree);
			error = git_diff_tree_to_index(&diff, repo, other_tree, index, &opts);
		} else {
			xfree(opts.pathspec.strings);
			rb_raise(rb_eTypeError, "A Rugged::Commit or Rugged::Tree instance is required");
		}
	}

	xfree(opts.pathspec.strings);
	rugged_exception_check(error);

	return rugged_diff_new(rb_cRuggedDiff, owner, diff);
}
Exemplo n.º 28
0
void test_object_tree_read__largefile(void)
{
	git_reference *ref;
	git_commit *commit;
	git_tree *tree;
	git_oid oid;
	const git_tree_entry *entry;
	git_object *object;
	git_buf file = GIT_BUF_INIT;
	int fd;
	git_index *idx;

	if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE"))
		cl_skip();

	cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/master"));
	cl_git_pass(git_repository_index(&idx, g_repo));

	cl_git_pass(git_buf_puts(&file, git_repository_workdir(g_repo)));
	cl_git_pass(git_buf_joinpath(&file, file.ptr, BIGFILE));

	fd = p_open(git_buf_cstr(&file), O_CREAT|O_RDWR, 0644);
	cl_assert_(fd >= 0, "invalid file descriptor");

	cl_must_pass(p_fallocate(fd, 0, BIGFILE_SIZE));
	cl_must_pass(p_close(fd));

	cl_git_pass(git_index_add_bypath(idx, BIGFILE));
	cl_repo_commit_from_index(&oid, g_repo, NULL, 0, "bigfile");

	cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
	cl_git_pass(git_commit_tree(&tree, commit));

	entry = git_tree_entry_byname(tree, BIGFILE);
	cl_assert_(entry, "entry was NULL");

	cl_git_pass(git_tree_entry_to_object(&object, g_repo, entry));

	git_buf_dispose(&file);
	git_object_free(object);
	git_tree_free(tree);
	git_index_free(idx);
	git_commit_free(commit);
	git_reference_free(ref);
}
Exemplo n.º 29
0
static int do_git_load(git_repository *repo, const char *branch)
{
	int ret;
	git_object *object;
	git_commit *commit;
	git_tree *tree;

	ret = find_commit(repo, branch, &commit);
	if (ret)
		return ret;
	if (git_commit_tree(&tree, commit))
		return report_error("Could not look up tree of commit in branch '%s'", branch);
	ret = load_dives_from_tree(repo, tree);
	if (!ret)
		set_git_id(git_commit_id(commit));
	git_object_free((git_object *)tree);
	return ret;
}
Exemplo n.º 30
0
int CGitHeadFileList::ReadTree()
{
	CStringA gitdir = CUnicodeUtils::GetMulti(m_Gitdir,CP_ACP) ;
	gitdir += "\\.git";
	git_repository *repository = NULL;
	git_commit *commit = NULL;
	git_tree * tree = NULL;
	int ret = 0;
	this->clear(); // hack to avoid duplicates in the head list, which are introduced in GitStatus::GetFileStatus when this method is called
	do
	{
		ret = git_repository_open(&repository, gitdir.GetBuffer());
		if(ret)
			break;
		ret = git_commit_lookup(&commit, repository, (const git_oid*)m_Head.m_hash);
		if(ret)
			break;

		ret = git_commit_tree(&tree, commit);
		if(ret)
			break;

		ret = ReadTreeRecursive(*repository, tree,"", CGitHeadFileList::CallBack,this);
		if(ret)
			break;

		std::sort(this->begin(), this->end(), SortTree);
		this->m_TreeHash = (char*)(git_commit_id(commit)->id);

	} while(0);

	if (tree)
		git_tree_free(tree);

	if (commit)
		git_commit_free(commit);

	if (repository)
		git_repository_free(repository);

	return ret;

}