Skip to content

Commit d0f379c

Browse files
sbeyergitster
authored andcommitted
reset: use "unpack_trees()" directly instead of "git read-tree"
This patch makes "reset_index_file()" call "unpack_trees()" directly instead of forking and execing "git read-tree". So the code is more efficient. And it's also easier to see which unpack_tree() options will be used, as we don't need to follow "git read-tree"'s command line parsing which is quite complex. As Daniel Barkalow found, there is a difference between this new version and the old one. The old version gives an error for "git reset --merge" with unmerged entries, and the new version does not when we reset the entries to some states that differ from HEAD. Instead, it resets the index entry and succeeds, while leaving the conflict markers in the corresponding file in the work tree (which will be corrected by the next patch). The code comes from the sequencer GSoC project: git://repo.or.cz/git/sbeyer.git (at commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079) Mentored-by: Daniel Barkalow <[email protected]> Mentored-by: Christian Couder <[email protected]> Signed-off-by: Stephan Beyer <[email protected]> Signed-off-by: Christian Couder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c939669 commit d0f379c

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

Documentation/git-reset.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ entries:
122122
X U A B --soft (disallowed)
123123
--mixed X B B
124124
--hard B B B
125-
--merge (disallowed)
125+
--merge X B B
126126

127127
working index HEAD target working index HEAD
128128
----------------------------------------------------

builtin-reset.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "tree.h"
1919
#include "branch.h"
2020
#include "parse-options.h"
21+
#include "unpack-trees.h"
22+
#include "cache-tree.h"
2123

2224
static const char * const git_reset_usage[] = {
2325
"git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
@@ -54,27 +56,44 @@ static inline int is_merge(void)
5456

5557
static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet)
5658
{
57-
int i = 0;
58-
const char *args[6];
59+
int nr = 1;
60+
int newfd;
61+
struct tree_desc desc[2];
62+
struct unpack_trees_options opts;
63+
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
5964

60-
args[i++] = "read-tree";
65+
memset(&opts, 0, sizeof(opts));
66+
opts.head_idx = 1;
67+
opts.src_index = &the_index;
68+
opts.dst_index = &the_index;
69+
opts.fn = oneway_merge;
70+
opts.merge = 1;
6171
if (!quiet)
62-
args[i++] = "-v";
72+
opts.verbose_update = 1;
6373
switch (reset_type) {
6474
case MERGE:
65-
args[i++] = "-u";
66-
args[i++] = "-m";
75+
opts.update = 1;
6776
break;
6877
case HARD:
69-
args[i++] = "-u";
78+
opts.update = 1;
7079
/* fallthrough */
7180
default:
72-
args[i++] = "--reset";
81+
opts.reset = 1;
7382
}
74-
args[i++] = sha1_to_hex(sha1);
75-
args[i] = NULL;
7683

77-
return run_command_v_opt(args, RUN_GIT_CMD);
84+
newfd = hold_locked_index(lock, 1);
85+
86+
read_cache_unmerged();
87+
88+
if (!fill_tree_descriptor(desc + nr - 1, sha1))
89+
return error("Failed to find tree of %s.", sha1_to_hex(sha1));
90+
if (unpack_trees(nr, desc, &opts))
91+
return -1;
92+
if (write_cache(newfd, active_cache, active_nr) ||
93+
commit_locked_index(lock))
94+
return error("Could not write new index file.");
95+
96+
return 0;
7897
}
7998

8099
static void print_new_head_line(struct commit *commit)

t/t7110-reset-merge.sh

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,14 @@ test_expect_success 'setup 2 different branches' '
135135
#
136136
# working index HEAD target working index HEAD
137137
# ----------------------------------------------------
138-
# file1: X U B C --merge (disallowed)
139-
test_expect_success '"reset --merge HEAD^" fails with pending merge' '
138+
# file1: X U B C --merge X C C
139+
test_expect_success '"reset --merge HEAD^" is ok with pending merge' '
140140
test_must_fail git merge branch1 &&
141-
test_must_fail git reset --merge HEAD^ &&
142-
test "$(git rev-parse HEAD)" = "$(git rev-parse third)" &&
143-
test -n "$(git diff --cached)"
141+
cat file1 >orig_file1 &&
142+
git reset --merge HEAD^ &&
143+
test "$(git rev-parse HEAD)" = "$(git rev-parse second)" &&
144+
test -z "$(git diff --cached)" &&
145+
test_cmp file1 orig_file1
144146
'
145147

146148
# The next test will test the following:

0 commit comments

Comments
 (0)