Skip to content

Commit 8336832

Browse files
committed
Merge branch 'nd/reset-intent-to-add'
* nd/reset-intent-to-add: reset: support "--mixed --intent-to-add" mode
2 parents 795dd11 + b4b313f commit 8336832

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

Documentation/git-reset.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SYNOPSIS
1010
[verse]
1111
'git reset' [-q] [<tree-ish>] [--] <paths>...
1212
'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...]
13-
'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
13+
'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
1414

1515
DESCRIPTION
1616
-----------
@@ -60,6 +60,9 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
6060
Resets the index but not the working tree (i.e., the changed files
6161
are preserved but not marked for commit) and reports what has not
6262
been updated. This is the default action.
63+
+
64+
If `-N` is specified, removed paths are marked as intent-to-add (see
65+
linkgit:git-add[1]).
6366

6467
--hard::
6568
Resets the index and working tree. Any changes to tracked files in the

builtin/reset.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,32 +116,42 @@ static void update_index_from_diff(struct diff_queue_struct *q,
116116
struct diff_options *opt, void *data)
117117
{
118118
int i;
119+
int intent_to_add = *(int *)data;
119120

120121
for (i = 0; i < q->nr; i++) {
121122
struct diff_filespec *one = q->queue[i]->one;
122-
if (one->mode && !is_null_sha1(one->sha1)) {
123-
struct cache_entry *ce;
124-
ce = make_cache_entry(one->mode, one->sha1, one->path,
125-
0, 0);
126-
if (!ce)
127-
die(_("make_cache_entry failed for path '%s'"),
128-
one->path);
129-
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD |
130-
ADD_CACHE_OK_TO_REPLACE);
131-
} else
123+
int is_missing = !(one->mode && !is_null_sha1(one->sha1));
124+
struct cache_entry *ce;
125+
126+
if (is_missing && !intent_to_add) {
132127
remove_file_from_cache(one->path);
128+
continue;
129+
}
130+
131+
ce = make_cache_entry(one->mode, one->sha1, one->path,
132+
0, 0);
133+
if (!ce)
134+
die(_("make_cache_entry failed for path '%s'"),
135+
one->path);
136+
if (is_missing) {
137+
ce->ce_flags |= CE_INTENT_TO_ADD;
138+
set_object_name_for_intent_to_add_entry(ce);
139+
}
140+
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
133141
}
134142
}
135143

136144
static int read_from_tree(const struct pathspec *pathspec,
137-
unsigned char *tree_sha1)
145+
unsigned char *tree_sha1,
146+
int intent_to_add)
138147
{
139148
struct diff_options opt;
140149

141150
memset(&opt, 0, sizeof(opt));
142151
copy_pathspec(&opt.pathspec, pathspec);
143152
opt.output_format = DIFF_FORMAT_CALLBACK;
144153
opt.format_callback = update_index_from_diff;
154+
opt.format_callback_data = &intent_to_add;
145155

146156
if (do_diff_cache(tree_sha1, &opt))
147157
return 1;
@@ -258,6 +268,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
258268
const char *rev;
259269
unsigned char sha1[20];
260270
struct pathspec pathspec;
271+
int intent_to_add = 0;
261272
const struct option options[] = {
262273
OPT__QUIET(&quiet, N_("be quiet, only report errors")),
263274
OPT_SET_INT(0, "mixed", &reset_type,
@@ -270,6 +281,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
270281
OPT_SET_INT(0, "keep", &reset_type,
271282
N_("reset HEAD but keep local changes"), KEEP),
272283
OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
284+
OPT_BOOL('N', "intent-to-add", &intent_to_add,
285+
N_("record only the fact that removed paths will be added later")),
273286
OPT_END()
274287
};
275288

@@ -327,6 +340,9 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
327340
die(_("%s reset is not allowed in a bare repository"),
328341
_(reset_type_names[reset_type]));
329342

343+
if (intent_to_add && reset_type != MIXED)
344+
die(_("-N can only be used with --mixed"));
345+
330346
/* Soft reset does not touch the index file nor the working tree
331347
* at all, but requires them in a good order. Other resets reset
332348
* the index file to the tree object we are switching to. */
@@ -338,7 +354,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
338354
int newfd = hold_locked_index(lock, 1);
339355
if (reset_type == MIXED) {
340356
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
341-
if (read_from_tree(&pathspec, sha1))
357+
if (read_from_tree(&pathspec, sha1, intent_to_add))
342358
return 1;
343359
refresh_index(&the_index, flags, NULL, NULL,
344360
_("Unstaged changes after reset:"));

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ extern int add_to_index(struct index_state *, const char *path, struct stat *, i
487487
extern int add_file_to_index(struct index_state *, const char *path, int flags);
488488
extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options);
489489
extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b);
490+
extern void set_object_name_for_intent_to_add_entry(struct cache_entry *ce);
490491
extern int index_name_is_other(const struct index_state *, const char *, int);
491492
extern void *read_blob_data_from_index(struct index_state *, const char *, unsigned long *);
492493

read-cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_
584584
return new;
585585
}
586586

587-
static void record_intent_to_add(struct cache_entry *ce)
587+
void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
588588
{
589589
unsigned char sha1[20];
590590
if (write_sha1_file("", 0, blob_type, sha1))
@@ -670,7 +670,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
670670
if (index_path(ce->sha1, path, st, HASH_WRITE_OBJECT))
671671
return error("unable to index file %s", path);
672672
} else
673-
record_intent_to_add(ce);
673+
set_object_name_for_intent_to_add_entry(ce);
674674

675675
if (ignore_case && alias && different_name(ce, alias))
676676
ce = create_alias_ce(ce, alias);

t/t7102-reset.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,4 +535,19 @@ test_expect_success 'reset with paths accepts tree' '
535535
git diff HEAD --exit-code
536536
'
537537

538+
test_expect_success 'reset -N keeps removed files as intent-to-add' '
539+
echo new-file >new-file &&
540+
git add new-file &&
541+
git reset -N HEAD &&
542+
543+
tree=$(git write-tree) &&
544+
git ls-tree $tree new-file >actual &&
545+
>expect &&
546+
test_cmp expect actual &&
547+
548+
git diff --name-only >actual &&
549+
echo new-file >expect &&
550+
test_cmp expect actual
551+
'
552+
538553
test_done

0 commit comments

Comments
 (0)