read-cache: move shared add/checkout/commit code

The function add_files_to_cache(), plus associated helper functions, were defined in builtin/add.c, but also shared with builtin/checkout.c and builtin/commit.c. Move these shared functions to read-cache.c. Diff best viewed with `--color-moved`. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed May 16, 2023 at 06:33 UTC 6cee5ebc7af2a05dce64d04ac2ed6aa7ed872f88
2 files changed +102 -100
builtin/add.c
-100
@@ -36,13 +36,6 @@ static int pathspec_file_nul;
36 static int include_sparse;
37 static const char *pathspec_from_file;
38
39 -struct update_callback_data {
40 - struct index_state *index;
41 - int include_sparse;
42 - int flags;
43 - int add_errors;
44 -};
45 -
39 static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only)
40 {
41 int i, ret = 0;
@@ -71,99 +64,6 @@ static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only)
64 return ret;
65 }
66
74 -static int fix_unmerged_status(struct diff_filepair *p,
75 - struct update_callback_data *data)
76 -{
77 - if (p->status != DIFF_STATUS_UNMERGED)
78 - return p->status;
79 - if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
80 - /*
81 - * This is not an explicit add request, and the
82 - * path is missing from the working tree (deleted)
83 - */
84 - return DIFF_STATUS_DELETED;
85 - else
86 - /*
87 - * Either an explicit add request, or path exists
88 - * in the working tree. An attempt to explicitly
89 - * add a path that does not exist in the working tree
90 - * will be caught as an error by the caller immediately.
91 - */
92 - return DIFF_STATUS_MODIFIED;
93 -}
94 -
95 -static void update_callback(struct diff_queue_struct *q,
96 - struct diff_options *opt UNUSED, void *cbdata)
97 -{
98 - int i;
99 - struct update_callback_data *data = cbdata;
100 -
101 - for (i = 0; i < q->nr; i++) {
102 - struct diff_filepair *p = q->queue[i];
103 - const char *path = p->one->path;
104 -
105 - if (!data->include_sparse &&
106 - !path_in_sparse_checkout(path, data->index))
107 - continue;
108 -
109 - switch (fix_unmerged_status(p, data)) {
110 - default:
111 - die(_("unexpected diff status %c"), p->status);
112 - case DIFF_STATUS_MODIFIED:
113 - case DIFF_STATUS_TYPE_CHANGED:
114 - if (add_file_to_index(data->index, path, data->flags)) {
115 - if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
116 - die(_("updating files failed"));
117 - data->add_errors++;
118 - }
119 - break;
120 - case DIFF_STATUS_DELETED:
121 - if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
122 - break;
123 - if (!(data->flags & ADD_CACHE_PRETEND))
124 - remove_file_from_index(data->index, path);
125 - if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
126 - printf(_("remove '%s'\n"), path);
127 - break;
128 - }
129 - }
130 -}
131 -
132 -int add_files_to_cache(struct repository *repo, const char *prefix,
133 - const struct pathspec *pathspec, int include_sparse,
134 - int flags)
135 -{
136 - struct update_callback_data data;
137 - struct rev_info rev;
138 -
139 - memset(&data, 0, sizeof(data));
140 - data.index = repo->index;
141 - data.include_sparse = include_sparse;
142 - data.flags = flags;
143 -
144 - repo_init_revisions(repo, &rev, prefix);
145 - setup_revisions(0, NULL, &rev, NULL);
146 - if (pathspec)
147 - copy_pathspec(&rev.prune_data, pathspec);
148 - rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
149 - rev.diffopt.format_callback = update_callback;
150 - rev.diffopt.format_callback_data = &data;
151 - rev.diffopt.flags.override_submodule_config = 1;
152 - rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
153 -
154 - /*
155 - * Use an ODB transaction to optimize adding multiple objects.
156 - * This function is invoked from commands other than 'add', which
157 - * may not have their own transaction active.
158 - */
159 - begin_odb_transaction();
160 - run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
161 - end_odb_transaction();
162 -
163 - release_revisions(&rev);
164 - return !!data.add_errors;
165 -}
166 -
67 static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
68 {
69 int i, retval = 0;
read-cache.c
+102
@@ -5,6 +5,7 @@
5 */
6 #include "cache.h"
7 #include "alloc.h"
8 +#include "bulk-checkin.h"
9 #include "config.h"
10 #include "date.h"
11 #include "diff.h"
@@ -26,6 +27,7 @@
27 #include "mem-pool.h"
28 #include "object-name.h"
29 #include "resolve-undo.h"
30 +#include "revision.h"
31 #include "run-command.h"
32 #include "strbuf.h"
33 #include "trace2.h"
@@ -3943,3 +3945,103 @@ void overlay_tree_on_index(struct index_state *istate,
3945 }
3946 }
3947 }
3948 +
3949 +struct update_callback_data {
3950 + struct index_state *index;
3951 + int include_sparse;
3952 + int flags;
3953 + int add_errors;
3954 +};
3955 +
3956 +static int fix_unmerged_status(struct diff_filepair *p,
3957 + struct update_callback_data *data)
3958 +{
3959 + if (p->status != DIFF_STATUS_UNMERGED)
3960 + return p->status;
3961 + if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
3962 + /*
3963 + * This is not an explicit add request, and the
3964 + * path is missing from the working tree (deleted)
3965 + */
3966 + return DIFF_STATUS_DELETED;
3967 + else
3968 + /*
3969 + * Either an explicit add request, or path exists
3970 + * in the working tree. An attempt to explicitly
3971 + * add a path that does not exist in the working tree
3972 + * will be caught as an error by the caller immediately.
3973 + */
3974 + return DIFF_STATUS_MODIFIED;
3975 +}
3976 +
3977 +static void update_callback(struct diff_queue_struct *q,
3978 + struct diff_options *opt UNUSED, void *cbdata)
3979 +{
3980 + int i;
3981 + struct update_callback_data *data = cbdata;
3982 +
3983 + for (i = 0; i < q->nr; i++) {
3984 + struct diff_filepair *p = q->queue[i];
3985 + const char *path = p->one->path;
3986 +
3987 + if (!data->include_sparse &&
3988 + !path_in_sparse_checkout(path, data->index))
3989 + continue;
3990 +
3991 + switch (fix_unmerged_status(p, data)) {
3992 + default:
3993 + die(_("unexpected diff status %c"), p->status);
3994 + case DIFF_STATUS_MODIFIED:
3995 + case DIFF_STATUS_TYPE_CHANGED:
3996 + if (add_file_to_index(data->index, path, data->flags)) {
3997 + if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
3998 + die(_("updating files failed"));
3999 + data->add_errors++;
4000 + }
4001 + break;
4002 + case DIFF_STATUS_DELETED:
4003 + if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
4004 + break;
4005 + if (!(data->flags & ADD_CACHE_PRETEND))
4006 + remove_file_from_index(data->index, path);
4007 + if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
4008 + printf(_("remove '%s'\n"), path);
4009 + break;
4010 + }
4011 + }
4012 +}
4013 +
4014 +int add_files_to_cache(struct repository *repo, const char *prefix,
4015 + const struct pathspec *pathspec, int include_sparse,
4016 + int flags)
4017 +{
4018 + struct update_callback_data data;
4019 + struct rev_info rev;
4020 +
4021 + memset(&data, 0, sizeof(data));
4022 + data.index = repo->index;
4023 + data.include_sparse = include_sparse;
4024 + data.flags = flags;
4025 +
4026 + repo_init_revisions(repo, &rev, prefix);
4027 + setup_revisions(0, NULL, &rev, NULL);
4028 + if (pathspec)
4029 + copy_pathspec(&rev.prune_data, pathspec);
4030 + rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
4031 + rev.diffopt.format_callback = update_callback;
4032 + rev.diffopt.format_callback_data = &data;
4033 + rev.diffopt.flags.override_submodule_config = 1;
4034 + rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
4035 +
4036 + /*
4037 + * Use an ODB transaction to optimize adding multiple objects.
4038 + * This function is invoked from commands other than 'add', which
4039 + * may not have their own transaction active.
4040 + */
4041 + begin_odb_transaction();
4042 + run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
4043 + end_odb_transaction();
4044 +
4045 + release_revisions(&rev);
4046 + return !!data.add_errors;
4047 +}