diff options
Diffstat (limited to 'builtin/add.c')
-rw-r--r-- | builtin/add.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/builtin/add.c b/builtin/add.c index 4baf3a5635..9f53f020d0 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -5,6 +5,7 @@ */ #include "cache.h" #include "builtin.h" +#include "lockfile.h" #include "dir.h" #include "pathspec.h" #include "exec_cmd.h" @@ -18,7 +19,7 @@ #include "argv-array.h" static const char * const builtin_add_usage[] = { - N_("git add [options] [--] <pathspec>..."), + N_("git add [<options>] [--] <pathspec>..."), NULL }; static int patch_interactive, add_interactive, edit_interactive; @@ -29,6 +30,21 @@ struct update_callback_data { int add_errors; }; +static void chmod_pathspec(struct pathspec *pathspec, int force_mode) +{ + int i; + + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + + if (pathspec && !ce_path_match(ce, pathspec, NULL)) + continue; + + if (chmod_cache_entry(ce, force_mode) < 0) + fprintf(stderr, "cannot chmod '%s'", ce->name); + } +} + static int fix_unmerged_status(struct diff_filepair *p, struct update_callback_data *data) { @@ -64,7 +80,7 @@ static void update_callback(struct diff_queue_struct *q, die(_("unexpected diff status %c"), p->status); case DIFF_STATUS_MODIFIED: case DIFF_STATUS_TYPE_CHANGED: - if (add_file_to_index(&the_index, path, data->flags)) { + if (add_file_to_index(&the_index, path, data->flags)) { if (!(data->flags & ADD_CACHE_IGNORE_ERRORS)) die(_("updating files failed")); data->add_errors++; @@ -180,7 +196,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix) char *file = git_pathdup("ADD_EDIT.patch"); const char *apply_argv[] = { "apply", "--recount", "--cached", NULL, NULL }; - struct child_process child; + struct child_process child = CHILD_PROCESS_INIT; struct rev_info rev; int out; struct stat st; @@ -207,14 +223,14 @@ static int edit_patch(int argc, const char **argv, const char *prefix) if (run_diff_files(&rev, 0)) die(_("Could not write patch")); - launch_editor(file, NULL, NULL); + if (launch_editor(file, NULL, NULL)) + die(_("editing patch failed")); if (stat(file, &st)) die_errno(_("Could not stat '%s'"), file); if (!st.st_size) die(_("Empty patch. Aborted.")); - memset(&child, 0, sizeof(child)); child.git_cmd = 1; child.argv = apply_argv; if (run_command(&child)) @@ -237,6 +253,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing; static int addremove = ADDREMOVE_DEFAULT; static int addremove_explicit = -1; /* unspecified */ +static char *chmod_arg; + static int ignore_removal_cb(const struct option *opt, const char *arg, int unset) { /* if we are told to ignore, we are not adding removals */ @@ -262,6 +280,7 @@ static struct option builtin_add_options[] = { OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")), OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")), OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")), + OPT_STRING( 0 , "chmod", &chmod_arg, N_("(+/-)x"), N_("override the executable bit of the listed files")), OPT_END(), }; @@ -284,11 +303,11 @@ static int add_files(struct dir_struct *dir, int flags) for (i = 0; i < dir->ignored_nr; i++) fprintf(stderr, "%s\n", dir->ignored[i]->name); fprintf(stderr, _("Use -f if you really want to add them.\n")); - die(_("no files added")); + exit_status = 1; } for (i = 0; i < dir->nr; i++) - if (add_file_to_cache(dir->entries[i]->name, flags)) { + if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) { if (!ignore_add_errors) die(_("adding files failed")); exit_status = 1; @@ -335,16 +354,14 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (!show_only && ignore_missing) die(_("Option --ignore-missing can only be used together with --dry-run")); - if ((0 < addremove_explicit || take_worktree_changes) && !argc) { - static const char *whole[2] = { ":/", NULL }; - argc = 1; - argv = whole; - } + if (chmod_arg && ((chmod_arg[0] != '-' && chmod_arg[0] != '+') || + chmod_arg[1] != 'x' || chmod_arg[2])) + die(_("--chmod param '%s' must be either -x or +x"), chmod_arg); add_new_files = !take_worktree_changes && !refresh_only; - require_pathspec = !take_worktree_changes; + require_pathspec = !(take_worktree_changes || (0 < addremove_explicit)); - hold_locked_index(&lock_file, 1); + hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); flags = ((verbose ? ADD_CACHE_VERBOSE : 0) | (show_only ? ADD_CACHE_PRETEND : 0) | @@ -374,7 +391,6 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (add_new_files) { int baselen; - struct pathspec empty_pathspec; /* Set up the default git porcelain excludes */ memset(&dir, 0, sizeof(dir)); @@ -383,7 +399,6 @@ int cmd_add(int argc, const char **argv, const char *prefix) setup_standard_excludes(&dir); } - memset(&empty_pathspec, 0, sizeof(empty_pathspec)); /* This picks up the paths that are not tracked */ baselen = fill_directory(&dir, &pathspec); if (pathspec.nr) @@ -438,6 +453,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (add_new_files) exit_status |= add_files(&dir, flags); + if (chmod_arg && pathspec.nr) + chmod_pathspec(&pathspec, chmod_arg[0]); unplug_bulk_checkin(); finish: |