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
f19e3ca2
Commit
f19e3ca2
authored
Feb 10, 2012
by
Vicent Martí
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
odb: Proper symlink hashing
parent
18e5b854
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
107 additions
and
25 deletions
+107
-25
src/blob.c
+40
-25
src/odb.c
+42
-0
src/odb.h
+25
-0
No files found.
src/blob.c
View file @
f19e3ca2
...
...
@@ -68,10 +68,7 @@ int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *b
int
git_blob_create_fromfile
(
git_oid
*
oid
,
git_repository
*
repo
,
const
char
*
path
)
{
int
error
=
GIT_SUCCESS
;
int
islnk
=
0
;
int
fd
=
0
;
git_buf
full_path
=
GIT_BUF_INIT
;
char
buffer
[
2048
];
git_off_t
size
;
git_odb_stream
*
stream
=
NULL
;
struct
stat
st
;
...
...
@@ -92,39 +89,59 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
goto
cleanup
;
}
islnk
=
S_ISLNK
(
st
.
st_mode
);
size
=
st
.
st_size
;
error
=
git_repository_odb__weakptr
(
&
odb
,
repo
);
if
(
error
<
GIT_SUCCESS
)
goto
cleanup
;
if
(
!
islnk
)
{
if
((
fd
=
p_open
(
full_path
.
ptr
,
O_RDONLY
))
<
0
)
{
error
=
git__throw
(
GIT_ENOTFOUND
,
"Failed to create blob. Could not open '%s'"
,
full_path
.
ptr
);
goto
cleanup
;
}
}
if
((
error
=
git_odb_open_wstream
(
&
stream
,
odb
,
(
size_t
)
size
,
GIT_OBJ_BLOB
))
<
GIT_SUCCESS
)
goto
cleanup
;
while
(
size
>
0
)
{
if
(
S_ISLNK
(
st
.
st_mode
))
{
char
*
link_data
;
ssize_t
read_len
;
if
(
!
islnk
)
read_len
=
p_read
(
fd
,
buffer
,
sizeof
(
buffer
));
else
read_len
=
p_readlink
(
full_path
.
ptr
,
buffer
,
sizeof
(
buffer
));
link_data
=
git__malloc
(
size
);
if
(
!
link_data
)
{
error
=
GIT_ENOMEM
;
goto
cleanup
;
}
read_len
=
p_readlink
(
full_path
.
ptr
,
link_data
,
size
);
if
(
read_len
<
0
)
{
error
=
git__throw
(
GIT_EOSERR
,
"Failed to create blob. Can't read full file"
);
if
(
read_len
!=
(
ssize_t
)
size
)
{
error
=
git__throw
(
GIT_EOSERR
,
"Failed to create blob. Can't read symlink"
);
free
(
link_data
);
goto
cleanup
;
}
stream
->
write
(
stream
,
buffer
,
read_len
);
size
-=
read_len
;
stream
->
write
(
stream
,
link_data
,
size
);
free
(
link_data
);
}
else
{
int
fd
;
char
buffer
[
2048
];
if
((
fd
=
p_open
(
full_path
.
ptr
,
O_RDONLY
))
<
0
)
{
error
=
git__throw
(
GIT_ENOTFOUND
,
"Failed to create blob. Could not open '%s'"
,
full_path
.
ptr
);
goto
cleanup
;
}
while
(
size
>
0
)
{
ssize_t
read_len
=
p_read
(
fd
,
buffer
,
sizeof
(
buffer
));
if
(
read_len
<
0
)
{
error
=
git__throw
(
GIT_EOSERR
,
"Failed to create blob. Can't read full file"
);
p_close
(
fd
);
goto
cleanup
;
}
stream
->
write
(
stream
,
buffer
,
read_len
);
size
-=
read_len
;
}
p_close
(
fd
);
}
error
=
stream
->
finalize_write
(
oid
,
stream
);
...
...
@@ -132,11 +149,9 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
cleanup:
if
(
stream
)
stream
->
free
(
stream
);
if
(
!
islnk
&&
fd
)
p_close
(
fd
);
git_buf_free
(
&
full_path
);
return
error
==
GIT_SUCCESS
?
GIT_SUCCESS
:
git__rethrow
(
error
,
"Failed to create blob"
);
return
error
;
}
src/odb.c
View file @
f19e3ca2
...
...
@@ -145,6 +145,48 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
return
GIT_SUCCESS
;
}
int
git_odb__hashlink
(
git_oid
*
out
,
const
char
*
path
)
{
struct
stat
st
;
int
error
;
git_off_t
size
;
error
=
p_lstat
(
path
,
&
st
);
if
(
error
<
0
)
return
git__throw
(
GIT_EOSERR
,
"Failed to stat blob. %s"
,
strerror
(
errno
));
size
=
st
.
st_size
;
if
(
!
git__is_sizet
(
size
))
return
git__throw
(
GIT_EOSERR
,
"File size overflow for 32-bit systems"
);
if
(
S_ISLNK
(
st
.
st_mode
))
{
char
*
link_data
;
ssize_t
read_len
;
link_data
=
git__malloc
(
size
);
if
(
link_data
==
NULL
)
return
GIT_ENOMEM
;
read_len
=
p_readlink
(
path
,
link_data
,
size
+
1
);
if
(
read_len
!=
(
ssize_t
)
size
)
return
git__throw
(
GIT_EOSERR
,
"Failed to read symlink data"
);
error
=
git_odb_hash
(
out
,
link_data
,
(
size_t
)
size
,
GIT_OBJ_BLOB
);
free
(
link_data
);
}
else
{
int
fd
;
if
((
fd
=
p_open
(
path
,
O_RDONLY
))
<
0
)
return
git__throw
(
GIT_ENOTFOUND
,
"Could not open '%s'"
,
path
);
error
=
git_odb__hashfd
(
out
,
fd
,
(
size_t
)
size
,
GIT_OBJ_BLOB
);
p_close
(
fd
);
}
return
error
;
}
int
git_odb_hashfile
(
git_oid
*
out
,
const
char
*
path
,
git_otype
type
)
{
int
fd
,
error
;
...
...
src/odb.h
View file @
f19e3ca2
...
...
@@ -39,7 +39,32 @@ struct git_odb {
git_cache
cache
;
};
/*
* Hash a git_rawobj internally.
* The `git_rawobj` is supposed to be previously initialized
*/
int
git_odb__hashobj
(
git_oid
*
id
,
git_rawobj
*
obj
);
/*
* Hash an open file descriptor.
* This is a performance call when the contents of a fd need to be hashed,
* but the fd is already open and we have the size of the contents.
*
* Saves us some `stat` calls.
*
* The fd is never closed, not even on error. It must be opened and closed
* by the caller
*/
int
git_odb__hashfd
(
git_oid
*
out
,
git_file
fd
,
size_t
size
,
git_otype
type
);
/*
* Hash a `path`, assuming it could be a POSIX symlink: if the path is a symlink,
* then the raw contents of the symlink will be hashed. Otherwise, this will
* fallback to `git_odb__hashfd`.
*
* The hash type for this call is always `GIT_OBJ_BLOB` because symlinks may only
* point to blobs.
*/
int
git_odb__hashlink
(
git_oid
*
out
,
const
char
*
path
);
#endif
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