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
Nov 02, 2015
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
);
}
...
...
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
(
...
...
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
(
...
...
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
);
}
}
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