Skip to content

Commit

Permalink
Merge branch 'mt/parallel-checkout-part-1'
Browse files Browse the repository at this point in the history
Preparatory API changes for parallel checkout.

* mt/parallel-checkout-part-1:
  entry: add checkout_entry_ca() taking preloaded conv_attrs
  entry: move conv_attrs lookup up to checkout_entry()
  entry: extract update_ce_after_write() from write_entry()
  entry: make fstat_output() and read_blob_entry() public
  entry: extract a header file for entry.c functions
  convert: add classification for conv_attrs struct
  convert: add get_stream_filter_ca() variant
  convert: add [async_]convert_to_working_tree_ca() variants
  convert: make convert_attrs() and convert structs public
  • Loading branch information
gitster committed Apr 2, 2021
2 parents a65ce7f + ae22751 commit c47679d
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 137 deletions.
1 change: 1 addition & 0 deletions apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "quote.h"
#include "rerere.h"
#include "apply.h"
#include "entry.h"

struct gitdiff_data {
struct strbuf *root;
Expand Down
1 change: 1 addition & 0 deletions builtin/checkout-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "quote.h"
#include "cache-tree.h"
#include "parse-options.h"
#include "entry.h"

#define CHECKOUT_ALL 4
static int nul_term_line;
Expand Down
1 change: 1 addition & 0 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "unpack-trees.h"
#include "wt-status.h"
#include "xdiff-interface.h"
#include "entry.h"

static const char * const checkout_usage[] = {
N_("git checkout [<options>] <branch>"),
Expand Down
1 change: 1 addition & 0 deletions builtin/difftool.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "lockfile.h"
#include "object-store.h"
#include "dir.h"
#include "entry.h"

static int trust_exit_code;

Expand Down
2 changes: 2 additions & 0 deletions builtin/stash.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
#include "strvec.h"
#include "run-command.h"
#include "dir.h"
#include "entry.h"
#include "rerere.h"
#include "revision.h"
#include "log-tree.h"
#include "diffcore.h"
#include "exec-cmd.h"
#include "entry.h"

#define INCLUDE_ALL_FILES 2

Expand Down
24 changes: 0 additions & 24 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1621,30 +1621,6 @@ const char *show_ident_date(const struct ident_split *id,
*/
int ident_cmp(const struct ident_split *, const struct ident_split *);

struct checkout {
struct index_state *istate;
const char *base_dir;
int base_dir_len;
struct delayed_checkout *delayed_checkout;
struct checkout_metadata meta;
unsigned force:1,
quiet:1,
not_new:1,
clone:1,
refresh_cache:1;
};
#define CHECKOUT_INIT { NULL, "" }

#define TEMPORARY_FILENAME_LENGTH 25
int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath, int *nr_checkouts);
void enable_delayed_checkout(struct checkout *state);
int finish_delayed_checkout(struct checkout *state, int *nr_checkouts);
/*
* Unlink the last component and schedule the leading directories for
* removal, such that empty directories get removed.
*/
void unlink_entry(const struct cache_entry *ce);

struct cache_def {
struct strbuf path;
int flags;
Expand Down
143 changes: 73 additions & 70 deletions convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@
#define CONVERT_STAT_BITS_TXT_CRLF 0x2
#define CONVERT_STAT_BITS_BIN 0x4

enum crlf_action {
CRLF_UNDEFINED,
CRLF_BINARY,
CRLF_TEXT,
CRLF_TEXT_INPUT,
CRLF_TEXT_CRLF,
CRLF_AUTO,
CRLF_AUTO_INPUT,
CRLF_AUTO_CRLF
};

struct text_stat {
/* NUL, CR, LF and CRLF counts */
unsigned nul, lonecr, lonelf, crlf;
Expand Down Expand Up @@ -172,7 +161,7 @@ static int text_eol_is_crlf(void)
return 0;
}

static enum eol output_eol(enum crlf_action crlf_action)
static enum eol output_eol(enum convert_crlf_action crlf_action)
{
switch (crlf_action) {
case CRLF_BINARY:
Expand Down Expand Up @@ -246,7 +235,7 @@ static int has_crlf_in_index(const struct index_state *istate, const char *path)
}

static int will_convert_lf_to_crlf(struct text_stat *stats,
enum crlf_action crlf_action)
enum convert_crlf_action crlf_action)
{
if (output_eol(crlf_action) != EOL_CRLF)
return 0;
Expand Down Expand Up @@ -499,7 +488,7 @@ static int encode_to_worktree(const char *path, const char *src, size_t src_len,
static int crlf_to_git(const struct index_state *istate,
const char *path, const char *src, size_t len,
struct strbuf *buf,
enum crlf_action crlf_action, int conv_flags)
enum convert_crlf_action crlf_action, int conv_flags)
{
struct text_stat stats;
char *dst;
Expand Down Expand Up @@ -585,8 +574,8 @@ static int crlf_to_git(const struct index_state *istate,
return 1;
}

static int crlf_to_worktree(const char *src, size_t len,
struct strbuf *buf, enum crlf_action crlf_action)
static int crlf_to_worktree(const char *src, size_t len, struct strbuf *buf,
enum convert_crlf_action crlf_action)
{
char *to_free = NULL;
struct text_stat stats;
Expand Down Expand Up @@ -1247,7 +1236,7 @@ static const char *git_path_check_encoding(struct attr_check_item *check)
return value;
}

static enum crlf_action git_path_check_crlf(struct attr_check_item *check)
static enum convert_crlf_action git_path_check_crlf(struct attr_check_item *check)
{
const char *value = check->value;

Expand Down Expand Up @@ -1297,18 +1286,10 @@ static int git_path_check_ident(struct attr_check_item *check)
return !!ATTR_TRUE(value);
}

struct conv_attrs {
struct convert_driver *drv;
enum crlf_action attr_action; /* What attr says */
enum crlf_action crlf_action; /* When no attr is set, use core.autocrlf */
int ident;
const char *working_tree_encoding; /* Supported encoding or default encoding if NULL */
};

static struct attr_check *check;

static void convert_attrs(const struct index_state *istate,
struct conv_attrs *ca, const char *path)
void convert_attrs(const struct index_state *istate,
struct conv_attrs *ca, const char *path)
{
struct attr_check_item *ccheck = NULL;

Expand Down Expand Up @@ -1465,19 +1446,16 @@ void convert_to_git_filter_fd(const struct index_state *istate,
ident_to_git(dst->buf, dst->len, dst, ca.ident);
}

static int convert_to_working_tree_internal(const struct index_state *istate,
const char *path, const char *src,
size_t len, struct strbuf *dst,
int normalizing,
const struct checkout_metadata *meta,
struct delayed_checkout *dco)
static int convert_to_working_tree_ca_internal(const struct conv_attrs *ca,
const char *path, const char *src,
size_t len, struct strbuf *dst,
int normalizing,
const struct checkout_metadata *meta,
struct delayed_checkout *dco)
{
int ret = 0, ret_filter = 0;
struct conv_attrs ca;

convert_attrs(istate, &ca, path);

ret |= ident_to_worktree(src, len, dst, ca.ident);
ret |= ident_to_worktree(src, len, dst, ca->ident);
if (ret) {
src = dst->buf;
len = dst->len;
Expand All @@ -1487,49 +1465,56 @@ static int convert_to_working_tree_internal(const struct index_state *istate,
* is a smudge or process filter (even if the process filter doesn't
* support smudge). The filters might expect CRLFs.
*/
if ((ca.drv && (ca.drv->smudge || ca.drv->process)) || !normalizing) {
ret |= crlf_to_worktree(src, len, dst, ca.crlf_action);
if ((ca->drv && (ca->drv->smudge || ca->drv->process)) || !normalizing) {
ret |= crlf_to_worktree(src, len, dst, ca->crlf_action);
if (ret) {
src = dst->buf;
len = dst->len;
}
}

ret |= encode_to_worktree(path, src, len, dst, ca.working_tree_encoding);
ret |= encode_to_worktree(path, src, len, dst, ca->working_tree_encoding);
if (ret) {
src = dst->buf;
len = dst->len;
}

ret_filter = apply_filter(
path, src, len, -1, dst, ca.drv, CAP_SMUDGE, meta, dco);
if (!ret_filter && ca.drv && ca.drv->required)
die(_("%s: smudge filter %s failed"), path, ca.drv->name);
path, src, len, -1, dst, ca->drv, CAP_SMUDGE, meta, dco);
if (!ret_filter && ca->drv && ca->drv->required)
die(_("%s: smudge filter %s failed"), path, ca->drv->name);

return ret | ret_filter;
}

int async_convert_to_working_tree(const struct index_state *istate,
const char *path, const char *src,
size_t len, struct strbuf *dst,
const struct checkout_metadata *meta,
void *dco)
int async_convert_to_working_tree_ca(const struct conv_attrs *ca,
const char *path, const char *src,
size_t len, struct strbuf *dst,
const struct checkout_metadata *meta,
void *dco)
{
return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, dco);
return convert_to_working_tree_ca_internal(ca, path, src, len, dst, 0,
meta, dco);
}

int convert_to_working_tree(const struct index_state *istate,
const char *path, const char *src,
size_t len, struct strbuf *dst,
const struct checkout_metadata *meta)
int convert_to_working_tree_ca(const struct conv_attrs *ca,
const char *path, const char *src,
size_t len, struct strbuf *dst,
const struct checkout_metadata *meta)
{
return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, NULL);
return convert_to_working_tree_ca_internal(ca, path, src, len, dst, 0,
meta, NULL);
}

int renormalize_buffer(const struct index_state *istate, const char *path,
const char *src, size_t len, struct strbuf *dst)
{
int ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL, NULL);
struct conv_attrs ca;
int ret;

convert_attrs(istate, &ca, path);
ret = convert_to_working_tree_ca_internal(&ca, path, src, len, dst, 1,
NULL, NULL);
if (ret) {
src = dst->buf;
len = dst->len;
Expand Down Expand Up @@ -1956,41 +1941,41 @@ static struct stream_filter *ident_filter(const struct object_id *oid)
}

/*
* Return an appropriately constructed filter for the path, or NULL if
* Return an appropriately constructed filter for the given ca, or NULL if
* the contents cannot be filtered without reading the whole thing
* in-core.
*
* Note that you would be crazy to set CRLF, smudge/clean or ident to a
* large binary blob you would want us not to slurp into the memory!
*/
struct stream_filter *get_stream_filter(const struct index_state *istate,
const char *path,
const struct object_id *oid)
struct stream_filter *get_stream_filter_ca(const struct conv_attrs *ca,
const struct object_id *oid)
{
struct conv_attrs ca;
struct stream_filter *filter = NULL;

convert_attrs(istate, &ca, path);
if (ca.drv && (ca.drv->process || ca.drv->smudge || ca.drv->clean))
return NULL;

if (ca.working_tree_encoding)
if (classify_conv_attrs(ca) != CA_CLASS_STREAMABLE)
return NULL;

if (ca.crlf_action == CRLF_AUTO || ca.crlf_action == CRLF_AUTO_CRLF)
return NULL;

if (ca.ident)
if (ca->ident)
filter = ident_filter(oid);

if (output_eol(ca.crlf_action) == EOL_CRLF)
if (output_eol(ca->crlf_action) == EOL_CRLF)
filter = cascade_filter(filter, lf_to_crlf_filter());
else
filter = cascade_filter(filter, &null_filter_singleton);

return filter;
}

struct stream_filter *get_stream_filter(const struct index_state *istate,
const char *path,
const struct object_id *oid)
{
struct conv_attrs ca;
convert_attrs(istate, &ca, path);
return get_stream_filter_ca(&ca, oid);
}

void free_stream_filter(struct stream_filter *filter)
{
filter->vtbl->free(filter);
Expand Down Expand Up @@ -2024,3 +2009,21 @@ void clone_checkout_metadata(struct checkout_metadata *dst,
if (blob)
oidcpy(&dst->blob, blob);
}

enum conv_attrs_classification classify_conv_attrs(const struct conv_attrs *ca)
{
if (ca->drv) {
if (ca->drv->process)
return CA_CLASS_INCORE_PROCESS;
if (ca->drv->smudge || ca->drv->clean)
return CA_CLASS_INCORE_FILTER;
}

if (ca->working_tree_encoding)
return CA_CLASS_INCORE;

if (ca->crlf_action == CRLF_AUTO || ca->crlf_action == CRLF_AUTO_CRLF)
return CA_CLASS_INCORE;

return CA_CLASS_STREAMABLE;
}
Loading

0 comments on commit c47679d

Please sign in to comment.