Skip to content

Commit daabf56

Browse files
dschogitster
authored andcommitted
built-in add -i: re-implement add-untracked in C
This is yet another command, ported to C. It builds nicely on the support functions introduced for other commands, with the notable difference that only names are displayed for untracked files, no file type or diff summary. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent dea080c commit daabf56

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

add-interactive.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "refs.h"
88
#include "string-list.h"
99
#include "lockfile.h"
10+
#include "dir.h"
1011

1112
struct add_i_state {
1213
struct repository *r;
@@ -560,6 +561,7 @@ static int is_valid_prefix(const char *prefix, size_t prefix_len)
560561
struct print_file_item_data {
561562
const char *modified_fmt, *color, *reset;
562563
struct strbuf buf, name, index, worktree;
564+
unsigned only_names:1;
563565
};
564566

565567
static void print_file_item(int i, int selected, struct string_list_item *item,
@@ -583,6 +585,12 @@ static void print_file_item(int i, int selected, struct string_list_item *item,
583585
highlighted = d->name.buf;
584586
}
585587

588+
if (d->only_names) {
589+
printf("%c%2d: %s", selected ? '*' : ' ', i + 1,
590+
highlighted ? highlighted : item->string);
591+
return;
592+
}
593+
586594
render_adddel(&d->worktree, &c->worktree, _("nothing"));
587595
render_adddel(&d->index, &c->index, _("unchanged"));
588596

@@ -762,6 +770,88 @@ static int run_revert(struct add_i_state *s, const struct pathspec *ps,
762770
return res;
763771
}
764772

773+
static int get_untracked_files(struct repository *r,
774+
struct prefix_item_list *files,
775+
const struct pathspec *ps)
776+
{
777+
struct dir_struct dir = { 0 };
778+
size_t i;
779+
struct strbuf buf = STRBUF_INIT;
780+
781+
if (repo_read_index(r) < 0)
782+
return error(_("could not read index"));
783+
784+
prefix_item_list_clear(files);
785+
setup_standard_excludes(&dir);
786+
add_pattern_list(&dir, EXC_CMDL, "--exclude option");
787+
fill_directory(&dir, r->index, ps);
788+
789+
for (i = 0; i < dir.nr; i++) {
790+
struct dir_entry *ent = dir.entries[i];
791+
792+
if (index_name_is_other(r->index, ent->name, ent->len)) {
793+
strbuf_reset(&buf);
794+
strbuf_add(&buf, ent->name, ent->len);
795+
add_file_item(&files->items, buf.buf);
796+
}
797+
}
798+
799+
strbuf_release(&buf);
800+
return 0;
801+
}
802+
803+
static int run_add_untracked(struct add_i_state *s, const struct pathspec *ps,
804+
struct prefix_item_list *files,
805+
struct list_and_choose_options *opts)
806+
{
807+
struct print_file_item_data *d = opts->list_opts.print_item_data;
808+
int res = 0, fd;
809+
size_t count, i;
810+
struct lock_file index_lock;
811+
812+
if (get_untracked_files(s->r, files, ps) < 0)
813+
return -1;
814+
815+
if (!files->items.nr) {
816+
printf(_("No untracked files.\n"));
817+
goto finish_add_untracked;
818+
}
819+
820+
opts->prompt = N_("Add untracked");
821+
d->only_names = 1;
822+
count = list_and_choose(s, files, opts);
823+
d->only_names = 0;
824+
if (count <= 0)
825+
goto finish_add_untracked;
826+
827+
fd = repo_hold_locked_index(s->r, &index_lock, LOCK_REPORT_ON_ERROR);
828+
if (fd < 0) {
829+
res = -1;
830+
goto finish_add_untracked;
831+
}
832+
833+
for (i = 0; i < files->items.nr; i++) {
834+
const char *name = files->items.items[i].string;
835+
if (files->selected[i] &&
836+
add_file_to_index(s->r->index, name, 0) < 0) {
837+
res = error(_("could not stage '%s'"), name);
838+
break;
839+
}
840+
}
841+
842+
if (!res &&
843+
write_locked_index(s->r->index, &index_lock, COMMIT_LOCK) < 0)
844+
res = error(_("could not write index"));
845+
846+
if (!res)
847+
printf(Q_("added %d path\n",
848+
"added %d paths\n", count), (int)count);
849+
850+
finish_add_untracked:
851+
putchar('\n');
852+
return res;
853+
}
854+
765855
static int run_help(struct add_i_state *s, const struct pathspec *unused_ps,
766856
struct prefix_item_list *unused_files,
767857
struct list_and_choose_options *unused_opts)
@@ -858,6 +948,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
858948
{ "status", run_status },
859949
{ "update", run_update },
860950
{ "revert", run_revert },
951+
{ "add untracked", run_add_untracked },
861952
{ "help", run_help },
862953
};
863954
struct prefix_item_list commands = PREFIX_ITEM_LIST_INIT;

0 commit comments

Comments
 (0)