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
793545ef
Commit
793545ef
authored
Jun 03, 2011
by
Vicent Martí
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #227 from Romain-Geissler/discovery-path-v2
Discovery path v2
parents
3a42e0a3
fd0574e5
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
381 additions
and
52 deletions
+381
-52
include/git2/repository.h
+28
-0
src/filebuf.c
+2
-4
src/fileops.c
+68
-25
src/fileops.h
+17
-3
src/repository.c
+261
-15
src/sha1_lookup.c
+2
-2
tests/t00-core.c
+3
-3
No files found.
include/git2/repository.h
View file @
793545ef
...
...
@@ -133,6 +133,34 @@ GIT_EXTERN(int) git_repository_open3(git_repository **repository,
const
char
*
git_work_tree
);
/**
* Look for a git repository and copy its path in the given buffer. The lookup start
* from base_path and walk across parent directories if nothing has been found. The
* lookup ends when the first repository is found, or when reaching a directory
* referenced in ceiling_dirs or when the filesystem changes (in case across_fs
* is true).
*
* The method will automatically detect if the repository is bare (if there is
* a repository).
*
* @param repository_path The user allocated buffer which will contain the found path.
*
* @param size repository_path size
*
* @param start_path The base path where the lookup starts.
*
* @param across_fs If true, then the lookup will not stop when a filesystem device change
* is detected while exploring parent directories.
*
* @param ceiling_dirs A colon separated of absolute symbolic link free paths. The lookup will
* stop when any of this paths is reached. Note that the lookup always performs on start_path
* no matter start_path appears in ceiling_dirs
* ceiling_dirs might be NULL (which is equivalent to an empty string)
*
* @return 0 on success; error code otherwise
*/
GIT_EXTERN
(
int
)
git_repository_discover
(
char
*
repository_path
,
size_t
size
,
const
char
*
start_path
,
int
across_fs
,
const
char
*
ceiling_dirs
);
/**
* Get the object database behind a Git repository
*
* @param repo a repository object
...
...
src/filebuf.c
View file @
793545ef
...
...
@@ -41,16 +41,14 @@ static int lock_file(git_filebuf *file, int flags)
/* create path to the file buffer is required */
if
(
flags
&
GIT_FILEBUF_FORCE
)
{
file
->
fd
=
gitfo_creat_force
(
file
->
path_lock
,
0644
);
file
->
fd
=
gitfo_creat_
locked_
force
(
file
->
path_lock
,
0644
);
}
else
{
file
->
fd
=
gitfo_creat
(
file
->
path_lock
,
0644
);
file
->
fd
=
gitfo_creat
_locked
(
file
->
path_lock
,
0644
);
}
if
(
file
->
fd
<
0
)
return
git__throw
(
GIT_EOSERR
,
"Failed to create lock"
);
/* TODO: do a flock() in the descriptor file_lock */
if
((
flags
&
GIT_FILEBUF_APPEND
)
&&
gitfo_exists
(
file
->
path_original
)
==
0
)
{
git_file
source
;
char
buffer
[
2048
];
...
...
src/fileops.c
View file @
793545ef
...
...
@@ -66,6 +66,20 @@ int gitfo_creat_force(const char *path, int mode)
return
gitfo_creat
(
path
,
mode
);
}
int
gitfo_creat_locked
(
const
char
*
path
,
int
mode
)
{
int
fd
=
open
(
path
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
|
O_BINARY
|
O_EXCL
,
mode
);
return
fd
>=
0
?
fd
:
git__throw
(
GIT_EOSERR
,
"Failed to create locked file. Could not open %s"
,
path
);
}
int
gitfo_creat_locked_force
(
const
char
*
path
,
int
mode
)
{
if
(
gitfo_mkdir_2file
(
path
)
<
GIT_SUCCESS
)
return
git__throw
(
GIT_EOSERR
,
"Failed to create locked file %s"
,
path
);
return
gitfo_creat_locked
(
path
,
mode
);
}
int
gitfo_read
(
git_file
fd
,
void
*
buf
,
size_t
cnt
)
{
char
*
b
=
buf
;
...
...
@@ -131,7 +145,26 @@ int gitfo_isdir(const char *path)
return
git__throw
(
GIT_ENOTFOUND
,
"%s does not exist"
,
path
);
if
(
!
S_ISDIR
(
st
.
st_mode
))
return
git__throw
(
GIT_ENOTFOUND
,
"%s is a file"
,
path
);
return
git__throw
(
GIT_ENOTFOUND
,
"%s is not a directory"
,
path
);
return
GIT_SUCCESS
;
}
int
gitfo_isfile
(
const
char
*
path
)
{
struct
stat
st
;
int
stat_error
;
if
(
!
path
)
return
git__throw
(
GIT_ENOTFOUND
,
"No path given to gitfo_isfile"
);
stat_error
=
gitfo_stat
(
path
,
&
st
);
if
(
stat_error
<
GIT_SUCCESS
)
return
git__throw
(
GIT_ENOTFOUND
,
"%s does not exist"
,
path
);
if
(
!
S_ISREG
(
st
.
st_mode
))
return
git__throw
(
GIT_ENOTFOUND
,
"%s is not a file"
,
path
);
return
GIT_SUCCESS
;
}
...
...
@@ -301,8 +334,19 @@ int gitfo_dirent(
return
GIT_SUCCESS
;
}
void
gitfo_posixify_path
(
char
*
path
)
{
#if GIT_PLATFORM_PATH_SEP != '/'
while
(
*
path
)
{
if
(
*
path
==
GIT_PLATFORM_PATH_SEP
)
*
path
=
'/'
;
int
retrieve_path_root_offset
(
const
char
*
path
)
path
++
;
}
#endif
}
int
gitfo_retrieve_path_root_offset
(
const
char
*
path
)
{
int
offset
=
0
;
...
...
@@ -320,7 +364,6 @@ int retrieve_path_root_offset(const char *path)
return
-
1
;
/* Not a real error. Rather a signal than the path is not rooted */
}
int
gitfo_mkdir_recurs
(
const
char
*
path
,
int
mode
)
{
int
error
,
root_path_offset
;
...
...
@@ -333,7 +376,7 @@ int gitfo_mkdir_recurs(const char *path, int mode)
error
=
GIT_SUCCESS
;
pp
=
path_copy
;
root_path_offset
=
retrieve_path_root_offset
(
pp
);
root_path_offset
=
gitfo_
retrieve_path_root_offset
(
pp
);
if
(
root_path_offset
>
0
)
pp
+=
root_path_offset
;
/* On Windows, will skip the drive name (eg. C: or D:) */
...
...
@@ -367,7 +410,7 @@ static int retrieve_previous_path_component_start(const char *path)
{
int
offset
,
len
,
root_offset
,
start
=
0
;
root_offset
=
retrieve_path_root_offset
(
path
);
root_offset
=
gitfo_
retrieve_path_root_offset
(
path
);
if
(
root_offset
>
-
1
)
start
+=
root_offset
;
...
...
@@ -392,7 +435,7 @@ static int retrieve_previous_path_component_start(const char *path)
return
offset
;
}
int
gitfo_prettify_dir_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
)
int
gitfo_prettify_dir_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
,
const
char
*
base_path
)
{
int
len
=
0
,
segment_len
,
only_dots
,
root_path_offset
,
error
=
GIT_SUCCESS
;
char
*
current
;
...
...
@@ -402,11 +445,20 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path)
buffer_end
=
path
+
strlen
(
path
);
buffer_out_start
=
buffer_out
;
root_path_offset
=
retrieve_path_root_offset
(
path
);
root_path_offset
=
gitfo_
retrieve_path_root_offset
(
path
);
if
(
root_path_offset
<
0
)
{
error
=
gitfo_getcwd
(
buffer_out
,
size
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
/* The callee already takes care of setting the correct error message. */
if
(
base_path
==
NULL
)
{
error
=
gitfo_getcwd
(
buffer_out
,
size
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
/* The callee already takes care of setting the correct error message. */
}
else
{
if
(
size
<
(
strlen
(
base_path
)
+
1
)
*
sizeof
(
char
))
return
git__throw
(
GIT_EOVERFLOW
,
"Failed to prettify dir path: the base path is too long for the buffer."
);
strcpy
(
buffer_out
,
base_path
);
gitfo_posixify_path
(
buffer_out
);
git__joinpath
(
buffer_out
,
buffer_out
,
""
);
}
len
=
strlen
(
buffer_out
);
buffer_out
+=
len
;
...
...
@@ -470,9 +522,9 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path)
return
GIT_SUCCESS
;
}
int
gitfo_prettify_file_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
)
int
gitfo_prettify_file_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
,
const
char
*
base_path
)
{
int
error
,
path_len
,
i
;
int
error
,
path_len
,
i
,
root_offset
;
const
char
*
pattern
=
"/.."
;
path_len
=
strlen
(
path
);
...
...
@@ -487,12 +539,13 @@ int gitfo_prettify_file_path(char *buffer_out, size_t size, const char *path)
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
);
error
=
gitfo_prettify_dir_path
(
buffer_out
,
size
,
path
,
base_path
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
/* The callee already takes care of setting the correct error message. */
path_len
=
strlen
(
buffer_out
);
if
(
path_len
<
2
)
/* TODO: Fixme. We should also take of detecting Windows rooted path (probably through usage of retrieve_path_root_offset) */
root_offset
=
gitfo_retrieve_path_root_offset
(
buffer_out
)
+
1
;
if
(
path_len
==
root_offset
)
return
git__throw
(
GIT_EINVALIDPATH
,
"Failed to normalize file path `%s`. The path points to a folder"
,
path
);
/* Remove the trailing slash */
...
...
@@ -519,16 +572,6 @@ int gitfo_cmp_path(const char *name1, int len1, int isdir1,
return
0
;
}
static
void
posixify_path
(
char
*
path
)
{
while
(
*
path
)
{
if
(
*
path
==
'\\'
)
*
path
=
'/'
;
path
++
;
}
}
int
gitfo_getcwd
(
char
*
buffer_out
,
size_t
size
)
{
char
*
cwd_buffer
;
...
...
@@ -544,7 +587,7 @@ int gitfo_getcwd(char *buffer_out, size_t size)
if
(
cwd_buffer
==
NULL
)
return
git__throw
(
GIT_EOSERR
,
"Failed to retrieve current working directory"
);
posixify_path
(
buffer_out
);
gitfo_
posixify_path
(
buffer_out
);
git__joinpath
(
buffer_out
,
buffer_out
,
""
);
//Ensure the path ends with a trailing slash
...
...
src/fileops.h
View file @
793545ef
...
...
@@ -12,6 +12,14 @@
#include <fcntl.h>
#include <time.h>
#define GIT_PATH_LIST_SEPARATOR ':'
#ifdef GIT_WIN32
#define GIT_PLATFORM_PATH_SEP '\\'
#else
#define GIT_PLATFORM_PATH_SEP '/'
#endif
#ifdef GIT_WIN32
GIT_INLINE
(
int
)
link
(
const
char
*
GIT_UNUSED
(
old
),
const
char
*
GIT_UNUSED
(
new
))
{
...
...
@@ -57,8 +65,11 @@ extern int gitfo_exists(const char *path);
extern
int
gitfo_open
(
const
char
*
path
,
int
flags
);
extern
int
gitfo_creat
(
const
char
*
path
,
int
mode
);
extern
int
gitfo_creat_force
(
const
char
*
path
,
int
mode
);
extern
int
gitfo_creat_locked
(
const
char
*
path
,
int
mode
);
extern
int
gitfo_creat_locked_force
(
const
char
*
path
,
int
mode
);
extern
int
gitfo_mktemp
(
char
*
path_out
,
const
char
*
filename
);
extern
int
gitfo_isdir
(
const
char
*
path
);
extern
int
gitfo_isfile
(
const
char
*
path
);
extern
int
gitfo_mkdir_recurs
(
const
char
*
path
,
int
mode
);
extern
int
gitfo_mkdir_2file
(
const
char
*
path
);
#define gitfo_close(fd) close(fd)
...
...
@@ -162,7 +173,7 @@ extern int gitfo_getcwd(char *buffer_out, size_t size);
* - GIT_SUCCESS on success;
* - GIT_ERROR when the input path is invalid or escapes the current directory.
*/
int
gitfo_prettify_dir_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
);
int
gitfo_prettify_dir_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
,
const
char
*
base_path
);
/**
* Clean up a provided absolute or relative file path.
...
...
@@ -185,7 +196,10 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path);
* - GIT_SUCCESS on success;
* - GIT_ERROR when the input path is invalid or escapes the current directory.
*/
int
gitfo_prettify_file_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
);
int
gitfo_prettify_file_path
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
,
const
char
*
base_path
);
void
gitfo_posixify_path
(
char
*
path
);
int
gitfo_retrieve_path_root_offset
(
const
char
*
path
);
int
retrieve_path_root_offset
(
const
char
*
path
);
#endif
/* INCLUDE_fileops_h__ */
src/repository.c
View file @
793545ef
...
...
@@ -38,6 +38,9 @@
#define GIT_OBJECTS_INFO_DIR GIT_OBJECTS_DIR "info/"
#define GIT_OBJECTS_PACK_DIR GIT_OBJECTS_DIR "pack/"
#define GIT_FILE_CONTENT_PREFIX "gitdir: "
#define GIT_FILE_CONTENT_PREFIX_LENGTH 8
#define GIT_BRANCH_MASTER "master"
typedef
struct
{
...
...
@@ -65,7 +68,7 @@ static int assign_repository_dirs(
if
(
git_dir
==
NULL
)
return
git__throw
(
GIT_ENOTFOUND
,
"Failed to open repository. Git dir not found"
);
error
=
gitfo_prettify_dir_path
(
path_aux
,
sizeof
(
path_aux
),
git_dir
);
error
=
gitfo_prettify_dir_path
(
path_aux
,
sizeof
(
path_aux
),
git_dir
,
NULL
);
if
(
error
<
GIT_SUCCESS
)
return
git__rethrow
(
error
,
"Failed to open repository"
);
...
...
@@ -78,7 +81,7 @@ static int assign_repository_dirs(
if
(
git_object_directory
==
NULL
)
git__joinpath
(
path_aux
,
repo
->
path_repository
,
GIT_OBJECTS_DIR
);
else
{
error
=
gitfo_prettify_dir_path
(
path_aux
,
sizeof
(
path_aux
),
git_object_directory
);
error
=
gitfo_prettify_dir_path
(
path_aux
,
sizeof
(
path_aux
),
git_object_directory
,
NULL
);
if
(
error
<
GIT_SUCCESS
)
return
git__rethrow
(
error
,
"Failed to open repository"
);
}
...
...
@@ -92,7 +95,7 @@ static int assign_repository_dirs(
if
(
git_work_tree
==
NULL
)
repo
->
is_bare
=
1
;
else
{
error
=
gitfo_prettify_dir_path
(
path_aux
,
sizeof
(
path_aux
),
git_work_tree
);
error
=
gitfo_prettify_dir_path
(
path_aux
,
sizeof
(
path_aux
),
git_work_tree
,
NULL
);
if
(
error
<
GIT_SUCCESS
)
return
git__rethrow
(
error
,
"Failed to open repository"
);
...
...
@@ -105,7 +108,7 @@ static int assign_repository_dirs(
if
(
git_index_file
==
NULL
)
git__joinpath
(
path_aux
,
repo
->
path_repository
,
GIT_INDEX_FILE
);
else
{
error
=
gitfo_prettify_file_path
(
path_aux
,
sizeof
(
path_aux
),
git_index_file
);
error
=
gitfo_prettify_file_path
(
path_aux
,
sizeof
(
path_aux
),
git_index_file
,
NULL
);
if
(
error
<
GIT_SUCCESS
)
return
git__rethrow
(
error
,
"Failed to open repository"
);
}
...
...
@@ -268,6 +271,21 @@ cleanup:
return
git__rethrow
(
error
,
"Failed to open repository"
);
}
static
int
discover_repository_dirs
(
git_repository
*
repo
,
const
char
*
path
)
{
int
error
;
error
=
guess_repository_dirs
(
repo
,
path
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
error
=
check_repository_dirs
(
repo
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
return
GIT_SUCCESS
;
}
int
git_repository_open
(
git_repository
**
repo_out
,
const
char
*
path
)
{
git_repository
*
repo
;
...
...
@@ -279,11 +297,7 @@ int git_repository_open(git_repository **repo_out, const char *path)
if
(
repo
==
NULL
)
return
GIT_ENOMEM
;
error
=
guess_repository_dirs
(
repo
,
path
);
if
(
error
<
GIT_SUCCESS
)
goto
cleanup
;
error
=
check_repository_dirs
(
repo
);
error
=
discover_repository_dirs
(
repo
,
path
);
if
(
error
<
GIT_SUCCESS
)
goto
cleanup
;
...
...
@@ -299,18 +313,137 @@ cleanup:
return
git__rethrow
(
error
,
"Failed to open repository"
);
}
void
git_repository_free
(
git_repository
*
repo
)
static
int
abspath
(
char
*
buffer_out
,
size_t
size
,
const
char
*
path
)
{
if
(
repo
==
NULL
)
return
;
assert
(
buffer_out
&&
size
>=
GIT_PATH_MAX
);
git_cache_free
(
&
repo
->
objects
);
git_repository__refcache_free
(
&
repo
->
references
);
#ifdef GIT_WIN32
if
(
_fullpath
(
buffer_out
,
path
,
size
)
==
NULL
)
return
git__throw
(
GIT_EOSERR
,
"Failed to retrieve real path: %s causing errors"
,
buffer_out
);
#else
if
(
realpath
(
path
,
buffer_out
)
==
NULL
)
return
git__throw
(
GIT_EOSERR
,
"Failed to retrieve real path: %s causing errors"
,
buffer_out
);
#endif
gitfo_posixify_path
(
buffer_out
);
return
GIT_SUCCESS
;
}
static
dev_t
retrieve_device
(
dev_t
*
device_out
,
const
char
*
path
)
{
struct
stat
path_info
;
assert
(
device_out
);
if
(
gitfo_stat
(
path
,
&
path_info
))
return
git__throw
(
GIT_EOSERR
,
"Failed to get file informations: %s"
,
path
);
*
device_out
=
path_info
.
st_dev
;
return
GIT_SUCCESS
;
}
static
int
retrieve_ceiling_directories_offset
(
const
char
*
path
,
const
char
*
ceiling_directories
)
{
char
buf
[
GIT_PATH_MAX
+
1
];
char
buf2
[
GIT_PATH_MAX
+
1
];
const
char
*
ceil
,
*
sep
;
int
len
,
max_len
=
-
1
;
int
min_len
;
assert
(
path
);
min_len
=
gitfo_retrieve_path_root_offset
(
path
)
+
1
;
if
(
ceiling_directories
==
NULL
||
min_len
==
0
)
return
min_len
;
for
(
sep
=
ceil
=
ceiling_directories
;
*
sep
;
ceil
=
sep
+
1
)
{
for
(
sep
=
ceil
;
*
sep
&&
*
sep
!=
GIT_PATH_LIST_SEPARATOR
;
sep
++
);
len
=
sep
-
ceil
;
if
(
len
==
0
||
len
>
GIT_PATH_MAX
||
gitfo_retrieve_path_root_offset
(
ceil
)
==
-
1
)
continue
;
strncpy
(
buf
,
ceil
,
len
);
buf
[
len
]
=
'\0'
;
gitfo_posixify_path
(
buf
);
if
(
gitfo_prettify_dir_path
(
buf2
,
sizeof
(
buf2
),
buf
,
NULL
)
<
GIT_SUCCESS
)
continue
;
len
=
strlen
(
buf2
);
if
(
len
>
0
&&
buf2
[
len
-
1
]
==
'/'
)
buf
[
--
len
]
=
'\0'
;
if
(
!
strncmp
(
path
,
buf2
,
len
)
&&
path
[
len
]
==
'/'
&&
len
>
max_len
)
{
max_len
=
len
;
}
}
return
max_len
<=
min_len
?
min_len
:
max_len
;
}
static
int
read_gitfile
(
char
*
path_out
,
size_t
size
,
const
char
*
file_path
,
const
char
*
base_path
)
{
gitfo_buf
file
;
int
error
,
end_offset
;
char
*
data
;
assert
(
file_path
&&
path_out
&&
size
>
0
);
error
=
gitfo_read_file
(
&
file
,
file_path
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
data
=
(
char
*
)(
file
.
data
);
if
(
git__prefixcmp
(
data
,
GIT_FILE_CONTENT_PREFIX
))
{
gitfo_free_buf
(
&
file
);
return
git__throw
(
GIT_ENOTFOUND
,
"Invalid gitfile format `%s`"
,
file_path
);
}
end_offset
=
strlen
(
data
)
-
1
;
for
(;
data
[
end_offset
]
!=
'\r'
&&
data
[
end_offset
]
!=
'\n'
;
--
end_offset
);
data
[
end_offset
]
=
'\0'
;
if
(
GIT_FILE_CONTENT_PREFIX_LENGTH
==
end_offset
)
{
gitfo_free_buf
(
&
file
);
return
git__throw
(
GIT_ENOTFOUND
,
"No path in git file `%s`"
,
file_path
);
}
error
=
gitfo_prettify_dir_path
(
path_out
,
size
,
data
+
GIT_FILE_CONTENT_PREFIX_LENGTH
,
base_path
);
gitfo_free_buf
(
&
file
);
return
error
;
}
static
void
git_repository__free_dirs
(
git_repository
*
repo
)
{
free
(
repo
->
path_workdir
);
repo
->
path_workdir
=
NULL
;
free
(
repo
->
path_index
);
repo
->
path_index
=
NULL
;
free
(
repo
->
path_repository
);
repo
->
path_repository
=
NULL
;
free
(
repo
->
path_odb
);
repo
->
path_odb
=
NULL
;
}
void
git_repository_free
(
git_repository
*
repo
)
{
if
(
repo
==
NULL
)
return
;
git_cache_free
(
&
repo
->
objects
);
git_repository__refcache_free
(
&
repo
->
references
);
git_repository__free_dirs
(
repo
);
if
(
repo
->
db
!=
NULL
)
git_odb_close
(
repo
->
db
);
...
...
@@ -318,6 +451,119 @@ void git_repository_free(git_repository *repo)
free
(
repo
);
}
int
git_repository_discover
(
char
*
repository_path
,
size_t
size
,
const
char
*
start_path
,
int
across_fs
,
const
char
*
ceiling_dirs
)
{
git_repository
repo
;
int
error
,
ceiling_offset
;
char
bare_path
[
GIT_PATH_MAX
];
char
normal_path
[
GIT_PATH_MAX
];
char
*
found_path
;
dev_t
current_device
;
assert
(
start_path
&&
repository_path
);
memset
(
&
repo
,
0x0
,
sizeof
(
git_repository
));
error
=
abspath
(
bare_path
,
sizeof
(
bare_path
),
start_path
);
if
(
error
<
GIT_SUCCESS
)
goto
cleanup
;
if
(
!
across_fs
)
{
error
=
retrieve_device
(
&
current_device
,
bare_path
);
if
(
error
<
GIT_SUCCESS
)
goto
cleanup
;
}
ceiling_offset
=
retrieve_ceiling_directories_offset
(
bare_path
,
ceiling_dirs
);
git__joinpath
(
normal_path
,
bare_path
,
DOT_GIT
);
while
(
1
){
//look for .git file
if
(
gitfo_isfile
(
normal_path
)
==
GIT_SUCCESS
)
{
error
=
read_gitfile
(
repository_path
,
size
,
normal_path
,
bare_path
);
if
(
error
<
GIT_SUCCESS
)
{
git__rethrow
(
error
,
"Unable to read git file `%s`"
,
normal_path
);
goto
cleanup
;
}
error
=
discover_repository_dirs
(
&
repo
,
repository_path
);
if
(
error
<
GIT_SUCCESS
)
goto
cleanup
;
git_repository__free_dirs
(
&
repo
);
return
GIT_SUCCESS
;
}
//look for .git repository
error
=
discover_repository_dirs
(
&
repo
,
normal_path
);
if
(
error
<
GIT_SUCCESS
&&
error
!=
GIT_ENOTAREPO
)
goto
cleanup
;
if
(
error
==
GIT_SUCCESS
)
{
found_path
=
normal_path
;
break
;
}
git_repository__free_dirs
(
&
repo
);
//look for bare repository in current directory
error
=
discover_repository_dirs
(
&
repo
,
bare_path
);
if
(
error
<
GIT_SUCCESS
&&
error
!=
GIT_ENOTAREPO
)
goto
cleanup
;
if
(
error
==
GIT_SUCCESS
)
{
found_path
=
bare_path
;
break
;
}
git_repository__free_dirs
(
&
repo
);
//nothing has been found, lets try the parent directory
if
(
bare_path
[
ceiling_offset
]
==
'\0'
)
{
error
=
git__throw
(
GIT_ENOTAREPO
,
"Not a git repository (or any of the parent directories): %s"
,
start_path
);
goto
cleanup
;
}
if
(
git__dirname_r
(
normal_path
,
sizeof
(
normal_path
),
bare_path
)
<
GIT_SUCCESS
)
goto
cleanup
;
if
(
!
across_fs
)
{
dev_t
new_device
;
error
=
retrieve_device
(
&
new_device
,
normal_path
);
if
(
error
<
GIT_SUCCESS
)
goto
cleanup
;
if
(
current_device
!=
new_device
)
{
error
=
git__throw
(
GIT_ENOTAREPO
,
"Not a git repository (or any parent up to mount parent %s)
\n
"
"Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM_ENVIRONMENT not set)."
,
bare_path
);
goto
cleanup
;
}
current_device
=
new_device
;
}
strcpy
(
bare_path
,
normal_path
);
git__joinpath
(
normal_path
,
bare_path
,
DOT_GIT
);
}
if
(
size
<
(
strlen
(
found_path
)
+
1
)
*
sizeof
(
char
))
{
error
=
git__throw
(
GIT_EOVERFLOW
,
"The repository buffer is not long enough to handle the repository path `%s`"
,
found_path
);
goto
cleanup
;
}
strcpy
(
repository_path
,
found_path
);
git_repository__free_dirs
(
&
repo
);
return
GIT_SUCCESS
;
cleanup:
git_repository__free_dirs
(
&
repo
);
return
git__rethrow
(
error
,
"Failed to discover repository"
);
}
git_odb
*
git_repository_database
(
git_repository
*
repo
)
{
assert
(
repo
);
...
...
@@ -390,7 +636,7 @@ static int repo_init_find_dir(repo_init *results, const char* path)
char
temp_path
[
GIT_PATH_MAX
];
int
error
=
GIT_SUCCESS
;
error
=
gitfo_prettify_dir_path
(
temp_path
,
sizeof
(
temp_path
),
path
);
error
=
gitfo_prettify_dir_path
(
temp_path
,
sizeof
(
temp_path
),
path
,
NULL
);
if
(
error
<
GIT_SUCCESS
)
return
git__rethrow
(
error
,
"Failed to find directory to initialize repository"
);
...
...
src/sha1_lookup.c
View file @
793545ef
...
...
@@ -97,7 +97,7 @@ int sha1_entry_pos(const void *table,
unsigned
lo
,
unsigned
hi
,
unsigned
nr
,
const
unsigned
char
*
key
)
{
const
unsigned
char
*
base
=
table
;
const
unsigned
char
*
base
=
(
const
unsigned
char
*
)
table
;
const
unsigned
char
*
hi_key
,
*
lo_key
;
unsigned
ofs_0
;
...
...
@@ -192,5 +192,5 @@ int sha1_entry_pos(const void *table,
lo_key
=
mi_key
+
elem_size
;
}
}
while
(
lo
<
hi
);
return
-
lo
-
1
;
return
-
((
int
)
lo
)
-
1
;
}
tests/t00-core.c
View file @
793545ef
...
...
@@ -151,7 +151,7 @@ BEGIN_TEST(path2, "get the latest component in a path")
#undef TOPDIR_TEST
END_TEST
typedef
int
(
normalize_path
)(
char
*
,
size_t
,
const
char
*
);
typedef
int
(
normalize_path
)(
char
*
,
size_t
,
const
char
*
,
const
char
*
);
/* Assert flags */
#define CWD_AS_PREFIX 1
...
...
@@ -168,7 +168,7 @@ static int ensure_normalized(const char *input_path, const char *expected_path,
if
(
error
<
GIT_SUCCESS
)
return
error
;
error
=
normalizer
(
buffer_out
,
sizeof
(
buffer_out
),
input_path
);
error
=
normalizer
(
buffer_out
,
sizeof
(
buffer_out
),
input_path
,
NULL
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
...
...
@@ -417,7 +417,7 @@ BEGIN_TEST(path7, "prevent a path which escapes the root directory from being pr
for
(
i
=
0
;
i
<
number_to_escape
+
1
;
i
++
)
git__joinpath
(
current_workdir
,
current_workdir
,
"../"
);
must_fail
(
gitfo_prettify_dir_path
(
prettified
,
sizeof
(
prettified
),
current_workdir
));
must_fail
(
gitfo_prettify_dir_path
(
prettified
,
sizeof
(
prettified
),
current_workdir
,
NULL
));
END_TEST
typedef
struct
name_data
{
...
...
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