Skip to content

Commit 480d3d6

Browse files
newrengitster
authored andcommitted
Change unpack_trees' 'reset' flag into an enum
Traditionally, unpack_trees_options->reset was used to signal that it was okay to delete any untracked files in the way. This was used by `git read-tree --reset`, but then started appearing in other places as well. However, many of the other uses should not be deleting untracked files in the way. Change this value to an enum so that a value of 1 (i.e. "true") can be split into two: UNPACK_RESET_PROTECT_UNTRACKED, UNPACK_RESET_OVERWRITE_UNTRACKED In order to catch accidental misuses (i.e. where folks call it the way they traditionally used to), define the special enum value of UNPACK_RESET_INVALID = 1 which will trigger a BUG(). Modify existing callers so that read-tree --reset reset --hard checkout --force continue using the UNPACK_RESET_OVERWRITE_UNTRACKED logic, while other callers, including am checkout without --force stash (though currently dead code; reset always had a value of 0) numerous callers from rebase/sequencer to reset_head() will use the new UNPACK_RESET_PROTECT_UNTRACKED value. Also, note that it has been reported that 'git checkout <treeish> <pathspec>' currently also allows overwriting untracked files[1]. That case should also be fixed, but it does not use unpack_trees() and thus is outside the scope of the current changes. [1] https://lore.kernel.org/git/[email protected]/ Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1b5f373 commit 480d3d6

File tree

9 files changed

+39
-16
lines changed

9 files changed

+39
-16
lines changed

builtin/am.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,9 +1918,8 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
19181918
opts.dst_index = &the_index;
19191919
opts.update = 1;
19201920
opts.merge = 1;
1921-
opts.reset = reset;
1922-
if (!reset)
1923-
opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
1921+
opts.reset = reset ? UNPACK_RESET_PROTECT_UNTRACKED : 0;
1922+
opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
19241923
opts.fn = twoway_merge;
19251924
init_tree_desc(&t[0], head->buffer, head->size);
19261925
init_tree_desc(&t[1], remote->buffer, remote->size);

builtin/checkout.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,9 +646,10 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
646646
opts.head_idx = -1;
647647
opts.update = worktree;
648648
opts.skip_unmerged = !worktree;
649-
opts.reset = 1;
649+
opts.reset = o->force ? UNPACK_RESET_OVERWRITE_UNTRACKED :
650+
UNPACK_RESET_PROTECT_UNTRACKED;
651+
opts.preserve_ignored = (!o->force && !o->overwrite_ignore);
650652
opts.merge = 1;
651-
opts.preserve_ignored = 0;
652653
opts.fn = oneway_merge;
653654
opts.verbose_update = o->show_progress;
654655
opts.src_index = &the_index;

builtin/read-tree.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
166166
if (1 < opts.merge + opts.reset + prefix_set)
167167
die("Which one? -m, --reset, or --prefix?");
168168

169+
if (opts.reset)
170+
opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED;
171+
169172
/*
170173
* NEEDSWORK
171174
*

builtin/reset.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,14 @@ static int reset_index(const char *ref, const struct object_id *oid, int reset_t
7171
break;
7272
case HARD:
7373
opts.update = 1;
74-
/* fallthrough */
74+
opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED;
75+
break;
76+
case MIXED:
77+
opts.reset = UNPACK_RESET_PROTECT_UNTRACKED;
78+
/* but opts.update=0, so working tree not updated */
79+
break;
7580
default:
76-
opts.reset = 1;
81+
BUG("invalid reset_type passed to reset_index");
7782
}
7883

7984
read_cache_unmerged();

builtin/stash.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ static int reset_tree(struct object_id *i_tree, int update, int reset)
256256
opts.src_index = &the_index;
257257
opts.dst_index = &the_index;
258258
opts.merge = 1;
259-
opts.reset = reset;
259+
opts.reset = reset ? UNPACK_RESET_PROTECT_UNTRACKED : 0;
260260
opts.update = update;
261-
if (update && !reset)
261+
if (update)
262262
opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
263263
opts.fn = oneway_merge;
264264

