コード例 #1
0
static bool checkout_is_workdir_modified(
    checkout_data *data,
    const git_diff_file *baseitem,
    const git_index_entry *wditem)
{
    git_oid oid;
    const git_index_entry *ie;

    /* handle "modified" submodule */
    if (wditem->mode == GIT_FILEMODE_COMMIT) {
        git_submodule *sm;
        unsigned int sm_status = 0;
        const git_oid *sm_oid = NULL;

        if (git_submodule_lookup(&sm, data->repo, wditem->path) < 0 ||
                git_submodule_status(&sm_status, sm) < 0)
            return true;

        if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
            return true;

        sm_oid = git_submodule_wd_id(sm);
        if (!sm_oid)
            return false;

        return (git_oid__cmp(&baseitem->oid, sm_oid) != 0);
    }

    /* Look at the cache to decide if the workdir is modified.  If not,
     * we can simply compare the oid in the cache to the baseitem instead
     * of hashing the file.
     */
    if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) {
        if (wditem->mtime.seconds == ie->mtime.seconds &&
                wditem->mtime.nanoseconds == ie->mtime.nanoseconds &&
                wditem->file_size == ie->file_size)
            return (git_oid__cmp(&baseitem->oid, &ie->oid) != 0);
    }

    /* depending on where base is coming from, we may or may not know
     * the actual size of the data, so we can't rely on this shortcut.
     */
    if (baseitem->size && wditem->file_size != baseitem->size)
        return true;

    if (git_diff__oid_for_file(
                data->repo, wditem->path, wditem->mode,
                wditem->file_size, &oid) < 0)
        return false;

    return (git_oid__cmp(&baseitem->oid, &oid) != 0);
}
コード例 #2
0
ファイル: diff_file.c プロジェクト: CodeSmithyIDE/libgit2
static int diff_file_content_commit_to_str(
	git_diff_file_content *fc, bool check_status)
{
	char oid[GIT_OID_HEXSZ+1];
	git_buf content = GIT_BUF_INIT;
	const char *status = "";

	if (check_status) {
		int error = 0;
		git_submodule *sm = NULL;
		unsigned int sm_status = 0;
		const git_oid *sm_head;

		if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0) {
			/* GIT_EEXISTS means a "submodule" that has not been git added */
			if (error == GIT_EEXISTS) {
				giterr_clear();
				error = 0;
			}
			return error;
		}

		if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0) {
			git_submodule_free(sm);
			return error;
		}

		/* update OID if we didn't have it previously */
		if ((fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0 &&
			((sm_head = git_submodule_wd_id(sm)) != NULL ||
			 (sm_head = git_submodule_head_id(sm)) != NULL))
		{
			git_oid_cpy(&fc->file->id, sm_head);
			fc->file->flags |= GIT_DIFF_FLAG_VALID_ID;
		}

		if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
			status = "-dirty";

		git_submodule_free(sm);
	}

	git_oid_tostr(oid, sizeof(oid), &fc->file->id);
	if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0)
		return -1;

	fc->map.len  = git_buf_len(&content);
	fc->map.data = git_buf_detach(&content);
	fc->flags |= GIT_DIFF_FLAG__FREE_DATA;

	return 0;
}