clone: create intermediate directories of destination repo
The shell version used to use "mkdir -p" to create the repo
path, but the C version just calls "mkdir". Let's replicate
the old behavior. We have to create the git and worktree
leading dirs separately; while most of the time, the
worktree dir contains the git dir (as .git), the user can
override this using GIT_WORK_TREE.
We can reuse safe_create_leading_directories, but we need to
make a copy of our const buffer to do so. Since
merge-recursive uses the same pattern, we can factor this
out into a global function. This has two other cleanup
advantages for merge-recursive:
  1. mkdir_p wasn't a very good name. "mkdir -p foo/bar" actually
     creates bar, but this function just creates the leading
     directories.
  2. mkdir_p took a mode argument, but it was completely
     ignored.
Acked-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
			
			
				maint
			
			
		
							parent
							
								
									4ace4fc584
								
							
						
					
					
						commit
						2beebd22f4
					
				|  | @ -400,6 +400,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | ||||||
|  |  | ||||||
| 	if (!option_bare) { | 	if (!option_bare) { | ||||||
| 		junk_work_tree = work_tree; | 		junk_work_tree = work_tree; | ||||||
|  | 		if (safe_create_leading_directories_const(work_tree) < 0) | ||||||
|  | 			die("could not create leading directories of '%s'", | ||||||
|  | 					work_tree); | ||||||
| 		if (mkdir(work_tree, 0755)) | 		if (mkdir(work_tree, 0755)) | ||||||
| 			die("could not create work tree dir '%s'.", work_tree); | 			die("could not create work tree dir '%s'.", work_tree); | ||||||
| 		set_git_work_tree(work_tree); | 		set_git_work_tree(work_tree); | ||||||
|  | @ -410,6 +413,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | ||||||
|  |  | ||||||
| 	setenv(CONFIG_ENVIRONMENT, xstrdup(mkpath("%s/config", git_dir)), 1); | 	setenv(CONFIG_ENVIRONMENT, xstrdup(mkpath("%s/config", git_dir)), 1); | ||||||
|  |  | ||||||
|  | 	if (safe_create_leading_directories_const(git_dir) < 0) | ||||||
|  | 		die("could not create leading directories of '%s'", git_dir); | ||||||
| 	set_git_dir(make_absolute_path(git_dir)); | 	set_git_dir(make_absolute_path(git_dir)); | ||||||
|  |  | ||||||
| 	fprintf(stderr, "Initialize %s\n", git_dir); | 	fprintf(stderr, "Initialize %s\n", git_dir); | ||||||
|  |  | ||||||
|  | @ -481,15 +481,6 @@ static char *unique_path(const char *path, const char *branch) | ||||||
| 	return newpath; | 	return newpath; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int mkdir_p(const char *path, unsigned long mode) |  | ||||||
| { |  | ||||||
| 	/* path points to cache entries, so xstrdup before messing with it */ |  | ||||||
| 	char *buf = xstrdup(path); |  | ||||||
| 	int result = safe_create_leading_directories(buf); |  | ||||||
| 	free(buf); |  | ||||||
| 	return result; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void flush_buffer(int fd, const char *buf, unsigned long size) | static void flush_buffer(int fd, const char *buf, unsigned long size) | ||||||
| { | { | ||||||
| 	while (size > 0) { | 	while (size > 0) { | ||||||
|  | @ -512,7 +503,7 @@ static int make_room_for_path(const char *path) | ||||||
| 	int status; | 	int status; | ||||||
| 	const char *msg = "failed to create path '%s'%s"; | 	const char *msg = "failed to create path '%s'%s"; | ||||||
|  |  | ||||||
| 	status = mkdir_p(path, 0777); | 	status = safe_create_leading_directories_const(path); | ||||||
| 	if (status) { | 	if (status) { | ||||||
| 		if (status == -3) { | 		if (status == -3) { | ||||||
| 			/* something else exists */ | 			/* something else exists */ | ||||||
|  | @ -583,7 +574,7 @@ static void update_file_flags(const unsigned char *sha, | ||||||
| 			close(fd); | 			close(fd); | ||||||
| 		} else if (S_ISLNK(mode)) { | 		} else if (S_ISLNK(mode)) { | ||||||
| 			char *lnk = xmemdupz(buf, size); | 			char *lnk = xmemdupz(buf, size); | ||||||
| 			mkdir_p(path, 0777); | 			safe_create_leading_directories_const(path); | ||||||
| 			unlink(path); | 			unlink(path); | ||||||
| 			symlink(lnk, path); | 			symlink(lnk, path); | ||||||
| 			free(lnk); | 			free(lnk); | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										1
									
								
								cache.h
								
								
								
								
							|  | @ -518,6 +518,7 @@ enum sharedrepo { | ||||||
| int git_config_perm(const char *var, const char *value); | int git_config_perm(const char *var, const char *value); | ||||||
| int adjust_shared_perm(const char *path); | int adjust_shared_perm(const char *path); | ||||||
| int safe_create_leading_directories(char *path); | int safe_create_leading_directories(char *path); | ||||||
|  | int safe_create_leading_directories_const(const char *path); | ||||||
| char *enter_repo(char *path, int strict); | char *enter_repo(char *path, int strict); | ||||||
| static inline int is_absolute_path(const char *path) | static inline int is_absolute_path(const char *path) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -116,6 +116,15 @@ int safe_create_leading_directories(char *path) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int safe_create_leading_directories_const(const char *path) | ||||||
|  | { | ||||||
|  | 	/* path points to cache entries, so xstrdup before messing with it */ | ||||||
|  | 	char *buf = xstrdup(path); | ||||||
|  | 	int result = safe_create_leading_directories(buf); | ||||||
|  | 	free(buf); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
| char *sha1_to_hex(const unsigned char *sha1) | char *sha1_to_hex(const unsigned char *sha1) | ||||||
| { | { | ||||||
| 	static int bufno; | 	static int bufno; | ||||||
|  |  | ||||||
|  | @ -30,4 +30,26 @@ test_expect_success 'clone checks out files' ' | ||||||
|  |  | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'clone respects GIT_WORK_TREE' ' | ||||||
|  |  | ||||||
|  | 	GIT_WORK_TREE=worktree git clone src bare && | ||||||
|  | 	test -f bare/config && | ||||||
|  | 	test -f worktree/file | ||||||
|  |  | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'clone creates intermediate directories' ' | ||||||
|  |  | ||||||
|  | 	git clone src long/path/to/dst && | ||||||
|  | 	test -f long/path/to/dst/file | ||||||
|  |  | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'clone creates intermediate directories for bare repo' ' | ||||||
|  |  | ||||||
|  | 	git clone --bare src long/path/to/bare/dst && | ||||||
|  | 	test -f long/path/to/bare/dst/config | ||||||
|  |  | ||||||
|  | ' | ||||||
|  |  | ||||||
| test_done | test_done | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Jeff King
						Jeff King