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
500ec543
Commit
500ec543
authored
Feb 03, 2015
by
Edward Thomson
Committed by
Edward Thomson
Feb 04, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
checkout: hold seen dir paths in a map
parent
f58cc280
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
76 additions
and
49 deletions
+76
-49
src/checkout.c
+39
-38
src/fileops.c
+26
-9
src/fileops.h
+11
-2
No files found.
src/checkout.c
View file @
500ec543
...
...
@@ -29,6 +29,10 @@
#include "merge_file.h"
#include "path.h"
#include "attr.h"
#include "pool.h"
#include "strmap.h"
GIT__USE_STRMAP
;
/* See docs/checkout-internals.md for more information */
...
...
@@ -69,7 +73,7 @@ typedef struct {
size_t
total_steps
;
size_t
completed_steps
;
git_checkout_perfdata
perfdata
;
git_
buf
last_mkdir
;
git_
strmap
*
mkdir_map
;
git_attr_session
attr_session
;
}
checkout_data
;
...
...
@@ -1293,25 +1297,6 @@ fail:
return
error
;
}
static
int
checkout_mkdir
(
checkout_data
*
data
,
const
char
*
path
,
const
char
*
base
,
mode_t
mode
,
unsigned
int
flags
)
{
struct
git_futils_mkdir_perfdata
mkdir_perfdata
=
{
0
};
int
error
=
git_futils_mkdir_withperf
(
path
,
base
,
mode
,
flags
,
&
mkdir_perfdata
);
data
->
perfdata
.
mkdir_calls
+=
mkdir_perfdata
.
mkdir_calls
;
data
->
perfdata
.
stat_calls
+=
mkdir_perfdata
.
stat_calls
;
data
->
perfdata
.
chmod_calls
+=
mkdir_perfdata
.
chmod_calls
;
return
error
;
}
static
bool
should_remove_existing
(
checkout_data
*
data
)
{
int
ignorecase
=
0
;
...
...
@@ -1327,31 +1312,43 @@ static bool should_remove_existing(checkout_data *data)
#define MKDIR_REMOVE_EXISTING \
MKDIR_NORMAL | GIT_MKDIR_REMOVE_FILES | GIT_MKDIR_REMOVE_SYMLINKS
static
int
checkout_mkdir
(
checkout_data
*
data
,
const
char
*
path
,
const
char
*
base
,
mode_t
mode
,
unsigned
int
flags
)
{
struct
git_futils_mkdir_options
mkdir_opts
=
{
0
};
int
error
;
mkdir_opts
.
dir_map
=
data
->
mkdir_map
;
mkdir_opts
.
pool
=
&
data
->
pool
;
error
=
git_futils_mkdir_ext
(
path
,
base
,
mode
,
flags
,
&
mkdir_opts
);
data
->
perfdata
.
mkdir_calls
+=
mkdir_opts
.
perfdata
.
mkdir_calls
;
data
->
perfdata
.
stat_calls
+=
mkdir_opts
.
perfdata
.
stat_calls
;
data
->
perfdata
.
chmod_calls
+=
mkdir_opts
.
perfdata
.
chmod_calls
;
return
error
;
}
static
int
mkpath2file
(
checkout_data
*
data
,
const
char
*
path
,
unsigned
int
mode
)
{
git_buf
*
mkdir_path
=
&
data
->
tmp
;
struct
stat
st
;
bool
remove_existing
=
should_remove_existing
(
data
);
unsigned
int
flags
=
(
remove_existing
?
MKDIR_REMOVE_EXISTING
:
MKDIR_NORMAL
)
|
GIT_MKDIR_SKIP_LAST
;
int
error
;
if
((
error
=
git_buf_sets
(
mkdir_path
,
path
))
<
0
)
if
((
error
=
checkout_mkdir
(
data
,
path
,
data
->
opts
.
target_directory
,
mode
,
flags
))
<
0
)
return
error
;
git_buf_rtruncate_at_char
(
mkdir_path
,
'/'
);
if
(
!
data
->
last_mkdir
.
size
||
data
->
last_mkdir
.
size
!=
mkdir_path
->
size
||
memcmp
(
mkdir_path
->
ptr
,
data
->
last_mkdir
.
ptr
,
mkdir_path
->
size
)
!=
0
)
{
if
((
error
=
checkout_mkdir
(
data
,
mkdir_path
->
ptr
,
data
->
opts
.
target_directory
,
mode
,
remove_existing
?
MKDIR_REMOVE_EXISTING
:
MKDIR_NORMAL
))
<
0
)
return
error
;
git_buf_swap
(
&
data
->
last_mkdir
,
mkdir_path
);
}
if
(
remove_existing
)
{
data
->
perfdata
.
stat_calls
++
;
...
...
@@ -2215,13 +2212,16 @@ static void checkout_data_clear(checkout_data *data)
git__free
(
data
->
pfx
);
data
->
pfx
=
NULL
;
git_buf_free
(
&
data
->
last_mkdir
);
git_strmap_free
(
data
->
mkdir_map
);
git_buf_free
(
&
data
->
path
);
git_buf_free
(
&
data
->
tmp
);
git_index_free
(
data
->
index
);
data
->
index
=
NULL
;
git_strmap_free
(
data
->
mkdir_map
);
git_attr_session__free
(
&
data
->
attr_session
);
}
...
...
@@ -2360,7 +2360,8 @@ static int checkout_data_init(
(
error
=
git_vector_init
(
&
data
->
update_conflicts
,
0
,
NULL
))
<
0
||
(
error
=
git_pool_init
(
&
data
->
pool
,
1
,
0
))
<
0
||
(
error
=
git_buf_puts
(
&
data
->
path
,
data
->
opts
.
target_directory
))
<
0
||
(
error
=
git_path_to_dir
(
&
data
->
path
))
<
0
)
(
error
=
git_path_to_dir
(
&
data
->
path
))
<
0
||
(
error
=
git_strmap_alloc
(
&
data
->
mkdir_map
))
<
0
)
goto
cleanup
;
data
->
workdir_len
=
git_buf_len
(
&
data
->
path
);
...
...
src/fileops.c
View file @
500ec543
...
...
@@ -7,11 +7,14 @@
#include "common.h"
#include "fileops.h"
#include "global.h"
#include "strmap.h"
#include <ctype.h>
#if GIT_WIN32
#include "win32/findfile.h"
#endif
GIT__USE_STRMAP
;
int
git_futils_mkpath2file
(
const
char
*
file_path
,
const
mode_t
mode
)
{
return
git_futils_mkdir
(
...
...
@@ -321,12 +324,12 @@ GIT_INLINE(int) validate_existing(
return
0
;
}
int
git_futils_mkdir_
withperf
(
int
git_futils_mkdir_
ext
(
const
char
*
path
,
const
char
*
base
,
mode_t
mode
,
uint32_t
flags
,
struct
git_futils_mkdir_
perfdata
*
perfdata
)
struct
git_futils_mkdir_
options
*
opts
)
{
int
error
=
-
1
;
git_buf
make_path
=
GIT_BUF_INIT
;
...
...
@@ -394,11 +397,14 @@ int git_futils_mkdir_withperf(
*
tail
=
'\0'
;
st
.
st_mode
=
0
;
if
(
opts
->
dir_map
&&
git_strmap_exists
(
opts
->
dir_map
,
make_path
.
ptr
))
continue
;
/* See what's going on with this path component */
perfdata
->
stat_calls
++
;
opts
->
perfdata
.
stat_calls
++
;
if
(
p_lstat
(
make_path
.
ptr
,
&
st
)
<
0
)
{
perfdata
->
mkdir_calls
++
;
opts
->
perfdata
.
mkdir_calls
++
;
if
(
errno
!=
ENOENT
||
p_mkdir
(
make_path
.
ptr
,
mode
)
<
0
)
{
giterr_set
(
GITERR_OS
,
"Failed to make directory '%s'"
,
make_path
.
ptr
);
...
...
@@ -416,7 +422,7 @@ int git_futils_mkdir_withperf(
}
if
((
error
=
validate_existing
(
make_path
.
ptr
,
&
st
,
mode
,
flags
,
perfdata
))
<
0
)
make_path
.
ptr
,
&
st
,
mode
,
flags
,
&
opts
->
perfdata
))
<
0
)
goto
done
;
}
...
...
@@ -425,7 +431,7 @@ int git_futils_mkdir_withperf(
(
lastch
==
'\0'
&&
(
flags
&
GIT_MKDIR_CHMOD
)
!=
0
))
&&
st
.
st_mode
!=
mode
)
{
perfdata
->
chmod_calls
++
;
opts
->
perfdata
.
chmod_calls
++
;
if
((
error
=
p_chmod
(
make_path
.
ptr
,
mode
))
<
0
&&
lastch
==
'\0'
)
{
...
...
@@ -434,6 +440,17 @@ int git_futils_mkdir_withperf(
goto
done
;
}
}
if
(
opts
->
dir_map
&&
opts
->
pool
)
{
char
*
cache_path
=
git_pool_malloc
(
opts
->
pool
,
make_path
.
size
+
1
);
GITERR_CHECK_ALLOC
(
cache_path
);
memcpy
(
cache_path
,
make_path
.
ptr
,
make_path
.
size
+
1
);
git_strmap_insert
(
opts
->
dir_map
,
cache_path
,
cache_path
,
error
);
if
(
error
<
0
)
goto
done
;
}
}
error
=
0
;
...
...
@@ -441,7 +458,7 @@ int git_futils_mkdir_withperf(
/* check that full path really is a directory if requested & needed */
if
((
flags
&
GIT_MKDIR_VERIFY_DIR
)
!=
0
&&
lastch
!=
'\0'
)
{
perfdata
->
stat_calls
++
;
opts
->
perfdata
.
stat_calls
++
;
if
(
p_stat
(
make_path
.
ptr
,
&
st
)
<
0
||
!
S_ISDIR
(
st
.
st_mode
))
{
giterr_set
(
GITERR_OS
,
"Path is not a directory '%s'"
,
...
...
@@ -461,8 +478,8 @@ int git_futils_mkdir(
mode_t
mode
,
uint32_t
flags
)
{
struct
git_futils_mkdir_
perfdata
perfdata
=
{
0
};
return
git_futils_mkdir_
withperf
(
path
,
base
,
mode
,
flags
,
&
perfdata
);
struct
git_futils_mkdir_
options
options
=
{
0
};
return
git_futils_mkdir_
ext
(
path
,
base
,
mode
,
flags
,
&
options
);
}
int
git_futils_mkdir_r
(
const
char
*
path
,
const
char
*
base
,
const
mode_t
mode
)
...
...
src/fileops.h
View file @
500ec543
...
...
@@ -11,6 +11,8 @@
#include "map.h"
#include "posix.h"
#include "path.h"
#include "pool.h"
#include "strmap.h"
/**
* Filebuffer methods
...
...
@@ -95,6 +97,13 @@ struct git_futils_mkdir_perfdata
size_t
chmod_calls
;
};
struct
git_futils_mkdir_options
{
git_strmap
*
dir_map
;
git_pool
*
pool
;
struct
git_futils_mkdir_perfdata
perfdata
;
};
/**
* Create a directory or entire path.
*
...
...
@@ -106,10 +115,10 @@ struct git_futils_mkdir_perfdata
* @param base Root for relative path. These directories will never be made.
* @param mode The mode to use for created directories.
* @param flags Combination of the mkdir flags above.
* @param
perfdata Performance data, use `git_futils_mkdir` if you don't want this data
.
* @param
opts Extended options, use `git_futils_mkdir` if you are not interested
.
* @return 0 on success, else error code
*/
extern
int
git_futils_mkdir_
withperf
(
const
char
*
path
,
const
char
*
base
,
mode_t
mode
,
uint32_t
flags
,
struct
git_futils_mkdir_perfdata
*
perfdata
);
extern
int
git_futils_mkdir_
ext
(
const
char
*
path
,
const
char
*
base
,
mode_t
mode
,
uint32_t
flags
,
struct
git_futils_mkdir_options
*
opts
);
/**
* Create a directory or entire path. Similar to `git_futils_mkdir_withperf`
...
...
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