reset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action,
5959
unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
6060
init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL);
6161
if (!detach_head)
62-
unpack_tree_opts.reset = 1;
62+
unpack_tree_opts.reset = UNPACK_RESET_PROTECT_UNTRACKED;
6363

6464
if (repo_read_index_unmerged(r) < 0) {
6565
ret = error(_("could not read index"));

t/t2500-untracked-overwriting.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ test_setup_checkout_m () {
9292
)
9393
}
9494

95-
test_expect_failure 'checkout -m does not nuke untracked file' '
95+
test_expect_success 'checkout -m does not nuke untracked file' '
9696
test_setup_checkout_m &&
9797
(
9898
cd checkout &&
@@ -138,7 +138,7 @@ test_setup_sequencing () {
138138
)
139139
}
140140

141-
test_expect_failure 'git rebase --abort and untracked files' '
141+
test_expect_success 'git rebase --abort and untracked files' '
142142
test_setup_sequencing rebase_abort_and_untracked &&
143143
(
144144
cd sequencing_rebase_abort_and_untracked &&
@@ -155,7 +155,7 @@ test_expect_failure 'git rebase --abort and untracked files' '
155155
)
156156
'
157157

158-
test_expect_failure 'git rebase fast forwarding and untracked files' '
158+
test_expect_success 'git rebase fast forwarding and untracked files' '
159159
test_setup_sequencing rebase_fast_forward_and_untracked &&
160160
(
161161
cd sequencing_rebase_fast_forward_and_untracked &&

unpack-trees.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,9 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
16941694
int free_pattern_list = 0;
16951695
struct dir_struct dir = DIR_INIT;
16961696

1697+
if (o->reset == UNPACK_RESET_INVALID)
1698+
BUG("o->reset had a value of 1; should be UNPACK_TREES_*_UNTRACKED");
1699+
16971700
if (len > MAX_UNPACK_TREES)
16981701
die("unpack_trees takes at most %d trees", MAX_UNPACK_TREES);
16991702
if (o->dir)
@@ -1708,6 +1711,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
17081711
ensure_full_index(o->dst_index);
17091712
}
17101713

1714+
if (o->reset == UNPACK_RESET_OVERWRITE_UNTRACKED &&
1715+
o->preserve_ignored)
1716+
BUG("UNPACK_RESET_OVERWRITE_UNTRACKED incompatible with preserved ignored files");
1717+
17111718
if (!o->preserve_ignored) {
17121719
o->dir = &dir;
17131720
o->dir->flags |= DIR_SHOW_IGNORED;
@@ -2231,7 +2238,8 @@ static int verify_absent_1(const struct cache_entry *ce,
22312238
int len;
22322239
struct stat st;
22332240

2234-
if (o->index_only || o->reset || !o->update)
2241+
if (o->index_only || !o->update ||
2242+
o->reset == UNPACK_RESET_OVERWRITE_UNTRACKED)
22352243
return 0;
22362244

22372245
len = check_leading_path(ce->name, ce_namelen(ce), 0);

unpack-trees.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,15 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
4545
*/
4646
void clear_unpack_trees_porcelain(struct unpack_trees_options *opts);
4747

48+
enum unpack_trees_reset_type {
49+
UNPACK_RESET_NONE = 0, /* traditional "false" value; still valid */
50+
UNPACK_RESET_INVALID = 1, /* "true" no longer valid; use below values */
51+
UNPACK_RESET_PROTECT_UNTRACKED,
52+
UNPACK_RESET_OVERWRITE_UNTRACKED
53+
};
54+
4855
struct unpack_trees_options {
49-
unsigned int reset,
50-
merge,
56+
unsigned int merge,
5157
update,
5258
preserve_ignored,
5359
clone,
@@ -65,6 +71,7 @@ struct unpack_trees_options {
6571
exiting_early,
6672
show_all_errors,
6773
dry_run;
74+
enum unpack_trees_reset_type reset;
6875
const char *prefix;
6976
int cache_bottom;
7077
struct pathspec *pathspec;

0 commit comments

Comments
 (0)