Teach "git-read-tree -u" to check out submodules as a directory
This actually allows us to check out a supermodule after cloning, although the submodules themselves will obviously not be checked out, and will just be empty directories. Checking out the submodules will be up to higher levels - we may not even want to! Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
6e2f441bd4
commit
f0807e62b4
45
entry.c
45
entry.c
@ -62,26 +62,33 @@ static int create_file(const char *path, unsigned int mode)
|
|||||||
return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *read_blob_entry(struct cache_entry *ce, const char *path, unsigned long *size)
|
||||||
|
{
|
||||||
|
enum object_type type;
|
||||||
|
void *new = read_sha1_file(ce->sha1, &type, size);
|
||||||
|
|
||||||
|
if (new) {
|
||||||
|
if (type == OBJ_BLOB)
|
||||||
|
return new;
|
||||||
|
free(new);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int write_entry(struct cache_entry *ce, char *path, struct checkout *state, int to_tempfile)
|
static int write_entry(struct cache_entry *ce, char *path, struct checkout *state, int to_tempfile)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
void *new;
|
|
||||||
unsigned long size;
|
|
||||||
long wrote;
|
long wrote;
|
||||||
enum object_type type;
|
|
||||||
|
|
||||||
new = read_sha1_file(ce->sha1, &type, &size);
|
|
||||||
if (!new || type != OBJ_BLOB) {
|
|
||||||
if (new)
|
|
||||||
free(new);
|
|
||||||
return error("git-checkout-index: unable to read sha1 file of %s (%s)",
|
|
||||||
path, sha1_to_hex(ce->sha1));
|
|
||||||
}
|
|
||||||
switch (ntohl(ce->ce_mode) & S_IFMT) {
|
switch (ntohl(ce->ce_mode) & S_IFMT) {
|
||||||
char *buf;
|
char *buf, *new;
|
||||||
unsigned long nsize;
|
unsigned long size, nsize;
|
||||||
|
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
|
new = read_blob_entry(ce, path, &size);
|
||||||
|
if (!new)
|
||||||
|
return error("git-checkout-index: unable to read sha1 file of %s (%s)",
|
||||||
|
path, sha1_to_hex(ce->sha1));
|
||||||
if (to_tempfile) {
|
if (to_tempfile) {
|
||||||
strcpy(path, ".merge_file_XXXXXX");
|
strcpy(path, ".merge_file_XXXXXX");
|
||||||
fd = mkstemp(path);
|
fd = mkstemp(path);
|
||||||
@ -111,6 +118,10 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
|
|||||||
return error("git-checkout-index: unable to write file %s", path);
|
return error("git-checkout-index: unable to write file %s", path);
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
|
new = read_blob_entry(ce, path, &size);
|
||||||
|
if (!new)
|
||||||
|
return error("git-checkout-index: unable to read sha1 file of %s (%s)",
|
||||||
|
path, sha1_to_hex(ce->sha1));
|
||||||
if (to_tempfile || !has_symlinks) {
|
if (to_tempfile || !has_symlinks) {
|
||||||
if (to_tempfile) {
|
if (to_tempfile) {
|
||||||
strcpy(path, ".merge_link_XXXXXX");
|
strcpy(path, ".merge_link_XXXXXX");
|
||||||
@ -136,8 +147,13 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
|
|||||||
"symlink %s (%s)", path, strerror(errno));
|
"symlink %s (%s)", path, strerror(errno));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case S_IFDIRLNK:
|
||||||
|
if (to_tempfile)
|
||||||
|
return error("git-checkout-index: cannot create temporary subproject %s", path);
|
||||||
|
if (mkdir(path, 0777) < 0)
|
||||||
|
return error("git-checkout-index: cannot create subproject directory %s", path);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
free(new);
|
|
||||||
return error("git-checkout-index: unknown file mode for %s", path);
|
return error("git-checkout-index: unknown file mode for %s", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +195,9 @@ int checkout_entry(struct cache_entry *ce, struct checkout *state, char *topath)
|
|||||||
*/
|
*/
|
||||||
unlink(path);
|
unlink(path);
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
/* If it is a gitlink, leave it alone! */
|
||||||
|
if (S_ISDIRLNK(ntohl(ce->ce_mode)))
|
||||||
|
return 0;
|
||||||
if (!state->force)
|
if (!state->force)
|
||||||
return error("%s is a directory", path);
|
return error("%s is a directory", path);
|
||||||
remove_subtree(path);
|
remove_subtree(path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user