git
/
entry.c
611 строк · 16.0 Кб
1#define USE_THE_REPOSITORY_VARIABLE2
3#include "git-compat-util.h"4#include "object-store-ll.h"5#include "dir.h"6#include "environment.h"7#include "gettext.h"8#include "hex.h"9#include "name-hash.h"10#include "sparse-index.h"11#include "streaming.h"12#include "submodule.h"13#include "symlinks.h"14#include "progress.h"15#include "fsmonitor.h"16#include "entry.h"17#include "parallel-checkout.h"18
19static void create_directories(const char *path, int path_len,20const struct checkout *state)21{
22char *buf = xmallocz(path_len);23int len = 0;24
25while (len < path_len) {26do {27buf[len] = path[len];28len++;29} while (len < path_len && path[len] != '/');30if (len >= path_len)31break;32buf[len] = 0;33
34/*35* For 'checkout-index --prefix=<dir>', <dir> is
36* allowed to be a symlink to an existing directory,
37* and we set 'state->base_dir_len' below, such that
38* we test the path components of the prefix with the
39* stat() function instead of the lstat() function.
40*/
41if (has_dirs_only_path(buf, len, state->base_dir_len))42continue; /* ok, it is already a directory. */43
44/*45* If this mkdir() would fail, it could be that there
46* is already a symlink or something else exists
47* there, therefore we then try to unlink it and try
48* one more time to create the directory.
49*/
50if (mkdir(buf, 0777)) {51if (errno == EEXIST && state->force &&52!unlink_or_warn(buf) && !mkdir(buf, 0777))53continue;54die_errno("cannot create directory at '%s'", buf);55}56}57free(buf);58}
59
60static void remove_subtree(struct strbuf *path)61{
62DIR *dir = opendir(path->buf);63struct dirent *de;64int origlen = path->len;65
66if (!dir)67die_errno("cannot opendir '%s'", path->buf);68while ((de = readdir_skip_dot_and_dotdot(dir)) != NULL) {69struct stat st;70
71strbuf_addch(path, '/');72strbuf_addstr(path, de->d_name);73if (lstat(path->buf, &st))74die_errno("cannot lstat '%s'", path->buf);75if (S_ISDIR(st.st_mode))76remove_subtree(path);77else if (unlink(path->buf))78die_errno("cannot unlink '%s'", path->buf);79strbuf_setlen(path, origlen);80}81closedir(dir);82if (rmdir(path->buf))83die_errno("cannot rmdir '%s'", path->buf);84}
85
86static int create_file(const char *path, unsigned int mode)87{
88mode = (mode & 0100) ? 0777 : 0666;89return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);90}
91
92void *read_blob_entry(const struct cache_entry *ce, size_t *size)93{
94enum object_type type;95unsigned long ul;96void *blob_data = repo_read_object_file(the_repository, &ce->oid,97&type, &ul);98
99*size = ul;100if (blob_data) {101if (type == OBJ_BLOB)102return blob_data;103free(blob_data);104}105return NULL;106}
107
108static int open_output_fd(char *path, const struct cache_entry *ce, int to_tempfile)109{
110int symlink = (ce->ce_mode & S_IFMT) != S_IFREG;111if (to_tempfile) {112xsnprintf(path, TEMPORARY_FILENAME_LENGTH, "%s",113symlink ? ".merge_link_XXXXXX" : ".merge_file_XXXXXX");114return mkstemp(path);115} else {116return create_file(path, !symlink ? ce->ce_mode : 0666);117}118}
119
120int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st)121{
122/* use fstat() only when path == ce->name */123if (fstat_is_reliable() &&124state->refresh_cache && !state->base_dir_len) {125return !fstat(fd, st);126}127return 0;128}
129
130static int streaming_write_entry(const struct cache_entry *ce, char *path,131struct stream_filter *filter,132const struct checkout *state, int to_tempfile,133int *fstat_done, struct stat *statbuf)134{
135int result = 0;136int fd;137
138fd = open_output_fd(path, ce, to_tempfile);139if (fd < 0)140return -1;141
142result |= stream_blob_to_fd(fd, &ce->oid, filter, 1);143*fstat_done = fstat_checkout_output(fd, state, statbuf);144result |= close(fd);145
146if (result)147unlink(path);148return result;149}
150
151void enable_delayed_checkout(struct checkout *state)152{
153if (!state->delayed_checkout) {154state->delayed_checkout = xmalloc(sizeof(*state->delayed_checkout));155state->delayed_checkout->state = CE_CAN_DELAY;156string_list_init_nodup(&state->delayed_checkout->filters);157string_list_init_nodup(&state->delayed_checkout->paths);158}159}
160
161static int remove_available_paths(struct string_list_item *item, void *cb_data)162{
163struct string_list *available_paths = cb_data;164struct string_list_item *available;165
166available = string_list_lookup(available_paths, item->string);167if (available)168available->util = item->util;169return !available;170}
171
172static int string_is_not_null(struct string_list_item *item, void *data UNUSED)173{
174return !!item->string;175}
176
177int finish_delayed_checkout(struct checkout *state, int show_progress)178{
179int errs = 0;180unsigned processed_paths = 0;181off_t filtered_bytes = 0;182struct string_list_item *filter, *path;183struct progress *progress = NULL;184struct delayed_checkout *dco = state->delayed_checkout;185
186if (!state->delayed_checkout)187return errs;188
189dco->state = CE_RETRY;190if (show_progress)191progress = start_delayed_progress(_("Filtering content"), dco->paths.nr);192while (dco->filters.nr > 0) {193for_each_string_list_item(filter, &dco->filters) {194struct string_list available_paths = STRING_LIST_INIT_DUP;195
196if (!async_query_available_blobs(filter->string, &available_paths)) {197/* Filter reported an error */198errs = 1;199filter->string = NULL;200continue;201}202if (available_paths.nr <= 0) {203/*204* Filter responded with no entries. That means
205* the filter is done and we can remove the
206* filter from the list (see
207* "string_list_remove_empty_items" call below).
208*/
209filter->string = NULL;210continue;211}212
213/*214* In dco->paths we store a list of all delayed paths.
215* The filter just send us a list of available paths.
216* Remove them from the list.
217*/
218filter_string_list(&dco->paths, 0,219&remove_available_paths, &available_paths);220
221for_each_string_list_item(path, &available_paths) {222struct cache_entry* ce;223
224if (!path->util) {225error("external filter '%s' signaled that '%s' "226"is now available although it has not been "227"delayed earlier",228filter->string, path->string);229errs |= 1;230
231/*232* Do not ask the filter for available blobs,
233* again, as the filter is likely buggy.
234*/
235filter->string = NULL;236continue;237}238ce = index_file_exists(state->istate, path->string,239strlen(path->string), 0);240if (ce) {241display_progress(progress, ++processed_paths);242errs |= checkout_entry(ce, state, NULL, path->util);243filtered_bytes += ce->ce_stat_data.sd_size;244display_throughput(progress, filtered_bytes);245} else246errs = 1;247}248
249string_list_clear(&available_paths, 0);250}251
252filter_string_list(&dco->filters, 0, string_is_not_null, NULL);253}254stop_progress(&progress);255string_list_clear(&dco->filters, 0);256
257/* At this point we should not have any delayed paths anymore. */258errs |= dco->paths.nr;259for_each_string_list_item(path, &dco->paths) {260error("'%s' was not filtered properly", path->string);261}262string_list_clear(&dco->paths, 0);263
264free(dco);265state->delayed_checkout = NULL;266
267return errs;268}
269
270void update_ce_after_write(const struct checkout *state, struct cache_entry *ce,271struct stat *st)272{
273if (state->refresh_cache) {274assert(state->istate);275fill_stat_cache_info(state->istate, ce, st);276ce->ce_flags |= CE_UPDATE_IN_BASE;277mark_fsmonitor_invalid(state->istate, ce);278state->istate->cache_changed |= CE_ENTRY_CHANGED;279}280}
281
282/* Note: ca is used (and required) iff the entry refers to a regular file. */
283static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca,284const struct checkout *state, int to_tempfile,285int *nr_checkouts)286{
287unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;288struct delayed_checkout *dco = state->delayed_checkout;289int fd, ret, fstat_done = 0;290char *new_blob;291struct strbuf buf = STRBUF_INIT;292size_t size;293ssize_t wrote;294size_t newsize = 0;295struct stat st;296const struct submodule *sub;297struct checkout_metadata meta;298static int scratch_nr_checkouts;299
300clone_checkout_metadata(&meta, &state->meta, &ce->oid);301
302if (ce_mode_s_ifmt == S_IFREG) {303struct stream_filter *filter = get_stream_filter_ca(ca, &ce->oid);304if (filter &&305!streaming_write_entry(ce, path, filter,306state, to_tempfile,307&fstat_done, &st))308goto finish;309}310
311switch (ce_mode_s_ifmt) {312case S_IFLNK:313new_blob = read_blob_entry(ce, &size);314if (!new_blob)315return error("unable to read sha1 file of %s (%s)",316ce->name, oid_to_hex(&ce->oid));317
318/*319* We can't make a real symlink; write out a regular file entry
320* with the symlink destination as its contents.
321*/
322if (!has_symlinks || to_tempfile)323goto write_file_entry;324
325ret = symlink(new_blob, path);326free(new_blob);327if (ret)328return error_errno("unable to create symlink %s", path);329break;330
331case S_IFREG:332/*333* We do not send the blob in case of a retry, so do not
334* bother reading it at all.
335*/
336if (dco && dco->state == CE_RETRY) {337new_blob = NULL;338size = 0;339} else {340new_blob = read_blob_entry(ce, &size);341if (!new_blob)342return error("unable to read sha1 file of %s (%s)",343ce->name, oid_to_hex(&ce->oid));344}345
346/*347* Convert from git internal format to working tree format
348*/
349if (dco && dco->state != CE_NO_DELAY) {350ret = async_convert_to_working_tree_ca(ca, ce->name,351new_blob, size,352&buf, &meta, dco);353if (ret) {354struct string_list_item *item =355string_list_lookup(&dco->paths, ce->name);356if (item) {357item->util = nr_checkouts ? nr_checkouts358: &scratch_nr_checkouts;359free(new_blob);360goto delayed;361}362}363} else {364ret = convert_to_working_tree_ca(ca, ce->name, new_blob,365size, &buf, &meta);366}367
368if (ret) {369free(new_blob);370new_blob = strbuf_detach(&buf, &newsize);371size = newsize;372}373/*374* No "else" here as errors from convert are OK at this
375* point. If the error would have been fatal (e.g.
376* filter is required), then we would have died already.
377*/
378
379write_file_entry:380fd = open_output_fd(path, ce, to_tempfile);381if (fd < 0) {382free(new_blob);383return error_errno("unable to create file %s", path);384}385
386wrote = write_in_full(fd, new_blob, size);387if (!to_tempfile)388fstat_done = fstat_checkout_output(fd, state, &st);389close(fd);390free(new_blob);391if (wrote < 0)392return error("unable to write file %s", path);393break;394
395case S_IFGITLINK:396if (to_tempfile)397return error("cannot create temporary submodule %s", ce->name);398if (mkdir(path, 0777) < 0)399return error("cannot create submodule directory %s", path);400sub = submodule_from_ce(ce);401if (sub)402return submodule_move_head(ce->name, state->super_prefix,403NULL, oid_to_hex(&ce->oid),404state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);405break;406
407default:408return error("unknown file mode for %s in index", ce->name);409}410
411finish:412if (state->refresh_cache) {413if (!fstat_done && lstat(ce->name, &st) < 0)414return error_errno("unable to stat just-written file %s",415ce->name);416update_ce_after_write(state, ce , &st);417}418if (nr_checkouts)419(*nr_checkouts)++;420delayed:421return 0;422}
423
424/*
425* This is like 'lstat()', except it refuses to follow symlinks
426* in the path, after skipping "skiplen".
427*/
428static int check_path(const char *path, int len, struct stat *st, int skiplen)429{
430const char *slash = path + len;431
432while (path < slash && *slash != '/')433slash--;434if (!has_dirs_only_path(path, slash - path, skiplen)) {435errno = ENOENT;436return -1;437}438return lstat(path, st);439}
440
441static void mark_colliding_entries(const struct checkout *state,442struct cache_entry *ce, struct stat *st)443{
444int i, trust_ino = check_stat;445
446#if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__)447trust_ino = 0;448#endif449
450ce->ce_flags |= CE_MATCHED;451
452/* TODO: audit for interaction with sparse-index. */453ensure_full_index(state->istate);454for (i = 0; i < state->istate->cache_nr; i++) {455struct cache_entry *dup = state->istate->cache[i];456
457if (dup == ce) {458/*459* Parallel checkout doesn't create the files in index
460* order. So the other side of the collision may appear
461* after the given cache_entry in the array.
462*/
463if (parallel_checkout_status() == PC_RUNNING)464continue;465else466break;467}468
469if (dup->ce_flags & (CE_MATCHED | CE_VALID | CE_SKIP_WORKTREE))470continue;471
472if ((trust_ino && !match_stat_data(&dup->ce_stat_data, st)) ||473paths_collide(ce->name, dup->name)) {474dup->ce_flags |= CE_MATCHED;475break;476}477}478}
479
480int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca,481const struct checkout *state, char *topath,482int *nr_checkouts)483{
484static struct strbuf path = STRBUF_INIT;485struct stat st;486struct conv_attrs ca_buf;487
488if (ce->ce_flags & CE_WT_REMOVE) {489if (topath)490/*491* No content and thus no path to create, so we have
492* no pathname to return.
493*/
494BUG("Can't remove entry to a path");495unlink_entry(ce, state->super_prefix);496return 0;497}498
499if (topath) {500if (S_ISREG(ce->ce_mode) && !ca) {501convert_attrs(state->istate, &ca_buf, ce->name);502ca = &ca_buf;503}504return write_entry(ce, topath, ca, state, 1, nr_checkouts);505}506
507strbuf_reset(&path);508strbuf_add(&path, state->base_dir, state->base_dir_len);509strbuf_add(&path, ce->name, ce_namelen(ce));510
511if (!check_path(path.buf, path.len, &st, state->base_dir_len)) {512const struct submodule *sub;513unsigned changed = ie_match_stat(state->istate, ce, &st,514CE_MATCH_IGNORE_VALID | CE_MATCH_IGNORE_SKIP_WORKTREE);515/*516* Needs to be checked before !changed returns early,
517* as the possibly empty directory was not changed
518*/
519sub = submodule_from_ce(ce);520if (sub) {521int err;522if (!is_submodule_populated_gently(ce->name, &err)) {523struct stat sb;524if (lstat(ce->name, &sb))525die(_("could not stat file '%s'"), ce->name);526if (!(st.st_mode & S_IFDIR))527unlink_or_warn(ce->name);528
529return submodule_move_head(ce->name, state->super_prefix,530NULL, oid_to_hex(&ce->oid), 0);531} else532return submodule_move_head(ce->name, state->super_prefix,533"HEAD", oid_to_hex(&ce->oid),534state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);535}536
537if (!changed)538return 0;539if (!state->force) {540if (!state->quiet)541fprintf(stderr,542"%s already exists, no checkout\n",543path.buf);544return -1;545}546
547if (state->clone)548mark_colliding_entries(state, ce, &st);549
550/*551* We unlink the old file, to get the new one with the
552* right permissions (including umask, which is nasty
553* to emulate by hand - much easier to let the system
554* just do the right thing)
555*/
556if (S_ISDIR(st.st_mode)) {557/* If it is a gitlink, leave it alone! */558if (S_ISGITLINK(ce->ce_mode))559return 0;560/*561* We must avoid replacing submodules' leading
562* directories with symbolic links, lest recursive
563* clones can write into arbitrary locations.
564*
565* Technically, this logic is not limited
566* to recursive clones, or for that matter to
567* submodules' paths colliding with symbolic links'
568* paths. Yet it strikes a balance in favor of
569* simplicity, and if paths are colliding, we might
570* just as well keep the directories during a clone.
571*/
572if (state->clone && S_ISLNK(ce->ce_mode))573return 0;574remove_subtree(&path);575} else if (unlink(path.buf))576return error_errno("unable to unlink old '%s'", path.buf);577} else if (state->not_new)578return 0;579
580create_directories(path.buf, path.len, state);581
582if (S_ISREG(ce->ce_mode) && !ca) {583convert_attrs(state->istate, &ca_buf, ce->name);584ca = &ca_buf;585}586
587if (!enqueue_checkout(ce, ca, nr_checkouts))588return 0;589
590return write_entry(ce, path.buf, ca, state, 0, nr_checkouts);591}
592
593void unlink_entry(const struct cache_entry *ce, const char *super_prefix)594{
595const struct submodule *sub = submodule_from_ce(ce);596if (sub) {597/* state.force is set at the caller. */598submodule_move_head(ce->name, super_prefix, "HEAD", NULL,599SUBMODULE_MOVE_HEAD_FORCE);600}601if (check_leading_path(ce->name, ce_namelen(ce), 1) >= 0)602return;603if (remove_or_warn(ce->ce_mode, ce->name))604return;605schedule_dir_for_removal(ce->name, ce_namelen(ce));606}
607
608int remove_or_warn(unsigned int mode, const char *file)609{
610return S_ISGITLINK(mode) ? rmdir_or_warn(file) : unlink_or_warn(file);611}
612