static int write_file_filtered( git_oid *id, git_off_t *size, git_odb *odb, const char *full_path, git_filter_list *fl) { int error; git_buf tgt = GIT_BUF_INIT; error = git_filter_list_apply_to_file(&tgt, fl, NULL, full_path); /* Write the file to disk if it was properly filtered */ if (!error) { *size = tgt.size; error = git_odb_write(id, odb, tgt.ptr, tgt.size, GIT_OBJECT_BLOB); } git_buf_dispose(&tgt); return error; }
static int workdir_reader_read( git_buf *out, git_oid *out_id, git_filemode_t *out_filemode, git_reader *_reader, const char *filename) { workdir_reader *reader = (workdir_reader *)_reader; git_buf path = GIT_BUF_INIT; struct stat st; git_filemode_t filemode; git_filter_list *filters = NULL; const git_index_entry *idx_entry; git_oid id; int error; if ((error = git_buf_joinpath(&path, git_repository_workdir(reader->repo), filename)) < 0) goto done; if ((error = p_lstat(path.ptr, &st)) < 0) { if (error == -1 && errno == ENOENT) error = GIT_ENOTFOUND; giterr_set(GITERR_OS, "could not stat '%s'", path.ptr); goto done; } filemode = git_futils_canonical_mode(st.st_mode); /* * Patch application - for example - uses the filtered version of * the working directory data to match git. So we will run the * workdir -> ODB filter on the contents in this workdir reader. */ if ((error = git_filter_list_load(&filters, reader->repo, NULL, filename, GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT)) < 0) goto done; if ((error = git_filter_list_apply_to_file(out, filters, reader->repo, path.ptr)) < 0) goto done; if (out_id || reader->index) { if ((error = git_odb_hash(&id, out->ptr, out->size, GIT_OBJ_BLOB)) < 0) goto done; } if (reader->index) { if (!(idx_entry = git_index_get_bypath(reader->index, filename, 0)) || filemode != idx_entry->mode || !git_oid_equal(&id, &idx_entry->id)) { error = GIT_READER_MISMATCH; goto done; } } if (out_id) git_oid_cpy(out_id, &id); if (out_filemode) *out_filemode = filemode; done: git_filter_list_free(filters); git_buf_dispose(&path); return error; }