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
db1edf91
Commit
db1edf91
authored
9 years ago
by
Edward Thomson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3491 from libgit2/cmn/config-checksum
Use checksums to detect config file changes
parents
76319fa8
3547b122
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
59 additions
and
36 deletions
+59
-36
src/config_file.c
+5
-10
src/fileops.c
+32
-25
src/fileops.h
+2
-1
tests/config/stress.c
+20
-0
No files found.
src/config_file.c
View file @
db1edf91
...
...
@@ -77,8 +77,7 @@ typedef struct git_config_file_iter {
(iter) = (tmp))
struct
reader
{
time_t
file_mtime
;
size_t
file_size
;
git_oid
checksum
;
char
*
file_path
;
git_buf
buffer
;
char
*
read_ptr
;
...
...
@@ -285,7 +284,7 @@ static int config_open(git_config_backend *cfg, git_config_level_t level)
git_buf_init
(
&
reader
->
buffer
,
0
);
res
=
git_futils_readbuffer_updated
(
&
reader
->
buffer
,
b
->
file_path
,
&
reader
->
file_mtime
,
&
reader
->
file_size
,
NULL
);
&
reader
->
buffer
,
b
->
file_path
,
&
reader
->
checksum
,
NULL
);
/* It's fine if the file doesn't exist */
if
(
res
==
GIT_ENOTFOUND
)
...
...
@@ -345,7 +344,7 @@ static int config_refresh(git_config_backend *cfg)
reader
=
git_array_get
(
b
->
readers
,
i
);
error
=
git_futils_readbuffer_updated
(
&
reader
->
buffer
,
reader
->
file_path
,
&
reader
->
file_mtime
,
&
reader
->
file_size
,
&
updated
);
&
reader
->
checksum
,
&
updated
);
if
(
error
<
0
&&
error
!=
GIT_ENOTFOUND
)
return
error
;
...
...
@@ -1618,7 +1617,7 @@ static int read_on_variable(
git_buf_init
(
&
r
->
buffer
,
0
);
result
=
git_futils_readbuffer_updated
(
&
r
->
buffer
,
r
->
file_path
,
&
r
->
file_mtime
,
&
r
->
file_size
,
NULL
);
&
r
->
buffer
,
r
->
file_path
,
&
r
->
checksum
,
NULL
);
if
(
result
==
0
)
{
result
=
config_read
(
parse_data
->
values
,
parse_data
->
cfg_file
,
r
,
parse_data
->
level
,
parse_data
->
depth
+
1
);
...
...
@@ -1894,7 +1893,7 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
}
else
{
/* Lock the file */
if
((
result
=
git_filebuf_open
(
&
file
,
cfg
->
file_path
,
0
,
GIT_CONFIG_FILE_MODE
))
<
0
)
{
&
file
,
cfg
->
file_path
,
GIT_FILEBUF_HASH_CONTENTS
,
GIT_CONFIG_FILE_MODE
))
<
0
)
{
git_buf_free
(
&
reader
->
buffer
);
return
result
;
}
...
...
@@ -1945,10 +1944,6 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
git_buf_attach
(
&
cfg
->
locked_content
,
git_buf_detach
(
&
buf
),
len
);
}
else
{
git_filebuf_write
(
&
file
,
git_buf_cstr
(
&
buf
),
git_buf_len
(
&
buf
));
/* refresh stats - if this errors, then commit will error too */
(
void
)
git_filebuf_stats
(
&
reader
->
file_mtime
,
&
reader
->
file_size
,
&
file
);
result
=
git_filebuf_commit
(
&
file
);
}
...
...
This diff is collapsed.
Click to expand it.
src/fileops.c
View file @
db1edf91
...
...
@@ -153,13 +153,15 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
}
int
git_futils_readbuffer_updated
(
git_buf
*
buf
,
const
char
*
path
,
time_t
*
mtime
,
size_t
*
size
,
int
*
updated
)
git_buf
*
out
,
const
char
*
path
,
git_oid
*
checksum
,
int
*
updated
)
{
int
error
;
git_file
fd
;
struct
stat
st
;
bool
changed
=
false
;
git_buf
buf
=
GIT_BUF_INIT
;
git_oid
checksum_new
;
assert
(
buf
&&
path
&&
*
path
);
assert
(
out
&&
path
&&
*
path
);
if
(
updated
!=
NULL
)
*
updated
=
0
;
...
...
@@ -178,45 +180,50 @@ int git_futils_readbuffer_updated(
return
-
1
;
}
/*
* If we were given a time and/or a size, we only want to read the file
* if it has been modified.
*/
if
(
size
&&
*
size
!=
(
size_t
)
st
.
st_size
)
changed
=
true
;
if
(
mtime
&&
*
mtime
!=
(
time_t
)
st
.
st_mtime
)
changed
=
true
;
if
(
!
size
&&
!
mtime
)
changed
=
true
;
if
(
!
changed
)
{
return
0
;
}
if
(
mtime
!=
NULL
)
*
mtime
=
st
.
st_mtime
;
if
(
size
!=
NULL
)
*
size
=
(
size_t
)
st
.
st_size
;
if
((
fd
=
git_futils_open_ro
(
path
))
<
0
)
return
fd
;
if
(
git_futils_readbuffer_fd
(
buf
,
fd
,
(
size_t
)
st
.
st_size
)
<
0
)
{
if
(
git_futils_readbuffer_fd
(
&
buf
,
fd
,
(
size_t
)
st
.
st_size
)
<
0
)
{
p_close
(
fd
);
return
-
1
;
}
p_close
(
fd
);
if
((
error
=
git_hash_buf
(
&
checksum_new
,
buf
.
ptr
,
buf
.
size
))
<
0
)
{
git_buf_free
(
&
buf
);
return
error
;
}
/*
* If we were given a checksum, we only want to use it if it's different
*/
if
(
checksum
&&
!
git_oid__cmp
(
checksum
,
&
checksum_new
))
{
git_buf_free
(
&
buf
);
if
(
updated
)
*
updated
=
0
;
return
0
;
}
/*
* If we're here, the file did change, or the user didn't have an old version
*/
if
(
checksum
)
git_oid_cpy
(
checksum
,
&
checksum_new
);
if
(
updated
!=
NULL
)
*
updated
=
1
;
git_buf_swap
(
out
,
&
buf
);
git_buf_free
(
&
buf
);
return
0
;
}
int
git_futils_readbuffer
(
git_buf
*
buf
,
const
char
*
path
)
{
return
git_futils_readbuffer_updated
(
buf
,
path
,
NULL
,
NULL
,
NULL
);
return
git_futils_readbuffer_updated
(
buf
,
path
,
NULL
,
NULL
);
}
int
git_futils_writebuffer
(
...
...
This diff is collapsed.
Click to expand it.
src/fileops.h
View file @
db1edf91
...
...
@@ -13,6 +13,7 @@
#include "path.h"
#include "pool.h"
#include "strmap.h"
#include "oid.h"
/**
* Filebuffer methods
...
...
@@ -21,7 +22,7 @@
*/
extern
int
git_futils_readbuffer
(
git_buf
*
obj
,
const
char
*
path
);
extern
int
git_futils_readbuffer_updated
(
git_buf
*
obj
,
const
char
*
path
,
time_t
*
mtime
,
size_t
*
size
,
int
*
updated
);
git_buf
*
obj
,
const
char
*
path
,
git_oid
*
checksum
,
int
*
updated
);
extern
int
git_futils_readbuffer_fd
(
git_buf
*
obj
,
git_file
fd
,
size_t
len
);
extern
int
git_futils_writebuffer
(
...
...
This diff is collapsed.
Click to expand it.
tests/config/stress.c
View file @
db1edf91
...
...
@@ -107,3 +107,23 @@ void test_config_stress__complex(void)
git_config_free
(
config
);
}
void
test_config_stress__quick_write
(
void
)
{
git_config
*
config_w
,
*
config_r
;
const
char
*
path
=
"./config-quick-write"
;
const
char
*
key
=
"quick.write"
;
int32_t
i
;
/* Create an external writer for one instance with the other one */
cl_git_pass
(
git_config_open_ondisk
(
&
config_w
,
path
));
cl_git_pass
(
git_config_open_ondisk
(
&
config_r
,
path
));
/* Write and read in the same second (repeat to increase the chance of it happening) */
for
(
i
=
0
;
i
<
10
;
i
++
)
{
int32_t
val
;
cl_git_pass
(
git_config_set_int32
(
config_w
,
key
,
i
));
cl_git_pass
(
git_config_get_int32
(
&
val
,
config_r
,
key
));
cl_assert_equal_i
(
i
,
val
);
}
}
This diff is collapsed.
Click to expand it.
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