From: Jonathan Nieder <jrnieder@gmail.com>
To: git@vger.kernel.org
Cc: Jens Lehmann <Jens.Lehmann@web.de>, Heiko Voigt <hvoigt@hvoigt.net>
Subject: [PATCH 3/5] submodule: teach unpack_trees() to repopulate submodules
Date: Thu, 26 Dec 2013 08:14:10 -0800 [thread overview]
Message-ID: <20131226161410.GO20443@google.com> (raw)
In-Reply-To: <20131226155857.GL20443@google.com>
From: Jens Lehmann <Jens.Lehmann@web.de>
Date: Mon, 18 Jun 2012 22:11:45 +0200
Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Neat. Would probably be clearer with some of the corresponding tests
squashed in to illustrate the intended behavior.
entry.c | 4 ++++
submodule.c | 44 +++++++++++++++++++++++++++++++++++++++++---
submodule.h | 1 +
unpack-trees.c | 19 +++++++++++++++++++
4 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/entry.c b/entry.c
index 7b7aa81..d1bf6ec 100644
--- a/entry.c
+++ b/entry.c
@@ -2,6 +2,7 @@
#include "blob.h"
#include "dir.h"
#include "streaming.h"
+#include "submodule.h"
static void create_directories(const char *path, int path_len,
const struct checkout *state)
@@ -203,6 +204,9 @@ static int write_entry(struct cache_entry *ce,
return error("cannot create temporary submodule %s", path);
if (mkdir(path, 0777) < 0)
return error("cannot create submodule directory %s", path);
+ if (submodule_needs_update(path) &&
+ populate_submodule(path, ce->sha1, state->force))
+ return error("cannot checkout submodule %s", path);
break;
default:
return error("unknown file mode for %s in index", path);
diff --git a/submodule.c b/submodule.c
index a25db46..06df5ae 100644
--- a/submodule.c
+++ b/submodule.c
@@ -412,6 +412,42 @@ int submodule_needs_update(const char *path)
return config_update_recurse_submodules != RECURSE_SUBMODULES_OFF;
}
+int populate_submodule(const char *path, unsigned char sha1[20], int force)
+{
+ struct string_list_item *path_option;
+ const char *name, *real_git_dir;
+ struct strbuf buf = STRBUF_INIT;
+ struct child_process cp;
+ const char *argv[] = {"read-tree", force ? "--reset" : "-m", "-u", NULL, NULL};
+
+ path_option = unsorted_string_list_lookup(&config_name_for_path, path);
+ if (!path_option)
+ return 0;
+
+ name = path_option->util;
+
+ strbuf_addf(&buf, "%s/modules/%s", resolve_gitdir(get_git_dir()), name);
+ real_git_dir = resolve_gitdir(buf.buf);
+ if (!real_git_dir)
+ goto out;
+ connect_work_tree_and_git_dir(path, real_git_dir);
+
+ /* Run read-tree --reset sha1 */
+ memset(&cp, 0, sizeof(cp));
+ cp.argv = argv;
+ cp.env = local_repo_env;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.dir = path;
+ argv[3] = sha1_to_hex(sha1);
+ if (run_command(&cp))
+ warning(_("Checking out submodule %s failed"), path);
+
+out:
+ strbuf_release(&buf);
+ return 0;
+}
+
int depopulate_submodule(const char *path)
{
struct strbuf dot_git = STRBUF_INIT;
@@ -1207,6 +1243,7 @@ void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
{
struct strbuf file_name = STRBUF_INIT;
struct strbuf rel_path = STRBUF_INIT;
+ const char *real_git_dir = xstrdup(real_path(git_dir));
const char *real_work_tree = xstrdup(real_path(work_tree));
FILE *fp;
@@ -1215,15 +1252,15 @@ void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
fp = fopen(file_name.buf, "w");
if (!fp)
die(_("Could not create git link %s"), file_name.buf);
- fprintf(fp, "gitdir: %s\n", relative_path(git_dir, real_work_tree,
+ fprintf(fp, "gitdir: %s\n", relative_path(real_git_dir, real_work_tree,
&rel_path));
fclose(fp);
/* Update core.worktree setting */
strbuf_reset(&file_name);
- strbuf_addf(&file_name, "%s/config", git_dir);
+ strbuf_addf(&file_name, "%s/config", real_git_dir);
if (git_config_set_in_file(file_name.buf, "core.worktree",
- relative_path(real_work_tree, git_dir,
+ relative_path(real_work_tree, real_git_dir,
&rel_path)))
die(_("Could not set core.worktree in %s"),
file_name.buf);
@@ -1231,4 +1268,5 @@ void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
strbuf_release(&file_name);
strbuf_release(&rel_path);
free((void *)real_work_tree);
+ free((void *)real_git_dir);
}
diff --git a/submodule.h b/submodule.h
index df291cf..3657ca8 100644
--- a/submodule.h
+++ b/submodule.h
@@ -24,6 +24,7 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);
int parse_update_recurse_submodules_arg(const char *opt, const char *arg);
int submodule_needs_update(const char *path);
+int populate_submodule(const char *path, unsigned char sha1[20], int force);
int depopulate_submodule(const char *path);
void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
diff --git a/unpack-trees.c b/unpack-trees.c
index 89b506a..ed48d41 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -1367,6 +1367,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
struct unpack_trees_options *o)
{
const struct cache_entry *result;
+ char *name_copy, *separator;
/*
* It may be that the 'lstat()' succeeded even though
@@ -1409,6 +1410,24 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
return 0;
}
+ /*
+ * If the path lies inside a to be added submodule it
+ * is ok to remove it.
+ */
+ name_copy = xstrdup(name);
+ while ((separator = strrchr(name_copy, '/'))) {
+ int i;
+ *separator = '\0';
+ for (i = 0; i < the_index.cache_nr; i++) {
+ struct cache_entry *ce = the_index.cache[i];
+ if (!strcmp(ce->name, name_copy) && S_ISGITLINK(ce->ce_mode)) {
+ free(name_copy);
+ return 0;
+ }
+ }
+ }
+ free(name_copy);
+
return o->gently ? -1 :
add_rejected_path(o, error_type, name);
}
--
1.8.5.1
next prev parent reply other threads:[~2013-12-26 16:14 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-26 15:58 [WIP/PATCH 0/5] git checkout --recurse-submodules Jonathan Nieder
2013-12-26 16:02 ` [PATCH 1/5] submodule: prepare for recursive checkout of submodules Jonathan Nieder
2013-12-27 13:42 ` Jens Lehmann
2013-12-26 16:12 ` [PATCH 2/5] submodule: teach unpack_trees() to remove submodule contents Jonathan Nieder
2013-12-27 13:58 ` Jens Lehmann
2013-12-26 16:14 ` Jonathan Nieder [this message]
2013-12-26 16:15 ` [PATCH 4/5] submodule: teach unpack_trees() to update submodules Jonathan Nieder
2013-12-26 16:22 ` [PATCH 5/5] Teach checkout to recursively checkout submodules Jonathan Nieder
2013-12-27 14:14 ` Jens Lehmann
2013-12-26 19:58 ` [WIP/PATCH 0/5] git checkout --recurse-submodules Junio C Hamano
2013-12-27 13:34 ` Jens Lehmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131226161410.GO20443@google.com \
--to=jrnieder@gmail.com \
--cc=Jens.Lehmann@web.de \
--cc=git@vger.kernel.org \
--cc=hvoigt@hvoigt.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).