summaryrefslogtreecommitdiff
path: root/unpack-trees.c
diff options
context:
space:
mode:
Diffstat (limited to 'unpack-trees.c')
-rw-r--r--unpack-trees.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/unpack-trees.c b/unpack-trees.c
index e73745051e..3a85a02a77 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -1,5 +1,6 @@
#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
+#include "argv-array.h"
#include "repository.h"
#include "config.h"
#include "dir.h"
@@ -103,6 +104,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
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"
@@ -119,7 +122,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
"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");
@@ -139,7 +142,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
? _("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
@@ -156,7 +160,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
? _("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
@@ -179,6 +184,12 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
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)
{
@@ -290,7 +301,7 @@ static void load_gitmodules_file(struct index_state *index,
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);
}
@@ -398,7 +409,7 @@ static int check_updates(struct unpack_trees_options *o)
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;
@@ -1284,10 +1295,21 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
o->result.timestamp.sec = o->src_index->timestamp.sec;
o->result.timestamp.nsec = o->src_index->timestamp.nsec;
o->result.version = o->src_index->version;
- o->result.split_index = o->src_index->split_index;
- if (o->result.split_index)
+ if (!o->src_index->split_index) {
+ o->result.split_index = NULL;
+ } else if (o->src_index == o->dst_index) {
+ /*
+ * o->dst_index (and thus o->src_index) will be discarded
+ * and overwritten with o->result at the end of this function,
+ * so just use src_index's split_index to avoid having to
+ * create a new one.
+ */
+ o->result.split_index = o->src_index->split_index;
o->result.split_index->refcount++;
- hashcpy(o->result.sha1, o->src_index->sha1);
+ } else {
+ o->result.split_index = init_split_index(&o->result);
+ }
+ oidcpy(&o->result.oid, &o->src_index->oid);
o->merge_size = len;
mark_all_ce_unused(o->src_index);
@@ -1401,7 +1423,6 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
}
}
- o->src_index = NULL;
ret = check_updates(o) ? (-2) : 0;
if (o->dst_index) {
if (!ret) {
@@ -1412,12 +1433,13 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
WRITE_TREE_SILENT |
WRITE_TREE_REPAIR);
}
- move_index_extensions(&o->result, o->dst_index);
+ move_index_extensions(&o->result, o->src_index);
discard_index(o->dst_index);
*o->dst_index = o->result;
} else {
discard_index(&o->result);
}
+ o->src_index = NULL;
done:
clear_exclude_list(&el);
@@ -1509,8 +1531,8 @@ static int verify_uptodate_1(const struct cache_entry *ce,
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;