Skip to content

Commit 0df9985

Browse files
prertikgitster
authored andcommitted
sequencer: refactor the code to detach HEAD to checkout.c
In the upcoming builtin rebase, we will have to start by detaching the HEAD, just like shell script version does. Essentially, we have to do the same thing as `git checkout -q <revision>^0 --`, in pure C. The aforementioned functionality was already present in `sequencer.c` in `do_reset()` function. But `do_reset()` performs more than detaching the HEAD, and performs action specific to `sequencer.c`. So this commit refactors out that part from `do_reset()`, and moves it to a new function called `detach_head_to()`. As this function has nothing to do with the sequencer, and everything to do with what `git checkout -q <revision>^0 --` does, we move that function to checkout.c. This refactoring actually introduces a slight change in behavior: previously, the index was locked before parsing the argument to the todo command `reset`, while it now gets locked *after* that, in the `detach_head_to()` function. It does not make a huge difference, and the upside is that this closes a few (unlikely) code paths where the index would not be unlocked upon error. Signed-off-by: Pratik Karki <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d515be8 commit 0df9985

File tree

3 files changed

+72
-53
lines changed

3 files changed

+72
-53
lines changed

checkout.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
#include "remote.h"
33
#include "refspec.h"
44
#include "checkout.h"
5+
#include "unpack-trees.h"
6+
#include "lockfile.h"
7+
#include "refs.h"
8+
#include "tree.h"
9+
#include "cache-tree.h"
510

611
struct tracking_name_data {
712
/* const */ char *src_ref;
@@ -42,3 +47,62 @@ const char *unique_tracking_name(const char *name, struct object_id *oid)
4247
free(cb_data.dst_ref);
4348
return NULL;
4449
}
50+
51+
int detach_head_to(struct object_id *oid, const char *action,
52+
const char *reflog_message)
53+
{
54+
struct strbuf ref_name = STRBUF_INIT;
55+
struct tree_desc desc;
56+
struct lock_file lock = LOCK_INIT;
57+
struct unpack_trees_options unpack_tree_opts;
58+
struct tree *tree;
59+
int ret = 0;
60+
61+
if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0)
62+
return -1;
63+
64+
memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
65+
setup_unpack_trees_porcelain(&unpack_tree_opts, action);
66+
unpack_tree_opts.head_idx = 1;
67+
unpack_tree_opts.src_index = &the_index;
68+
unpack_tree_opts.dst_index = &the_index;
69+
unpack_tree_opts.fn = oneway_merge;
70+
unpack_tree_opts.merge = 1;
71+
unpack_tree_opts.update = 1;
72+
73+
if (read_cache_unmerged()) {
74+
rollback_lock_file(&lock);
75+
strbuf_release(&ref_name);
76+
return error_resolve_conflict(_(action));
77+
}
78+
79+
if (!fill_tree_descriptor(&desc, oid)) {
80+
error(_("failed to find tree of %s"), oid_to_hex(oid));
81+
rollback_lock_file(&lock);
82+
free((void *)desc.buffer);
83+
strbuf_release(&ref_name);
84+
return -1;
85+
}
86+
87+
if (unpack_trees(1, &desc, &unpack_tree_opts)) {
88+
rollback_lock_file(&lock);
89+
free((void *)desc.buffer);
90+
strbuf_release(&ref_name);
91+
return -1;
92+
}
93+
94+
tree = parse_tree_indirect(oid);
95+
prime_cache_tree(&the_index, tree);
96+
97+
if (write_locked_index(&the_index, &lock, COMMIT_LOCK) < 0)
98+
ret = error(_("could not write index"));
99+
free((void *)desc.buffer);
100+
101+
if (!ret)
102+
ret = update_ref(reflog_message, "HEAD", oid,
103+
NULL, 0, UPDATE_REFS_MSG_ON_ERR);
104+
105+
strbuf_release(&ref_name);
106+
return ret;
107+
108+
}

