コード例 #1
0
ファイル: preload-index.c プロジェクト: asoltys/git
static void *preload_thread(void *_data)
{
	int nr;
	struct thread_data *p = _data;
	struct index_state *index = p->index;
	struct cache_entry **cep = index->cache + p->offset;
	struct cache_def cache;

	memset(&cache, 0, sizeof(cache));
	nr = p->nr;
	if (nr + p->offset > index->cache_nr)
		nr = index->cache_nr - p->offset;

	do {
		struct cache_entry *ce = *cep++;
		struct stat st;

		if (ce_stage(ce))
			continue;
		if (ce_uptodate(ce))
			continue;
		if (!ce_path_match(ce, p->pathspec))
			continue;
		if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
			continue;
		if (lstat(ce->name, &st))
			continue;
		if (ie_match_stat(index, ce, &st, CE_MATCH_RACY_IS_DIRTY))
			continue;
		ce_mark_uptodate(ce);
	} while (--nr > 0);
	return NULL;
}
コード例 #2
0
ファイル: preload-index.c プロジェクト: Nowher2/git
static void *preload_thread(void *_data)
{
	int nr;
	struct thread_data *p = _data;
	struct index_state *index = p->index;
	struct cache_entry **cep = index->cache + p->offset;
	struct cache_def cache = CACHE_DEF_INIT;

	nr = p->nr;
	if (nr + p->offset > index->cache_nr)
		nr = index->cache_nr - p->offset;

	do {
		struct cache_entry *ce = *cep++;
		struct stat st;

		if (ce_stage(ce))
			continue;
		if (S_ISGITLINK(ce->ce_mode))
			continue;
		if (ce_uptodate(ce))
			continue;
		if (ce_skip_worktree(ce))
			continue;
		if (ce->ce_flags & CE_FSMONITOR_VALID)
			continue;
		if (!ce_path_match(index, ce, &p->pathspec, NULL))
			continue;
		if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
			continue;
		if (lstat(ce->name, &st))
			continue;
		if (ie_match_stat(index, ce, &st, CE_MATCH_RACY_IS_DIRTY|CE_MATCH_IGNORE_FSMONITOR))
			continue;
		ce_mark_uptodate(ce);
		mark_fsmonitor_valid(ce);
	} while (--nr > 0);
	cache_def_clear(&cache);
	return NULL;
}
コード例 #3
0
ファイル: diff-lib.c プロジェクト: AndyA/git-andya
int run_diff_files(struct rev_info *revs, unsigned int option)
{
	int entries, i;
	int diff_unmerged_stage = revs->max_count;
	int silent_on_removed = option & DIFF_SILENT_ON_REMOVED;
	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
			      ? CE_MATCH_RACY_IS_DIRTY : 0);

	diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");

	if (diff_unmerged_stage < 0)
		diff_unmerged_stage = 2;
	entries = active_nr;
	for (i = 0; i < entries; i++) {
		struct stat st;
		unsigned int oldmode, newmode;
		struct cache_entry *ce = active_cache[i];
		int changed;

		if (DIFF_OPT_TST(&revs->diffopt, QUIET) &&
			DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
			break;

		if (!ce_path_match(ce, revs->prune_data))
			continue;

		if (ce_stage(ce)) {
			struct combine_diff_path *dpath;
			int num_compare_stages = 0;
			size_t path_len;

			path_len = ce_namelen(ce);

			dpath = xmalloc(combine_diff_path_size(5, path_len));
			dpath->path = (char *) &(dpath->parent[5]);

			dpath->next = NULL;
			dpath->len = path_len;
			memcpy(dpath->path, ce->name, path_len);
			dpath->path[path_len] = '\0';
			hashclr(dpath->sha1);
			memset(&(dpath->parent[0]), 0,
			       sizeof(struct combine_diff_parent)*5);

			changed = check_removed(ce, &st);
			if (!changed)
				dpath->mode = ce_mode_from_stat(ce, st.st_mode);
			else {
				if (changed < 0) {
					perror(ce->name);
					continue;
				}
				if (silent_on_removed)
					continue;
			}

			while (i < entries) {
				struct cache_entry *nce = active_cache[i];
				int stage;

				if (strcmp(ce->name, nce->name))
					break;

				/* Stage #2 (ours) is the first parent,
				 * stage #3 (theirs) is the second.
				 */
				stage = ce_stage(nce);
				if (2 <= stage) {
					int mode = nce->ce_mode;
					num_compare_stages++;
					hashcpy(dpath->parent[stage-2].sha1, nce->sha1);
					dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode);
					dpath->parent[stage-2].status =
						DIFF_STATUS_MODIFIED;
				}

				/* diff against the proper unmerged stage */
				if (stage == diff_unmerged_stage)
					ce = nce;
				i++;
			}
			/*
			 * Compensate for loop update
			 */
			i--;

			if (revs->combine_merges && num_compare_stages == 2) {
				show_combined_diff(dpath, 2,
						   revs->dense_combined_merges,
						   revs);
				free(dpath);
				continue;
			}
			free(dpath);
			dpath = NULL;

			/*
			 * Show the diff for the 'ce' if we found the one
			 * from the desired stage.
			 */
			diff_unmerge(&revs->diffopt, ce->name, 0, null_sha1);
			if (ce_stage(ce) != diff_unmerged_stage)
				continue;
		}

		if (ce_uptodate(ce))
			continue;

		changed = check_removed(ce, &st);
		if (changed) {
			if (changed < 0) {
				perror(ce->name);
				continue;
			}
			if (silent_on_removed)
				continue;
			diff_addremove(&revs->diffopt, '-', ce->ce_mode,
				       ce->sha1, ce->name);
			continue;
		}
		changed = ce_match_stat(ce, &st, ce_option);
		if (!changed) {
			ce_mark_uptodate(ce);
			if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
				continue;
		}
		oldmode = ce->ce_mode;
		newmode = ce_mode_from_stat(ce, st.st_mode);
		diff_change(&revs->diffopt, oldmode, newmode,
			    ce->sha1, (changed ? null_sha1 : ce->sha1),
			    ce->name);

	}
	diffcore_std(&revs->diffopt);
	diff_flush(&revs->diffopt);
	return 0;
}
コード例 #4
0
ファイル: status.c プロジェクト: AlanForeverAi/seafile
void wt_status_collect_changes_worktree(struct index_state *index,
                                        GList **results,
                                        const char *worktree)
{
    DiffEntry *de;
    int entries, i;

    GList *ignore_list = seaf_repo_load_ignore_files (worktree);

    entries = index->cache_nr;
    for (i = 0; i < entries; i++) {
        char *realpath;
        SeafStat st;
        struct cache_entry *ce = index->cache[i];
        int changed = 0;

        if (ce_stage(ce)) {
            int mask = 0;

            mask |= 1 << ce_stage(ce);
            while (i < entries) {
                struct cache_entry *nce = index->cache[i];

                if (strcmp(ce->name, nce->name))
                    break;

                mask |= 1 << ce_stage(nce);
                i++;
            }

            /*
             * Compensate for loop update
             */
            i--;

            de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_UNMERGED,
                                 ce->sha1, ce->name);
            de->unmerge_state = diff_unmerged_state (mask);
            *results = g_list_prepend (*results, de);

            continue;
        }

        if (ce_uptodate(ce) || ce_skip_worktree(ce))
            continue;

        realpath = g_build_path (PATH_SEPERATOR, worktree, ce->name, NULL);
        if (seaf_stat(realpath, &st) < 0) {
            if (errno != ENOENT && errno != ENOTDIR)
                changed = -1;
            else
                changed = 1;
        }

        if (changed) {
            if (changed < 0) {
                g_warning ("Faile to stat %s: %s\n", ce->name, strerror(errno));
                g_free (realpath);
                continue;
            }

            if (ce->ce_ctime.sec == 0) {
                g_free (realpath);
                continue;
            }

            de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_DELETED,
                                 ce->sha1, ce->name);
            *results = g_list_prepend (*results, de);
            g_free (realpath);
            continue;
        }

        if (S_ISDIR (ce->ce_mode)) {
            g_free (realpath);
            continue;
        }

        /* Don't check changes to ignored files.
         * This can happen when a file is committed and then added to
         * ignore.txt. After that changes to this file will not committed,
         * and it should be ignored here.
         */
        if (seaf_repo_check_ignore_file (ignore_list, realpath)) {
            g_free (realpath);
            continue;
        }

        g_free (realpath);

        changed = ie_match_stat (index, ce, &st, 0);
        if (!changed) {
            ce_mark_uptodate (ce);
            continue;
        }

        de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_MODIFIED,
                             ce->sha1, ce->name);
        *results = g_list_prepend (*results, de);
    }

    seaf_repo_free_ignore_files (ignore_list);
}
コード例 #5
0
ファイル: diff-lib.c プロジェクト: 0369/git
int run_diff_files(struct rev_info *revs, unsigned int option)
{
	int entries, i;
	int diff_unmerged_stage = revs->max_count;
	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
			      ? CE_MATCH_RACY_IS_DIRTY : 0);

	diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");

	if (diff_unmerged_stage < 0)
		diff_unmerged_stage = 2;
	entries = active_nr;
	for (i = 0; i < entries; i++) {
		unsigned int oldmode, newmode;
		struct cache_entry *ce = active_cache[i];
		int changed;
		unsigned dirty_submodule = 0;
		const unsigned char *old_sha1, *new_sha1;

		if (diff_can_quit_early(&revs->diffopt))
			break;

		if (!ce_path_match(ce, &revs->prune_data, NULL))
			continue;

		if (ce_stage(ce)) {
			struct combine_diff_path *dpath;
			struct diff_filepair *pair;
			unsigned int wt_mode = 0;
			int num_compare_stages = 0;
			size_t path_len;
			struct stat st;

			path_len = ce_namelen(ce);

			dpath = xmalloc(combine_diff_path_size(5, path_len));
			dpath->path = (char *) &(dpath->parent[5]);

			dpath->next = NULL;
			memcpy(dpath->path, ce->name, path_len);
			dpath->path[path_len] = '\0';
			oidclr(&dpath->oid);
			memset(&(dpath->parent[0]), 0,
			       sizeof(struct combine_diff_parent)*5);

			changed = check_removed(ce, &st);
			if (!changed)
				wt_mode = ce_mode_from_stat(ce, st.st_mode);
			else {
				if (changed < 0) {
					perror(ce->name);
					continue;
				}
				wt_mode = 0;
			}
			dpath->mode = wt_mode;

			while (i < entries) {
				struct cache_entry *nce = active_cache[i];
				int stage;

				if (strcmp(ce->name, nce->name))
					break;

				/* Stage #2 (ours) is the first parent,
				 * stage #3 (theirs) is the second.
				 */
				stage = ce_stage(nce);
				if (2 <= stage) {
					int mode = nce->ce_mode;
					num_compare_stages++;
					hashcpy(dpath->parent[stage-2].oid.hash, nce->sha1);
					dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode);
					dpath->parent[stage-2].status =
						DIFF_STATUS_MODIFIED;
				}

				/* diff against the proper unmerged stage */
				if (stage == diff_unmerged_stage)
					ce = nce;
				i++;
			}
			/*
			 * Compensate for loop update
			 */
			i--;

			if (revs->combine_merges && num_compare_stages == 2) {
				show_combined_diff(dpath, 2,
						   revs->dense_combined_merges,
						   revs);
				free(dpath);
				continue;
			}
			free(dpath);
			dpath = NULL;

			/*
			 * Show the diff for the 'ce' if we found the one
			 * from the desired stage.
			 */
			pair = diff_unmerge(&revs->diffopt, ce->name);
			if (wt_mode)
				pair->two->mode = wt_mode;
			if (ce_stage(ce) != diff_unmerged_stage)
				continue;
		}

		if (ce_uptodate(ce) || ce_skip_worktree(ce))
			continue;

		/* If CE_VALID is set, don't look at workdir for file removal */
		if (ce->ce_flags & CE_VALID) {
			changed = 0;
			newmode = ce->ce_mode;
		} else {
			struct stat st;

			changed = check_removed(ce, &st);
			if (changed) {
				if (changed < 0) {
					perror(ce->name);
					continue;
				}
				diff_addremove(&revs->diffopt, '-', ce->ce_mode,
					       ce->sha1, !is_null_sha1(ce->sha1),
					       ce->name, 0);
				continue;
			}

			changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
							    ce_option, &dirty_submodule);
			newmode = ce_mode_from_stat(ce, st.st_mode);
		}

		if (!changed && !dirty_submodule) {
			ce_mark_uptodate(ce);
			if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
				continue;
		}
		oldmode = ce->ce_mode;
		old_sha1 = ce->sha1;
		new_sha1 = changed ? null_sha1 : ce->sha1;
		diff_change(&revs->diffopt, oldmode, newmode,
			    old_sha1, new_sha1,
			    !is_null_sha1(old_sha1),
			    !is_null_sha1(new_sha1),
			    ce->name, 0, dirty_submodule);

	}
	diffcore_std(&revs->diffopt);
	diff_flush(&revs->diffopt);
	return 0;
}
コード例 #6
0
ファイル: diff-lib.c プロジェクト: MichaelBlume/git
int run_diff_files(struct rev_info *revs, unsigned int option)
{
	int entries, i;
	int diff_unmerged_stage = revs->max_count;
	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
			      ? CE_MATCH_RACY_IS_DIRTY : 0);
	uint64_t start = getnanotime();
	struct index_state *istate = revs->diffopt.repo->index;

	diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");

	if (diff_unmerged_stage < 0)
		diff_unmerged_stage = 2;
	entries = istate->cache_nr;
	for (i = 0; i < entries; i++) {
		unsigned int oldmode, newmode;
		struct cache_entry *ce = istate->cache[i];
		int changed;
		unsigned dirty_submodule = 0;
		const struct object_id *old_oid, *new_oid;

		if (diff_can_quit_early(&revs->diffopt))
			break;

		if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
			continue;

		if (ce_stage(ce)) {
			struct combine_diff_path *dpath;
			struct diff_filepair *pair;
			unsigned int wt_mode = 0;
			int num_compare_stages = 0;
			size_t path_len;
			struct stat st;

			path_len = ce_namelen(ce);

			dpath = xmalloc(combine_diff_path_size(5, path_len));
			dpath->path = (char *) &(dpath->parent[5]);

			dpath->next = NULL;
			memcpy(dpath->path, ce->name, path_len);
			dpath->path[path_len] = '\0';
			oidclr(&dpath->oid);
			memset(&(dpath->parent[0]), 0,
			       sizeof(struct combine_diff_parent)*5);

			changed = check_removed(ce, &st);
			if (!changed)
				wt_mode = ce_mode_from_stat(ce, st.st_mode);
			else {
				if (changed < 0) {
					perror(ce->name);
					continue;
				}
				wt_mode = 0;
			}
			dpath->mode = wt_mode;

			while (i < entries) {
				struct cache_entry *nce = istate->cache[i];
				int stage;

				if (strcmp(ce->name, nce->name))
					break;

				/* Stage #2 (ours) is the first parent,
				 * stage #3 (theirs) is the second.
				 */
				stage = ce_stage(nce);
				if (2 <= stage) {
					int mode = nce->ce_mode;
					num_compare_stages++;
					oidcpy(&dpath->parent[stage - 2].oid,
					       &nce->oid);
					dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode);
					dpath->parent[stage-2].status =
						DIFF_STATUS_MODIFIED;
				}

				/* diff against the proper unmerged stage */
				if (stage == diff_unmerged_stage)
					ce = nce;
				i++;
			}
			/*
			 * Compensate for loop update
			 */
			i--;

			if (revs->combine_merges && num_compare_stages == 2) {
				show_combined_diff(dpath, 2,
						   revs->dense_combined_merges,
						   revs);
				free(dpath);
				continue;
			}
			FREE_AND_NULL(dpath);

			/*
			 * Show the diff for the 'ce' if we found the one
			 * from the desired stage.
			 */
			pair = diff_unmerge(&revs->diffopt, ce->name);
			if (wt_mode)
				pair->two->mode = wt_mode;
			if (ce_stage(ce) != diff_unmerged_stage)
				continue;
		}

		if (ce_uptodate(ce) || ce_skip_worktree(ce))
			continue;

		/* If CE_VALID is set, don't look at workdir for file removal */
		if (ce->ce_flags & CE_VALID) {
			changed = 0;
			newmode = ce->ce_mode;
		} else {
			struct stat st;

			changed = check_removed(ce, &st);
			if (changed) {
				if (changed < 0) {
					perror(ce->name);
					continue;
				}
				diff_addremove(&revs->diffopt, '-', ce->ce_mode,
					       &ce->oid,
					       !is_null_oid(&ce->oid),
					       ce->name, 0);
				continue;
			} else if (revs->diffopt.ita_invisible_in_index &&
				   ce_intent_to_add(ce)) {
				diff_addremove(&revs->diffopt, '+', ce->ce_mode,
					       the_hash_algo->empty_tree, 0,
					       ce->name, 0);
				continue;
			}

			changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
							    ce_option, &dirty_submodule);
			newmode = ce_mode_from_stat(ce, st.st_mode);
		}

		if (!changed && !dirty_submodule) {
			ce_mark_uptodate(ce);
			mark_fsmonitor_valid(ce);
			if (!revs->diffopt.flags.find_copies_harder)
				continue;
		}
		oldmode = ce->ce_mode;
		old_oid = &ce->oid;
		new_oid = changed ? &null_oid : &ce->oid;
		diff_change(&revs->diffopt, oldmode, newmode,
			    old_oid, new_oid,
			    !is_null_oid(old_oid),
			    !is_null_oid(new_oid),
			    ce->name, 0, dirty_submodule);

	}
	diffcore_std(&revs->diffopt);
	diff_flush(&revs->diffopt);
	trace_performance_since(start, "diff-files");
	return 0;
}
コード例 #7
0
ファイル: status.c プロジェクト: sheyong/seafile
void wt_status_collect_changes_worktree(struct index_state *index,
                                        GList **results,
                                        const char *worktree,
                                        IgnoreFunc ignore_func)
{
    DiffEntry *de;
    int entries, i;

    entries = index->cache_nr;
    for (i = 0; i < entries; i++) {
        char *realpath;
        struct stat st;
        struct cache_entry *ce = index->cache[i];
        int changed = 0;

        if (ce_stage(ce)) {
            int mask = 0;

            mask |= 1 << ce_stage(ce);
            while (i < entries) {
                struct cache_entry *nce = index->cache[i];

                if (strcmp(ce->name, nce->name))
                    break;

                mask |= 1 << ce_stage(nce);
                i++;
            }

            /*
             * Compensate for loop update
             */
            i--;

            de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_UNMERGED,
                                 ce->sha1, ce->name);
            de->unmerge_state = diff_unmerged_state (mask);
            *results = g_list_prepend (*results, de);

            continue;
        }

        if (ce_uptodate(ce) || ce_skip_worktree(ce))
            continue;

        realpath = g_build_path (PATH_SEPERATOR, worktree, ce->name, NULL);
        if (g_lstat(realpath, &st) < 0) {
            if (errno != ENOENT && errno != ENOTDIR)
                changed = -1;
            changed = 1;
        }

        if (changed) {
            if (changed < 0) {
                g_warning ("Faile to stat %s: %s\n", ce->name, strerror(errno));
                g_free (realpath);
                continue;
            }

            de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_DELETED,
                                 ce->sha1, ce->name);
            *results = g_list_prepend (*results, de);
            g_free (realpath);
            continue;
        }

        if (S_ISDIR (ce->ce_mode)) {
            if (!S_ISDIR (st.st_mode) ||
                !is_empty_dir (realpath, ignore_func)) {
                de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_DIR_DELETED,
                                     ce->sha1, ce->name);
                *results = g_list_prepend (*results, de);
            }
            g_free (realpath);
            continue;
        }
        g_free (realpath);

        changed = ie_match_stat (index, ce, &st, 0);
        if (!changed) {
            ce_mark_uptodate (ce);
            continue;
        }

        de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_MODIFIED,
                             ce->sha1, ce->name);
        *results = g_list_prepend (*results, de);
    }
}