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
94711cad
Commit
94711cad
authored
May 17, 2011
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Plain Diff
Merge upstream/development
parents
c0335005
335d6c99
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
397 additions
and
290 deletions
+397
-290
.gitattributes
+2
-0
README.md
+4
-1
include/git2.h
+2
-2
include/git2/common.h
+0
-86
include/git2/errors.h
+100
-0
include/git2/index.h
+2
-2
include/git2/thread-utils.h
+1
-0
src/backends/hiredis.c
+5
-4
src/blob.c
+3
-3
src/cache.c
+27
-59
src/cache.h
+1
-2
src/commit.c
+1
-1
src/common.h
+5
-1
src/errors.c
+64
-0
src/fileops.c
+36
-25
src/index.c
+1
-1
src/odb.c
+9
-5
src/odb_loose.c
+1
-2
src/refs.c
+19
-14
src/repository.c
+35
-24
src/revwalk.c
+7
-7
src/signature.c
+13
-13
src/tag.c
+10
-9
src/tree.c
+7
-7
src/util.h
+34
-10
src/vector.c
+4
-7
src/win32/pthread.c
+3
-4
tests/t10-refs.c
+1
-1
No files found.
.gitattributes
0 → 100644
View file @
94711cad
*.c eol=lf
*.h eol=lf
README.md
View file @
94711cad
...
...
@@ -39,7 +39,7 @@ Under Unix-like systems, like Linux, *BSD and Mac OS X, libgit2 expects `pthread
they should be installed by default on all systems. Under Windows, libgit2 uses the native Windows API
for threading.
Additionally, he following libraries may be used as replacement for built-in functionality:
Additionally,
t
he following libraries may be used as replacement for built-in functionality:
*
LibSSL
**(optional)**
<http://www.openssl.org/>
...
...
@@ -88,6 +88,9 @@ The waf build system for libgit2 accepts the following flags:
--with-sqlite
Enable sqlite support.
--with-redis
Enable redis support.
You can run
`./waf --help`
to see a full list of install options and
targets.
...
...
include/git2.h
View file @
94711cad
...
...
@@ -26,9 +26,9 @@
#ifndef INCLUDE_git_git_h__
#define INCLUDE_git_git_h__
#define LIBGIT2_VERSION "0.1
1
.0"
#define LIBGIT2_VERSION "0.1
2
.0"
#define LIBGIT2_VER_MAJOR 0
#define LIBGIT2_VER_MINOR 1
1
#define LIBGIT2_VER_MINOR 1
2
#define LIBGIT2_VER_REVISION 0
#include "git2/common.h"
...
...
include/git2/common.h
View file @
94711cad
...
...
@@ -84,92 +84,6 @@
* @{
*/
/** Operation completed successfully. */
#define GIT_SUCCESS 0
/**
* Operation failed, with unspecified reason.
* This value also serves as the base error code; all other
* error codes are subtracted from it such that all errors
* are < 0, in typical POSIX C tradition.
*/
#define GIT_ERROR -1
/** Input was not a properly formatted Git object id. */
#define GIT_ENOTOID (GIT_ERROR - 1)
/** Input does not exist in the scope searched. */
#define GIT_ENOTFOUND (GIT_ERROR - 2)
/** Not enough space available. */
#define GIT_ENOMEM (GIT_ERROR - 3)
/** Consult the OS error information. */
#define GIT_EOSERR (GIT_ERROR - 4)
/** The specified object is of invalid type */
#define GIT_EOBJTYPE (GIT_ERROR - 5)
/** The specified object has its data corrupted */
#define GIT_EOBJCORRUPTED (GIT_ERROR - 6)
/** The specified repository is invalid */
#define GIT_ENOTAREPO (GIT_ERROR - 7)
/** The object or config variable type is invalid or doesn't match */
#define GIT_EINVALIDTYPE (GIT_ERROR - 8)
/** The object cannot be written because it's missing internal data */
#define GIT_EMISSINGOBJDATA (GIT_ERROR - 9)
/** The packfile for the ODB is corrupted */
#define GIT_EPACKCORRUPTED (GIT_ERROR - 10)
/** Failed to acquire or release a file lock */
#define GIT_EFLOCKFAIL (GIT_ERROR - 11)
/** The Z library failed to inflate/deflate an object's data */
#define GIT_EZLIB (GIT_ERROR - 12)
/** The queried object is currently busy */
#define GIT_EBUSY (GIT_ERROR - 13)
/** The index file is not backed up by an existing repository */
#define GIT_EBAREINDEX (GIT_ERROR - 14)
/** The name of the reference is not valid */
#define GIT_EINVALIDREFNAME (GIT_ERROR - 15)
/** The specified reference has its data corrupted */
#define GIT_EREFCORRUPTED (GIT_ERROR - 16)
/** The specified symbolic reference is too deeply nested */
#define GIT_ETOONESTEDSYMREF (GIT_ERROR - 17)
/** The pack-refs file is either corrupted or its format is not currently supported */
#define GIT_EPACKEDREFSCORRUPTED (GIT_ERROR - 18)
/** The path is invalid */
#define GIT_EINVALIDPATH (GIT_ERROR - 19)
/** The revision walker is empty; there are no more commits left to iterate */
#define GIT_EREVWALKOVER (GIT_ERROR - 20)
/** The state of the reference is not valid */
#define GIT_EINVALIDREFSTATE (GIT_ERROR - 21)
/** This feature has not been implemented yet */
#define GIT_ENOTIMPLEMENTED (GIT_ERROR - 22)
/** A reference with this name already exists */
#define GIT_EEXISTS (GIT_ERROR - 23)
/** The given integer literal is too large to be parsed */
#define GIT_EOVERFLOW (GIT_ERROR - 24)
/** The given literal is not a valid number */
#define GIT_ENOTNUM (GIT_ERROR - 25)
GIT_BEGIN_DECL
typedef
struct
{
...
...
include/git2/errors.h
View file @
94711cad
...
...
@@ -25,6 +25,8 @@
#ifndef INCLUDE_git_errors_h__
#define INCLUDE_git_errors_h__
#include "common.h"
/**
* @file git2/errors.h
* @brief Git error handling routines and variables
...
...
@@ -33,8 +35,106 @@
*/
GIT_BEGIN_DECL
typedef
enum
{
GIT_SUCCESS
=
0
,
GIT_ERROR
=
-
1
,
/** Input was not a properly formatted Git object id. */
GIT_ENOTOID
=
-
2
,
/** Input does not exist in the scope searched. */
GIT_ENOTFOUND
=
-
3
,
/** Not enough space available. */
GIT_ENOMEM
=
-
4
,
/** Consult the OS error information. */
GIT_EOSERR
=
-
5
,
/** The specified object is of invalid type */
GIT_EOBJTYPE
=
-
6
,
/** The specified repository is invalid */
GIT_ENOTAREPO
=
-
7
,
/** The object type is invalid or doesn't match */
GIT_EINVALIDTYPE
=
-
8
,
/** The object cannot be written because it's missing internal data */
GIT_EMISSINGOBJDATA
=
-
9
,
/** The packfile for the ODB is corrupted */
GIT_EPACKCORRUPTED
=
-
10
,
/** Failed to acquire or release a file lock */
GIT_EFLOCKFAIL
=
-
11
,
/** The Z library failed to inflate/deflate an object's data */
GIT_EZLIB
=
-
12
,
/** The queried object is currently busy */
GIT_EBUSY
=
-
13
,
/** The index file is not backed up by an existing repository */
GIT_EBAREINDEX
=
-
14
,
/** The name of the reference is not valid */
GIT_EINVALIDREFNAME
=
-
15
,
/** The specified reference has its data corrupted */
GIT_EREFCORRUPTED
=
-
16
,
/** The specified symbolic reference is too deeply nested */
GIT_ETOONESTEDSYMREF
=
-
17
,
/** The pack-refs file is either corrupted or its format is not currently supported */
GIT_EPACKEDREFSCORRUPTED
=
-
18
,
/** The path is invalid */
GIT_EINVALIDPATH
=
-
19
,
/** The revision walker is empty; there are no more commits left to iterate */
GIT_EREVWALKOVER
=
-
20
,
/** The state of the reference is not valid */
GIT_EINVALIDREFSTATE
=
-
21
,
/** This feature has not been implemented yet */
GIT_ENOTIMPLEMENTED
=
-
22
,
/** A reference with this name already exists */
GIT_EEXISTS
=
-
23
,
/** The given integer literal is too large to be parsed */
GIT_EOVERFLOW
=
-
24
,
/** The given literal is not a valid number */
GIT_ENOTNUM
=
-
25
,
/** Streaming error */
GIT_ESTREAM
=
-
26
,
/** invalid arguments to function */
GIT_EINVALIDARGS
=
-
27
,
/** The specified object has its data corrupted */
GIT_EOBJCORRUPTED
=
-
28
,
}
git_error
;
/**
* Return a detailed error string with the latest error
* that occurred in the library.
* @return a string explaining the error
*/
GIT_EXTERN
(
const
char
*
)
git_lasterror
(
void
);
/**
* strerror() for the Git library
*
* Get a string description for a given error code.
* NOTE: This method will be eventually deprecated in favor
* of the new `git_lasterror`.
*
* @param num The error code to explain
* @return a string explaining the error code
*/
...
...
include/git2/index.h
View file @
94711cad
...
...
@@ -232,10 +232,10 @@ GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
* @param source_entry new entry object
* @return 0 on success, otherwise an error code
*/
GIT_EXTERN
(
int
)
git_index_app
p
end2
(
git_index
*
index
,
const
git_index_entry
*
source_entry
);
GIT_EXTERN
(
int
)
git_index_append2
(
git_index
*
index
,
const
git_index_entry
*
source_entry
);
/**
* Remove an entry from the index
* Remove an entry from the index
*
* @param index an existing index object
* @param position position of the entry to remove
...
...
include/git2/thread-utils.h
View file @
94711cad
...
...
@@ -35,6 +35,7 @@
#if defined(__APPLE__) && defined(__MACH__)
# undef GIT_TLS
# define GIT_TLS
#elif defined(__GNUC__) || \
defined(__SUNPRO_C) || \
...
...
src/backends/hiredis.c
View file @
94711cad
...
...
@@ -53,7 +53,7 @@ int hiredis_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_backe
reply
=
redisCommand
(
backend
->
db
,
"HMGET %b %s %s"
,
oid
->
id
,
GIT_OID_RAWSZ
,
"type"
,
"size"
);
if
(
reply
->
type
==
REDIS_REPLY_ARRAY
)
{
if
(
reply
&&
reply
->
type
==
REDIS_REPLY_ARRAY
)
{
if
(
reply
->
element
[
0
]
->
type
!=
REDIS_REPLY_NIL
&&
reply
->
element
[
0
]
->
type
!=
REDIS_REPLY_NIL
)
{
*
type_p
=
(
git_otype
)
atoi
(
reply
->
element
[
0
]
->
str
);
...
...
@@ -83,7 +83,7 @@ int hiredis_backend__read(void **data_p, size_t *len_p, git_otype *type_p, git_o
reply
=
redisCommand
(
backend
->
db
,
"HMGET %b %s %s %s"
,
oid
->
id
,
GIT_OID_RAWSZ
,
"type"
,
"size"
,
"data"
);
if
(
reply
->
type
==
REDIS_REPLY_ARRAY
)
{
if
(
reply
&&
reply
->
type
==
REDIS_REPLY_ARRAY
)
{
if
(
reply
->
element
[
0
]
->
type
!=
REDIS_REPLY_NIL
&&
reply
->
element
[
1
]
->
type
!=
REDIS_REPLY_NIL
&&
reply
->
element
[
2
]
->
type
!=
REDIS_REPLY_NIL
)
{
...
...
@@ -118,7 +118,7 @@ int hiredis_backend__exists(git_odb_backend *_backend, const git_oid *oid) {
found
=
0
;
reply
=
redisCommand
(
backend
->
db
,
"exists %b"
,
oid
->
id
,
GIT_OID_RAWSZ
);
if
(
reply
->
type
!=
REDIS_REPLY_NIL
&&
reply
->
type
!=
REDIS_REPLY_ERROR
)
if
(
reply
&&
reply
->
type
!=
REDIS_REPLY_NIL
&&
reply
->
type
!=
REDIS_REPLY_ERROR
)
found
=
1
;
...
...
@@ -144,7 +144,8 @@ int hiredis_backend__write(git_oid *id, git_odb_backend *_backend, const void *d
"size %d "
"data %b "
,
id
->
id
,
GIT_OID_RAWSZ
,
(
int
)
type
,
len
,
data
,
len
);
error
=
reply
->
type
==
REDIS_REPLY_ERROR
?
GIT_ERROR
:
GIT_SUCCESS
;
error
=
(
reply
==
NULL
||
reply
->
type
==
REDIS_REPLY_ERROR
)
?
GIT_ERROR
:
GIT_SUCCESS
;
freeReplyObject
(
reply
);
return
error
;
...
...
src/blob.c
View file @
94711cad
...
...
@@ -62,7 +62,7 @@ int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *b
git_odb_stream
*
stream
;
if
((
error
=
git_odb_open_wstream
(
&
stream
,
repo
->
db
,
len
,
GIT_OBJ_BLOB
))
<
GIT_SUCCESS
)
return
error
;
return
git__rethrow
(
error
,
"Failed to create blob. Can't open write stream"
)
;
stream
->
write
(
stream
,
buffer
,
len
);
...
...
@@ -81,7 +81,7 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
git_odb_stream
*
stream
;
if
(
repo
->
path_workdir
==
NULL
)
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Failed to create blob. No workdir given"
)
;
git__joinpath
(
full_path
,
repo
->
path_workdir
,
path
);
...
...
@@ -106,7 +106,7 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
if
(
read_len
<
0
)
{
gitfo_close
(
fd
);
stream
->
free
(
stream
);
return
GIT_EOSERR
;
return
git__throw
(
GIT_EOSERR
,
"Failed to create blob. Can't read full file"
)
;
}
stream
->
write
(
stream
,
buffer
,
read_len
);
...
...
src/cache.c
View file @
94711cad
...
...
@@ -29,10 +29,7 @@
#include "thread-utils.h"
#include "cache.h"
#define GIT_CACHE_OPENADR 3
void
git_cache_init
(
git_cache
*
cache
,
size_t
size
,
git_cached_obj_freeptr
free_ptr
)
int
git_cache_init
(
git_cache
*
cache
,
size_t
size
,
git_cached_obj_freeptr
free_ptr
)
{
size_t
i
;
...
...
@@ -52,12 +49,15 @@ void git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_p
cache
->
free_obj
=
free_ptr
;
cache
->
nodes
=
git__malloc
((
size
+
1
)
*
sizeof
(
cache_node
));
if
(
cache
->
nodes
==
NULL
)
return
GIT_ENOMEM
;
for
(
i
=
0
;
i
<
(
size
+
1
);
++
i
)
{
git_mutex_init
(
&
cache
->
nodes
[
i
].
lock
);
cache
->
nodes
[
i
].
ptr
=
NULL
;
cache
->
nodes
[
i
].
lru
=
0
;
}
return
GIT_SUCCESS
;
}
void
git_cache_free
(
git_cache
*
cache
)
...
...
@@ -77,85 +77,53 @@ void git_cache_free(git_cache *cache)
void
*
git_cache_get
(
git_cache
*
cache
,
const
git_oid
*
oid
)
{
const
uint32_t
*
hash
;
size_t
i
,
pos
,
found
=
0
;
cache_node
*
node
=
NULL
;
void
*
result
=
NULL
;
hash
=
(
const
uint32_t
*
)
oid
->
id
;
node
=
&
cache
->
nodes
[
hash
[
0
]
&
cache
->
size_mask
];
for
(
i
=
0
;
!
found
&&
i
<
GIT_CACHE_OPENADR
;
++
i
)
{
pos
=
hash
[
i
]
&
cache
->
size_mask
;
node
=
&
cache
->
nodes
[
pos
];
git_mutex_lock
(
&
node
->
lock
);
{
if
(
node
->
ptr
&&
git_cached_obj_compare
(
node
->
ptr
,
oid
)
==
0
)
{
git_cached_obj_incref
(
node
->
ptr
);
node
->
lru
=
++
cache
->
lru_count
;
found
=
1
;
}
git_mutex_lock
(
&
node
->
lock
);
{
if
(
node
->
ptr
&&
git_cached_obj_compare
(
node
->
ptr
,
oid
)
==
0
)
{
git_cached_obj_incref
(
node
->
ptr
);
result
=
node
->
ptr
;
}
git_mutex_unlock
(
&
node
->
lock
);
}
git_mutex_unlock
(
&
node
->
lock
);
return
found
?
node
->
ptr
:
NULL
;
return
result
;
}
void
*
git_cache_try_store
(
git_cache
*
cache
,
void
*
entry
)
{
cache_node
*
nodes
[
GIT_CACHE_OPENADR
],
*
lru_node
;
const
uint32_t
*
hash
;
const
git_oid
*
oid
;
size_t
i
;
cache_node
*
node
=
NULL
;
oid
=
&
((
git_cached_obj
*
)
entry
)
->
oid
;
hash
=
(
const
uint32_t
*
)
oid
->
id
;
node
=
&
cache
->
nodes
[
hash
[
0
]
&
cache
->
size_mask
];
/* increase the refcount on this object, because
* the cache now owns it */
git_cached_obj_incref
(
entry
);
for
(
i
=
0
;
i
<
GIT_CACHE_OPENADR
;
++
i
)
{
size_t
pos
=
hash
[
i
]
&
cache
->
size_mask
;
nodes
[
i
]
=
&
cache
->
nodes
[
pos
];
git_mutex_lock
(
&
nodes
[
i
]
->
lock
);
}
lru_node
=
nodes
[
0
];
for
(
i
=
0
;
i
<
GIT_CACHE_OPENADR
;
++
i
)
{
if
(
nodes
[
i
]
->
ptr
==
NULL
)
{
nodes
[
i
]
->
ptr
=
entry
;
nodes
[
i
]
->
lru
=
++
cache
->
lru_count
;
break
;
}
else
if
(
git_cached_obj_compare
(
nodes
[
i
]
->
ptr
,
oid
)
==
0
)
{
git_cached_obj_decref
(
entry
,
cache
->
free_obj
);
entry
=
nodes
[
i
]
->
ptr
;
nodes
[
i
]
->
lru
=
++
cache
->
lru_count
;
break
;
}
if
(
nodes
[
i
]
->
lru
<
lru_node
->
lru
)
lru_node
=
nodes
[
i
];
}
if
(
i
==
GIT_CACHE_OPENADR
)
{
void
*
old_entry
=
lru_node
->
ptr
;
assert
(
old_entry
);
git_cached_obj_decref
(
old_entry
,
cache
->
free_obj
);
lru_node
->
ptr
=
entry
;
lru_node
->
lru
=
++
cache
->
lru_count
;
git_mutex_lock
(
&
node
->
lock
);
if
(
node
->
ptr
==
NULL
)
{
node
->
ptr
=
entry
;
}
else
if
(
git_cached_obj_compare
(
node
->
ptr
,
oid
)
==
0
)
{
git_cached_obj_decref
(
entry
,
cache
->
free_obj
);
entry
=
node
->
ptr
;
}
else
{
git_cached_obj_decref
(
node
->
ptr
,
cache
->
free_obj
);
node
->
ptr
=
entry
;
}
/* increase the refcount again, because we are
* returning it to the user */
git_cached_obj_incref
(
entry
);
for
(
i
=
0
;
i
<
GIT_CACHE_OPENADR
;
++
i
)
git_mutex_unlock
(
&
nodes
[
i
]
->
lock
);
git_mutex_unlock
(
&
node
->
lock
);
return
entry
;
}
src/cache.h
View file @
94711cad
...
...
@@ -19,7 +19,6 @@ typedef struct {
typedef
struct
{
git_cached_obj
*
ptr
;
git_mutex
lock
;
unsigned
int
lru
;
}
cache_node
;
typedef
struct
{
...
...
@@ -31,7 +30,7 @@ typedef struct {
}
git_cache
;
void
git_cache_init
(
git_cache
*
cache
,
size_t
size
,
git_cached_obj_freeptr
free_ptr
);
int
git_cache_init
(
git_cache
*
cache
,
size_t
size
,
git_cached_obj_freeptr
free_ptr
);
void
git_cache_free
(
git_cache
*
cache
);
void
*
git_cache_try_store
(
git_cache
*
cache
,
void
*
entry
);
...
...
src/commit.c
View file @
94711cad
...
...
@@ -286,7 +286,7 @@ int commit_parse_buffer(git_commit *commit, const void *data, size_t len)
if
(
buffer
<
buffer_end
)
{
const
char
*
line_end
;
size_t
message_len
=
buffer_end
-
buffer
;
size_t
message_len
;
/* Long message */
message_len
=
buffer_end
-
buffer
;
...
...
src/common.h
View file @
94711cad
...
...
@@ -50,10 +50,14 @@ typedef SSIZE_T ssize_t;
#include "git2/common.h"
#include "git2/types.h"
#include "
util
.h"
#include "
git2/errors
.h"
#include "thread-utils.h"
#include "bswap.h"
#define GIT_PATH_MAX 4096
extern
int
git__throw
(
int
error
,
const
char
*
,
...)
GIT_FORMAT_PRINTF
(
2
,
3
);
extern
int
git__rethrow
(
int
error
,
const
char
*
,
...)
GIT_FORMAT_PRINTF
(
2
,
3
);
#include "util.h"
#endif
/* INCLUDE_common_h__ */
src/errors.c
View file @
94711cad
/*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "common.h"
#include "git2/thread-utils.h"
/* for GIT_TLS */
#include "thread-utils.h"
/* for GIT_TLS */
#include <stdarg.h>
static
GIT_TLS
char
g_last_error
[
1024
];
static
struct
{
int
num
;
const
char
*
str
;
...
...
@@ -46,3 +75,38 @@ const char *git_strerror(int num)
return
"Unknown error"
;
}
int
git__rethrow
(
int
error
,
const
char
*
msg
,
...)
{
char
new_error
[
1024
];
char
*
old_error
=
NULL
;
va_list
va
;
va_start
(
va
,
msg
);
vsnprintf
(
new_error
,
sizeof
(
new_error
),
msg
,
va
);
va_end
(
va
);
old_error
=
strdup
(
g_last_error
);
snprintf
(
g_last_error
,
sizeof
(
g_last_error
),
"%s
\n
- %s"
,
new_error
,
old_error
);
free
(
old_error
);
return
error
;
}
int
git__throw
(
int
error
,
const
char
*
msg
,
...)
{
va_list
va
;
va_start
(
va
,
msg
);
vsnprintf
(
g_last_error
,
sizeof
(
g_last_error
),
msg
,
va
);
va_end
(
va
);
return
error
;
}
const
char
*
git_lasterror
(
void
)
{
return
g_last_error
;
}
src/fileops.c
View file @
94711cad
...
...
@@ -10,7 +10,7 @@ int gitfo_mkdir_2file(const char *file_path)
error
=
git__dirname_r
(
target_folder_path
,
sizeof
(
target_folder_path
),
file_path
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
return
git__throw
(
GIT_EINVALIDPATH
,
"Failed to recursively build `%s` tree structure. Unable to parse parent folder name"
,
file_path
)
;
/* Does the containing folder exist? */
if
(
gitfo_isdir
(
target_folder_path
))
{
...
...
@@ -19,7 +19,7 @@ int gitfo_mkdir_2file(const char *file_path)
/* Let's create the tree structure */
error
=
gitfo_mkdir_recurs
(
target_folder_path
,
mode
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
return
error
;
/* The callee already takes care of setting the correct error message. */
}
return
GIT_SUCCESS
;
...
...
@@ -164,19 +164,19 @@ int gitfo_read_file(gitfo_buf *obj, const char *path)
if
(((
size
=
gitfo_size
(
fd
))
<
0
)
||
!
git__is_sizet
(
size
+
1
))
{
gitfo_close
(
fd
);
return
GIT_ERROR
;
return
git__throw
(
GIT_ERROR
,
"Failed to read file `%s`. Either an error occured while calculating its size or the file is too large"
,
path
)
;
}
len
=
(
size_t
)
size
;
if
((
buff
=
git__malloc
(
len
+
1
))
==
NULL
)
{
gitfo_close
(
fd
);
return
GIT_E
RROR
;
return
GIT_E
NOMEM
;
}
if
(
gitfo_read
(
fd
,
buff
,
len
)
<
0
)
{
gitfo_close
(
fd
);
free
(
buff
);
return
GIT_ERROR
;
return
git__throw
(
GIT_ERROR
,
"Failed to read file `%s`"
,
path
)
;
}
buff
[
len
]
=
'\0'
;
...
...
@@ -197,13 +197,15 @@ void gitfo_free_buf(gitfo_buf *obj)
int
gitfo_mv
(
const
char
*
from
,
const
char
*
to
)
{
int
error
;
#ifdef GIT_WIN32
/*
* Win32 POSIX compilance my ass. If the destination
* file exists, the `rename` call fails. This is as
* close as it gets with the Win32 API.
*/
return
MoveFileEx
(
from
,
to
,
MOVEFILE_REPLACE_EXISTING
|
MOVEFILE_COPY_ALLOWED
)
?
GIT_SUCCESS
:
GIT_EOSERR
;
error
=
MoveFileEx
(
from
,
to
,
MOVEFILE_REPLACE_EXISTING
|
MOVEFILE_COPY_ALLOWED
)
?
GIT_SUCCESS
:
GIT_EOSERR
;
#else
/* Don't even try this on Win32 */
if
(
!
link
(
from
,
to
))
{
...
...
@@ -214,16 +216,21 @@ int gitfo_mv(const char *from, const char *to)
if
(
!
rename
(
from
,
to
))
return
GIT_SUCCESS
;
return
GIT_EOSERR
;
error
=
GIT_EOSERR
;
#endif
if
(
error
<
GIT_SUCCESS
)
return
git__throw
(
error
,
"Failed to move file from `%s`to `%s`"
,
from
,
to
);
return
GIT_SUCCESS
;
}
int
gitfo_mv_force
(
const
char
*
from
,
const
char
*
to
)
{
if
(
gitfo_mkdir_2file
(
to
)
<
GIT_SUCCESS
)
return
GIT_EOSERR
;
return
GIT_EOSERR
;
/* The callee already takes care of setting the correct error message. */
return
gitfo_mv
(
from
,
to
);
return
gitfo_mv
(
from
,
to
);
/* The callee already takes care of setting the correct error message. */
}
int
gitfo_map_ro
(
git_map
*
out
,
git_file
fd
,
git_off_t
begin
,
size_t
len
)
...
...
@@ -338,7 +345,7 @@ int gitfo_dirent(
struct
dirent
*
de
;
if
(
!
wd_len
||
path_sz
<
wd_len
+
2
)
return
GIT_ERROR
;
return
git__throw
(
GIT_EINVALIDARGS
,
"Failed to process `%s` tree structure. Path is either empty or buffer size is too short"
,
path
)
;
while
(
path
[
wd_len
-
1
]
==
'/'
)
wd_len
--
;
...
...
@@ -347,7 +354,7 @@ int gitfo_dirent(
dir
=
opendir
(
path
);
if
(
!
dir
)
return
GIT_EOSERR
;
return
git__throw
(
GIT_EOSERR
,
"Failed to process `%s` tree structure. An error occured while opening the directory"
,
path
)
;
while
((
de
=
readdir
(
dir
))
!=
NULL
)
{
size_t
de_len
;
...
...
@@ -364,14 +371,14 @@ int gitfo_dirent(
de_len
=
strlen
(
de
->
d_name
);
if
(
path_sz
<
wd_len
+
de_len
+
1
)
{
closedir
(
dir
);
return
GIT_ERROR
;
return
git__throw
(
GIT_ERROR
,
"Failed to process `%s` tree structure. Buffer size is too short"
,
path
)
;
}
strcpy
(
path
+
wd_len
,
de
->
d_name
);
result
=
fn
(
arg
,
path
);
if
(
result
<
GIT_SUCCESS
)
{
closedir
(
dir
);
return
result
;
return
result
;
/* The callee is reponsible for setting the correct error message */
}
if
(
result
>
0
)
{
closedir
(
dir
);
...
...
@@ -399,7 +406,7 @@ int retrieve_path_root_offset(const char *path)
if
(
*
(
path
+
offset
)
==
'/'
)
return
offset
;
return
GIT_ERROR
;
return
-
1
;
/* Not a real error. Rather a signal than the path is not rooted */
}
...
...
@@ -438,7 +445,11 @@ int gitfo_mkdir_recurs(const char *path, int mode)
error
=
gitfo_mkdir
(
path
,
mode
);
free
(
path_copy
);
return
error
;
if
(
error
<
GIT_SUCCESS
)
return
git__throw
(
error
,
"Failed to recursively create `%s` tree structure"
,
path
);
return
GIT_SUCCESS
;
}
static
int
retrieve_previous_path_component_start
(
const
char
*
path
)
...
...
@@ -484,7 +495,7 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path)
if
(
root_path_offset
<
0
)
{
error
=
gitfo_getcwd
(
buffer_out
,
size
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
return
error
;
/* The callee already takes care of setting the correct error message. */
len
=
strlen
(
buffer_out
);
buffer_out
+=
len
;
...
...
@@ -529,7 +540,7 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path)
/* Are we escaping out of the root dir? */
if
(
len
<
0
)
return
GIT_EINVALIDPATH
;
return
git__throw
(
GIT_EINVALIDPATH
,
"Failed to normalize path `%s`. The path escapes out of the root directory"
,
path
)
;
buffer_out
=
(
char
*
)
buffer_out_start
+
len
;
continue
;
...
...
@@ -537,7 +548,7 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path)
/* Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html) */
if
(
only_dots
&&
segment_len
>
0
)
return
GIT_EINVALIDPATH
;
return
git__throw
(
GIT_EINVALIDPATH
,
"Failed to normalize path `%s`. The path contains a segment with three `.` or more"
,
path
)
;
*
buffer_out
++
=
'/'
;
len
++
;
...
...
@@ -557,21 +568,21 @@ int gitfo_prettify_file_path(char *buffer_out, size_t size, const char *path)
/* Let's make sure the filename isn't empty nor a dot */
if
(
path_len
==
0
||
(
path_len
==
1
&&
*
path
==
'.'
))
return
GIT_EINVALIDPATH
;
return
git__throw
(
GIT_EINVALIDPATH
,
"Failed to normalize file path `%s`. The path is either empty or equals `.`"
,
path
)
;
/* Let's make sure the filename doesn't end with "/", "/." or "/.." */
for
(
i
=
1
;
path_len
>
i
&&
i
<
4
;
i
++
)
{
if
(
!
strncmp
(
path
+
path_len
-
i
,
pattern
,
i
))
return
GIT_EINVALIDPATH
;
return
git__throw
(
GIT_EINVALIDPATH
,
"Failed to normalize file path `%s`. The path points to a folder"
,
path
)
;
}
error
=
gitfo_prettify_dir_path
(
buffer_out
,
size
,
path
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
return
error
;
/* The callee already takes care of setting the correct error message. */
path_len
=
strlen
(
buffer_out
);
if
(
path_len
<
2
)
return
GIT_EINVALIDPATH
;
if
(
path_len
<
2
)
/* TODO: Fixme. We should also take of detecting Windows rooted path (probably through usage of retrieve_path_root_offset) */
return
git__throw
(
GIT_EINVALIDPATH
,
"Failed to normalize file path `%s`. The path points to a folder"
,
path
)
;
/* Remove the trailing slash */
buffer_out
[
path_len
-
1
]
=
'\0'
;
...
...
@@ -616,11 +627,11 @@ int gitfo_getcwd(char *buffer_out, size_t size)
#ifdef GIT_WIN32
cwd_buffer
=
_getcwd
(
buffer_out
,
size
);
#else
cwd_buffer
=
getcwd
(
buffer_out
,
size
);
//TODO: Fixme. Ensure the required headers are correctly included
cwd_buffer
=
getcwd
(
buffer_out
,
size
);
#endif
if
(
cwd_buffer
==
NULL
)
return
GIT_EOSERR
;
return
git__throw
(
GIT_EOSERR
,
"Failed to retrieve current working directory"
)
;
posixify_path
(
buffer_out
);
...
...
src/index.c
View file @
94711cad
...
...
@@ -421,7 +421,7 @@ int git_index_add2(git_index *index, const git_index_entry *source_entry)
return
index_insert
(
index
,
source_entry
,
1
);
}
int
git_index_app
p
end2
(
git_index
*
index
,
const
git_index_entry
*
source_entry
)
int
git_index_append2
(
git_index
*
index
,
const
git_index_entry
*
source_entry
)
{
return
index_insert
(
index
,
source_entry
,
0
);
}
...
...
src/odb.c
View file @
94711cad
...
...
@@ -221,7 +221,7 @@ static int init_fake_wstream(git_odb_stream **stream_p, git_odb_backend *backend
*
***********************************************************/
int
backend_sort_cmp
(
const
void
*
a
,
const
void
*
b
)
static
int
backend_sort_cmp
(
const
void
*
a
,
const
void
*
b
)
{
const
backend_internal
*
backend_a
=
*
(
const
backend_internal
**
)(
a
);
const
backend_internal
*
backend_b
=
*
(
const
backend_internal
**
)(
b
);
...
...
@@ -234,15 +234,19 @@ int backend_sort_cmp(const void *a, const void *b)
int
git_odb_new
(
git_odb
**
out
)
{
int
error
;
git_odb
*
db
=
git__calloc
(
1
,
sizeof
(
*
db
));
if
(
!
db
)
return
GIT_ENOMEM
;
git_cache_init
(
&
db
->
cache
,
GIT_DEFAULT_CACHE_SIZE
,
&
free_odb_object
);
error
=
git_cache_init
(
&
db
->
cache
,
GIT_DEFAULT_CACHE_SIZE
,
&
free_odb_object
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
if
(
git_vector_init
(
&
db
->
backends
,
4
,
backend_sort_cmp
)
<
0
)
{
if
(
(
error
=
git_vector_init
(
&
db
->
backends
,
4
,
backend_sort_cmp
))
<
GIT_SUCCESS
)
{
free
(
db
);
return
GIT_ENOMEM
;
return
error
;
}
*
out
=
db
;
...
...
@@ -444,7 +448,7 @@ int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git
return
error
;
*
len_p
=
object
->
raw
.
len
;
*
type_p
=
object
->
raw
.
len
;
*
type_p
=
object
->
raw
.
type
;
git_odb_object_close
(
object
);
}
...
...
src/odb_loose.c
View file @
94711cad
...
...
@@ -336,7 +336,6 @@ static int inflate_disk_obj(git_rawobj *out, gitfo_buf *obj)
{
unsigned
char
head
[
64
],
*
buf
;
z_stream
zs
;
int
z_status
;
obj_hdr
hdr
;
size_t
used
;
...
...
@@ -350,7 +349,7 @@ static int inflate_disk_obj(git_rawobj *out, gitfo_buf *obj)
* inflate the initial part of the io buffer in order
* to parse the object header (type and size).
*/
if
(
(
z_status
=
start_inflate
(
&
zs
,
obj
,
head
,
sizeof
(
head
)
))
<
Z_OK
)
if
(
start_inflate
(
&
zs
,
obj
,
head
,
sizeof
(
head
))
<
Z_OK
)
return
GIT_ERROR
;
if
((
used
=
get_object_header
(
&
hdr
,
head
))
==
0
)
...
...
src/refs.c
View file @
94711cad
...
...
@@ -122,7 +122,8 @@ static int reference_create(
else
if
(
type
==
GIT_REF_OID
)
size
=
sizeof
(
reference_oid
);
else
return
GIT_EINVALIDREFSTATE
;
return
git__throw
(
GIT_EINVALIDARGS
,
"Invalid reference type. Use either GIT_REF_OID or GIT_REF_SYMBOLIC as type specifier"
);
reference
=
git__malloc
(
size
);
if
(
reference
==
NULL
)
...
...
@@ -159,11 +160,9 @@ static int reference_read(gitfo_buf *file_content, time_t *mtime, const char *re
/* Determine the full path of the file */
git__joinpath
(
path
,
repo_path
,
ref_name
);
if
(
gitfo_stat
(
path
,
&
st
)
<
0
)
return
GIT_ENOTFOUND
;
if
(
S_ISDIR
(
st
.
st_mode
))
return
GIT_EOBJCORRUPTED
;
if
(
gitfo_stat
(
path
,
&
st
)
<
0
||
S_ISDIR
(
st
.
st_mode
))
return
git__throw
(
GIT_ENOTFOUND
,
"Cannot read reference file '%s'"
,
ref_name
);
if
(
mtime
)
*
mtime
=
st
.
st_mtime
;
...
...
@@ -205,7 +204,8 @@ static int loose_update(git_reference *ref)
else
if
(
ref
->
type
==
GIT_REF_OID
)
error
=
loose_parse_oid
(
ref
,
&
ref_file
);
else
error
=
GIT_EINVALIDREFSTATE
;
error
=
git__throw
(
GIT_EOBJCORRUPTED
,
"Invalid reference type (%d) for loose reference"
,
ref
->
type
);
gitfo_free_buf
(
&
ref_file
);
...
...
@@ -229,7 +229,8 @@ static int loose_parse_symbolic(git_reference *ref, gitfo_buf *file_content)
ref_sym
=
(
reference_symbolic
*
)
ref
;
if
(
file_content
->
len
<
(
header_len
+
1
))
return
GIT_EREFCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse loose reference. Object too short"
);
/*
* Assume we have already checked for the header
...
...
@@ -246,7 +247,8 @@ static int loose_parse_symbolic(git_reference *ref, gitfo_buf *file_content)
/* remove newline at the end of file */
eol
=
strchr
(
ref_sym
->
target
,
'\n'
);
if
(
eol
==
NULL
)
return
GIT_EREFCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse loose reference. Missing EOL"
);
*
eol
=
'\0'
;
if
(
eol
[
-
1
]
==
'\r'
)
...
...
@@ -257,6 +259,7 @@ static int loose_parse_symbolic(git_reference *ref, gitfo_buf *file_content)
static
int
loose_parse_oid
(
git_reference
*
ref
,
gitfo_buf
*
file_content
)
{
int
error
;
reference_oid
*
ref_oid
;
char
*
buffer
;
...
...
@@ -265,17 +268,19 @@ static int loose_parse_oid(git_reference *ref, gitfo_buf *file_content)
/* File format: 40 chars (OID) + newline */
if
(
file_content
->
len
<
GIT_OID_HEXSZ
+
1
)
return
GIT_EREFCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse loose reference. Reference too short"
);
if
(
git_oid_mkstr
(
&
ref_oid
->
oid
,
buffer
)
<
GIT_SUCCESS
)
return
GIT_EREFCORRUPTED
;
if
(
(
error
=
git_oid_mkstr
(
&
ref_oid
->
oid
,
buffer
)
)
<
GIT_SUCCESS
)
return
git__rethrow
(
GIT_EOBJCORRUPTED
,
"Failed to parse loose reference."
)
;
buffer
=
buffer
+
GIT_OID_HEXSZ
;
if
(
*
buffer
==
'\r'
)
buffer
++
;
if
(
*
buffer
!=
'\n'
)
return
GIT_EREFCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse loose reference. Missing EOL"
);
return
GIT_SUCCESS
;
}
...
...
@@ -387,7 +392,7 @@ static int loose_write(git_reference *ref)
strcpy
(
ref_contents
,
GIT_SYMREF
);
strcat
(
ref_contents
,
ref_sym
->
target
);
}
else
{
error
=
GIT_EINVALIDREFSTATE
;
error
=
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to write reference. Invalid reference type"
)
;
goto
unlock
;
}
...
...
src/repository.c
View file @
94711cad
...
...
@@ -124,16 +124,16 @@ static int check_repository_dirs(git_repository *repo)
char
path_aux
[
GIT_PATH_MAX
];
if
(
gitfo_isdir
(
repo
->
path_repository
)
<
GIT_SUCCESS
)
return
GIT_ENOTAREPO
;
return
git__throw
(
GIT_ENOTAREPO
,
"`%s` is not a folder"
,
repo
->
path_repository
)
;
/* Ensure GIT_OBJECT_DIRECTORY exists */
if
(
gitfo_isdir
(
repo
->
path_odb
)
<
GIT_SUCCESS
)
return
GIT_ENOTAREPO
;
return
git__throw
(
GIT_ENOTAREPO
,
"`%s` does not exist"
,
repo
->
path_odb
)
;
/* Ensure HEAD file exists */
git__joinpath
(
path_aux
,
repo
->
path_repository
,
GIT_HEAD_FILE
);
if
(
gitfo_exists
(
path_aux
)
<
0
)
return
GIT_ENOTAREPO
;
return
git__throw
(
GIT_ENOTAREPO
,
"HEAD file is missing"
)
;
return
GIT_SUCCESS
;
}
...
...
@@ -145,12 +145,12 @@ static int guess_repository_dirs(git_repository *repo, const char *repository_pa
/* Git directory name */
if
(
git__basename_r
(
buffer
,
sizeof
(
buffer
),
repository_path
)
<
0
)
return
GIT_EINVALIDPATH
;
return
git__throw
(
GIT_EINVALIDPATH
,
"Unable to parse folder name from `%s`"
,
repository_path
)
;
if
(
strcmp
(
buffer
,
DOT_GIT
)
==
0
)
{
/* Path to working dir */
if
(
git__dirname_r
(
buffer
,
sizeof
(
buffer
),
repository_path
)
<
0
)
return
GIT_EINVALIDPATH
;
return
git__throw
(
GIT_EINVALIDPATH
,
"Unable to parse parent folder name from `%s`"
,
repository_path
)
;
path_work_tree
=
buffer
;
}
...
...
@@ -159,13 +159,19 @@ static int guess_repository_dirs(git_repository *repo, const char *repository_pa
static
git_repository
*
repository_alloc
()
{
int
error
;
git_repository
*
repo
=
git__malloc
(
sizeof
(
git_repository
));
if
(
!
repo
)
return
NULL
;
memset
(
repo
,
0x0
,
sizeof
(
git_repository
));
git_cache_init
(
&
repo
->
objects
,
GIT_DEFAULT_CACHE_SIZE
,
&
git_object__free
);
error
=
git_cache_init
(
&
repo
->
objects
,
GIT_DEFAULT_CACHE_SIZE
,
&
git_object__free
);
if
(
error
<
GIT_SUCCESS
)
{
free
(
repo
);
return
NULL
;
}
if
(
git_repository__refcache_init
(
&
repo
->
references
)
<
GIT_SUCCESS
)
{
free
(
repo
);
...
...
@@ -177,7 +183,7 @@ static git_repository *repository_alloc()
static
int
init_odb
(
git_repository
*
repo
)
{
return
git_odb_open
(
&
repo
->
db
,
repo
->
path_odb
);
return
git_odb_open
(
&
repo
->
db
,
repo
->
path_odb
);
/* TODO: Move odb.c to new error handling */
}
int
git_repository_open3
(
git_repository
**
repo_out
,
...
...
@@ -192,7 +198,7 @@ int git_repository_open3(git_repository **repo_out,
assert
(
repo_out
);
if
(
object_database
==
NULL
)
return
GIT_ERROR
;
return
git__throw
(
GIT_EINVALIDARGS
,
"Failed to open repository. `object_database` can't be null"
)
;
repo
=
repository_alloc
();
if
(
repo
==
NULL
)
...
...
@@ -218,7 +224,7 @@ int git_repository_open3(git_repository **repo_out,
cleanup:
git_repository_free
(
repo
);
return
error
;
return
git__rethrow
(
error
,
"Failed to open repository"
)
;
}
...
...
@@ -259,7 +265,7 @@ int git_repository_open2(git_repository **repo_out,
cleanup:
git_repository_free
(
repo
);
return
error
;
return
git__rethrow
(
error
,
"Failed to open repository"
)
;
}
int
git_repository_open
(
git_repository
**
repo_out
,
const
char
*
path
)
...
...
@@ -290,7 +296,7 @@ int git_repository_open(git_repository **repo_out, const char *path)
cleanup:
git_repository_free
(
repo
);
return
error
;
return
git__rethrow
(
error
,
"Failed to open repository"
)
;
}
void
git_repository_free
(
git_repository
*
repo
)
...
...
@@ -322,7 +328,7 @@ int git_repository_index(git_index **index_out, git_repository *repo)
assert
(
index_out
&&
repo
);
if
(
repo
->
index
==
NULL
)
{
error
=
git_index_open_inrepo
(
&
repo
->
index
,
repo
);
error
=
git_index_open_inrepo
(
&
repo
->
index
,
repo
);
/* TODO: move index.c to new error handling */
if
(
error
<
GIT_SUCCESS
)
return
error
;
...
...
@@ -349,7 +355,7 @@ static int repo_init_reinit(repo_init *results)
static
int
repo_init_createhead
(
git_repository
*
repo
)
{
git_reference
*
head_reference
;
return
git_reference_create_symbolic
(
&
head_reference
,
repo
,
GIT_HEAD_FILE
,
GIT_REFS_HEADS_MASTER_FILE
);
return
git_reference_create_symbolic
(
&
head_reference
,
repo
,
GIT_HEAD_FILE
,
GIT_REFS_HEADS_MASTER_FILE
);
/* TODO: finalize moving refs.c to new error handling */
}
static
int
repo_init_check_head_existence
(
char
*
repository_path
)
...
...
@@ -363,6 +369,7 @@ static int repo_init_check_head_existence(char * repository_path)
static
int
repo_init_structure
(
repo_init
*
results
)
{
const
int
mode
=
0755
;
/* or 0777 ? */
int
error
;
char
temp_path
[
GIT_PATH_MAX
];
char
*
git_dir
=
results
->
path_repository
;
...
...
@@ -372,23 +379,27 @@ static int repo_init_structure(repo_init *results)
/* Creates the '/objects/info/' directory */
git__joinpath
(
temp_path
,
git_dir
,
GIT_OBJECTS_INFO_DIR
);
if
(
gitfo_mkdir_recurs
(
temp_path
,
mode
)
<
GIT_SUCCESS
)
return
GIT_ERROR
;
error
=
gitfo_mkdir_recurs
(
temp_path
,
mode
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
/* Creates the '/objects/pack/' directory */
git__joinpath
(
temp_path
,
git_dir
,
GIT_OBJECTS_PACK_DIR
);
if
(
gitfo_mkdir
(
temp_path
,
mode
))
return
GIT_ERROR
;
error
=
gitfo_mkdir
(
temp_path
,
mode
);
if
(
error
<
GIT_SUCCESS
)
return
git__throw
(
error
,
"Unable to create `%s` folder"
,
temp_path
);
/* Creates the '/refs/heads/' directory */
git__joinpath
(
temp_path
,
git_dir
,
GIT_REFS_HEADS_DIR
);
if
(
gitfo_mkdir_recurs
(
temp_path
,
mode
))
return
GIT_ERROR
;
error
=
gitfo_mkdir_recurs
(
temp_path
,
mode
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
/* Creates the '/refs/tags/' directory */
git__joinpath
(
temp_path
,
git_dir
,
GIT_REFS_TAGS_DIR
);
if
(
gitfo_mkdir
(
temp_path
,
mode
))
return
GIT_ERROR
;
error
=
gitfo_mkdir
(
temp_path
,
mode
);
if
(
error
<
GIT_SUCCESS
)
return
git__throw
(
error
,
"Unable to create `%s` folder"
,
temp_path
);
/* TODO: what's left? templates? */
...
...
@@ -467,7 +478,7 @@ int git_repository_init(git_repository **repo_out, const char *path, unsigned is
cleanup:
free
(
results
.
path_repository
);
git_repository_free
(
repo
);
return
error
;
return
git__rethrow
(
error
,
"Failed to (re)init the repository `%s`"
,
path
)
;
}
int
git_repository_is_empty
(
git_repository
*
repo
)
...
...
@@ -477,10 +488,10 @@ int git_repository_is_empty(git_repository *repo)
error
=
git_reference_lookup
(
&
head
,
repo
,
"HEAD"
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
return
git__throw
(
error
,
"Failed to determine the emptiness of the repository. An error occured while retrieving the HEAD reference"
)
;
if
(
git_reference_type
(
head
)
!=
GIT_REF_SYMBOLIC
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to determine the emptiness of the repository. HEAD is probably in detached state"
)
;
return
git_reference_resolve
(
&
branch
,
head
)
==
GIT_SUCCESS
?
0
:
1
;
}
...
...
src/revwalk.c
View file @
94711cad
...
...
@@ -210,7 +210,7 @@ static int commit_quick_parse(git_revwalk *walk, commit_object *commit, git_rawo
git_oid
oid
;
if
(
git_oid_mkstr
(
&
oid
,
(
char
*
)
buffer
+
STRLEN
(
"parent "
))
<
GIT_SUCCESS
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse commit. Parent object is corrupted"
)
;
commit
->
parents
[
i
]
=
commit_lookup
(
walk
,
&
oid
);
if
(
commit
->
parents
[
i
]
==
NULL
)
...
...
@@ -222,14 +222,14 @@ static int commit_quick_parse(git_revwalk *walk, commit_object *commit, git_rawo
commit
->
out_degree
=
(
unsigned
short
)
parents
;
if
((
buffer
=
memchr
(
buffer
,
'\n'
,
buffer_end
-
buffer
))
==
NULL
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse commit. Object is corrupted"
)
;
buffer
=
memchr
(
buffer
,
'>'
,
buffer_end
-
buffer
);
if
(
buffer
==
NULL
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse commit. Can't find author"
)
;
if
(
git__strtol32
(
&
commit_time
,
(
char
*
)
buffer
+
2
,
NULL
,
10
)
<
GIT_SUCCESS
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse commit. Can't parse commit time"
)
;
commit
->
time
=
(
time_t
)
commit_time
;
commit
->
parsed
=
1
;
...
...
@@ -245,11 +245,11 @@ static int commit_parse(git_revwalk *walk, commit_object *commit)
return
GIT_SUCCESS
;
if
((
error
=
git_odb_read
(
&
obj
,
walk
->
repo
->
db
,
&
commit
->
oid
))
<
GIT_SUCCESS
)
return
error
;
return
git__rethrow
(
error
,
"Failed to parse commit. Can't read object"
)
;
if
(
obj
->
raw
.
type
!=
GIT_OBJ_COMMIT
)
{
git_odb_object_close
(
obj
);
return
GIT_EOBJTYPE
;
return
git__throw
(
GIT_EOBJTYPE
,
"Failed to parse commit. Object is no commit object"
)
;
}
error
=
commit_quick_parse
(
walk
,
commit
,
&
obj
->
raw
);
...
...
@@ -305,7 +305,7 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting)
commit
=
commit_lookup
(
walk
,
oid
);
if
(
commit
==
NULL
)
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Failed to push commit. Object not found"
)
;
commit
->
uninteresting
=
uninteresting
;
...
...
src/signature.c
View file @
94711cad
...
...
@@ -115,22 +115,22 @@ static int parse_timezone_offset(const char *buffer, long *offset_out)
}
if
(
offset_start
[
0
]
!=
'-'
&&
offset_start
[
0
]
!=
'+'
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse TZ offset. It doesn't start with '+' or '-'"
)
;
if
(
git__strtol32
(
&
dec_offset
,
offset_start
+
1
,
&
offset_end
,
10
)
<
GIT_SUCCESS
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse TZ offset. It isn't a number"
)
;
if
(
offset_end
-
offset_start
!=
5
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse TZ offset. Invalid length"
)
;
hours
=
dec_offset
/
100
;
mins
=
dec_offset
%
100
;
if
(
hours
>
14
)
// see http://www.worldtimezone.com/faq.html
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse TZ offset. Hour value too large"
);
;
if
(
mins
>
59
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse TZ offset. Minute value too large"
)
;
offset
=
(
hours
*
60
)
+
mins
;
...
...
@@ -157,19 +157,19 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
line_end
=
memchr
(
buffer
,
'\n'
,
buffer_end
-
buffer
);
if
(
!
line_end
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. No newline found"
);
;
if
(
buffer
+
(
header_len
+
1
)
>
line_end
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. Signature too short"
)
;
if
(
memcmp
(
buffer
,
header
,
header_len
)
!=
0
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. Expected prefix '%s' doesn't match actual"
,
header
)
;
buffer
+=
header_len
;
/* Parse name */
if
((
name_end
=
memchr
(
buffer
,
'<'
,
buffer_end
-
buffer
))
==
NULL
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. Can't find e-mail start"
)
;
name_length
=
name_end
-
buffer
-
1
;
sig
->
name
=
git__malloc
(
name_length
+
1
);
...
...
@@ -181,11 +181,11 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
buffer
=
name_end
+
1
;
if
(
buffer
>=
line_end
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. Ended unexpectedly"
)
;
/* Parse email */
if
((
email_end
=
memchr
(
buffer
,
'>'
,
buffer_end
-
buffer
))
==
NULL
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. Can't find e-mail end"
)
;
email_length
=
email_end
-
buffer
;
sig
->
email
=
git__malloc
(
email_length
+
1
);
...
...
@@ -197,10 +197,10 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
buffer
=
email_end
+
1
;
if
(
buffer
>=
line_end
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. Ended unexpectedly"
)
;
if
(
git__strtol32
(
&
time
,
buffer
,
&
buffer
,
10
)
<
GIT_SUCCESS
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse signature. Timestamp isn't a number"
)
;
sig
->
when
.
time
=
(
time_t
)
time
;
...
...
src/tag.c
View file @
94711cad
...
...
@@ -90,13 +90,13 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer
int
error
;
if
((
error
=
git__parse_oid
(
&
tag
->
target
,
&
buffer
,
buffer_end
,
"object "
))
<
0
)
return
error
;
return
git__rethrow
(
error
,
"Failed to parse tag. Object field invalid"
)
;
if
(
buffer
+
5
>=
buffer_end
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tag. Object too short"
)
;
if
(
memcmp
(
buffer
,
"type "
,
5
)
!=
0
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tag. Type field not found"
)
;
buffer
+=
5
;
tag
->
type
=
GIT_OBJ_BAD
;
...
...
@@ -105,7 +105,7 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer
size_t
type_length
=
strlen
(
tag_types
[
i
]);
if
(
buffer
+
type_length
>=
buffer_end
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tag. Object too short"
)
;
if
(
memcmp
(
buffer
,
tag_types
[
i
],
type_length
)
==
0
)
{
tag
->
type
=
i
;
...
...
@@ -115,18 +115,19 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer
}
if
(
tag
->
type
==
GIT_OBJ_BAD
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tag. Invalid object type"
)
;
if
(
buffer
+
4
>=
buffer_end
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tag. Object too short"
)
;
if
(
memcmp
(
buffer
,
"tag "
,
4
)
!=
0
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tag. Tag field not found"
);
buffer
+=
4
;
search
=
memchr
(
buffer
,
'\n'
,
buffer_end
-
buffer
);
if
(
search
==
NULL
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tag. Object too short"
)
;
text_len
=
search
-
buffer
;
...
...
@@ -218,7 +219,7 @@ static int tag_create(
}
if
(
!
git_odb_exists
(
repo
->
db
,
target
))
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Failed to create tag. Object to tag doesn't exist"
)
;
/* Try to find out what the type is */
if
(
target_type
==
GIT_OBJ_ANY
)
{
...
...
src/tree.c
View file @
94711cad
...
...
@@ -151,15 +151,15 @@ static int tree_parse_buffer(git_tree *tree, const char *buffer, const char *buf
return
GIT_ENOMEM
;
if
(
git__strtol32
((
long
*
)
&
entry
->
attr
,
buffer
,
&
buffer
,
8
)
<
GIT_SUCCESS
)
return
GIT_EOBJCORRUPTED
;
return
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tree. Can't parse attributes"
)
;
if
(
*
buffer
++
!=
' '
)
{
error
=
GIT_EOBJCORRUPTED
;
error
=
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tree. Object it corrupted"
)
;
break
;
}
if
(
memchr
(
buffer
,
0
,
buffer_end
-
buffer
)
==
NULL
)
{
error
=
GIT_EOBJCORRUPTED
;
error
=
git__throw
(
GIT_EOBJCORRUPTED
,
"Failed to parse tree. Object it corrupted"
)
;
break
;
}
...
...
@@ -274,7 +274,7 @@ int git_tree_create_fromindex(git_oid *oid, git_index *index)
int
error
;
if
(
index
->
repository
==
NULL
)
return
GIT_EBAREINDEX
;
return
git__throw
(
GIT_EBAREINDEX
,
"Failed to create tree. The index file is not backed up by an existing repository"
)
;
error
=
write_index
(
oid
,
index
,
""
,
0
,
0
,
git_index_entrycount
(
index
));
return
(
error
<
GIT_SUCCESS
)
?
error
:
GIT_SUCCESS
;
...
...
@@ -343,7 +343,7 @@ int git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, con
assert
(
bld
&&
id
&&
filename
);
if
(
!
valid_attributes
(
attributes
))
return
GIT_ERROR
;
return
git__throw
(
GIT_ERROR
,
"Failed to insert entry. Invalid atrributes"
)
;
if
((
pos
=
git_vector_bsearch2
(
&
bld
->
entries
,
entry_search_cmp
,
filename
))
!=
GIT_ENOTFOUND
)
{
entry
=
git_vector_get
(
&
bld
->
entries
,
pos
);
...
...
@@ -400,7 +400,7 @@ int git_treebuilder_remove(git_treebuilder *bld, const char *filename)
git_tree_entry
*
remove_ptr
=
(
git_tree_entry
*
)
git_treebuilder_get
(
bld
,
filename
);
if
(
remove_ptr
==
NULL
||
remove_ptr
->
removed
)
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Failed to remove entry. File isn't in the tree"
)
;
remove_ptr
->
removed
=
1
;
bld
->
entry_count
--
;
...
...
@@ -431,7 +431,7 @@ int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *b
}
if
((
error
=
git_odb_open_wstream
(
&
stream
,
git_repository_database
(
repo
),
size
,
GIT_OBJ_TREE
))
<
GIT_SUCCESS
)
return
error
;
return
git__rethrow
(
error
,
"Failed to write tree. Can't open write stream"
)
;
for
(
i
=
0
;
i
<
bld
->
entries
.
length
;
++
i
)
{
git_tree_entry
*
entry
=
bld
->
entries
.
contents
[
i
];
...
...
src/util.h
View file @
94711cad
...
...
@@ -6,17 +6,41 @@
#define MSB(x, bits) ((x) & (~0ULL << (bitsizeof(x) - (bits))))
/*
* Don't wrap malloc/calloc.
* Use the default versions in glibc, and make
* sure that any methods that allocate memory
* return a GIT_ENOMEM error when allocation
* fails.
* Custom memory allocation wrappers
* that set error code and error message
* on allocation failure
*/
#define git__malloc malloc
#define git__calloc calloc
#define git__realloc realloc
#define git__strdup strdup
#define git__strndup strndup
GIT_INLINE
(
void
*
)
git__malloc
(
size_t
len
)
{
void
*
ptr
=
malloc
(
len
);
if
(
!
ptr
)
git__throw
(
GIT_ENOMEM
,
"Out of memory. Failed to allocate %d bytes."
,
(
int
)
len
);
return
ptr
;
}
GIT_INLINE
(
void
*
)
git__calloc
(
size_t
nelem
,
size_t
elsize
)
{
void
*
ptr
=
calloc
(
nelem
,
elsize
);
if
(
!
ptr
)
git__throw
(
GIT_ENOMEM
,
"Out of memory. Failed to allocate %d bytes."
,
(
int
)
elsize
);
return
ptr
;
}
GIT_INLINE
(
char
*
)
git__strdup
(
const
char
*
str
)
{
char
*
ptr
=
strdup
(
str
);
if
(
!
ptr
)
git__throw
(
GIT_ENOMEM
,
"Out of memory. Failed to duplicate string"
);
return
ptr
;
}
GIT_INLINE
(
void
*
)
git__realloc
(
void
*
ptr
,
size_t
size
)
{
void
*
new_ptr
=
realloc
(
ptr
,
size
);
if
(
!
new_ptr
)
git__throw
(
GIT_ENOMEM
,
"Out of memory. Failed to allocate %d bytes."
,
(
int
)
size
);
return
new_ptr
;
}
extern
int
git__fmt
(
char
*
,
size_t
,
const
char
*
,
...)
GIT_FORMAT_PRINTF
(
3
,
4
);
...
...
src/vector.c
View file @
94711cad
...
...
@@ -106,7 +106,7 @@ int git_vector_bsearch2(git_vector *v, git_vector_cmp key_lookup, const void *ke
/* need comparison function to sort the vector */
if
(
v
->
_cmp
==
NULL
)
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Can't sort vector. No comparison function set"
)
;
git_vector_sort
(
v
);
...
...
@@ -114,7 +114,7 @@ int git_vector_bsearch2(git_vector *v, git_vector_cmp key_lookup, const void *ke
if
(
find
!=
NULL
)
return
(
int
)(
find
-
v
->
contents
);
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Can't find element"
)
;
}
int
git_vector_search2
(
git_vector
*
v
,
git_vector_cmp
key_lookup
,
const
void
*
key
)
...
...
@@ -128,7 +128,7 @@ int git_vector_search2(git_vector *v, git_vector_cmp key_lookup, const void *key
return
i
;
}
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Can't find element"
)
;
}
static
int
strict_comparison
(
const
void
*
a
,
const
void
*
b
)
...
...
@@ -143,9 +143,6 @@ int git_vector_search(git_vector *v, const void *entry)
int
git_vector_bsearch
(
git_vector
*
v
,
const
void
*
key
)
{
if
(
v
->
_cmp
==
NULL
)
return
GIT_ENOTFOUND
;
return
git_vector_bsearch2
(
v
,
v
->
_cmp
,
key
);
}
...
...
@@ -156,7 +153,7 @@ int git_vector_remove(git_vector *v, unsigned int idx)
assert
(
v
);
if
(
idx
>=
v
->
length
||
v
->
length
==
0
)
return
GIT_ENOTFOUND
;
return
git__throw
(
GIT_ENOTFOUND
,
"Can't remove element. Index out of bounds"
)
;
for
(
i
=
idx
;
i
<
v
->
length
-
1
;
++
i
)
v
->
contents
[
i
]
=
v
->
contents
[
i
+
1
];
...
...
src/win32/pthread.c
View file @
94711cad
...
...
@@ -48,16 +48,15 @@ int pthread_join(pthread_t thread, void **value_ptr)
int
pthread_mutex_init
(
pthread_mutex_t
*
GIT_RESTRICT
mutex
,
const
pthread_mutexattr_t
*
GIT_RESTRICT
GIT_UNUSED
(
mutexattr
))
{
GIT_UNUSED_ARG
(
mutexattr
);
GIT_UNUSED_ARG
(
mutexattr
);
InitializeCriticalSection
(
mutex
);
return
0
;
}
int
pthread_mutex_destroy
(
pthread_mutex_t
*
mutex
)
{
int
ret
;
ret
=
CloseHandle
(
mutex
);
return
-
(
!
ret
);
DeleteCriticalSection
(
mutex
);
return
0
;
}
int
pthread_mutex_lock
(
pthread_mutex_t
*
mutex
)
...
...
tests/t10-refs.c
View file @
94711cad
...
...
@@ -292,7 +292,7 @@ BEGIN_TEST(create2, "create a new OID reference")
/* Similar test with a fresh new repository */
must_pass
(
git_repository_open
(
&
repo2
,
TEMP_REPO_FOLDER
));
must_pass
(
git_reference_lookup
(
&
looked_up_ref
,
repo
,
new_head
));
must_pass
(
git_reference_lookup
(
&
looked_up_ref
,
repo
2
,
new_head
));
must_be_true
(
git_oid_cmp
(
&
id
,
git_reference_oid
(
looked_up_ref
))
==
0
);
close_temp_repo
(
repo2
);
...
...
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