checkout.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@
1010
*/
1111
extern const char *unique_tracking_name(const char *name, struct object_id *oid);
1212

13+
int detach_head_to(struct object_id *oid, const char *action,
14+
const char *reflog_message);
15+
1316
#endif /* CHECKOUT_H */

sequencer.c

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "oidset.h"
3030
#include "commit-slab.h"
3131
#include "alias.h"
32+
#include "checkout.h"
3233

3334
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
3435

@@ -2756,14 +2757,7 @@ static int do_reset(const char *name, int len, struct replay_opts *opts)
27562757
{
27572758
struct strbuf ref_name = STRBUF_INIT;
27582759
struct object_id oid;
2759-
struct lock_file lock = LOCK_INIT;
2760-
struct tree_desc desc;
2761-
struct tree *tree;
2762-
struct unpack_trees_options unpack_tree_opts;
2763-
int ret = 0, i;
2764-
2765-
if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0)
2766-
return -1;
2760+
int i;
27672761

27682762
if (len == 10 && !strncmp("[new root]", name, len)) {
27692763
if (!opts->have_squash_onto) {
@@ -2789,56 +2783,14 @@ static int do_reset(const char *name, int len, struct replay_opts *opts)
27892783
if (get_oid(ref_name.buf, &oid) &&
27902784
get_oid(ref_name.buf + strlen("refs/rewritten/"), &oid)) {
27912785
error(_("could not read '%s'"), ref_name.buf);
2792-
rollback_lock_file(&lock);
27932786
strbuf_release(&ref_name);
27942787
return -1;
27952788
}
27962789
}
27972790

2798-
memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
2799-
setup_unpack_trees_porcelain(&unpack_tree_opts, "reset");
2800-
unpack_tree_opts.head_idx = 1;
2801-
unpack_tree_opts.src_index = &the_index;
2802-
unpack_tree_opts.dst_index = &the_index;
2803-
unpack_tree_opts.fn = oneway_merge;
2804-
unpack_tree_opts.merge = 1;
2805-
unpack_tree_opts.update = 1;
2806-
2807-
if (read_cache_unmerged()) {
2808-
rollback_lock_file(&lock);
2809-
strbuf_release(&ref_name);
2810-
return error_resolve_conflict(_(action_name(opts)));
2811-
}
2812-
2813-
if (!fill_tree_descriptor(&desc, &oid)) {
2814-
error(_("failed to find tree of %s"), oid_to_hex(&oid));
2815-
rollback_lock_file(&lock);
2816-
free((void *)desc.buffer);
2817-
strbuf_release(&ref_name);
2818-
return -1;
2819-
}
2820-
2821-
if (unpack_trees(1, &desc, &unpack_tree_opts)) {
2822-
rollback_lock_file(&lock);
2823-
free((void *)desc.buffer);
2824-
strbuf_release(&ref_name);
2825-
return -1;
2826-
}
2827-
2828-
tree = parse_tree_indirect(&oid);
2829-
prime_cache_tree(&the_index, tree);
2830-
2831-
if (write_locked_index(&the_index, &lock, COMMIT_LOCK) < 0)
2832-
ret = error(_("could not write index"));
2833-
free((void *)desc.buffer);
2834-
2835-
if (!ret)
2836-
ret = update_ref(reflog_message(opts, "reset", "'%.*s'",
2837-
len, name), "HEAD", &oid,
2838-
NULL, 0, UPDATE_REFS_MSG_ON_ERR);
2839-
2840-
strbuf_release(&ref_name);
2841-
return ret;
2791+
return detach_head_to(&oid, action_name(opts),
2792+
reflog_message(opts, "reset", "'%.*s'",
2793+
len, name));
28422794
}
28432795

28442796
static int do_merge(struct commit *commit, const char *arg, int arg_len,

0 commit comments

Comments
 (0)