Skip to content

Commit

Permalink
Merge branch 'nd/reset-intent-to-add'
Browse files Browse the repository at this point in the history
* nd/reset-intent-to-add:
  reset: support "--mixed --intent-to-add" mode
  • Loading branch information
Junio C Hamano committed Feb 27, 2014
2 parents 795dd11 + b4b313f commit 8336832
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 15 deletions.
5 changes: 4 additions & 1 deletion Documentation/git-reset.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SYNOPSIS
[verse]
'git reset' [-q] [<tree-ish>] [--] <paths>...
'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...]
'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

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

--hard::
Resets the index and working tree. Any changes to tracked files in the
Expand Down
40 changes: 28 additions & 12 deletions builtin/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,32 +116,42 @@ static void update_index_from_diff(struct diff_queue_struct *q,
struct diff_options *opt, void *data)
{
int i;
int intent_to_add = *(int *)data;

for (i = 0; i < q->nr; i++) {
struct diff_filespec *one = q->queue[i]->one;
if (one->mode && !is_null_sha1(one->sha1)) {
struct cache_entry *ce;
ce = make_cache_entry(one->mode, one->sha1, one->path,
0, 0);
if (!ce)
die(_("make_cache_entry failed for path '%s'"),
one->path);
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD |
ADD_CACHE_OK_TO_REPLACE);
} else
int is_missing = !(one->mode && !is_null_sha1(one->sha1));
struct cache_entry *ce;

if (is_missing && !intent_to_add) {
remove_file_from_cache(one->path);
continue;
}

ce = make_cache_entry(one->mode, one->sha1, one->path,
0, 0);
if (!ce)
die(_("make_cache_entry failed for path '%s'"),
one->path);
if (is_missing) {
ce->ce_flags |= CE_INTENT_TO_ADD;
set_object_name_for_intent_to_add_entry(ce);
}
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
}
}

static int read_from_tree(const struct pathspec *pathspec,
unsigned char *tree_sha1)
unsigned char *tree_sha1,
int intent_to_add)
{
struct diff_options opt;

memset(&opt, 0, sizeof(opt));
copy_pathspec(&opt.pathspec, pathspec);
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
opt.format_callback_data = &intent_to_add;

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

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

if (intent_to_add && reset_type != MIXED)
die(_("-N can only be used with --mixed"));

/* Soft reset does not touch the index file nor the working tree
* at all, but requires them in a good order. Other resets reset
* the index file to the tree object we are switching to. */
Expand All @@ -338,7 +354,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
int newfd = hold_locked_index(lock, 1);
if (reset_type == MIXED) {
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
if (read_from_tree(&pathspec, sha1))
if (read_from_tree(&pathspec, sha1, intent_to_add))
return 1;
refresh_index(&the_index, flags, NULL, NULL,
_("Unstaged changes after reset:"));
Expand Down
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ extern int add_to_index(struct index_state *, const char *path, struct stat *, i
extern int add_file_to_index(struct index_state *, const char *path, int flags);
extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options);
extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b);
extern void set_object_name_for_intent_to_add_entry(struct cache_entry *ce);
extern int index_name_is_other(const struct index_state *, const char *, int);
extern void *read_blob_data_from_index(struct index_state *, const char *, unsigned long *);

Expand Down
4 changes: 2 additions & 2 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_
return new;
}

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

if (ignore_case && alias && different_name(ce, alias))
ce = create_alias_ce(ce, alias);
Expand Down
15 changes: 15 additions & 0 deletions t/t7102-reset.sh
Original file line number Diff line number Diff line change
Expand Up @@ -535,4 +535,19 @@ test_expect_success 'reset with paths accepts tree' '
git diff HEAD --exit-code
'

test_expect_success 'reset -N keeps removed files as intent-to-add' '
echo new-file >new-file &&
git add new-file &&
git reset -N HEAD &&
tree=$(git write-tree) &&
git ls-tree $tree new-file >actual &&
>expect &&
test_cmp expect actual &&
git diff --name-only >actual &&
echo new-file >expect &&
test_cmp expect actual
'

test_done

0 comments on commit 8336832

Please sign in to comment.