Merge branch 'sb/remove-unused-var-from-builtin-add' into maint
[git/git.git] / builtin / add.c
index fc7bf9f..b2a5c57 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include "cache.h"
 #include "builtin.h"
+#include "lockfile.h"
 #include "dir.h"
 #include "pathspec.h"
 #include "exec_cmd.h"
 #include "diffcore.h"
 #include "revision.h"
 #include "bulk-checkin.h"
+#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;
@@ -26,8 +28,6 @@ static int take_worktree_changes;
 struct update_callback_data {
        int flags;
        int add_errors;
-       /* only needed for 2.0 transition preparation */
-       int warn_add_would_remove;
 };
 
 static int fix_unmerged_status(struct diff_filepair *p,
@@ -51,24 +51,6 @@ static int fix_unmerged_status(struct diff_filepair *p,
                return DIFF_STATUS_MODIFIED;
 }
 
-static const char *add_would_remove_warning = N_(
-       "You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n"
-"whose behaviour will change in Git 2.0 with respect to paths you removed.\n"
-"Paths like '%s' that are\n"
-"removed from your working tree are ignored with this version of Git.\n"
-"\n"
-"* 'git add --ignore-removal <pathspec>', which is the current default,\n"
-"  ignores paths you removed from your working tree.\n"
-"\n"
-"* 'git add --all <pathspec>' will let you also record the removals.\n"
-"\n"
-"Run 'git status' to check the paths you removed from your working tree.\n");
-
-static void warn_add_would_remove(const char *path)
-{
-       warning(_(add_would_remove_warning), path);
-}
-
 static void update_callback(struct diff_queue_struct *q,
                            struct diff_options *opt, void *cbdata)
 {
@@ -90,10 +72,6 @@ static void update_callback(struct diff_queue_struct *q,
                        }
                        break;
                case DIFF_STATUS_DELETED:
-                       if (data->warn_add_would_remove) {
-                               warn_add_would_remove(path);
-                               data->warn_add_would_remove = 0;
-                       }
                        if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
                                break;
                        if (!(data->flags & ADD_CACHE_PRETEND))
@@ -105,31 +83,24 @@ static void update_callback(struct diff_queue_struct *q,
        }
 }
 
-static void update_files_in_cache(const char *prefix,
-                                 const struct pathspec *pathspec,
-                                 struct update_callback_data *data)
+int add_files_to_cache(const char *prefix,
+                      const struct pathspec *pathspec, int flags)
 {
+       struct update_callback_data data;
        struct rev_info rev;
 
+       memset(&data, 0, sizeof(data));
+       data.flags = flags;
+
        init_revisions(&rev, prefix);
        setup_revisions(0, NULL, &rev, NULL);
        if (pathspec)
                copy_pathspec(&rev.prune_data, pathspec);
        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = update_callback;
-       rev.diffopt.format_callback_data = data;
+       rev.diffopt.format_callback_data = &data;
        rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
        run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
-}
-
-int add_files_to_cache(const char *prefix,
-                      const struct pathspec *pathspec, int flags)
-{
-       struct update_callback_data data;
-
-       memset(&data, 0, sizeof(data));
-       data.flags = flags;
-       update_files_in_cache(prefix, pathspec, &data);
        return !!data.add_errors;
 }
 
@@ -172,23 +143,21 @@ static void refresh(int verbose, const struct pathspec *pathspec)
 int run_add_interactive(const char *revision, const char *patch_mode,
                        const struct pathspec *pathspec)
 {
-       int status, ac, i;
-       const char **args;
+       int status, i;
+       struct argv_array argv = ARGV_ARRAY_INIT;
 
-       args = xcalloc(sizeof(const char *), (pathspec->nr + 6));
-       ac = 0;
-       args[ac++] = "add--interactive";
+       argv_array_push(&argv, "add--interactive");
        if (patch_mode)
-               args[ac++] = patch_mode;
+               argv_array_push(&argv, patch_mode);
        if (revision)
-               args[ac++] = revision;
-       args[ac++] = "--";
+               argv_array_push(&argv, revision);
+       argv_array_push(&argv, "--");
        for (i = 0; i < pathspec->nr; i++)
                /* pass original pathspec, to be re-parsed */
-               args[ac++] = pathspec->items[i].original;
+               argv_array_push(&argv, pathspec->items[i].original);
 
-       status = run_command_v_opt(args, RUN_GIT_CMD);
-       free(args);
+       status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
+       argv_array_clear(&argv);
        return status;
 }
 
@@ -212,7 +181,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;
@@ -239,14 +208,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))
@@ -265,7 +234,7 @@ N_("The following paths are ignored by one of your .gitignore files:\n");
 static int verbose, show_only, ignored_too, refresh_only;
 static int ignore_add_errors, intent_to_add, ignore_missing;
 
-#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
+#define ADDREMOVE_DEFAULT 1
 static int addremove = ADDREMOVE_DEFAULT;
 static int addremove_explicit = -1; /* unspecified */
 
@@ -316,7 +285,7 @@ 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++)
@@ -331,14 +300,12 @@ static int add_files(struct dir_struct *dir, int flags)
 int cmd_add(int argc, const char **argv, const char *prefix)
 {
        int exit_status = 0;
-       int newfd;
        struct pathspec pathspec;
        struct dir_struct dir;
        int flags;
        int add_new_files;
        int require_pathspec;
        char *seen = NULL;
-       struct update_callback_data update_data;
 
        git_config(add_config, NULL);
 
@@ -362,25 +329,14 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        if (addremove && take_worktree_changes)
                die(_("-A and -u are mutually incompatible"));
 
-       /*
-        * Warn when "git add pathspec..." was given without "-u" or "-A"
-        * and pathspec... covers a removed path.
-        */
-       memset(&update_data, 0, sizeof(update_data));
-       if (!take_worktree_changes && addremove_explicit < 0)
-               update_data.warn_add_would_remove = 1;
-
        if (!take_worktree_changes && addremove_explicit < 0 && argc)
-               /*
-                * Turn "git add pathspec..." to "git add -A pathspec..."
-                * in Git 2.0 but not yet
-                */
-               ; /* addremove = 1; */
+               /* Turn "git add pathspec..." to "git add -A pathspec..." */
+               addremove = 1;
 
        if (!show_only && ignore_missing)
                die(_("Option --ignore-missing can only be used together with --dry-run"));
 
-       if ((addremove || take_worktree_changes) && !argc) {
+       if ((0 < addremove_explicit || take_worktree_changes) && !argc) {
                static const char *whole[2] = { ":/", NULL };
                argc = 1;
                argv = whole;
@@ -389,7 +345,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        add_new_files = !take_worktree_changes && !refresh_only;
        require_pathspec = !take_worktree_changes;
 
-       newfd = hold_locked_index(&lock_file, 1);
+       hold_locked_index(&lock_file, 1);
 
        flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
                 (show_only ? ADD_CACHE_PRETEND : 0) |
@@ -476,10 +432,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
        plug_bulk_checkin();
 
-       update_data.flags = flags;
-       update_files_in_cache(prefix, &pathspec, &update_data);
+       exit_status |= add_files_to_cache(prefix, &pathspec, flags);
 
-       exit_status |= !!update_data.add_errors;
        if (add_new_files)
                exit_status |= add_files(&dir, flags);
 
@@ -487,8 +441,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
 finish:
        if (active_cache_changed) {
-               if (write_cache(newfd, active_cache, active_nr) ||
-                   commit_locked_index(&lock_file))
+               if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
                        die(_("Unable to write new index file"));
        }