Esempio n. 1
0
static int check_updates(struct unpack_trees_options *o)
{
	unsigned cnt = 0, total = 0;
	struct progress *progress = NULL;
	struct index_state *index = &o->result;
	int i;
	int errs = 0;

	if (o->update && o->verbose_update) {
		for (total = cnt = 0; cnt < index->cache_nr; cnt++) {
			const struct cache_entry *ce = index->cache[cnt];
			if (ce->ce_flags & (CE_UPDATE | CE_WT_REMOVE))
				total++;
		}

		progress = start_progress_delay(_("Checking out files"),
						total, 50, 1);
		cnt = 0;
	}

	if (o->update)
		git_attr_set_direction(GIT_ATTR_CHECKOUT, &o->result);
	for (i = 0; i < index->cache_nr; i++) {
		const struct cache_entry *ce = index->cache[i];

		if (ce->ce_flags & CE_WT_REMOVE) {
			display_progress(progress, ++cnt);
			if (o->update && !o->dry_run)
				unlink_entry(ce);
			continue;
		}
	}
	remove_marked_cache_entries(&o->result);
	remove_scheduled_dirs();

	for (i = 0; i < index->cache_nr; i++) {
		struct cache_entry *ce = index->cache[i];

		if (ce->ce_flags & CE_UPDATE) {
			if (ce->ce_flags & CE_WT_REMOVE)
				die("BUG: both update and delete flags are set on %s",
				    ce->name);
			display_progress(progress, ++cnt);
			ce->ce_flags &= ~CE_UPDATE;
			if (o->update && !o->dry_run) {
				errs |= checkout_entry(ce, &state, NULL);
			}
		}
	}
	stop_progress(&progress);
	if (o->update)
		git_attr_set_direction(GIT_ATTR_CHECKIN, NULL);
	return errs != 0;
}
Esempio n. 2
0
int
update_worktree (struct unpack_trees_options *o,
                 gboolean recover_merge,
                 const char *conflict_head_id,
                 const char *default_conflict_suffix,
                 int *finished_entries)
{
    struct index_state *result = &o->result;
    int i;
    struct cache_entry *ce;
    char *conflict_suffix = NULL;
    int errs = 0;
    GHashTable *conflict_hash, *no_conflict_hash;

    for (i = 0; i < result->cache_nr; ++i) {
        ce = result->cache[i];
        if (ce->ce_flags & CE_WT_REMOVE)
            errs |= unlink_entry (ce, o);
    }

    conflict_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
                                           g_free, g_free);
    no_conflict_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
                                              g_free, NULL);

    for (i = 0; i < result->cache_nr; ++i) {
        ce = result->cache[i];
        if (ce->ce_flags & CE_UPDATE) {
            if (conflict_head_id) {
                conflict_suffix = get_last_changer_of_file (conflict_head_id,
                                                            ce->name);
                if (!conflict_suffix)
                    conflict_suffix = g_strdup(default_conflict_suffix);
            }
            errs |= checkout_entry (ce, o, recover_merge,
                                    conflict_suffix,
                                    conflict_hash, no_conflict_hash);
            g_free (conflict_suffix);
        }
        if (finished_entries)
            *finished_entries = *finished_entries + 1;
    }

    g_hash_table_destroy (conflict_hash);
    g_hash_table_destroy (no_conflict_hash);

    if (errs != 0)
        return -1;
    return 0;
}
Esempio n. 3
0
static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
			  const struct checkout *state, int *nr_checkouts,
			  int overlay_mode)
{
	while (pos < active_nr &&
	       !strcmp(active_cache[pos]->name, ce->name)) {
		if (ce_stage(active_cache[pos]) == stage)
			return checkout_entry(active_cache[pos], state,
					      NULL, nr_checkouts);
		pos++;
	}
	if (!overlay_mode) {
		unlink_entry(ce);
		return 0;
	}
	if (stage == 2)
		return error(_("path '%s' does not have our version"), ce->name);
	else
		return error(_("path '%s' does not have their version"), ce->name);
}
Esempio n. 4
0
int
update_worktree (struct unpack_trees_options *o,
                 gboolean recover_merge,
                 const char *conflict_head_id,
                 const char *default_conflict_suffix,
                 int *finished_entries)
{
    struct index_state *result = &o->result;
    int i;
    struct cache_entry *ce;
    char *conflict_suffix = NULL;
    int errs = 0;

    for (i = 0; i < result->cache_nr; ++i) {
        ce = result->cache[i];
        if (ce->ce_flags & CE_WT_REMOVE)
            errs |= unlink_entry (ce, o);
    }

    for (i = 0; i < result->cache_nr; ++i) {
        ce = result->cache[i];
        if (ce->ce_flags & CE_UPDATE) {
            if (conflict_head_id) {
                conflict_suffix = get_last_changer_of_file (conflict_head_id,
                                                            ce->name);
                if (!conflict_suffix)
                    conflict_suffix = g_strdup(default_conflict_suffix);
            }
            errs |= checkout_entry (ce, o, recover_merge, conflict_suffix);
            g_free (conflict_suffix);
        }
        if (finished_entries)
            *finished_entries = *finished_entries + 1;
    }

    return errs != 0;
}
Esempio n. 5
0
int main(int ac, char **av)
{
    GError *error = NULL;
    GOptionContext *context = g_option_context_new("PATH [PATH] ...");

    g_option_context_add_main_entries(context, entries, NULL);
    if (!g_option_context_parse(context, &ac, &av, &error)) {
        g_printerr("option parsing failed: %s\n", error->message);
        exit(EXIT_FAILURE);
    }

    if (!paths) {
        g_printerr("Please provide at least one path.\n");
        exit(EXIT_FAILURE);
    }

    /* Megabytize the argument */
    if (chunk)
        chunk <<= 20;

    FTS *fts = fts_open(paths, onefs ? FTS_XDEV : 0, NULL);
    FTSENT *e;

    while ((e = fts_read(fts))) {
        switch (e->fts_info) {
        case FTS_D:
            /* Directories are easiest,
             * only dealwith them after we cleaned them
             * We bail though, if we encounter directory in non-recursive mode
             */
            if (!recursive) {
                g_printerr("Directory (%s) encountered "
                           "in non-recursive mode.\n", e->fts_path);
                if (force) {
                    /* We skip the sub-tree and continue to next file */
                    fts_set(fts, e, FTS_SKIP);
                } else {
                    exit(EXIT_FAILURE);
                }
            }
            break;
        case FTS_DP:
            if (rmdir(e->fts_accpath) < 0) {
                g_printerr("Could not remove (%s) directory: %s\n",
                           e->fts_path, strerror(errno));
                if (!force)
                    exit(EXIT_FAILURE);
            }
            break;
        case FTS_F:
            /* Handling regular files. We sleep when we have
             * many smalls with large cumulative size.
             *
             * We also try to chunk large files and truncate
             * before dropping the fd
             *
             * If we're not running in force mode we
             * will bail pretty much all the time.
             *
             * Otherwise we will keep doing everything.
             */

            if (e->fts_statp->st_size > chunk && e->fts_statp->st_nlink <= 1) {
                /* Large file case.
                 * We only do this for files
                 * that are not hardlinked anywhere else.
                 */
                int fd = open(e->fts_accpath, O_RDWR);
                if (fd < 0) {
                    g_printerr("Could not open (%s) for truncation: %s",
                               e->fts_path, strerror(errno));
                    if (!force)
                        exit(EXIT_FAILURE);
                    break;
                }

                if (!unlink_entry(e))
                    break;

                off_t boundary = e->fts_statp->st_size;
                /* We don't care about sparseness of the
                 * file and approach this as logical trim */
                while (boundary >= chunk) {
                    boundary -= chunk;
                    if (ftruncate(fd, boundary) < 0) {
                        g_printerr("Could not truncate (%s): %s\n",
                                   e->fts_path, strerror(errno));
                        if (!force)
                            exit(EXIT_FAILURE);
                        break;
                    } else if (!nofsync) {
                        fsync(fd);
                    }
                    dream();
                }
                if (fd > -1)
                    close(fd);

            } else {
                /* Small file case */
                if (unlink_entry(e))
                    the_counter += e->fts_statp->st_size;
            }
            break;
        default:
            /* Everything else */
            unlink_entry(e);
        }
        if (the_counter > chunk) {
            if (!nofsync) {
                int fd = open(".", O_DIRECTORY);
                fsync(fd);
                if (fd >  -1)
                    close(fd);
            }
            dream();
        }
    }

    if (fts)
        fts_close(fts);

    return EXIT_SUCCESS;
}