Merge branch 'pt/am-builtin-abort-fix'

"git am" that was recently reimplemented in C had a performance
regression in "git am --abort" that goes back to the version before
an attempted (and failed) patch application.

* pt/am-builtin-abort-fix:
  am --skip/--abort: merge HEAD/ORIG_HEAD tree into index
This commit is contained in:
Junio C Hamano
2015-08-26 15:45:32 -07:00
2 changed files with 60 additions and 13 deletions

View File

@ -1962,16 +1962,49 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
return 0;
}
/**
* Merges a tree into the index. The index's stat info will take precedence
* over the merged tree's. Returns 0 on success, -1 on failure.
*/
static int merge_tree(struct tree *tree)
{
struct lock_file *lock_file;
struct unpack_trees_options opts;
struct tree_desc t[1];
if (parse_tree(tree))
return -1;
lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
memset(&opts, 0, sizeof(opts));
opts.head_idx = 1;
opts.src_index = &the_index;
opts.dst_index = &the_index;
opts.merge = 1;
opts.fn = oneway_merge;
init_tree_desc(&t[0], tree->buffer, tree->size);
if (unpack_trees(1, t, &opts)) {
rollback_lock_file(lock_file);
return -1;
}
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));
return 0;
}
/**
* Clean the index without touching entries that are not modified between
* `head` and `remote`.
*/
static int clean_index(const unsigned char *head, const unsigned char *remote)
{
struct lock_file *lock_file;
struct tree *head_tree, *remote_tree, *index_tree;
unsigned char index[GIT_SHA1_RAWSZ];
struct pathspec pathspec;
head_tree = parse_tree_indirect(head);
if (!head_tree)
@ -1996,18 +2029,8 @@ static int clean_index(const unsigned char *head, const unsigned char *remote)
if (fast_forward_to(index_tree, remote_tree, 0))
return -1;
memset(&pathspec, 0, sizeof(pathspec));
lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
if (read_tree(remote_tree, 0, &pathspec)) {
rollback_lock_file(lock_file);
if (merge_tree(remote_tree))
return -1;
}
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));
remove_branch_state();