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
ae996e02
Commit
ae996e02
authored
Sep 18, 2011
by
Vicent Martí
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #394 from carlosmn/tree-fromindex
Use git_treebuilder to write the index as a tree
parents
6640266e
4a619797
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
83 additions
and
70 deletions
+83
-70
src/tree.c
+83
-70
No files found.
src/tree.c
View file @
ae996e02
...
...
@@ -201,89 +201,101 @@ int git_tree__parse(git_tree *tree, git_odb_object *obj)
return
tree_parse_buffer
(
tree
,
(
char
*
)
obj
->
raw
.
data
,
(
char
*
)
obj
->
raw
.
data
+
obj
->
raw
.
len
);
}
static
int
write_
index_entry
(
char
*
buffer
,
int
mode
,
const
char
*
path
,
size_t
path_len
,
const
git_oid
*
oid
)
static
int
write_
tree
(
git_oid
*
oid
,
git_index
*
index
,
const
char
*
dirname
,
unsigned
int
start
)
{
int
written
;
written
=
sprintf
(
buffer
,
"%o %.*s%c"
,
mode
,
(
int
)
path_len
,
path
,
0
);
memcpy
(
buffer
+
written
,
&
oid
->
id
,
GIT_OID_RAWSZ
);
return
written
+
GIT_OID_RAWSZ
;
}
git_treebuilder
*
bld
=
NULL
;
unsigned
int
i
,
entries
=
git_index_entrycount
(
index
);
int
error
;
size_t
dirname_len
=
strlen
(
dirname
);
static
int
write_index
(
git_oid
*
oid
,
git_index
*
index
,
const
char
*
base
,
int
baselen
,
int
entry_no
,
int
maxentries
)
{
size_t
size
,
offset
;
char
*
buffer
;
int
nr
,
error
;
/* Guess at some random initial size */
size
=
maxentries
*
40
;
buffer
=
git__malloc
(
size
);
if
(
buffer
==
NULL
)
error
=
git_treebuilder_create
(
&
bld
,
NULL
);
if
(
bld
==
NULL
)
{
return
GIT_ENOMEM
;
}
offset
=
0
;
for
(
nr
=
entry_no
;
nr
<
maxentries
;
++
nr
)
{
git_index_entry
*
entry
=
git_index_get
(
index
,
nr
);
const
char
*
pathname
=
entry
->
path
,
*
filename
,
*
dirname
;
int
pathlen
=
strlen
(
pathname
),
entrylen
;
unsigned
int
write_mode
;
git_oid
subtree_oid
;
git_oid
*
write_oid
;
/* Did we hit the end of the directory? Return how many we wrote */
if
(
baselen
>=
pathlen
||
memcmp
(
base
,
pathname
,
baselen
)
!=
0
)
/*
* This loop is unfortunate, but necessary. The index doesn't have
* any directores, so we need to handle that manually, and we
* need to keep track of the current position.
*/
for
(
i
=
start
;
i
<
entries
;
++
i
)
{
git_index_entry
*
entry
=
git_index_get
(
index
,
i
);
char
*
filename
,
*
next_slash
;
/*
* If we've left our (sub)tree, exit the loop and return. The
* first check is an early out (and security for the
* third). The second check is a simple prefix comparison. The
* third check catches situations where there is a directory
* win32/sys and a file win32mmap.c. Without it, the following
* code believes there is a file win32/mmap.c
*/
if
(
strlen
(
entry
->
path
)
<
dirname_len
||
memcmp
(
entry
->
path
,
dirname
,
dirname_len
)
||
(
dirname_len
>
0
&&
entry
->
path
[
dirname_len
]
!=
'/'
))
{
break
;
}
/* Do we have _further_ subdirectories? */
filename
=
pathname
+
baselen
;
dirname
=
strchr
(
filename
,
'/'
);
write_oid
=
&
entry
->
oid
;
write_mode
=
entry
->
mode
;
if
(
dirname
)
{
int
subdir_written
;
#if 0
if (entry->mode != S_IFDIR) {
free(buffer);
return GIT_EOBJCORRUPTED;
filename
=
entry
->
path
+
dirname_len
;
if
(
*
filename
==
'/'
)
filename
++
;
next_slash
=
strchr
(
filename
,
'/'
);
if
(
next_slash
)
{
git_oid
sub_oid
;
int
written
;
char
*
subdir
,
*
last_comp
;
subdir
=
git__strndup
(
entry
->
path
,
next_slash
-
entry
->
path
);
if
(
subdir
==
NULL
)
{
error
=
GIT_ENOMEM
;
goto
cleanup
;
}
#endif
subdir_written
=
write_index
(
&
subtree_oid
,
index
,
pathname
,
dirname
-
pathname
+
1
,
nr
,
maxentries
);
if
(
subdir_written
<
GIT_SUCCESS
)
{
free
(
buffer
);
return
subdir_written
;
/* Write out the subtree */
written
=
write_tree
(
&
sub_oid
,
index
,
subdir
,
i
);
if
(
written
<
0
)
{
error
=
git__rethrow
(
written
,
"Failed to write subtree %s"
,
subdir
);
}
else
{
i
=
written
-
1
;
/* -1 because of the loop increment */
}
nr
=
subdir_written
-
1
;
/* Now we need to write out the directory entry into this tree.. */
pathlen
=
dirname
-
pathname
;
write_oid
=
&
subtree_oid
;
write_mode
=
S_IFDIR
;
}
entrylen
=
pathlen
-
baselen
;
if
(
offset
+
entrylen
+
32
>
size
)
{
size
=
alloc_nr
(
offset
+
entrylen
+
32
);
buffer
=
git__realloc
(
buffer
,
size
);
if
(
buffer
==
NULL
)
return
GIT_ENOMEM
;
/*
* We need to figure out what we want toinsert
* into this tree. If we're traversing
* deps/zlib/, then we only want to write
* 'zlib' into the tree.
*/
last_comp
=
strrchr
(
subdir
,
'/'
);
if
(
last_comp
)
{
last_comp
++
;
/* Get rid of the '/' */
}
else
{
last_comp
=
subdir
;
}
error
=
git_treebuilder_insert
(
NULL
,
bld
,
last_comp
,
&
sub_oid
,
S_IFDIR
);
free
(
subdir
);
if
(
error
<
GIT_SUCCESS
)
{
error
=
git__rethrow
(
error
,
"Failed to insert dir"
);
goto
cleanup
;
}
}
else
{
error
=
git_treebuilder_insert
(
NULL
,
bld
,
filename
,
&
entry
->
oid
,
entry
->
mode
);
if
(
error
<
GIT_SUCCESS
)
{
error
=
git__rethrow
(
error
,
"Failed to insert file"
);
}
}
offset
+=
write_index_entry
(
buffer
+
offset
,
write_mode
,
filename
,
entrylen
,
write_oid
);
}
error
=
git_odb_write
(
oid
,
index
->
repository
->
db
,
buffer
,
offset
,
GIT_OBJ_TREE
);
free
(
buffer
);
error
=
git_treebuilder_write
(
oid
,
index
->
repository
,
bld
);
if
(
error
<
GIT_SUCCESS
)
error
=
git__rethrow
(
error
,
"Failed to write tree to db"
);
return
(
error
==
GIT_SUCCESS
)
?
nr
:
git__rethrow
(
error
,
"Failed to write index"
);
cleanup:
git_treebuilder_free
(
bld
);
if
(
error
<
GIT_SUCCESS
)
return
error
;
else
return
i
;
}
int
git_tree_create_fromindex
(
git_oid
*
oid
,
git_index
*
index
)
...
...
@@ -293,7 +305,8 @@ int git_tree_create_fromindex(git_oid *oid, git_index *index)
if
(
index
->
repository
==
NULL
)
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
));
/* The tree cache didn't help us */
error
=
write_tree
(
oid
,
index
,
""
,
0
);
return
(
error
<
GIT_SUCCESS
)
?
git__rethrow
(
error
,
"Failed to create tree"
)
:
GIT_SUCCESS
;
}
...
...
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