entry.c: create submodules when interesting

When a submodule is introduced with a new revision we need to create the submodule in the worktree as well. As 'submodule_move_head' handles edge cases, all we have to do is call it from within the function that creates new files in the working tree for workingtree operations. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Mar 14, 2017 at 14:46 UTC 6d14eac3ec3e935ada977dfbdf4c61a0a3222010
1 file changed +30
entry.c
+30
@@ -2,6 +2,7 @@
2 #include "blob.h"
3 #include "dir.h"
4 #include "streaming.h"
5 +#include "submodule.h"
6
7 static void create_directories(const char *path, int path_len,
8 const struct checkout *state)
@@ -146,6 +147,7 @@ static int write_entry(struct cache_entry *ce,
147 unsigned long size;
148 size_t wrote, newsize = 0;
149 struct stat st;
150 + const struct submodule *sub;
151
152 if (ce_mode_s_ifmt == S_IFREG) {
153 struct stream_filter *filter = get_stream_filter(ce->name,
@@ -203,6 +205,10 @@ static int write_entry(struct cache_entry *ce,
205 return error("cannot create temporary submodule %s", path);
206 if (mkdir(path, 0777) < 0)
207 return error("cannot create submodule directory %s", path);
208 + sub = submodule_from_ce(ce);
209 + if (sub)
210 + return submodule_move_head(ce->name,
211 + NULL, oid_to_hex(&ce->oid), SUBMODULE_MOVE_HEAD_FORCE);
212 break;
213 default:
214 return error("unknown file mode for %s in index", path);
@@ -259,7 +265,31 @@ int checkout_entry(struct cache_entry *ce,
265 strbuf_add(&path, ce->name, ce_namelen(ce));
266
267 if (!check_path(path.buf, path.len, &st, state->base_dir_len)) {
268 + const struct submodule *sub;
269 unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
270 + /*
271 + * Needs to be checked before !changed returns early,
272 + * as the possibly empty directory was not changed
273 + */
274 + sub = submodule_from_ce(ce);
275 + if (sub) {
276 + int err;
277 + if (!is_submodule_populated_gently(ce->name, &err)) {
278 + struct stat sb;
279 + if (lstat(ce->name, &sb))
280 + die(_("could not stat file '%s'"), ce->name);
281 + if (!(st.st_mode & S_IFDIR))
282 + unlink_or_warn(ce->name);
283 +
284 + return submodule_move_head(ce->name,
285 + NULL, oid_to_hex(&ce->oid),
286 + SUBMODULE_MOVE_HEAD_FORCE);
287 + } else
288 + return submodule_move_head(ce->name,
289 + "HEAD", oid_to_hex(&ce->oid),
290 + SUBMODULE_MOVE_HEAD_FORCE);
291 + }
292 +
293 if (!changed)
294 return 0;
295 if (!state->force) {