26
#include "strvec.h"
27
#include "submodule.h"
28
#include "add-interactive.h"
29
+#include "merge-ll.h"
30
31
static const char * const builtin_add_usage[] = {
32
N_("git add [<options>] [--] <pathspec>..."),
36
static struct interactive_options interactive_opts = INTERACTIVE_OPTIONS_INIT;
37
static int take_worktree_changes;
38
static int add_renormalize;
39
+static int add_resolved;
40
static int pathspec_file_nul;
41
static int include_sparse;
42
static const char *pathspec_from_file;
267
OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
268
OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
269
OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
270
+ OPT_BOOL(0, "resolved", &add_resolved, N_("add conflict-resolved tracked files")),
271
OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
272
OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
273
OPT_CALLBACK_F(0, "ignore-removal", &addremove_explicit,
382
return exit_status;
383
}
384
385
+static int failed_to_add(int flags, const char *path)
386
+{
387
+ if (!(flags & ADD_CACHE_IGNORE_ERRORS))
388
+ die(_("updating file '%s' failed"), path);
389
+ return 1;
390
+}
391
+
392
+static int add_resolved_files(struct repository *repo,
393
+ const struct pathspec *pathspec,
394
+ int flags)
395
+{
396
+ struct index_state *istate = repo->index;
397
+ struct string_list unmerged_paths = STRING_LIST_INIT_DUP;
398
+ struct string_list unresolved_paths = STRING_LIST_INIT_DUP;
399
+ int exit_status = 0;
400
+ size_t i;
401
+
402
+ for (i = 0; i < istate->cache_nr; i++) {
403
+ struct cache_entry *ce = istate->cache[i];
404
+ if (!ce_stage(ce))
405
+ continue;
406
+ if (pathspec->nr && !ce_path_match(istate, ce, pathspec, NULL))
407
+ continue;
408
+ if (!unmerged_paths.nr ||
409
+ strcmp(unmerged_paths.items[unmerged_paths.nr - 1].string, ce->name))
410
+ string_list_append(&unmerged_paths, ce->name);
411
+ }
412
+
413
+ if (!unmerged_paths.nr) {
414
+ string_list_clear(&unmerged_paths, 0);
415
+ return 0;
416
+ }
417
+
418
+ for (i = 0; i < unmerged_paths.nr; i++) {
419
+ const char *path = unmerged_paths.items[i].string;
420
+ struct stat st;
421
+
422
+ if (!lstat(path, &st) && S_ISREG(st.st_mode)) {
423
+ if (has_conflict_markers(istate, path))
424
+ string_list_append(&unresolved_paths, path);
425
+ }
426
+ }
427
+
428
+ if (unresolved_paths.nr) {
429
+ struct strbuf sb = STRBUF_INIT;
430
+ for (i = 0; i < unresolved_paths.nr; i++)
431
+ strbuf_addf(&sb, "\t%s\n", unresolved_paths.items[i].string);
432
+ die(_("the following paths still have conflict markers:\n%s"), sb.buf);
433
+ }
434
+
435
+ for (i = 0; i < unmerged_paths.nr; i++) {
436
+ const char *path = unmerged_paths.items[i].string;
437
+ struct stat st;
438
+
439
+ if (lstat(path, &st)) {
440
+ if (errno != ENOENT)
441
+ die_errno(_("cannot lstat: '%s'"), path);
442
+ if (remove_file_from_index_with_flags(istate, path, flags))
443
+ exit_status = failed_to_add(flags, path);
444
+ } else {
445
+ if (add_file_to_index(istate, path, flags))
446
+ exit_status = failed_to_add(flags, path);
447
+ }
448
+ }
449
+
450
+ string_list_clear(&unmerged_paths, 0);
451
+ string_list_clear(&unresolved_paths, 0);
452
+ return exit_status;
453
+}
454
+
455
int cmd_add(int argc,
456
const char **argv,
457
const char *prefix,
511
else if (take_worktree_changes && ADDREMOVE_DEFAULT)
512
addremove = 0; /* "-u" was given but not "-A" */
513
441
- if (addremove && take_worktree_changes)
442
- die(_("options '%s' and '%s' cannot be used together"), "-A", "-u");
514
+ die_for_incompatible_opt3(take_worktree_changes, "-u/--update",
515
+ 0 < addremove_explicit, "-A/--all",
516
+ add_resolved, "--resolved");
517
518
if (!show_only && ignore_missing)
519
die(_("the option '%s' requires '%s'"), "--ignore-missing", "--dry-run");
522
chmod_arg[1] != 'x' || chmod_arg[2]))
523
die(_("--chmod param '%s' must be either -x or +x"), chmod_arg);
524
451
- add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
452
- require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
525
+ add_new_files = !take_worktree_changes && !refresh_only &&
526
+ !add_renormalize && !add_resolved;
527
+ require_pathspec = !(take_worktree_changes ||
528
+ (0 < addremove_explicit) ||
529
+ add_resolved);
530
531
repo_hold_locked_index(repo, &lock_file, LOCK_DIE_ON_ERROR);
532
558
return 0;
559
}
560
484
- if (!take_worktree_changes && addremove_explicit < 0 && pathspec.nr)
561
+ if (!take_worktree_changes && !add_resolved &&
562
+ addremove_explicit < 0 && pathspec.nr)
563
/* Turn "git add pathspec..." to "git add -A pathspec..." */
564
addremove = 1;
565
662
odb_transaction_begin_or_die(repo->objects, &transaction, 0);
663
664
ps_matched = xcalloc(pathspec.nr, 1);
587
- if (add_renormalize)
665
+ if (add_resolved)
666
+ exit_status |= add_resolved_files(repo, &pathspec, flags);
667
+ else if (add_renormalize)
668
exit_status |= renormalize_tracked_files(repo, &pathspec, flags);
669
else
670
exit_status |= add_files_to_cache(repo, prefix,