コード例 #1
0
ファイル: git2r_commit.c プロジェクト: CODECOMMUNITY/git2r
/**
 * Retrieve parents of the commit under construction
 *
 * @param parents The vector of parents to create and populate.
 * @param n_parents The length of parents vector
 * @param repository The repository
 * @return 0 on succes, or error code
 */
static int git2r_retrieve_parents(
    git_commit ***parents,
    size_t *n_parents,
    git_repository *repository)
{
    int err;
    git_oid oid;
    git2r_merge_head_cb_data cb_data = {0, NULL, NULL};
    git_repository_state_t state;

    err = git_repository_head_unborn(repository);
    if (1 == err) {
        *n_parents = 0;
        return GIT_OK;
    } else if (0 != err) {
        return err;
    }

    state = git_repository_state(repository);
    if (state == GIT_REPOSITORY_STATE_MERGE) {
        /* Count number of merge heads */
        err = git_repository_mergehead_foreach(
            repository,
            git2r_repository_mergehead_foreach_cb,
            &cb_data);
        if (GIT_OK != err)
            return err;
    }

    *parents = calloc(cb_data.n + 1, sizeof(git_commit*));
    if (!parents) {
        giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer);
        return GIT_ERROR;
    }
    *n_parents = cb_data.n + 1;

    err = git_reference_name_to_id(&oid, repository, "HEAD");
    if (GIT_OK != err)
        return err;

    err = git_commit_lookup(&**parents, repository, &oid);
    if (GIT_OK != err)
        return err;

    if (state == GIT_REPOSITORY_STATE_MERGE) {
        /* Append merge heads to parents */
        cb_data.n = 0;
        cb_data.repository = repository;
        cb_data.parents = *parents + 1;
        err = git_repository_mergehead_foreach(
            repository,
            git2r_repository_mergehead_foreach_cb,
            &cb_data);
        if (GIT_OK != err)
            return err;
    }

    return GIT_OK;
}
コード例 #2
0
ファイル: repository.c プロジェクト: cjwatson/pygit2
PyObject *
Repository_head_is_unborn__get__(Repository *self)
{
    if (git_repository_head_unborn(self->repo) > 0)
        Py_RETURN_TRUE;

    Py_RETURN_FALSE;
}
コード例 #3
0
ファイル: head.c プロジェクト: CodeSmithyIDE/libgit2
void test_repo_head__unborn_head(void)
{
	git_reference *ref;

	cl_git_pass(git_repository_head_detached(repo));

	make_head_unborn(repo, NON_EXISTING_HEAD);

	cl_assert(git_repository_head_unborn(repo) == 1);


	/* take the repo back to it's original state */
	cl_git_pass(git_reference_symbolic_create(&ref, repo, "HEAD", "refs/heads/master", 1, NULL));
	cl_assert(git_repository_head_unborn(repo) == 0);

	git_reference_free(ref);
}
コード例 #4
0
ファイル: nonetwork.c プロジェクト: benqian/repobuild
void test_clone_nonetwork__can_checkout_given_branch(void)
{
	g_options.checkout_branch = "test";
	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));

	cl_assert_equal_i(0, git_repository_head_unborn(g_repo));

	cl_git_pass(git_repository_head(&g_ref, g_repo));
	cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test");
}
コード例 #5
0
void test_network_remote_defaultbranch__unborn_HEAD_with_branches(void)
{
    git_reference *ref;
    git_repository *cloned_repo;

    cl_git_pass(git_reference_symbolic_create(&ref, g_repo_a, "HEAD", "refs/heads/i-dont-exist", 1, NULL, NULL));
    git_reference_free(ref);

    cl_git_pass(git_clone(&cloned_repo, git_repository_path(g_repo_a), "./semi-empty", NULL));

    cl_assert(git_repository_head_unborn(cloned_repo));

    git_repository_free(cloned_repo);
}
コード例 #6
0
ファイル: clone.c プロジェクト: RsrchBoy/p5-Git-Raw
void test_online_clone__empty_repository(void)
{
	git_reference *head;

	cl_git_pass(git_clone(&g_repo, LIVE_EMPTYREPO_URL, "./foo", &g_options));

	cl_assert_equal_i(true, git_repository_is_empty(g_repo));
	cl_assert_equal_i(true, git_repository_head_unborn(g_repo));

	cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE));
	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));

	git_reference_free(head);
}
コード例 #7
0
ファイル: clone.c プロジェクト: benqian/repobuild
static bool should_checkout(
	git_repository *repo,
	bool is_bare,
	const git_checkout_opts *opts)
{
	if (is_bare)
		return false;

	if (!opts)
		return false;

	if (opts->checkout_strategy == GIT_CHECKOUT_NONE)
		return false;

	return !git_repository_head_unborn(repo);
}
コード例 #8
0
int CRepositoryBrowser::ReadTree(CShadowFilesTree * treeroot)
{
	CStringA gitdir = CUnicodeUtils::GetMulti(g_Git.m_CurrentDir, CP_UTF8);
	git_repository *repository = NULL;
	git_commit *commit = NULL;
	git_tree * tree = NULL;
	int ret = 0;
	do
	{
		ret = git_repository_open(&repository, gitdir.GetBuffer());
		if (ret)
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR);
			break;
		}

		if (m_sRevision == _T("HEAD"))
		{
			ret = git_repository_head_unborn(repository);
			if (ret == 1)	// is orphan
				break;
			else if (ret != 0)
			{
				MessageBox(g_Git.GetLibGit2LastErr(_T("Could not check HEAD.")), _T("TortoiseGit"), MB_ICONERROR);
				break;
			}
		}

		CGitHash hash;
		if (g_Git.GetHash(hash, m_sRevision))
		{
			MessageBox(g_Git.GetGitLastErr(_T("Could not get hash of ") + m_sRevision + _T(".")), _T("TortoiseGit"), MB_ICONERROR);
			break;
		}
		ret = git_commit_lookup(&commit, repository, (git_oid *) hash.m_hash);
		if (ret)
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup commit.")), _T("TortoiseGit"), MB_ICONERROR);
			break;
		}

		ret = git_commit_tree(&tree, commit);
		if (ret)
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not get tree of commit.")), _T("TortoiseGit"), MB_ICONERROR);
			break;
		}

		treeroot->m_hash = CGitHash((char *)git_tree_id(tree)->id);
		ReadTreeRecursive(*repository, tree, treeroot);

		// try to resolve hash to a branch name
		if (m_sRevision == hash.ToString())
		{
			MAP_HASH_NAME map;
			if (g_Git.GetMapHashToFriendName(map))
				MessageBox(g_Git.GetGitLastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR);
			if (!map[hash].empty())
				m_sRevision = map[hash].at(0);
		}
		this->GetDlgItem(IDC_BUTTON_REVISION)->SetWindowText(m_sRevision);
	} while(0);

	if (tree)
		git_tree_free(tree);

	if (commit)
		git_commit_free(commit);

	if (repository)
		git_repository_free(repository);

	return ret;
}
コード例 #9
0
int CRepositoryBrowser::ReadTree(CShadowFilesTree * treeroot, const CString& root)
{
	CWaitCursor wait;
	CAutoRepository repository(g_Git.GetGitRepository());
	if (!repository)
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	if (m_sRevision == _T("HEAD"))
	{
		int ret = git_repository_head_unborn(repository);
		if (ret == 1)	// is orphan
			return ret;
		else if (ret != 0)
		{
			MessageBox(g_Git.GetLibGit2LastErr(_T("Could not check HEAD.")), _T("TortoiseGit"), MB_ICONERROR);
			return ret;
		}
	}

	CGitHash hash;
	if (CGit::GetHash(repository, hash, m_sRevision))
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not get hash of ") + m_sRevision + _T(".")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	CAutoCommit commit;
	if (git_commit_lookup(commit.GetPointer(), repository, (git_oid *)hash.m_hash))
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup commit.")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	CAutoTree tree;
	if (git_commit_tree(tree.GetPointer(), commit))
	{
		MessageBox(CGit::GetLibGit2LastErr(_T("Could not get tree of commit.")), _T("TortoiseGit"), MB_ICONERROR);
		return -1;
	}

	if (!root.IsEmpty())
	{
		CAutoTreeEntry treeEntry;
		if (git_tree_entry_bypath(treeEntry.GetPointer(), tree, CUnicodeUtils::GetUTF8(root)))
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}
		if (git_tree_entry_type(treeEntry) != GIT_OBJ_TREE)
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}

		CAutoObject object;
		if (git_tree_entry_to_object(object.GetPointer(), repository, treeEntry))
		{
			MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR);
			return -1;
		}

		tree = (git_tree*)object.Detach();
	}

	treeroot->m_hash = CGitHash((char *)git_tree_id(tree)->id);
	ReadTreeRecursive(*repository, tree, treeroot);

	// try to resolve hash to a branch name
	if (m_sRevision == hash.ToString())
	{
		MAP_HASH_NAME map;
		if (CGit::GetMapHashToFriendName(repository, map))
			MessageBox(g_Git.GetLibGit2LastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR);
		if (!map[hash].empty())
			m_sRevision = map[hash].at(0);
	}
	this->GetDlgItem(IDC_BUTTON_REVISION)->SetWindowText(m_sRevision);

	return 0;
}
コード例 #10
0
ファイル: qgit.cpp プロジェクト: bokic/gitmaster
void QGit::commit(QString message)
{
    git_repository *repo = nullptr;
    git_signature *me = nullptr;
    git_commit *parent = nullptr;
    git_index *index = nullptr;
    git_tree *tree = nullptr;
    git_oid new_commit_id = { {0} };
    git_oid parent_id = { {0} };
    git_oid tree_id = { {0} };
    git_object *git_obj = nullptr;
    git_diff *diff = nullptr;
    size_t _count = 0;
    int unborn = 0;
    int res = 0;

    QGitError error;

    try {

        res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData());
        if (res)
        {
            throw QGitError("git_repository_open", res);
        }

        /// Check if somthing is staged
        res = git_revparse_single(&git_obj, repo, "HEAD^{tree}");
        if (res)
        {
            throw QGitError("git_revparse_single(staged)", res);
        }

        res = git_tree_lookup(&tree, repo, git_object_id(git_obj));
        if (res)
        {
            throw QGitError("git_tree_lookup(staged)", res);
        }

        res = git_diff_tree_to_index(&diff, repo, tree, nullptr, nullptr);
        if (res)
        {
            throw QGitError("git_diff_tree_to_index(staged)", res);
        }

        _count = git_diff_num_deltas(diff);

        if (_count == 0)
        {
            throw QGitError("Nothing staged.", res);
        }

        if (tree)
        {
            git_tree_free(tree);
            tree = nullptr;
        }
        /// Check end

        res = git_signature_default(&me, repo);
        if (res)
        {
            throw QGitError("git_signature_default", res);
        }

        res = git_repository_index(&index, repo);
        if (res)
        {
            throw QGitError("git_repository_index", res);
        }

        res = git_index_write_tree(&tree_id, index);
        if (res)
        {
            throw QGitError("git_index_write_tree", res);
        }

        res = git_tree_lookup(&tree, repo, &tree_id);
        if (res)
        {
            throw QGitError("git_tree_lookup", res);
        }

        unborn = git_repository_head_unborn(repo);
        if (unborn)
        {
            res = git_commit_create_v(
              &new_commit_id,
              repo,
              "HEAD",                        /* name of ref to update */
              me,                            /* author */
              me,                            /* committer */
              nullptr,                       /* nullptr = UTF-8 message encoding */
              message.toUtf8().constData(),  /* message */
              tree,                          /* root tree */
              0);                            /* parent count */
            if (res)
            {
                throw QGitError("git_commit_create_v", res);
            }
        }
        else
        {
            res = git_reference_name_to_id(&parent_id, repo, "HEAD");
            if (res)
            {
                throw QGitError("git_reference_name_to_id", res);
            }

            res = git_commit_lookup(&parent, repo, &parent_id);
            if (res)
            {
                throw QGitError("git_commit_lookup", res);
            }

            res = git_commit_create_v(
              &new_commit_id,
              repo,
              "HEAD",                        /* name of ref to update */
              me,                            /* author */
              me,                            /* committer */
              nullptr,                       /* nullptr = UTF-8 message encoding */
              message.toUtf8().constData(),  /* message */
              tree,                          /* root tree */
              1,                             /* parent count */
              parent);                       /* parent */
            if (res)
            {
                throw QGitError("git_commit_create_v", res);
            }
        }

    } catch(const QGitError &ex) {
        error = ex;
    }

    emit commitReply(QString::fromUtf8(reinterpret_cast<const char *>(new_commit_id.id)), error);

    if (parent)
    {
        git_commit_free(parent);
        parent = nullptr;
    }


    if (index)
    {
        git_index_free(index);
        index = nullptr;
    }

    if (tree)
    {
        git_tree_free(tree);
        tree = nullptr;
    }

    if (me)
    {
        git_signature_free(me);
        me = nullptr;
    }

    if (diff)
    {
        git_diff_free(diff);
        diff = nullptr;
    }

    if (git_obj)
    {
        git_object_free(git_obj);
        git_obj = nullptr;
    }

    if (repo)
    {
        git_repository_free(repo);
        repo = nullptr;
    }
}
コード例 #11
0
ファイル: pmrworkspace.cpp プロジェクト: dbrnz/opencor
void PmrWorkspace::stageFile(const QString &pPath, bool pStage)
{
    // Un/stage the file, which path is given, and let people know of the
    // outcome

    if (isOpen()) {
        QByteArray relativePathByteArray = QDir(mPath).relativeFilePath(pPath).toUtf8();
        const char *relativePath = relativePathByteArray.constData();
        bool success = false;
        git_index *index;

       if (git_repository_index(&index, mGitRepository) == GIT_OK) {
            if (pStage) {
                uint statusFlags = 0;

                git_status_file(&statusFlags, mGitRepository, relativePath);

                if ((statusFlags & GIT_STATUS_WT_DELETED) != 0) {
                    success = git_index_remove_bypath(index, relativePath) == GIT_OK;
                } else {
                    success = git_index_add_bypath(index, relativePath) == GIT_OK;
                }
            } else if (git_repository_head_unborn(mGitRepository) == 1) {
                success = git_index_remove_bypath(index, relativePath) == GIT_OK;
            } else {
                // We need to add a "reset stage" to the index, which means
                // getting the tree for HEAD and tree_entry for the file

                git_reference *head;

                if (git_repository_head(&head, mGitRepository) == GIT_OK) {
                    git_tree *headTree;

                    if (git_reference_peel(reinterpret_cast<git_object **>(&headTree),
                                           head, GIT_OBJECT_TREE) == GIT_OK) {
                        git_tree_entry *headEntry;

                        if (git_tree_entry_bypath(&headEntry, headTree,
                                                  relativePath) == GIT_OK) {
                            git_index_entry indexEntry;

                            memset(&indexEntry, '\0', sizeof(git_index_entry));

                            indexEntry.id = *git_tree_entry_id(headEntry);
                            indexEntry.mode = uint32_t(git_tree_entry_filemode(headEntry));
                            indexEntry.path = relativePath;

                            git_index_add(index, &indexEntry);

                            git_tree_entry_free(headEntry);

                            success = true;
                        } else {
                            success = git_index_remove_bypath(index, relativePath) == GIT_OK;
                        }

                        git_tree_free(headTree);
                    }

                    git_reference_free(head);
                }
            }

            if (success) {
                git_index_write(index);
            }

            git_index_free(index);
        }

        if (!success) {
            emitGitError(tr("An error occurred while trying to stage %1.").arg(pPath));
        }
    }
}
コード例 #12
0
ファイル: pmrworkspace.cpp プロジェクト: dbrnz/opencor
PmrWorkspace::WorkspaceStatus PmrWorkspace::gitWorkspaceStatus() const
{
    // Get the status of the workspace

    WorkspaceStatus res = StatusUnknown;

    if (isOpen()) {
        if (git_repository_head_unborn(mGitRepository) == 1) {
            res = StatusCurrent;
        } else {
            git_oid masterOid;
            bool error = false;

            if (git_reference_name_to_id(&masterOid, mGitRepository,
                                         "refs/heads/master") == GIT_OK) {
                git_oid originMasterOid;

                if (git_reference_name_to_id(&originMasterOid, mGitRepository,
                                             "refs/remotes/origin/master") == GIT_OK) {
                    size_t ahead = 0;
                    size_t behind = 0;

                    if (git_graph_ahead_behind(&ahead, &behind, mGitRepository,
                                               &masterOid, &originMasterOid) == GIT_OK) {
                        res = (ahead != 0)?
                                  StatusAhead:
                                  (behind != 0)?
                                      StatusBehind:
                                      StatusCurrent;
                    } else {
                        error = true;
                    }
                } else {
                    res = StatusAhead;
                }
            } else {
                error = true;
            }

            if (error) {
                emitGitError(tr("An error occurred while trying to get the remote status of %1.").arg(mPath));
            }
        }

        git_index *index;

        if (git_repository_index(&index, mGitRepository) == GIT_OK) {
            if (git_index_has_conflicts(index) != 0) {
                res = WorkspaceStatus(res|StatusConflict);
            } else {
                if (mStagedCount != 0) {
                    res = WorkspaceStatus(res|StatusStaged);
                }

                if (mUnstagedCount != 0) {
                    res = WorkspaceStatus(res|StatusUnstaged);
                }
            }

            git_index_free(index);
        }
    }

    return res;
}
コード例 #13
0
ファイル: pmrworkspace.cpp プロジェクト: dbrnz/opencor
bool PmrWorkspace::commit(const QString &pMessage)
{
    // Make sure that we are open

    if (!isOpen()) {
        return false;
    }

    // Get an empty buffer to hold the cleaned message

    git_buf message;

    message.ptr = nullptr;

    git_buf_set(&message, nullptr, 0);

    // Clean up the message and remove comments (which start with ";")

    git_message_prettify(&message, pMessage.toUtf8().constData(), 1, ';');

    bool res = true;

    if (message.size != 0) {
        int parentsCount = -1;
        git_commit *parent = nullptr;

        if (git_repository_head_unborn(mGitRepository) == 1) {
            // We are committing to an empty repository

            parentsCount = 0;
        } else {
            // Get HEAD as the commit object to use as the parent of the commit

            git_oid parentId;

            if (   (git_reference_name_to_id(&parentId, mGitRepository, "HEAD") == GIT_OK)
                && (git_commit_lookup(&parent, mGitRepository, &parentId) == GIT_OK)) {
                parentsCount = 1;
            }
        }

        if (parentsCount >= 0) {
            res = commit(message.ptr, size_t(parentsCount),
                         const_cast<const git_commit **>(&parent));

            if (!res) {
                emitGitError(tr("An error occurred while trying to commit to the workspace (you must provide both a name and an email)."));
            }
        }

        if (parent != nullptr) {
            git_commit_free(parent);
        }
    } else {
        emitGitError(tr("An error occurred while trying to commit to the workspace (you must provide a message)."));
    }

    git_buf_dispose(&message);

    return res;
}
コード例 #14
0
void CGitPropertyPage::InitWorkfileView()
{
	if (filenames.empty())
		return;

	CTGitPath path(filenames.front().c_str());

	CString ProjectTopDir;
	if(!path.HasAdminDir(&ProjectTopDir))
		return;

	CAutoRepository repository(CUnicodeUtils::GetUTF8(ProjectTopDir));
	if (!repository)
		return;

	CString username;
	CString useremail;
	CString autocrlf;
	CString safecrlf;

	CAutoConfig config(repository);
	if (config)
	{
		config.GetString(L"user.name", username);
		config.GetString(L"user.email", useremail);
		config.GetString(L"core.autocrlf", autocrlf);
		config.GetString(L"core.safecrlf", safecrlf);
	}

	CString branch;
	CString remotebranch;
	if (!git_repository_head_detached(repository))
	{
		CAutoReference head;
		if (git_repository_head_unborn(repository))
		{
			git_reference_lookup(head.GetPointer(), repository, "HEAD");
			branch = CUnicodeUtils::GetUnicode(git_reference_symbolic_target(head));
			if (branch.Find(_T("refs/heads/")) == 0)
				branch = branch.Mid(11); // 11 = len("refs/heads/")
		}
		else if (!git_repository_head(head.GetPointer(), repository))
		{
			const char * branchChar = git_reference_shorthand(head);
			branch = CUnicodeUtils::GetUnicode(branchChar);

			const char * branchFullChar = git_reference_name(head);
			CAutoBuf upstreambranchname;
			if (!git_branch_upstream_name(upstreambranchname, repository, branchFullChar))
			{
				remotebranch = CUnicodeUtils::GetUnicode(CStringA(upstreambranchname->ptr, (int)upstreambranchname->size));
				remotebranch = remotebranch.Mid(13); // 13=len("refs/remotes/")
			}
		}
	}
	else
		branch = _T("detached HEAD");

	if (autocrlf.Trim().IsEmpty())
		autocrlf = _T("false");
	if (safecrlf.Trim().IsEmpty())
		safecrlf = _T("false");

	SetDlgItemText(m_hwnd,IDC_CONFIG_USERNAME,username.Trim());
	SetDlgItemText(m_hwnd,IDC_CONFIG_USEREMAIL,useremail.Trim());
	SetDlgItemText(m_hwnd,IDC_CONFIG_AUTOCRLF,autocrlf.Trim());
	SetDlgItemText(m_hwnd,IDC_CONFIG_SAFECRLF,safecrlf.Trim());

	SetDlgItemText(m_hwnd,IDC_SHELL_CURRENT_BRANCH,branch.Trim());
	SetDlgItemText(m_hwnd,IDC_SHELL_REMOTE_BRANCH, remotebranch);

	git_oid oid;
	CAutoCommit HEADcommit;
	if (!git_reference_name_to_id(&oid, repository, "HEAD") && !git_commit_lookup(HEADcommit.GetPointer(), repository, &oid) && HEADcommit)
		DisplayCommit(HEADcommit, IDC_HEAD_HASH, IDC_HEAD_SUBJECT, IDC_HEAD_AUTHOR, IDC_HEAD_DATE);

	{
		int stripLength = ProjectTopDir.GetLength();
		if (ProjectTopDir[stripLength - 1] != _T('\\'))
			++stripLength;

		bool allAreFiles = true;
		for (auto it = filenames.cbegin(); it < filenames.cend(); ++it)
		{
			if (PathIsDirectory(it->c_str()))
			{
				allAreFiles = false;
				break;
			}
		}
		if (allAreFiles)
		{
			size_t assumevalid = 0;
			size_t skipworktree = 0;
			size_t executable = 0;
			size_t symlink = 0;
			do
			{
				CAutoIndex index;
				if (git_repository_index(index.GetPointer(), repository))
					break;

				for (auto it = filenames.cbegin(); it < filenames.cend(); ++it)
				{
					CTGitPath file;
					file.SetFromWin(CString(it->c_str()).Mid(stripLength));
					CStringA pathA = CUnicodeUtils::GetMulti(file.GetGitPathString(), CP_UTF8);
					size_t idx;
					if (!git_index_find(&idx, index, pathA))
					{
						const git_index_entry *e = git_index_get_byindex(index, idx);

						if (e->flags & GIT_IDXENTRY_VALID)
							++assumevalid;

						if (e->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE)
							++skipworktree;

						if (e->mode & 0111)
							++executable;

						if ((e->mode & GIT_FILEMODE_LINK) == GIT_FILEMODE_LINK)
							++symlink;
					}
					else
					{
						// do not show checkboxes for unversioned files
						ShowWindow(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), SW_HIDE);
						ShowWindow(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), SW_HIDE);
						ShowWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), SW_HIDE);
						ShowWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), SW_HIDE);
						break;
					}
				}
			} while (0);

			if (assumevalid != 0 && assumevalid != filenames.size())
			{
				SendMessage(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0);
				SendMessage(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), BM_SETCHECK, BST_INDETERMINATE, 0);
			}
			else
				SendMessage(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), BM_SETCHECK, (assumevalid == 0) ? BST_UNCHECKED : BST_CHECKED, 0);

			if (skipworktree != 0 && skipworktree != filenames.size())
			{
				SendMessage(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0);
				SendMessage(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), BM_SETCHECK, BST_INDETERMINATE, 0);
			}
			else
				SendMessage(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), BM_SETCHECK, (skipworktree == 0) ? BST_UNCHECKED : BST_CHECKED, 0);

			if (executable != 0 && executable != filenames.size())
			{
				SendMessage(GetDlgItem(m_hwnd, IDC_EXECUTABLE), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_EXECUTABLE), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0);
				SendMessage(GetDlgItem(m_hwnd, IDC_EXECUTABLE), BM_SETCHECK, BST_INDETERMINATE, 0);
				EnableWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), TRUE);
			}
			else
			{
				SendMessage(GetDlgItem(m_hwnd, IDC_EXECUTABLE), BM_SETCHECK, (executable == 0) ? BST_UNCHECKED : BST_CHECKED, 0);
				EnableWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), (executable == 0) ? TRUE : FALSE);
			}

			if (symlink != 0 && symlink != filenames.size())
			{
				SendMessage(GetDlgItem(m_hwnd, IDC_SYMLINK), BM_SETSTYLE, (DWORD)GetWindowLong(GetDlgItem(m_hwnd, IDC_SYMLINK), GWL_STYLE) & ~BS_AUTOCHECKBOX | BS_AUTO3STATE, 0);
				SendMessage(GetDlgItem(m_hwnd, IDC_SYMLINK), BM_SETCHECK, BST_INDETERMINATE, 0);
				EnableWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), TRUE);
			}
			else
			{
				SendMessage(GetDlgItem(m_hwnd, IDC_SYMLINK), BM_SETCHECK, (symlink == 0) ? BST_UNCHECKED : BST_CHECKED, 0);
				EnableWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), (symlink == 0) ? TRUE : FALSE);
			}
		}
		else
		{
			ShowWindow(GetDlgItem(m_hwnd, IDC_ASSUMEVALID), SW_HIDE);
			ShowWindow(GetDlgItem(m_hwnd, IDC_SKIPWORKTREE), SW_HIDE);
			ShowWindow(GetDlgItem(m_hwnd, IDC_EXECUTABLE), SW_HIDE);
			ShowWindow(GetDlgItem(m_hwnd, IDC_SYMLINK), SW_HIDE);
		}
	}

	if (filenames.size() == 1 && !PathIsDirectory(filenames[0].c_str()))
	{
		SetDlgItemText(m_hwnd, IDC_LAST_SUBJECT, CString(MAKEINTRESOURCE(IDS_LOADING)));
		_beginthread(LogThreadEntry, 0, this);
	}
	else
		ShowWindow(GetDlgItem(m_hwnd, IDC_STATIC_LASTMODIFIED), SW_HIDE);
}