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)
...
@@ -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
);
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
;
git_treebuilder
*
bld
=
NULL
;
written
=
sprintf
(
buffer
,
"%o %.*s%c"
,
mode
,
(
int
)
path_len
,
path
,
0
);
unsigned
int
i
,
entries
=
git_index_entrycount
(
index
);
memcpy
(
buffer
+
written
,
&
oid
->
id
,
GIT_OID_RAWSZ
);
int
error
;
return
written
+
GIT_OID_RAWSZ
;
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
)
error
=
git_treebuilder_create
(
&
bld
,
NULL
);
{
if
(
bld
==
NULL
)
{
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
)
return
GIT_ENOMEM
;
return
GIT_ENOMEM
;
}
offset
=
0
;
/*
* This loop is unfortunate, but necessary. The index doesn't have
for
(
nr
=
entry_no
;
nr
<
maxentries
;
++
nr
)
{
* any directores, so we need to handle that manually, and we
git_index_entry
*
entry
=
git_index_get
(
index
,
nr
);
* need to keep track of the current position.
*/
const
char
*
pathname
=
entry
->
path
,
*
filename
,
*
dirname
;
for
(
i
=
start
;
i
<
entries
;
++
i
)
{
int
pathlen
=
strlen
(
pathname
),
entrylen
;
git_index_entry
*
entry
=
git_index_get
(
index
,
i
);
char
*
filename
,
*
next_slash
;
unsigned
int
write_mode
;
git_oid
subtree_oid
;
/*
git_oid
*
write_oid
;
* If we've left our (sub)tree, exit the loop and return. The
* first check is an early out (and security for the
/* Did we hit the end of the directory? Return how many we wrote */
* third). The second check is a simple prefix comparison. The
if
(
baselen
>=
pathlen
||
memcmp
(
base
,
pathname
,
baselen
)
!=
0
)
* 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
;
break
;
}
/* Do we have _further_ subdirectories? */
filename
=
entry
->
path
+
dirname_len
;
filename
=
pathname
+
baselen
;
if
(
*
filename
==
'/'
)
dirname
=
strchr
(
filename
,
'/'
);
filename
++
;
next_slash
=
strchr
(
filename
,
'/'
);
write_oid
=
&
entry
->
oid
;
if
(
next_slash
)
{
write_mode
=
entry
->
mode
;
git_oid
sub_oid
;
int
written
;
if
(
dirname
)
{
char
*
subdir
,
*
last_comp
;
int
subdir_written
;
subdir
=
git__strndup
(
entry
->
path
,
next_slash
-
entry
->
path
);
#if 0
if
(
subdir
==
NULL
)
{
if (entry->mode != S_IFDIR) {
error
=
GIT_ENOMEM
;
free(buffer);
goto
cleanup
;
return GIT_EOBJCORRUPTED;
}
}
#endif
subdir_written
=
write_index
(
&
subtree_oid
,
index
,
pathname
,
dirname
-
pathname
+
1
,
nr
,
maxentries
);
if
(
subdir_written
<
GIT_SUCCESS
)
{
/* Write out the subtree */
free
(
buffer
);
written
=
write_tree
(
&
sub_oid
,
index
,
subdir
,
i
);
return
subdir_written
;
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
;
/*
* We need to figure out what we want toinsert
/* Now we need to write out the directory entry into this tree.. */
* into this tree. If we're traversing
pathlen
=
dirname
-
pathname
;
* deps/zlib/, then we only want to write
write_oid
=
&
subtree_oid
;
* 'zlib' into the tree.
write_mode
=
S_IFDIR
;
*/
}
last_comp
=
strrchr
(
subdir
,
'/'
);
if
(
last_comp
)
{
entrylen
=
pathlen
-
baselen
;
last_comp
++
;
/* Get rid of the '/' */
if
(
offset
+
entrylen
+
32
>
size
)
{
}
else
{
size
=
alloc_nr
(
offset
+
entrylen
+
32
);
last_comp
=
subdir
;
buffer
=
git__realloc
(
buffer
,
size
);
}
error
=
git_treebuilder_insert
(
NULL
,
bld
,
last_comp
,
&
sub_oid
,
S_IFDIR
);
if
(
buffer
==
NULL
)
free
(
subdir
);
return
GIT_ENOMEM
;
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
);
error
=
git_treebuilder_write
(
oid
,
index
->
repository
,
bld
);
free
(
buffer
);
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
)
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)
...
@@ -293,7 +305,8 @@ int git_tree_create_fromindex(git_oid *oid, git_index *index)
if
(
index
->
repository
==
NULL
)
if
(
index
->
repository
==
NULL
)
return
git__throw
(
GIT_EBAREINDEX
,
"Failed to create tree. The index file is not backed up by an existing repository"
);
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
;
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