#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
+#include "argv-array.h"
#include "repository.h"
#include "config.h"
#include "dir.h"
#include "submodule.h"
#include "submodule-config.h"
#include "fsmonitor.h"
+#include "object-store.h"
#include "fetch-object.h"
/*
const char **msgs = opts->msgs;
const char *msg;
+ argv_array_init(&opts->msgs_to_free);
+
if (!strcmp(cmd, "checkout"))
msg = advice_commit_before_merge
? _("Your local changes to the following files would be overwritten by checkout:\n%%s"
"Please commit your changes or stash them before you %s.")
: _("Your local changes to the following files would be overwritten by %s:\n%%s");
msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] =
- xstrfmt(msg, cmd, cmd);
+ argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
msgs[ERROR_NOT_UPTODATE_DIR] =
_("Updating the following directories would lose untracked files in them:\n%s");
? _("The following untracked working tree files would be removed by %s:\n%%s"
"Please move or remove them before you %s.")
: _("The following untracked working tree files would be removed by %s:\n%%s");
- msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, cmd, cmd);
+ msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] =
+ argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
if (!strcmp(cmd, "checkout"))
msg = advice_commit_before_merge
? _("The following untracked working tree files would be overwritten by %s:\n%%s"
"Please move or remove them before you %s.")
: _("The following untracked working tree files would be overwritten by %s:\n%%s");
- msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, cmd, cmd);
+ msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] =
+ argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
/*
* Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we
opts->unpack_rejects[i].strdup_strings = 1;
}
+void clear_unpack_trees_porcelain(struct unpack_trees_options *opts)
+{
+ argv_array_clear(&opts->msgs_to_free);
+ memset(opts->msgs, 0, sizeof(opts->msgs));
+}
+
static int do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
unsigned int set, unsigned int clear)
{
ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
}
-static struct cache_entry *dup_entry(const struct cache_entry *ce)
-{
- unsigned int size = ce_size(ce);
- struct cache_entry *new_entry = xmalloc(size);
-
- memcpy(new_entry, ce, size);
- return new_entry;
-}
-
static void add_entry(struct unpack_trees_options *o,
const struct cache_entry *ce,
unsigned int set, unsigned int clear)
{
- do_add_entry(o, dup_entry(ce), set, clear);
+ do_add_entry(o, dup_cache_entry(ce, &o->result), set, clear);
}
/*
if (!state && ce->ce_flags & CE_WT_REMOVE) {
repo_read_gitmodules(the_repository);
} else if (state && (ce->ce_flags & CE_UPDATE)) {
- submodule_free();
+ submodule_free(the_repository);
checkout_entry(ce, state, NULL);
repo_read_gitmodules(the_repository);
}
if (ce->ce_flags & CE_UPDATE) {
if (ce->ce_flags & CE_WT_REMOVE)
- die("BUG: both update and delete flags are set on %s",
+ BUG("both update and delete flags are set on %s",
ce->name);
display_progress(progress, ++cnt);
ce->ce_flags &= ~CE_UPDATE;
return (info->pathlen < ce_namelen(ce));
}
-static struct cache_entry *create_ce_entry(const struct traverse_info *info, const struct name_entry *n, int stage)
+static struct cache_entry *create_ce_entry(const struct traverse_info *info,
+ const struct name_entry *n,
+ int stage,
+ struct index_state *istate,
+ int is_transient)
{
int len = traverse_path_len(info, n);
- struct cache_entry *ce = xcalloc(1, cache_entry_size(len));
+ struct cache_entry *ce =
+ is_transient ?
+ make_empty_transient_cache_entry(len) :
+ make_empty_cache_entry(istate, len);
ce->ce_mode = create_ce_mode(n->mode);
ce->ce_flags = create_ce_flags(stage);
stage = 3;
else
stage = 2;
- src[i + o->merge] = create_ce_entry(info, names + i, stage);
+
+ /*
+ * If the merge bit is set, then the cache entries are
+ * discarded in the following block. In this case,
+ * construct "transient" cache_entries, as they are
+ * not stored in the index. otherwise construct the
+ * cache entry from the index aware logic.
+ */
+ src[i + o->merge] = create_ce_entry(info, names + i, stage, &o->result, o->merge);
}
if (o->merge) {
for (i = 0; i < n; i++) {
struct cache_entry *ce = src[i + o->merge];
if (ce != o->df_conflict_entry)
- free(ce);
+ discard_cache_entry(ce);
}
return rc;
}
if (select_flag && !(ce->ce_flags & select_flag))
continue;
- if (!ce_stage(ce))
+ if (!ce_stage(ce) && !(ce->ce_flags & CE_CONFLICTED))
ce->ce_flags |= skip_wt_flag;
else
ce->ce_flags &= ~skip_wt_flag;
} else {
o->result.split_index = init_split_index(&o->result);
}
- hashcpy(o->result.sha1, o->src_index->sha1);
+ oidcpy(&o->result.oid, &o->src_index->oid);
o->merge_size = len;
mark_all_ce_unused(o->src_index);
add_rejected_path(o, error_type, ce->name);
}
-static int verify_uptodate(const struct cache_entry *ce,
- struct unpack_trees_options *o)
+int verify_uptodate(const struct cache_entry *ce,
+ struct unpack_trees_options *o)
{
if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE))
return 0;
struct unpack_trees_options *o)
{
int update = CE_UPDATE;
- struct cache_entry *merge = dup_entry(ce);
+ struct cache_entry *merge = dup_cache_entry(ce, &o->result);
if (!old) {
/*
if (verify_absent(merge,
ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) {
- free(merge);
+ discard_cache_entry(merge);
return -1;
}
invalidate_ce_path(merge, o);
update = 0;
} else {
if (verify_uptodate(old, o)) {
- free(merge);
+ discard_cache_entry(merge);
return -1;
}
/* Migrate old flags over */