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
dbeca796
Commit
dbeca796
authored
Apr 13, 2012
by
Russell Belfer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove old status implementation
This removes the code for the old status implementation.
parent
e8c3774f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1 additions
and
367 deletions
+1
-367
src/status.c
+1
-367
No files found.
src/status.c
View file @
dbeca796
...
...
@@ -345,316 +345,6 @@ static int status_entry_update_ignore(struct status_entry *e, git_ignores *ignor
return
0
;
}
struct
status_st
{
git_repository
*
repo
;
git_vector
*
vector
;
git_index
*
index
;
git_tree
*
tree
;
git_ignores
*
ignores
;
int
workdir_path_len
;
git_buf
head_tree_relative_path
;
int
head_tree_relative_path_len
;
unsigned
int
tree_position
;
unsigned
int
index_position
;
int
is_dir
:
1
;
};
static
int
retrieve_head_tree
(
git_tree
**
tree_out
,
git_repository
*
repo
)
{
git_reference
*
resolved_head_ref
;
git_commit
*
head_commit
=
NULL
;
git_tree
*
tree
;
int
error
=
0
;
*
tree_out
=
NULL
;
if
((
error
=
git_repository_head
(
&
resolved_head_ref
,
repo
))
<
0
)
{
/* Assume that a situation where HEAD exists but can not be resolved
* is valid. A new repository fits this description for instance.
*/
if
(
error
==
GIT_ENOTFOUND
)
return
0
;
return
error
;
}
if
((
error
=
git_commit_lookup
(
&
head_commit
,
repo
,
git_reference_oid
(
resolved_head_ref
)))
<
0
)
return
error
;
git_reference_free
(
resolved_head_ref
);
if
((
error
=
git_commit_tree
(
&
tree
,
head_commit
))
==
0
)
*
tree_out
=
tree
;
git_commit_free
(
head_commit
);
return
error
;
}
enum
path_type
{
GIT_STATUS_PATH_NULL
,
GIT_STATUS_PATH_IGNORE
,
GIT_STATUS_PATH_FILE
,
GIT_STATUS_PATH_FOLDER
,
};
static
int
dirent_cb
(
void
*
state
,
git_buf
*
full_path
);
static
int
alphasorted_futils_direach
(
git_buf
*
path
,
int
(
*
fn
)(
void
*
,
git_buf
*
),
void
*
arg
);
static
int
process_folder
(
struct
status_st
*
st
,
const
git_tree_entry
*
tree_entry
,
git_buf
*
full_path
,
enum
path_type
path_type
)
{
git_object
*
subtree
=
NULL
;
git_tree
*
pushed_tree
=
NULL
;
int
error
,
pushed_tree_position
=
0
;
git_otype
tree_entry_type
=
GIT_OBJ_BAD
;
if
(
tree_entry
!=
NULL
)
{
tree_entry_type
=
git_tree_entry_type
(
tree_entry
);
switch
(
tree_entry_type
)
{
case
GIT_OBJ_TREE
:
error
=
git_tree_entry_2object
(
&
subtree
,
((
git_object
*
)(
st
->
tree
))
->
repo
,
tree_entry
);
pushed_tree
=
st
->
tree
;
pushed_tree_position
=
st
->
tree_position
;
st
->
tree
=
(
git_tree
*
)
subtree
;
st
->
tree_position
=
0
;
st
->
head_tree_relative_path_len
+=
1
+
tree_entry
->
filename_len
;
/* path + '/' + name */
break
;
case
GIT_OBJ_BLOB
:
/* No op */
break
;
case
GIT_OBJ_COMMIT
:
/* TODO: proper submodule support */
break
;
default:
giterr_set
(
GITERR_REPOSITORY
,
"Unexpected tree entry type"
);
return
-
1
;
}
}
if
(
full_path
!=
NULL
&&
path_type
==
GIT_STATUS_PATH_FOLDER
)
{
git_ignores
ignores
,
*
old_ignores
;
if
((
error
=
git_ignore__for_path
(
st
->
repo
,
full_path
->
ptr
+
st
->
workdir_path_len
,
&
ignores
))
==
0
)
{
old_ignores
=
st
->
ignores
;
st
->
ignores
=
&
ignores
;
error
=
alphasorted_futils_direach
(
full_path
,
dirent_cb
,
st
);
git_ignore__free
(
st
->
ignores
);
st
->
ignores
=
old_ignores
;
}
}
else
{
error
=
dirent_cb
(
st
,
NULL
);
}
if
(
tree_entry_type
==
GIT_OBJ_TREE
)
{
git_object_free
(
subtree
);
st
->
head_tree_relative_path_len
-=
1
+
tree_entry
->
filename_len
;
st
->
tree
=
pushed_tree
;
st
->
tree_position
=
pushed_tree_position
;
st
->
tree_position
++
;
}
return
error
;
}
static
int
store_if_changed
(
struct
status_st
*
st
,
struct
status_entry
*
e
)
{
int
error
=
status_entry_update_flags
(
e
);
if
(
error
<
0
)
return
error
;
if
(
status_entry_is_ignorable
(
e
)
&&
(
error
=
status_entry_update_ignore
(
e
,
st
->
ignores
,
e
->
path
))
<
0
)
return
error
;
if
(
e
->
status_flags
==
GIT_STATUS_CURRENT
)
{
git__free
(
e
);
return
0
;
}
return
git_vector_insert
(
st
->
vector
,
e
);
}
static
int
determine_status
(
struct
status_st
*
st
,
int
in_head
,
int
in_index
,
int
in_workdir
,
const
git_tree_entry
*
tree_entry
,
const
git_index_entry
*
index_entry
,
git_buf
*
full_path
,
const
char
*
status_path
,
enum
path_type
path_type
)
{
struct
status_entry
*
e
;
int
error
=
0
;
git_otype
tree_entry_type
=
GIT_OBJ_BAD
;
if
(
tree_entry
!=
NULL
)
tree_entry_type
=
git_tree_entry_type
(
tree_entry
);
/* If we're dealing with a directory in the workdir, let's recursively tackle it first */
if
(
path_type
==
GIT_STATUS_PATH_FOLDER
)
return
process_folder
(
st
,
tree_entry
,
full_path
,
path_type
);
/* Are we dealing with a file somewhere? */
if
(
in_workdir
||
in_index
||
(
in_head
&&
tree_entry_type
==
GIT_OBJ_BLOB
))
{
e
=
status_entry_new
(
NULL
,
status_path
);
if
(
in_head
&&
tree_entry_type
==
GIT_OBJ_BLOB
)
{
status_entry_update_from_tree_entry
(
e
,
tree_entry
);
st
->
tree_position
++
;
}
if
(
in_index
)
{
status_entry_update_from_index_entry
(
e
,
index_entry
);
st
->
index_position
++
;
}
if
(
in_workdir
&&
(
error
=
status_entry_update_from_workdir
(
e
,
full_path
->
ptr
))
<
0
)
return
error
;
/* The callee has already set the error message */
return
store_if_changed
(
st
,
e
);
}
/* Are we dealing with a subtree? */
if
(
tree_entry_type
==
GIT_OBJ_TREE
)
{
assert
(
in_head
&&
!
in_index
&&
!
in_workdir
);
return
process_folder
(
st
,
tree_entry
,
full_path
,
path_type
);
}
/* We're dealing with something else -- most likely a submodule;
* skip it for now */
if
(
in_head
)
st
->
tree_position
++
;
if
(
in_index
)
st
->
index_position
++
;
return
0
;
}
static
int
path_type_from
(
git_buf
*
full_path
,
int
is_dir
)
{
if
(
full_path
==
NULL
)
return
GIT_STATUS_PATH_NULL
;
if
(
!
is_dir
)
return
GIT_STATUS_PATH_FILE
;
if
(
!
git__suffixcmp
(
full_path
->
ptr
,
"/"
DOT_GIT
"/"
))
return
GIT_STATUS_PATH_IGNORE
;
return
GIT_STATUS_PATH_FOLDER
;
}
static
const
char
*
status_path
(
const
char
*
first
,
const
char
*
second
,
const
char
*
third
)
{
/* At least one of them can not be NULL */
assert
(
first
!=
NULL
||
second
!=
NULL
||
third
!=
NULL
);
/* TODO: Fixme. Ensure that when non null, they're all equal */
if
(
first
!=
NULL
)
return
first
;
if
(
second
!=
NULL
)
return
second
;
return
third
;
}
static
int
compare
(
const
char
*
left
,
const
char
*
right
)
{
if
(
left
==
NULL
&&
right
==
NULL
)
return
0
;
if
(
left
==
NULL
)
return
1
;
if
(
right
==
NULL
)
return
-
1
;
return
strcmp
(
left
,
right
);
}
/* Greatly inspired from JGit IndexTreeWalker */
/* https://github.com/spearce/jgit/blob/ed47e29c777accfa78c6f50685a5df2b8f5b8ff5/org.spearce.jgit/src/org/spearce/jgit/lib/IndexTreeWalker.java#L88 */
static
int
dirent_cb
(
void
*
state
,
git_buf
*
a
)
{
const
git_tree_entry
*
m
;
const
git_index_entry
*
entry
;
enum
path_type
path_type
;
int
cmpma
,
cmpmi
,
cmpai
,
error
;
const
char
*
pm
,
*
pa
,
*
pi
;
const
char
*
m_name
,
*
i_name
,
*
a_name
;
struct
status_st
*
st
=
(
struct
status_st
*
)
state
;
path_type
=
path_type_from
(
a
,
st
->
is_dir
);
if
(
path_type
==
GIT_STATUS_PATH_IGNORE
)
return
0
;
/* Let's skip the ".git" directory */
a_name
=
(
path_type
!=
GIT_STATUS_PATH_NULL
)
?
a
->
ptr
+
st
->
workdir_path_len
:
NULL
;
/* Loop over head tree and index up to and including this workdir file */
while
(
1
)
{
if
(
st
->
tree
==
NULL
)
m
=
NULL
;
else
m
=
git_tree_entry_byindex
(
st
->
tree
,
st
->
tree_position
);
entry
=
git_index_get
(
st
->
index
,
st
->
index_position
);
if
((
m
==
NULL
)
&&
(
a
==
NULL
)
&&
(
entry
==
NULL
))
return
0
;
if
(
m
!=
NULL
)
{
git_buf_truncate
(
&
st
->
head_tree_relative_path
,
st
->
head_tree_relative_path_len
);
git_buf_joinpath
(
&
st
->
head_tree_relative_path
,
st
->
head_tree_relative_path
.
ptr
,
m
->
filename
);
/* When the tree entry is a folder, append a forward slash to its name */
if
(
git_tree_entry_type
(
m
)
==
GIT_OBJ_TREE
)
git_path_to_dir
(
&
st
->
head_tree_relative_path
);
if
(
git_buf_oom
(
&
st
->
head_tree_relative_path
))
return
-
1
;
m_name
=
st
->
head_tree_relative_path
.
ptr
;
}
else
m_name
=
NULL
;
i_name
=
(
entry
!=
NULL
)
?
entry
->
path
:
NULL
;
cmpma
=
compare
(
m_name
,
a_name
);
cmpmi
=
compare
(
m_name
,
i_name
);
cmpai
=
compare
(
a_name
,
i_name
);
pm
=
((
cmpma
<=
0
)
&&
(
cmpmi
<=
0
))
?
m_name
:
NULL
;
pa
=
((
cmpma
>=
0
)
&&
(
cmpai
<=
0
))
?
a_name
:
NULL
;
pi
=
((
cmpmi
>=
0
)
&&
(
cmpai
>=
0
))
?
i_name
:
NULL
;
if
((
error
=
determine_status
(
st
,
pm
!=
NULL
,
pi
!=
NULL
,
pa
!=
NULL
,
m
,
entry
,
a
,
status_path
(
pm
,
pi
,
pa
),
path_type
))
<
0
)
return
error
;
if
((
pa
!=
NULL
)
||
(
path_type
==
GIT_STATUS_PATH_FOLDER
))
return
0
;
}
}
static
int
recurse_tree_entry
(
git_tree
*
tree
,
struct
status_entry
*
e
,
const
char
*
path
)
{
char
*
dir_sep
;
...
...
@@ -728,7 +418,7 @@ int git_status_file(
status_entry_update_from_index
(
e
,
index
);
/* Try to find file in HEAD */
if
((
error
=
re
trieve_head
_tree
(
&
tree
,
repo
))
<
0
)
if
((
error
=
re
solve_head_to
_tree
(
&
tree
,
repo
))
<
0
)
goto
cleanup
;
if
(
tree
!=
NULL
)
{
...
...
@@ -761,62 +451,6 @@ cleanup:
return
error
;
}
/*
* git_path_direach is not supposed to return entries in an ordered manner.
* alphasorted_futils_direach wraps git_path_dirload and invokes the
* callback function by passing it alphabetically sorted path parameters.
*
*/
static
int
alphasorted_futils_direach
(
git_buf
*
path
,
int
(
*
fn
)(
void
*
,
git_buf
*
),
void
*
arg
)
{
int
error
;
char
*
entry
;
git_vector
entry_names
;
unsigned
int
idx
;
if
(
git_vector_init
(
&
entry_names
,
16
,
git__strcmp_cb
)
<
0
)
return
-
1
;
if
((
error
=
git_path_dirload
(
path
->
ptr
,
0
,
1
,
&
entry_names
))
<
0
)
return
error
;
git_vector_foreach
(
&
entry_names
,
idx
,
entry
)
{
size_t
entry_len
=
strlen
(
entry
);
if
(
git_path_isdir
(
entry
))
{
/* dirload allocated 1 extra byte so there is space for slash */
entry
[
entry_len
++
]
=
'/'
;
entry
[
entry_len
]
=
'\0'
;
}
}
git_vector_sort
(
&
entry_names
);
git_vector_foreach
(
&
entry_names
,
idx
,
entry
)
{
/* Walk the entire vector even if there is an error, in order to
* free up memory, but stop making callbacks after an error.
*/
if
(
!
error
)
{
git_buf
entry_path
=
GIT_BUF_INIT
;
git_buf_attach
(
&
entry_path
,
entry
,
0
);
((
struct
status_st
*
)
arg
)
->
is_dir
=
(
entry_path
.
ptr
[
entry_path
.
size
-
1
]
==
'/'
);
error
=
fn
(
arg
,
&
entry_path
);
}
git__free
(
entry
);
}
git_vector_free
(
&
entry_names
);
return
error
;
}
int
git_status_should_ignore
(
git_repository
*
repo
,
const
char
*
path
,
int
*
ignored
)
{
int
error
;
...
...
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