Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
555aa453
Commit
555aa453
authored
Apr 09, 2012
by
nulltoken
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fileops: Make git_futils_mkdir_r() able to skip non-empty directories
parent
731df570
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
57 additions
and
17 deletions
+57
-17
src/fileops.c
+17
-6
src/fileops.h
+16
-1
tests-clar/core/rmdir.c
+21
-7
tests-clar/status/worktree.c
+3
-3
No files found.
src/fileops.c
View file @
555aa453
...
@@ -298,13 +298,20 @@ int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
...
@@ -298,13 +298,20 @@ int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
static
int
_rmdir_recurs_foreach
(
void
*
opaque
,
git_buf
*
path
)
static
int
_rmdir_recurs_foreach
(
void
*
opaque
,
git_buf
*
path
)
{
{
int
force
=
*
(
int
*
)
opaque
;
enum
git_directory_removal_type
removal_type
=
*
(
enum
git_directory_removal_type
*
)
opaque
;
assert
(
removal_type
==
GIT_DIRREMOVAL_EMPTY_HIERARCHY
||
removal_type
==
GIT_DIRREMOVAL_FILES_AND_DIRS
||
removal_type
==
GIT_DIRREMOVAL_ONLY_EMPTY_DIRS
);
if
(
git_path_isdir
(
path
->
ptr
)
==
true
)
{
if
(
git_path_isdir
(
path
->
ptr
)
==
true
)
{
if
(
git_path_direach
(
path
,
_rmdir_recurs_foreach
,
opaque
)
<
0
)
if
(
git_path_direach
(
path
,
_rmdir_recurs_foreach
,
opaque
)
<
0
)
return
-
1
;
return
-
1
;
if
(
p_rmdir
(
path
->
ptr
)
<
0
)
{
if
(
p_rmdir
(
path
->
ptr
)
<
0
)
{
if
(
removal_type
==
GIT_DIRREMOVAL_ONLY_EMPTY_DIRS
&&
errno
==
ENOTEMPTY
)
return
0
;
giterr_set
(
GITERR_OS
,
"Could not remove directory '%s'"
,
path
->
ptr
);
giterr_set
(
GITERR_OS
,
"Could not remove directory '%s'"
,
path
->
ptr
);
return
-
1
;
return
-
1
;
}
}
...
@@ -312,7 +319,7 @@ static int _rmdir_recurs_foreach(void *opaque, git_buf *path)
...
@@ -312,7 +319,7 @@ static int _rmdir_recurs_foreach(void *opaque, git_buf *path)
return
0
;
return
0
;
}
}
if
(
force
)
{
if
(
removal_type
==
GIT_DIRREMOVAL_FILES_AND_DIRS
)
{
if
(
p_unlink
(
path
->
ptr
)
<
0
)
{
if
(
p_unlink
(
path
->
ptr
)
<
0
)
{
giterr_set
(
GITERR_OS
,
"Could not remove directory. File '%s' cannot be removed"
,
path
->
ptr
);
giterr_set
(
GITERR_OS
,
"Could not remove directory. File '%s' cannot be removed"
,
path
->
ptr
);
return
-
1
;
return
-
1
;
...
@@ -321,18 +328,22 @@ static int _rmdir_recurs_foreach(void *opaque, git_buf *path)
...
@@ -321,18 +328,22 @@ static int _rmdir_recurs_foreach(void *opaque, git_buf *path)
return
0
;
return
0
;
}
}
giterr_set
(
GITERR_OS
,
"Could not remove directory. File '%s' still present"
,
path
->
ptr
);
if
(
removal_type
==
GIT_DIRREMOVAL_EMPTY_HIERARCHY
)
{
return
-
1
;
giterr_set
(
GITERR_OS
,
"Could not remove directory. File '%s' still present"
,
path
->
ptr
);
return
-
1
;
}
return
0
;
}
}
int
git_futils_rmdir_r
(
const
char
*
path
,
int
forc
e
)
int
git_futils_rmdir_r
(
const
char
*
path
,
enum
git_directory_removal_type
removal_typ
e
)
{
{
int
error
;
int
error
;
git_buf
p
=
GIT_BUF_INIT
;
git_buf
p
=
GIT_BUF_INIT
;
error
=
git_buf_sets
(
&
p
,
path
);
error
=
git_buf_sets
(
&
p
,
path
);
if
(
!
error
)
if
(
!
error
)
error
=
_rmdir_recurs_foreach
(
&
forc
e
,
&
p
);
error
=
_rmdir_recurs_foreach
(
&
removal_typ
e
,
&
p
);
git_buf_free
(
&
p
);
git_buf_free
(
&
p
);
return
error
;
return
error
;
}
}
...
...
src/fileops.h
View file @
555aa453
...
@@ -58,10 +58,25 @@ extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t m
...
@@ -58,10 +58,25 @@ extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t m
*/
*/
extern
int
git_futils_mkpath2file
(
const
char
*
path
,
const
mode_t
mode
);
extern
int
git_futils_mkpath2file
(
const
char
*
path
,
const
mode_t
mode
);
typedef
enum
{
GIT_DIRREMOVAL_EMPTY_HIERARCHY
=
0
,
GIT_DIRREMOVAL_FILES_AND_DIRS
=
1
,
GIT_DIRREMOVAL_ONLY_EMPTY_DIRS
=
2
,
}
git_directory_removal_type
;
/**
/**
* Remove path and any files and directories beneath it.
* Remove path and any files and directories beneath it.
*
* @param path Path to to top level directory to process.
*
* @param removal_type GIT_DIRREMOVAL_EMPTY_HIERARCHY to remove a hierarchy
* of empty directories (will fail if any file is found), GIT_DIRREMOVAL_FILES_AND_DIRS
* to remove a hierarchy of files and folders, GIT_DIRREMOVAL_ONLY_EMPTY_DIRS to only remove
* empty directories (no failure on file encounter).
*
* @return 0 on success; -1 on error.
*/
*/
extern
int
git_futils_rmdir_r
(
const
char
*
path
,
int
forc
e
);
extern
int
git_futils_rmdir_r
(
const
char
*
path
,
enum
git_directory_removal_type
removal_typ
e
);
/**
/**
* Create and open a temporary file with a `_git2_` suffix.
* Create and open a temporary file with a `_git2_` suffix.
...
...
tests-clar/core/rmdir.c
View file @
555aa453
...
@@ -30,25 +30,39 @@ void test_core_rmdir__initialize(void)
...
@@ -30,25 +30,39 @@ void test_core_rmdir__initialize(void)
/* make sure empty dir can be deleted recusively */
/* make sure empty dir can be deleted recusively */
void
test_core_rmdir__delete_recursive
(
void
)
void
test_core_rmdir__delete_recursive
(
void
)
{
{
cl_git_pass
(
git_futils_rmdir_r
(
empty_tmp_dir
,
0
));
cl_git_pass
(
git_futils_rmdir_r
(
empty_tmp_dir
,
GIT_DIRREMOVAL_EMPTY_HIERARCHY
));
}
}
/* make sure non-empty dir cannot be deleted recusively */
/* make sure non-empty dir cannot be deleted recusively */
void
test_core_rmdir__fail_to_delete_non_empty_dir
(
void
)
void
test_core_rmdir__fail_to_delete_non_empty_dir
(
void
)
{
{
git_buf
file
=
GIT_BUF_INIT
;
git_buf
file
=
GIT_BUF_INIT
;
int
fd
;
cl_git_pass
(
git_buf_joinpath
(
&
file
,
empty_tmp_dir
,
"/two/file.txt"
));
cl_git_pass
(
git_buf_joinpath
(
&
file
,
empty_tmp_dir
,
"/two/file.txt"
));
fd
=
p_creat
(
file
.
ptr
,
0666
);
cl_git_mkfile
(
git_buf_cstr
(
&
file
),
"dummy"
);
cl_assert
(
fd
>=
0
);
cl_must_pass
(
p_close
(
fd
));
cl_git_fail
(
git_futils_rmdir_r
(
empty_tmp_dir
,
GIT_DIRREMOVAL_EMPTY_HIERARCHY
));
cl_git_fail
(
git_futils_rmdir_r
(
empty_tmp_dir
,
0
));
cl_must_pass
(
p_unlink
(
file
.
ptr
));
cl_must_pass
(
p_unlink
(
file
.
ptr
));
cl_git_pass
(
git_futils_rmdir_r
(
empty_tmp_dir
,
0
));
cl_git_pass
(
git_futils_rmdir_r
(
empty_tmp_dir
,
GIT_DIRREMOVAL_EMPTY_HIERARCHY
));
git_buf_free
(
&
file
);
}
void
test_core_rmdir__can_skip__non_empty_dir
(
void
)
{
git_buf
file
=
GIT_BUF_INIT
;
cl_git_pass
(
git_buf_joinpath
(
&
file
,
empty_tmp_dir
,
"/two/file.txt"
));
cl_git_mkfile
(
git_buf_cstr
(
&
file
),
"dummy"
);
cl_git_pass
(
git_futils_rmdir_r
(
empty_tmp_dir
,
GIT_DIRREMOVAL_ONLY_EMPTY_DIRS
));
cl_assert
(
git_path_exists
(
git_buf_cstr
(
&
file
))
==
true
);
cl_git_pass
(
git_futils_rmdir_r
(
empty_tmp_dir
,
GIT_DIRREMOVAL_FILES_AND_DIRS
));
cl_assert
(
git_path_exists
(
empty_tmp_dir
)
==
false
);
git_buf_free
(
&
file
);
git_buf_free
(
&
file
);
}
}
tests-clar/status/worktree.c
View file @
555aa453
...
@@ -110,7 +110,7 @@ static int remove_file_cb(void *data, git_buf *file)
...
@@ -110,7 +110,7 @@ static int remove_file_cb(void *data, git_buf *file)
return
0
;
return
0
;
if
(
git_path_isdir
(
filename
))
if
(
git_path_isdir
(
filename
))
cl_git_pass
(
git_futils_rmdir_r
(
filename
,
1
));
cl_git_pass
(
git_futils_rmdir_r
(
filename
,
GIT_DIRREMOVAL_FILES_AND_DIRS
));
else
else
cl_git_pass
(
p_unlink
(
git_buf_cstr
(
file
)));
cl_git_pass
(
p_unlink
(
git_buf_cstr
(
file
)));
...
@@ -346,7 +346,7 @@ void test_status_worktree__issue_592_3(void)
...
@@ -346,7 +346,7 @@ void test_status_worktree__issue_592_3(void)
repo
=
cl_git_sandbox_init
(
"issue_592"
);
repo
=
cl_git_sandbox_init
(
"issue_592"
);
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
repo
),
"c"
));
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
repo
),
"c"
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
1
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
GIT_DIRREMOVAL_FILES_AND_DIRS
));
cl_git_pass
(
git_status_foreach
(
repo
,
cb_status__check_592
,
"c/a.txt"
));
cl_git_pass
(
git_status_foreach
(
repo
,
cb_status__check_592
,
"c/a.txt"
));
...
@@ -376,7 +376,7 @@ void test_status_worktree__issue_592_5(void)
...
@@ -376,7 +376,7 @@ void test_status_worktree__issue_592_5(void)
repo
=
cl_git_sandbox_init
(
"issue_592"
);
repo
=
cl_git_sandbox_init
(
"issue_592"
);
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
repo
),
"t"
));
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
repo
),
"t"
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
1
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
GIT_DIRREMOVAL_FILES_AND_DIRS
));
cl_git_pass
(
p_mkdir
(
git_buf_cstr
(
&
path
),
0777
));
cl_git_pass
(
p_mkdir
(
git_buf_cstr
(
&
path
),
0777
));
cl_git_pass
(
git_status_foreach
(
repo
,
cb_status__check_592
,
NULL
));
cl_git_pass
(
git_status_foreach
(
repo
,
cb_status__check_592
,
NULL
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment