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
4e6e2ff2
Commit
4e6e2ff2
authored
May 30, 2013
by
Vicent Marti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...Aaaand this works
parent
ec24e542
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
194 additions
and
404 deletions
+194
-404
include/git2/refs.h
+1
-6
include/git2/sys/refdb_backend.h
+7
-2
src/branch.c
+8
-5
src/refdb.c
+30
-4
src/refdb.h
+9
-2
src/refdb_fs.c
+116
-20
src/refs.c
+22
-170
src/remote.c
+1
-4
tests-clar/refdb/testdb.c
+0
-182
tests-clar/refdb/testdb.h
+0
-9
No files found.
include/git2/refs.h
View file @
4e6e2ff2
...
@@ -257,11 +257,6 @@ GIT_EXTERN(int) git_reference_set_target(
...
@@ -257,11 +257,6 @@ GIT_EXTERN(int) git_reference_set_target(
* The new name will be checked for validity.
* The new name will be checked for validity.
* See `git_reference_create_symbolic()` for rules about valid names.
* See `git_reference_create_symbolic()` for rules about valid names.
*
*
* On success, the given git_reference will be deleted from disk and a
* new `git_reference` will be returned.
*
* The reference will be immediately renamed in-memory and on disk.
*
* If the `force` flag is not enabled, and there's already
* If the `force` flag is not enabled, and there's already
* a reference with the given name, the renaming will fail.
* a reference with the given name, the renaming will fail.
*
*
...
@@ -277,7 +272,7 @@ GIT_EXTERN(int) git_reference_set_target(
...
@@ -277,7 +272,7 @@ GIT_EXTERN(int) git_reference_set_target(
*
*
*/
*/
GIT_EXTERN
(
int
)
git_reference_rename
(
GIT_EXTERN
(
int
)
git_reference_rename
(
git_reference
**
out
,
git_reference
**
new_ref
,
git_reference
*
ref
,
git_reference
*
ref
,
const
char
*
new_name
,
const
char
*
new_name
,
int
force
);
int
force
);
...
...
include/git2/sys/refdb_backend.h
View file @
4e6e2ff2
...
@@ -92,13 +92,18 @@ struct git_refdb_backend {
...
@@ -92,13 +92,18 @@ struct git_refdb_backend {
* Writes the given reference to the refdb. A refdb implementation
* Writes the given reference to the refdb. A refdb implementation
* must provide this function.
* must provide this function.
*/
*/
int
(
*
write
)(
git_refdb_backend
*
backend
,
const
git_reference
*
ref
);
int
(
*
write
)(
git_refdb_backend
*
backend
,
const
git_reference
*
ref
,
int
force
);
int
(
*
rename
)(
git_reference
**
out
,
git_refdb_backend
*
backend
,
const
char
*
old_name
,
const
char
*
new_name
,
int
force
);
/**
/**
* Deletes the given reference from the refdb. A refdb implementation
* Deletes the given reference from the refdb. A refdb implementation
* must provide this function.
* must provide this function.
*/
*/
int
(
*
delete
)(
git_refdb_backend
*
backend
,
const
git_reference
*
ref
);
int
(
*
delete
)(
git_refdb_backend
*
backend
,
const
char
*
ref_name
);
/**
/**
* Suggests that the given refdb compress or optimize its references.
* Suggests that the given refdb compress or optimize its references.
...
...
src/branch.c
View file @
4e6e2ff2
...
@@ -182,18 +182,21 @@ int git_branch_move(
...
@@ -182,18 +182,21 @@ int git_branch_move(
if
(
!
git_reference_is_branch
(
branch
))
if
(
!
git_reference_is_branch
(
branch
))
return
not_a_local_branch
(
git_reference_name
(
branch
));
return
not_a_local_branch
(
git_reference_name
(
branch
));
if
((
error
=
git_buf_joinpath
(
&
new_reference_name
,
GIT_REFS_HEADS_DIR
,
new_branch_name
))
<
0
||
error
=
git_buf_joinpath
(
&
new_reference_name
,
GIT_REFS_HEADS_DIR
,
new_branch_name
);
(
error
=
git_buf_printf
(
&
old_config_section
,
"branch.%s"
,
git_reference_name
(
branch
)
+
strlen
(
GIT_REFS_HEADS_DIR
)))
<
0
||
if
(
error
<
0
)
(
error
=
git_buf_printf
(
&
new_config_section
,
"branch.%s"
,
new_branch_name
))
<
0
)
goto
done
;
goto
done
;
git_buf_printf
(
&
old_config_section
,
"branch.%s"
,
git_reference_name
(
branch
)
+
strlen
(
GIT_REFS_HEADS_DIR
));
git_buf_printf
(
&
new_config_section
,
"branch.%s"
,
new_branch_name
);
if
((
error
=
git_config_rename_section
(
git_reference_owner
(
branch
),
if
((
error
=
git_config_rename_section
(
git_reference_owner
(
branch
),
git_buf_cstr
(
&
old_config_section
),
git_buf_cstr
(
&
old_config_section
),
git_buf_cstr
(
&
new_config_section
)))
<
0
)
git_buf_cstr
(
&
new_config_section
)))
<
0
)
goto
done
;
goto
done
;
if
((
error
=
git_reference_rename
(
out
,
branch
,
git_buf_cstr
(
&
new_reference_name
),
force
))
<
0
)
error
=
git_reference_rename
(
out
,
branch
,
git_buf_cstr
(
&
new_reference_name
),
force
);
goto
done
;
done:
done:
git_buf_free
(
&
new_reference_name
);
git_buf_free
(
&
new_reference_name
);
...
...
src/refdb.c
View file @
4e6e2ff2
...
@@ -165,14 +165,40 @@ void git_refdb_iterator_free(git_reference_iterator *iter)
...
@@ -165,14 +165,40 @@ void git_refdb_iterator_free(git_reference_iterator *iter)
iter
->
free
(
iter
);
iter
->
free
(
iter
);
}
}
int
git_refdb_write
(
git_refdb
*
db
,
const
git_reference
*
ref
)
int
git_refdb_write
(
git_refdb
*
db
,
git_reference
*
ref
,
int
force
)
{
{
assert
(
db
&&
db
->
backend
);
assert
(
db
&&
db
->
backend
);
return
db
->
backend
->
write
(
db
->
backend
,
ref
);
GIT_REFCOUNT_INC
(
db
);
ref
->
db
=
db
;
return
db
->
backend
->
write
(
db
->
backend
,
ref
,
force
);
}
int
git_refdb_rename
(
git_reference
**
out
,
git_refdb
*
db
,
const
char
*
old_name
,
const
char
*
new_name
,
int
force
)
{
int
error
;
assert
(
db
&&
db
->
backend
);
error
=
db
->
backend
->
rename
(
out
,
db
->
backend
,
old_name
,
new_name
,
force
);
if
(
error
<
0
)
return
error
;
if
(
out
)
{
GIT_REFCOUNT_INC
(
db
);
(
*
out
)
->
db
=
db
;
}
return
0
;
}
}
int
git_refdb_delete
(
struct
git_refdb
*
db
,
const
git_reference
*
ref
)
int
git_refdb_delete
(
struct
git_refdb
*
db
,
const
char
*
ref_name
)
{
{
assert
(
db
&&
db
->
backend
);
assert
(
db
&&
db
->
backend
);
return
db
->
backend
->
delete
(
db
->
backend
,
ref
);
return
db
->
backend
->
delete
(
db
->
backend
,
ref
_name
);
}
}
src/refdb.h
View file @
4e6e2ff2
...
@@ -26,12 +26,19 @@ int git_refdb_lookup(
...
@@ -26,12 +26,19 @@ int git_refdb_lookup(
git_refdb
*
refdb
,
git_refdb
*
refdb
,
const
char
*
ref_name
);
const
char
*
ref_name
);
int
git_refdb_rename
(
git_reference
**
out
,
git_refdb
*
db
,
const
char
*
old_name
,
const
char
*
new_name
,
int
force
);
int
git_refdb_iterator
(
git_reference_iterator
**
out
,
git_refdb
*
db
,
const
char
*
glob
);
int
git_refdb_iterator
(
git_reference_iterator
**
out
,
git_refdb
*
db
,
const
char
*
glob
);
int
git_refdb_iterator_next
(
git_reference
**
out
,
git_reference_iterator
*
iter
);
int
git_refdb_iterator_next
(
git_reference
**
out
,
git_reference_iterator
*
iter
);
int
git_refdb_iterator_next_name
(
const
char
**
out
,
git_reference_iterator
*
iter
);
int
git_refdb_iterator_next_name
(
const
char
**
out
,
git_reference_iterator
*
iter
);
void
git_refdb_iterator_free
(
git_reference_iterator
*
iter
);
void
git_refdb_iterator_free
(
git_reference_iterator
*
iter
);
int
git_refdb_write
(
git_refdb
*
refdb
,
const
git_reference
*
ref
);
int
git_refdb_write
(
git_refdb
*
refdb
,
git_reference
*
ref
,
int
force
);
int
git_refdb_delete
(
git_refdb
*
refdb
,
const
git_reference
*
ref
);
int
git_refdb_delete
(
git_refdb
*
refdb
,
const
char
*
ref_name
);
#endif
#endif
src/refdb_fs.c
View file @
4e6e2ff2
...
@@ -116,11 +116,8 @@ static int packed_parse_oid(
...
@@ -116,11 +116,8 @@ static int packed_parse_oid(
git_oid_cpy
(
&
ref
->
oid
,
&
id
);
git_oid_cpy
(
&
ref
->
oid
,
&
id
);
ref
->
flags
=
0
;
*
ref_out
=
ref
;
*
ref_out
=
ref
;
*
buffer_out
=
refname_end
+
1
;
*
buffer_out
=
refname_end
+
1
;
return
0
;
return
0
;
corrupt:
corrupt:
...
@@ -735,6 +732,58 @@ static int refdb_fs_backend__iterator(
...
@@ -735,6 +732,58 @@ static int refdb_fs_backend__iterator(
return
0
;
return
0
;
}
}
static
bool
ref_is_available
(
const
char
*
old_ref
,
const
char
*
new_ref
,
const
char
*
this_ref
)
{
if
(
old_ref
==
NULL
||
strcmp
(
old_ref
,
this_ref
))
{
size_t
reflen
=
strlen
(
this_ref
);
size_t
newlen
=
strlen
(
new_ref
);
size_t
cmplen
=
reflen
<
newlen
?
reflen
:
newlen
;
const
char
*
lead
=
reflen
<
newlen
?
new_ref
:
this_ref
;
if
(
!
strncmp
(
new_ref
,
this_ref
,
cmplen
)
&&
lead
[
cmplen
]
==
'/'
)
{
return
false
;
}
}
return
true
;
}
static
int
reference_path_available
(
refdb_fs_backend
*
backend
,
const
char
*
new_ref
,
const
char
*
old_ref
,
int
force
)
{
struct
packref
*
this_ref
;
if
(
packed_load
(
backend
)
<
0
)
return
-
1
;
if
(
!
force
)
{
int
exists
;
if
(
refdb_fs_backend__exists
(
&
exists
,
(
git_refdb_backend
*
)
backend
,
new_ref
)
<
0
)
return
-
1
;
if
(
exists
)
{
giterr_set
(
GITERR_REFERENCE
,
"Failed to write reference '%s': a reference with "
" that name already exists."
,
new_ref
);
return
GIT_EEXISTS
;
}
}
git_strmap_foreach_value
(
backend
->
refcache
.
packfile
,
this_ref
,
{
if
(
!
ref_is_available
(
old_ref
,
new_ref
,
this_ref
->
name
))
{
giterr_set
(
GITERR_REFERENCE
,
"The path to reference '%s' collides with an existing one"
,
new_ref
);
return
-
1
;
}
});
return
0
;
}
static
int
loose_write
(
refdb_fs_backend
*
backend
,
const
git_reference
*
ref
)
static
int
loose_write
(
refdb_fs_backend
*
backend
,
const
git_reference
*
ref
)
{
{
...
@@ -744,8 +793,7 @@ static int loose_write(refdb_fs_backend *backend, const git_reference *ref)
...
@@ -744,8 +793,7 @@ static int loose_write(refdb_fs_backend *backend, const git_reference *ref)
/* Remove a possibly existing empty directory hierarchy
/* Remove a possibly existing empty directory hierarchy
* which name would collide with the reference name
* which name would collide with the reference name
*/
*/
if
(
git_futils_rmdir_r
(
ref
->
name
,
backend
->
path
,
if
(
git_futils_rmdir_r
(
ref
->
name
,
backend
->
path
,
GIT_RMDIR_SKIP_NONEMPTY
)
<
0
)
GIT_RMDIR_SKIP_NONEMPTY
)
<
0
)
return
-
1
;
return
-
1
;
if
(
git_buf_joinpath
(
&
ref_path
,
backend
->
path
,
ref
->
name
)
<
0
)
if
(
git_buf_joinpath
(
&
ref_path
,
backend
->
path
,
ref
->
name
)
<
0
)
...
@@ -1005,37 +1053,40 @@ cleanup_memory:
...
@@ -1005,37 +1053,40 @@ cleanup_memory:
static
int
refdb_fs_backend__write
(
static
int
refdb_fs_backend__write
(
git_refdb_backend
*
_backend
,
git_refdb_backend
*
_backend
,
const
git_reference
*
ref
)
const
git_reference
*
ref
,
int
force
)
{
{
refdb_fs_backend
*
backend
;
refdb_fs_backend
*
backend
;
int
error
;
assert
(
_backend
);
assert
(
_backend
);
backend
=
(
refdb_fs_backend
*
)
_backend
;
backend
=
(
refdb_fs_backend
*
)
_backend
;
error
=
reference_path_available
(
backend
,
ref
->
name
,
NULL
,
force
);
if
(
error
<
0
)
return
error
;
return
loose_write
(
backend
,
ref
);
return
loose_write
(
backend
,
ref
);
}
}
static
int
refdb_fs_backend__delete
(
static
int
refdb_fs_backend__delete
(
git_refdb_backend
*
_backend
,
git_refdb_backend
*
_backend
,
const
git_reference
*
ref
)
const
char
*
ref_name
)
{
{
refdb_fs_backend
*
backend
;
refdb_fs_backend
*
backend
;
git_repository
*
repo
;
git_buf
loose_path
=
GIT_BUF_INIT
;
git_buf
loose_path
=
GIT_BUF_INIT
;
struct
packref
*
pack_ref
;
struct
packref
*
pack_ref
;
khiter_t
pack_ref_pos
;
khiter_t
pack_ref_pos
;
int
error
=
0
,
pack_error
;
int
error
=
0
;
bool
loose_deleted
=
0
;
bool
loose_deleted
=
0
;
assert
(
_backend
);
assert
(
_backend
);
assert
(
ref
);
assert
(
ref
_name
);
backend
=
(
refdb_fs_backend
*
)
_backend
;
backend
=
(
refdb_fs_backend
*
)
_backend
;
repo
=
backend
->
repo
;
/* If a loose reference exists, remove it from the filesystem */
/* If a loose reference exists, remove it from the filesystem */
if
(
git_buf_joinpath
(
&
loose_path
,
backend
->
path
,
ref_name
)
<
0
)
if
(
git_buf_joinpath
(
&
loose_path
,
repo
->
path_repository
,
ref
->
name
)
<
0
)
return
-
1
;
return
-
1
;
if
(
git_path_isfile
(
loose_path
.
ptr
))
{
if
(
git_path_isfile
(
loose_path
.
ptr
))
{
...
@@ -1049,22 +1100,66 @@ static int refdb_fs_backend__delete(
...
@@ -1049,22 +1100,66 @@ static int refdb_fs_backend__delete(
return
error
;
return
error
;
/* If a packed reference exists, remove it from the packfile and repack */
/* If a packed reference exists, remove it from the packfile and repack */
error
=
packed_map_entry
(
&
pack_ref
,
&
pack_ref_pos
,
backend
,
ref_name
);
if
(
error
==
GIT_ENOTFOUND
)
return
loose_deleted
?
0
:
GIT_ENOTFOUND
;
if
(
(
pack_error
=
packed_map_entry
(
&
pack_ref
,
&
pack_ref_pos
,
backend
,
ref
->
name
))
==
0
)
{
if
(
error
==
0
)
{
git_strmap_delete_at
(
backend
->
refcache
.
packfile
,
pack_ref_pos
);
git_strmap_delete_at
(
backend
->
refcache
.
packfile
,
pack_ref_pos
);
git__free
(
pack_ref
);
git__free
(
pack_ref
);
error
=
packed_write
(
backend
);
error
=
packed_write
(
backend
);
}
}
if
(
pack_error
==
GIT_ENOTFOUND
)
error
=
loose_deleted
?
0
:
GIT_ENOTFOUND
;
else
error
=
pack_error
;
return
error
;
return
error
;
}
}
static
int
refdb_fs_backend__rename
(
git_reference
**
out
,
git_refdb_backend
*
_backend
,
const
char
*
old_name
,
const
char
*
new_name
,
int
force
)
{
refdb_fs_backend
*
backend
;
git_reference
*
old
,
*
new
;
int
error
;
assert
(
_backend
);
backend
=
(
refdb_fs_backend
*
)
_backend
;
error
=
reference_path_available
(
backend
,
new_name
,
old_name
,
force
);
if
(
error
<
0
)
return
error
;
error
=
refdb_fs_backend__lookup
(
&
old
,
_backend
,
old_name
);
if
(
error
<
0
)
return
error
;
error
=
refdb_fs_backend__delete
(
_backend
,
old_name
);
if
(
error
<
0
)
{
git_reference_free
(
old
);
return
error
;
}
new
=
realloc
(
old
,
sizeof
(
git_reference
)
+
strlen
(
new_name
)
+
1
);
memcpy
(
new
->
name
,
new_name
,
strlen
(
new_name
)
+
1
);
error
=
loose_write
(
backend
,
new
);
if
(
error
<
0
)
{
git_reference_free
(
new
);
return
error
;
}
if
(
out
)
{
*
out
=
new
;
}
else
{
git_reference_free
(
new
);
}
return
0
;
}
static
int
refdb_fs_backend__compress
(
git_refdb_backend
*
_backend
)
static
int
refdb_fs_backend__compress
(
git_refdb_backend
*
_backend
)
{
{
refdb_fs_backend
*
backend
;
refdb_fs_backend
*
backend
;
...
@@ -1172,6 +1267,7 @@ int git_refdb_backend_fs(
...
@@ -1172,6 +1267,7 @@ int git_refdb_backend_fs(
backend
->
parent
.
iterator
=
&
refdb_fs_backend__iterator
;
backend
->
parent
.
iterator
=
&
refdb_fs_backend__iterator
;
backend
->
parent
.
write
=
&
refdb_fs_backend__write
;
backend
->
parent
.
write
=
&
refdb_fs_backend__write
;
backend
->
parent
.
delete
=
&
refdb_fs_backend__delete
;
backend
->
parent
.
delete
=
&
refdb_fs_backend__delete
;
backend
->
parent
.
rename
=
&
refdb_fs_backend__rename
;
backend
->
parent
.
compress
=
&
refdb_fs_backend__compress
;
backend
->
parent
.
compress
=
&
refdb_fs_backend__compress
;
backend
->
parent
.
free
=
&
refdb_fs_backend__free
;
backend
->
parent
.
free
=
&
refdb_fs_backend__free
;
...
...
src/refs.c
View file @
4e6e2ff2
...
@@ -98,122 +98,9 @@ void git_reference_free(git_reference *reference)
...
@@ -98,122 +98,9 @@ void git_reference_free(git_reference *reference)
git__free
(
reference
);
git__free
(
reference
);
}
}
struct
reference_available_t
{
const
char
*
new_ref
;
const
char
*
old_ref
;
int
available
;
};
static
int
_reference_available_cb
(
const
char
*
refname
,
void
*
data
)
{
struct
reference_available_t
*
d
;
assert
(
refname
&&
data
);
d
=
(
struct
reference_available_t
*
)
data
;
if
(
!
d
->
old_ref
||
strcmp
(
d
->
old_ref
,
refname
))
{
size_t
reflen
=
strlen
(
refname
);
size_t
newlen
=
strlen
(
d
->
new_ref
);
size_t
cmplen
=
reflen
<
newlen
?
reflen
:
newlen
;
const
char
*
lead
=
reflen
<
newlen
?
d
->
new_ref
:
refname
;
if
(
!
strncmp
(
d
->
new_ref
,
refname
,
cmplen
)
&&
lead
[
cmplen
]
==
'/'
)
{
d
->
available
=
0
;
return
-
1
;
}
}
return
0
;
}
/**
* TODO: this should be part of the FS backend
*/
static
int
reference_path_available
(
git_repository
*
repo
,
const
char
*
ref
,
const
char
*
old_ref
)
{
int
error
;
struct
reference_available_t
data
;
data
.
new_ref
=
ref
;
data
.
old_ref
=
old_ref
;
data
.
available
=
1
;
error
=
git_reference_foreach_name
(
repo
,
_reference_available_cb
,
(
void
*
)
&
data
);
if
(
error
<
0
)
return
error
;
if
(
!
data
.
available
)
{
giterr_set
(
GITERR_REFERENCE
,
"The path to reference '%s' collides with an existing one"
,
ref
);
return
-
1
;
}
return
0
;
}
/*
* Check if a reference could be written to disk, based on:
*
* - Whether a reference with the same name already exists,
* and we are allowing or disallowing overwrites
*
* - Whether the name of the reference would collide with
* an existing path
*/
static
int
reference_can_write
(
git_repository
*
repo
,
const
char
*
refname
,
const
char
*
previous_name
,
int
force
)
{
git_refdb
*
refdb
;
if
(
git_repository_refdb__weakptr
(
&
refdb
,
repo
)
<
0
)
return
-
1
;
/* see if the reference shares a path with an existing reference;
* if a path is shared, we cannot create the reference, even when forcing */
if
(
reference_path_available
(
repo
,
refname
,
previous_name
)
<
0
)
return
-
1
;
/* check if the reference actually exists, but only if we are not forcing
* the rename. If we are forcing, it's OK to overwrite */
if
(
!
force
)
{
int
exists
;
if
(
git_refdb_exists
(
&
exists
,
refdb
,
refname
)
<
0
)
return
-
1
;
/* We cannot proceed if the reference already exists and we're not forcing
* the rename; the existing one would be overwritten */
if
(
exists
)
{
giterr_set
(
GITERR_REFERENCE
,
"A reference with that name (%s) already exists"
,
refname
);
return
GIT_EEXISTS
;
}
}
/* FIXME: if the reference exists and we are forcing, do we really need to
* remove the reference first?
*
* Two cases:
*
* - the reference already exists and is loose: not a problem, the file
* gets overwritten on disk
*
* - the reference already exists and is packed: we write a new one as
* loose, which by all means renders the packed one useless
*/
return
0
;
}
int
git_reference_delete
(
git_reference
*
ref
)
int
git_reference_delete
(
git_reference
*
ref
)
{
{
return
git_refdb_delete
(
ref
->
db
,
ref
);
return
git_refdb_delete
(
ref
->
db
,
ref
->
name
);
}
}
int
git_reference_lookup
(
git_reference
**
ref_out
,
int
git_reference_lookup
(
git_reference
**
ref_out
,
...
@@ -420,23 +307,24 @@ static int reference__create(
...
@@ -420,23 +307,24 @@ static int reference__create(
if
(
ref_out
)
if
(
ref_out
)
*
ref_out
=
NULL
;
*
ref_out
=
NULL
;
if
((
error
=
git_reference__normalize_name_lax
(
normalized
,
sizeof
(
normalized
),
name
))
<
0
||
error
=
git_reference__normalize_name_lax
(
normalized
,
sizeof
(
normalized
),
name
);
(
error
=
reference_can_write
(
repo
,
normalized
,
NULL
,
force
))
<
0
||
if
(
error
<
0
)
(
error
=
git_repository_refdb__weakptr
(
&
refdb
,
repo
))
<
0
)
return
error
;
error
=
git_repository_refdb__weakptr
(
&
refdb
,
repo
);
if
(
error
<
0
)
return
error
;
return
error
;
if
(
oid
!=
NULL
)
{
if
(
oid
!=
NULL
)
{
assert
(
symbolic
==
NULL
);
assert
(
symbolic
==
NULL
);
ref
=
git_reference__alloc
(
n
ame
,
oid
,
NULL
);
ref
=
git_reference__alloc
(
n
ormalized
,
oid
,
NULL
);
}
else
{
}
else
{
ref
=
git_reference__alloc_symbolic
(
n
ame
,
symbolic
);
ref
=
git_reference__alloc_symbolic
(
n
ormalized
,
symbolic
);
}
}
/* TODO: this needs to be written more explicitly */
GITERR_CHECK_ALLOC
(
ref
);
GITERR_CHECK_ALLOC
(
ref
);
ref
->
db
=
refdb
;
if
((
error
=
git_refdb_write
(
refdb
,
ref
))
<
0
)
{
if
((
error
=
git_refdb_write
(
refdb
,
ref
,
force
))
<
0
)
{
git_reference_free
(
ref
);
git_reference_free
(
ref
);
return
error
;
return
error
;
}
}
...
@@ -533,77 +421,41 @@ int git_reference_rename(
...
@@ -533,77 +421,41 @@ int git_reference_rename(
unsigned
int
normalization_flags
;
unsigned
int
normalization_flags
;
char
normalized
[
GIT_REFNAME_MAX
];
char
normalized
[
GIT_REFNAME_MAX
];
bool
should_head_be_updated
=
false
;
bool
should_head_be_updated
=
false
;
git_reference
*
result
=
NULL
;
int
error
=
0
;
int
error
=
0
;
int
reference_has_log
;
int
reference_has_log
;
*
out
=
NULL
;
normalization_flags
=
ref
->
type
==
GIT_REF_SYMBOLIC
?
normalization_flags
=
ref
->
type
==
GIT_REF_SYMBOLIC
?
GIT_REF_FORMAT_ALLOW_ONELEVEL
:
GIT_REF_FORMAT_NORMAL
;
GIT_REF_FORMAT_ALLOW_ONELEVEL
:
GIT_REF_FORMAT_NORMAL
;
if
((
error
=
git_reference_normalize_name
(
if
((
error
=
git_reference_normalize_name
(
normalized
,
sizeof
(
normalized
),
new_name
,
normalization_flags
))
<
0
||
normalized
,
sizeof
(
normalized
),
new_name
,
normalization_flags
))
<
0
)
(
error
=
reference_can_write
(
ref
->
db
->
repo
,
normalized
,
ref
->
name
,
force
))
<
0
)
return
error
;
return
error
;
/*
* Create the new reference.
*/
if
(
ref
->
type
==
GIT_REF_OID
)
{
result
=
git_reference__alloc
(
new_name
,
&
ref
->
target
.
oid
,
&
ref
->
peel
);
}
else
if
(
ref
->
type
==
GIT_REF_SYMBOLIC
)
{
result
=
git_reference__alloc_symbolic
(
new_name
,
ref
->
target
.
symbolic
);
}
else
{
assert
(
0
);
}
if
(
result
==
NULL
)
return
-
1
;
/* TODO: this is bad */
result
->
db
=
ref
->
db
;
/* Check if we have to update HEAD. */
/* Check if we have to update HEAD. */
if
((
error
=
git_branch_is_head
(
ref
))
<
0
)
if
((
error
=
git_branch_is_head
(
ref
))
<
0
)
goto
on_
error
;
return
error
;
should_head_be_updated
=
(
error
>
0
);
should_head_be_updated
=
(
error
>
0
);
/* Now delete the old ref and save the new one. */
if
((
error
=
git_refdb_rename
(
out
,
ref
->
db
,
ref
->
name
,
new_name
,
force
))
<
0
)
if
((
error
=
git_refdb_delete
(
ref
->
db
,
ref
))
<
0
)
return
error
;
goto
on_error
;
/* Save the new reference. */
if
((
error
=
git_refdb_write
(
ref
->
db
,
result
))
<
0
)
goto
rollback
;
/* Update HEAD it was poiting to the reference being renamed. */
/* Update HEAD it was poiting to the reference being renamed. */
if
(
should_head_be_updated
&&
(
error
=
git_repository_set_head
(
ref
->
db
->
repo
,
new_name
))
<
0
)
{
if
(
should_head_be_updated
&&
(
error
=
git_repository_set_head
(
ref
->
db
->
repo
,
new_name
))
<
0
)
{
giterr_set
(
GITERR_REFERENCE
,
"Failed to update HEAD after renaming reference"
);
giterr_set
(
GITERR_REFERENCE
,
"Failed to update HEAD after renaming reference"
);
goto
on_
error
;
return
error
;
}
}
/* Rename the reflog file, if it exists. */
/* Rename the reflog file, if it exists. */
reference_has_log
=
git_reference_has_log
(
ref
);
reference_has_log
=
git_reference_has_log
(
ref
);
if
(
reference_has_log
<
0
)
{
if
(
reference_has_log
<
0
)
error
=
reference_has_log
;
return
reference_has_log
;
goto
on_error
;
}
if
(
reference_has_log
&&
(
error
=
git_reflog_rename
(
ref
,
new_name
))
<
0
)
goto
on_error
;
*
out
=
result
;
return
error
;
rollback:
if
(
reference_has_log
&&
(
error
=
git_reflog_rename
(
ref
,
new_name
))
<
0
)
git_refdb_write
(
ref
->
db
,
ref
);
return
error
;
on_error:
git_reference_free
(
result
);
return
error
;
return
0
;
}
}
int
git_reference_resolve
(
git_reference
**
ref_out
,
const
git_reference
*
ref
)
int
git_reference_resolve
(
git_reference
**
ref_out
,
const
git_reference
*
ref
)
...
...
src/remote.c
View file @
4e6e2ff2
...
@@ -1245,7 +1245,6 @@ static int rename_one_remote_reference(
...
@@ -1245,7 +1245,6 @@ static int rename_one_remote_reference(
{
{
int
error
=
-
1
;
int
error
=
-
1
;
git_buf
new_name
=
GIT_BUF_INIT
;
git_buf
new_name
=
GIT_BUF_INIT
;
git_reference
*
newref
=
NULL
;
if
(
git_buf_printf
(
if
(
git_buf_printf
(
&
new_name
,
&
new_name
,
...
@@ -1254,11 +1253,9 @@ static int rename_one_remote_reference(
...
@@ -1254,11 +1253,9 @@ static int rename_one_remote_reference(
reference
->
name
+
strlen
(
GIT_REFS_REMOTES_DIR
)
+
strlen
(
old_remote_name
))
<
0
)
reference
->
name
+
strlen
(
GIT_REFS_REMOTES_DIR
)
+
strlen
(
old_remote_name
))
<
0
)
return
-
1
;
return
-
1
;
/* TODO: can we make this NULL? */
error
=
git_reference_rename
(
NULL
,
reference
,
git_buf_cstr
(
&
new_name
),
0
);
error
=
git_reference_rename
(
&
newref
,
reference
,
git_buf_cstr
(
&
new_name
),
0
);
git_reference_free
(
reference
);
git_reference_free
(
reference
);
git_reference_free
(
newref
);
git_buf_free
(
&
new_name
);
git_buf_free
(
&
new_name
);
return
error
;
return
error
;
}
}
...
...
tests-clar/refdb/testdb.c
deleted
100644 → 0
View file @
ec24e542
#include "vector.h"
#include "util.h"
#include "testdb.h"
typedef
struct
refdb_test_backend
{
git_refdb_backend
parent
;
git_repository
*
repo
;
git_vector
refs
;
}
refdb_test_backend
;
typedef
struct
refdb_test_entry
{
char
*
name
;
git_ref_t
type
;
union
{
git_oid
oid
;
char
*
symbolic
;
}
target
;
}
refdb_test_entry
;
static
int
ref_name_cmp
(
const
void
*
a
,
const
void
*
b
)
{
return
strcmp
(
git_reference_name
((
git_reference
*
)
a
),
git_reference_name
((
git_reference
*
)
b
));
}
static
int
refdb_test_backend__exists
(
int
*
exists
,
git_refdb_backend
*
_backend
,
const
char
*
ref_name
)
{
refdb_test_backend
*
backend
;
refdb_test_entry
*
entry
;
size_t
i
;
assert
(
_backend
);
backend
=
(
refdb_test_backend
*
)
_backend
;
*
exists
=
0
;
git_vector_foreach
(
&
backend
->
refs
,
i
,
entry
)
{
if
(
strcmp
(
entry
->
name
,
ref_name
)
==
0
)
{
*
exists
=
1
;
break
;
}
}
return
0
;
}
static
int
refdb_test_backend__write
(
git_refdb_backend
*
_backend
,
const
git_reference
*
ref
)
{
refdb_test_backend
*
backend
;
refdb_test_entry
*
entry
;
assert
(
_backend
);
backend
=
(
refdb_test_backend
*
)
_backend
;
entry
=
git__calloc
(
1
,
sizeof
(
refdb_test_entry
));
GITERR_CHECK_ALLOC
(
entry
);
entry
->
name
=
git__strdup
(
git_reference_name
(
ref
));
GITERR_CHECK_ALLOC
(
entry
->
name
);
entry
->
type
=
git_reference_type
(
ref
);
if
(
entry
->
type
==
GIT_REF_OID
)
git_oid_cpy
(
&
entry
->
target
.
oid
,
git_reference_target
(
ref
));
else
{
entry
->
target
.
symbolic
=
git__strdup
(
git_reference_symbolic_target
(
ref
));
GITERR_CHECK_ALLOC
(
entry
->
target
.
symbolic
);
}
git_vector_insert
(
&
backend
->
refs
,
entry
);
return
0
;
}
static
int
refdb_test_backend__lookup
(
git_reference
**
out
,
git_refdb_backend
*
_backend
,
const
char
*
ref_name
)
{
refdb_test_backend
*
backend
;
refdb_test_entry
*
entry
;
size_t
i
;
assert
(
_backend
);
backend
=
(
refdb_test_backend
*
)
_backend
;
git_vector_foreach
(
&
backend
->
refs
,
i
,
entry
)
{
if
(
strcmp
(
entry
->
name
,
ref_name
)
==
0
)
{
if
(
entry
->
type
==
GIT_REF_OID
)
{
*
out
=
git_reference__alloc
(
ref_name
,
&
entry
->
target
.
oid
,
NULL
);
}
else
if
(
entry
->
type
==
GIT_REF_SYMBOLIC
)
{
*
out
=
git_reference__alloc_symbolic
(
ref_name
,
entry
->
target
.
symbolic
);
}
if
(
*
out
==
NULL
)
return
-
1
;
return
0
;
}
}
return
GIT_ENOTFOUND
;
}
static
void
refdb_test_entry_free
(
refdb_test_entry
*
entry
)
{
if
(
entry
->
type
==
GIT_REF_SYMBOLIC
)
git__free
(
entry
->
target
.
symbolic
);
git__free
(
entry
->
name
);
git__free
(
entry
);
}
static
int
refdb_test_backend__delete
(
git_refdb_backend
*
_backend
,
const
git_reference
*
ref
)
{
refdb_test_backend
*
backend
;
refdb_test_entry
*
entry
;
size_t
i
;
assert
(
_backend
);
backend
=
(
refdb_test_backend
*
)
_backend
;
git_vector_foreach
(
&
backend
->
refs
,
i
,
entry
)
{
if
(
strcmp
(
entry
->
name
,
git_reference_name
(
ref
))
==
0
)
{
git_vector_remove
(
&
backend
->
refs
,
i
);
refdb_test_entry_free
(
entry
);
}
}
return
GIT_ENOTFOUND
;
}
static
void
refdb_test_backend__free
(
git_refdb_backend
*
_backend
)
{
refdb_test_backend
*
backend
;
refdb_test_entry
*
entry
;
size_t
i
;
assert
(
_backend
);
backend
=
(
refdb_test_backend
*
)
_backend
;
git_vector_foreach
(
&
backend
->
refs
,
i
,
entry
)
refdb_test_entry_free
(
entry
);
git_vector_free
(
&
backend
->
refs
);
git__free
(
backend
);
}
int
refdb_backend_test
(
git_refdb_backend
**
backend_out
,
git_repository
*
repo
)
{
refdb_test_backend
*
backend
;
backend
=
git__calloc
(
1
,
sizeof
(
refdb_test_backend
));
GITERR_CHECK_ALLOC
(
backend
);
git_vector_init
(
&
backend
->
refs
,
0
,
ref_name_cmp
);
backend
->
repo
=
repo
;
backend
->
parent
.
exists
=
&
refdb_test_backend__exists
;
backend
->
parent
.
lookup
=
&
refdb_test_backend__lookup
;
backend
->
parent
.
write
=
&
refdb_test_backend__write
;
backend
->
parent
.
delete
=
&
refdb_test_backend__delete
;
backend
->
parent
.
free
=
&
refdb_test_backend__free
;
*
backend_out
=
(
git_refdb_backend
*
)
backend
;
return
0
;
}
tests-clar/refdb/testdb.h
deleted
100644 → 0
View file @
ec24e542
#include <git2/errors.h>
#include <git2/repository.h>
#include <git2/refdb.h>
#include <git2/sys/refs.h>
#include <git2/sys/refdb_backend.h>
int
refdb_backend_test
(
git_refdb_backend
**
backend_out
,
git_repository
*
repo
);
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