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
243db06c
Commit
243db06c
authored
Jul 23, 2014
by
Vicent Marti
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2484 from libgit2/fix-git-status-list-new-unreadable-folder
Fix git status list new unreadable folder
parents
bf9a7e06
85b7268e
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
161 additions
and
4 deletions
+161
-4
include/git2/diff.h
+7
-0
include/git2/status.h
+3
-0
include/git2/types.h
+1
-1
src/checkout.c
+2
-0
src/diff.c
+21
-0
src/diff_file.c
+1
-0
src/diff_print.c
+2
-0
src/diff_tform.c
+3
-1
src/path.c
+8
-0
src/status.c
+11
-2
tests/status/status_helpers.c
+3
-0
tests/status/worktree.c
+99
-0
No files found.
include/git2/diff.h
View file @
243db06c
...
...
@@ -152,6 +152,12 @@ typedef enum {
*/
GIT_DIFF_UPDATE_INDEX
=
(
1u
<<
15
),
/** Include unreadable files in the diff */
GIT_DIFF_INCLUDE_UNREADABLE
=
(
1u
<<
16
),
/** Include unreadable files in the diff */
GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED
=
(
1u
<<
17
),
/*
* Options controlling how output will be generated
*/
...
...
@@ -237,6 +243,7 @@ typedef enum {
GIT_DELTA_IGNORED
=
6
,
/**< entry is ignored item in workdir */
GIT_DELTA_UNTRACKED
=
7
,
/**< entry is untracked item in workdir */
GIT_DELTA_TYPECHANGE
=
8
,
/**< type of entry changed between old and new */
GIT_DELTA_UNREADABLE
=
9
,
/**< entry is unreadable */
}
git_delta_t
;
/**
...
...
include/git2/status.h
View file @
243db06c
...
...
@@ -43,6 +43,7 @@ typedef enum {
GIT_STATUS_WT_DELETED
=
(
1u
<<
9
),
GIT_STATUS_WT_TYPECHANGE
=
(
1u
<<
10
),
GIT_STATUS_WT_RENAMED
=
(
1u
<<
11
),
GIT_STATUS_WT_UNREADABLE
=
(
1u
<<
12
),
GIT_STATUS_IGNORED
=
(
1u
<<
14
),
}
git_status_t
;
...
...
@@ -147,6 +148,8 @@ typedef enum {
GIT_STATUS_OPT_RENAMES_FROM_REWRITES
=
(
1u
<<
11
),
GIT_STATUS_OPT_NO_REFRESH
=
(
1u
<<
12
),
GIT_STATUS_OPT_UPDATE_INDEX
=
(
1u
<<
13
),
GIT_STATUS_OPT_INCLUDE_UNREADABLE
=
(
1u
<<
14
),
GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED
=
(
1u
<<
15
),
}
git_status_opt_t
;
#define GIT_STATUS_OPT_DEFAULTS \
...
...
include/git2/types.h
View file @
243db06c
...
...
@@ -198,7 +198,7 @@ typedef enum {
/** Valid modes for index and tree entries. */
typedef
enum
{
GIT_FILEMODE_
NEW
=
0000000
,
GIT_FILEMODE_
UNREADABLE
=
0000000
,
GIT_FILEMODE_TREE
=
0040000
,
GIT_FILEMODE_BLOB
=
0100644
,
GIT_FILEMODE_BLOB_EXECUTABLE
=
0100755
,
...
...
src/checkout.c
View file @
243db06c
...
...
@@ -119,6 +119,7 @@ static int checkout_notify(
case
GIT_DELTA_ADDED
:
case
GIT_DELTA_IGNORED
:
case
GIT_DELTA_UNTRACKED
:
case
GIT_DELTA_UNREADABLE
:
target
=
&
delta
->
new_file
;
break
;
case
GIT_DELTA_DELETED
:
...
...
@@ -2143,6 +2144,7 @@ int git_checkout_iterator(
diff_opts
.
flags
=
GIT_DIFF_INCLUDE_UNMODIFIED
|
GIT_DIFF_INCLUDE_UNREADABLE
|
GIT_DIFF_INCLUDE_UNTRACKED
|
GIT_DIFF_RECURSE_UNTRACKED_DIRS
|
/* needed to match baseline */
GIT_DIFF_INCLUDE_IGNORED
|
...
...
src/diff.c
View file @
243db06c
...
...
@@ -93,6 +93,10 @@ static int diff_delta__from_one(
DIFF_FLAG_ISNT_SET
(
diff
,
GIT_DIFF_INCLUDE_UNTRACKED
))
return
0
;
if
(
status
==
GIT_DELTA_UNREADABLE
&&
DIFF_FLAG_ISNT_SET
(
diff
,
GIT_DIFF_INCLUDE_UNREADABLE
))
return
0
;
if
(
!
git_pathspec__match
(
&
diff
->
pathspec
,
entry
->
path
,
DIFF_FLAG_IS_SET
(
diff
,
GIT_DIFF_DISABLE_PATHSPEC_MATCH
),
...
...
@@ -196,6 +200,7 @@ static git_diff_delta *diff_delta__last_for_item(
if
(
git_oid__cmp
(
&
delta
->
new_file
.
id
,
&
item
->
id
)
==
0
)
return
delta
;
break
;
case
GIT_DELTA_UNREADABLE
:
case
GIT_DELTA_UNTRACKED
:
if
(
diff
->
strcomp
(
delta
->
new_file
.
path
,
item
->
path
)
==
0
&&
git_oid__cmp
(
&
delta
->
new_file
.
id
,
&
item
->
id
)
==
0
)
...
...
@@ -293,6 +298,10 @@ bool git_diff_delta__should_skip(
(
flags
&
GIT_DIFF_INCLUDE_UNTRACKED
)
==
0
)
return
true
;
if
(
delta
->
status
==
GIT_DELTA_UNREADABLE
&&
(
flags
&
GIT_DIFF_INCLUDE_UNREADABLE
)
==
0
)
return
true
;
return
false
;
}
...
...
@@ -734,6 +743,11 @@ static int maybe_modified(
else
if
(
GIT_MODE_TYPE
(
omode
)
!=
GIT_MODE_TYPE
(
nmode
))
{
if
(
DIFF_FLAG_IS_SET
(
diff
,
GIT_DIFF_INCLUDE_TYPECHANGE
))
status
=
GIT_DELTA_TYPECHANGE
;
else
if
(
nmode
==
GIT_FILEMODE_UNREADABLE
)
{
if
(
!
(
error
=
diff_delta__from_one
(
diff
,
GIT_DELTA_DELETED
,
oitem
)))
error
=
diff_delta__from_one
(
diff
,
GIT_DELTA_UNREADABLE
,
nitem
);
return
error
;
}
else
{
if
(
!
(
error
=
diff_delta__from_one
(
diff
,
GIT_DELTA_DELETED
,
oitem
)))
error
=
diff_delta__from_one
(
diff
,
GIT_DELTA_ADDED
,
nitem
);
...
...
@@ -954,6 +968,13 @@ static int handle_unmatched_new_item(
}
}
else
if
(
nitem
->
mode
==
GIT_FILEMODE_UNREADABLE
)
{
if
(
DIFF_FLAG_IS_SET
(
diff
,
GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED
))
delta_type
=
GIT_DELTA_UNTRACKED
;
else
delta_type
=
GIT_DELTA_UNREADABLE
;
}
/* Actually create the record for this item if necessary */
if
((
error
=
diff_delta__from_one
(
diff
,
delta_type
,
nitem
))
!=
0
)
return
error
;
...
...
src/diff_file.c
View file @
243db06c
...
...
@@ -112,6 +112,7 @@ int git_diff_file_content__init_from_diff(
has_data
=
!
use_old
&&
(
diff
->
opts
.
flags
&
GIT_DIFF_SHOW_UNTRACKED_CONTENT
)
!=
0
;
break
;
case
GIT_DELTA_UNREADABLE
:
case
GIT_DELTA_MODIFIED
:
case
GIT_DELTA_COPIED
:
case
GIT_DELTA_RENAMED
:
...
...
src/diff_print.c
View file @
243db06c
...
...
@@ -89,6 +89,7 @@ char git_diff_status_char(git_delta_t status)
case
GIT_DELTA_COPIED
:
code
=
'C'
;
break
;
case
GIT_DELTA_IGNORED
:
code
=
'I'
;
break
;
case
GIT_DELTA_UNTRACKED
:
code
=
'?'
;
break
;
case
GIT_DELTA_UNREADABLE
:
code
=
'X'
;
break
;
default:
code
=
' '
;
break
;
}
...
...
@@ -441,6 +442,7 @@ static int diff_print_patch_file(
if
(
S_ISDIR
(
delta
->
new_file
.
mode
)
||
delta
->
status
==
GIT_DELTA_UNMODIFIED
||
delta
->
status
==
GIT_DELTA_IGNORED
||
delta
->
status
==
GIT_DELTA_UNREADABLE
||
(
delta
->
status
==
GIT_DELTA_UNTRACKED
&&
(
pi
->
flags
&
GIT_DIFF_SHOW_UNTRACKED_CONTENT
)
==
0
))
return
0
;
...
...
src/diff_tform.c
View file @
243db06c
...
...
@@ -114,7 +114,7 @@ static git_diff_delta *diff_delta__merge_like_cgit_reversed(
if
((
dup
=
diff_delta__dup
(
a
,
pool
))
==
NULL
)
return
NULL
;
if
(
b
->
status
==
GIT_DELTA_UNMODIFIED
||
b
->
status
==
GIT_DELTA_UNTRACKED
)
if
(
b
->
status
==
GIT_DELTA_UNMODIFIED
||
b
->
status
==
GIT_DELTA_UNTRACKED
||
b
->
status
==
GIT_DELTA_UNREADABLE
)
return
dup
;
if
(
dup
->
status
==
GIT_DELTA_DELETED
)
{
...
...
@@ -732,6 +732,7 @@ static bool is_rename_source(
switch
(
delta
->
status
)
{
case
GIT_DELTA_ADDED
:
case
GIT_DELTA_UNTRACKED
:
case
GIT_DELTA_UNREADABLE
:
case
GIT_DELTA_IGNORED
:
return
false
;
...
...
@@ -786,6 +787,7 @@ GIT_INLINE(bool) delta_is_new_only(git_diff_delta *delta)
{
return
(
delta
->
status
==
GIT_DELTA_ADDED
||
delta
->
status
==
GIT_DELTA_UNTRACKED
||
delta
->
status
==
GIT_DELTA_UNREADABLE
||
delta
->
status
==
GIT_DELTA_IGNORED
);
}
...
...
src/path.c
View file @
243db06c
...
...
@@ -1116,6 +1116,14 @@ int git_path_dirload_with_stat(
git_vector_remove
(
contents
,
i
--
);
continue
;
}
/* Treat the file as unreadable if we get any other error */
if
(
error
!=
0
)
{
giterr_clear
();
error
=
0
;
memset
(
&
ps
->
st
,
0
,
sizeof
(
ps
->
st
));
ps
->
st
.
st_mode
=
GIT_FILEMODE_UNREADABLE
;
continue
;
}
break
;
}
...
...
src/status.c
View file @
243db06c
...
...
@@ -62,6 +62,9 @@ static unsigned int workdir_delta2status(
case
GIT_DELTA_UNTRACKED
:
st
=
GIT_STATUS_WT_NEW
;
break
;
case
GIT_DELTA_UNREADABLE
:
st
=
GIT_STATUS_WT_UNREADABLE
;
break
;
case
GIT_DELTA_DELETED
:
st
=
GIT_STATUS_WT_DELETED
;
break
;
...
...
@@ -310,6 +313,10 @@ int git_status_list_new(
diffopt
.
flags
=
diffopt
.
flags
|
GIT_DIFF_IGNORE_SUBMODULES
;
if
((
flags
&
GIT_STATUS_OPT_UPDATE_INDEX
)
!=
0
)
diffopt
.
flags
=
diffopt
.
flags
|
GIT_DIFF_UPDATE_INDEX
;
if
((
flags
&
GIT_STATUS_OPT_INCLUDE_UNREADABLE
)
!=
0
)
diffopt
.
flags
=
diffopt
.
flags
|
GIT_DIFF_INCLUDE_UNREADABLE
;
if
((
flags
&
GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED
)
!=
0
)
diffopt
.
flags
=
diffopt
.
flags
|
GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED
;
if
((
flags
&
GIT_STATUS_OPT_RENAMES_FROM_REWRITES
)
!=
0
)
findopt
.
flags
=
findopt
.
flags
|
...
...
@@ -329,8 +336,9 @@ int git_status_list_new(
if
(
show
!=
GIT_STATUS_SHOW_INDEX_ONLY
)
{
if
((
error
=
git_diff_index_to_workdir
(
&
status
->
idx2wd
,
repo
,
index
,
&
diffopt
))
<
0
)
&
status
->
idx2wd
,
repo
,
index
,
&
diffopt
))
<
0
)
{
goto
done
;
}
if
((
flags
&
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR
)
!=
0
&&
(
error
=
git_diff_find_similar
(
status
->
idx2wd
,
&
findopt
))
<
0
)
...
...
@@ -407,8 +415,9 @@ int git_status_foreach_ext(
size_t
i
;
int
error
=
0
;
if
((
error
=
git_status_list_new
(
&
status
,
repo
,
opts
))
<
0
)
if
((
error
=
git_status_list_new
(
&
status
,
repo
,
opts
))
<
0
)
{
return
error
;
}
git_vector_foreach
(
&
status
->
paired
,
i
,
status_entry
)
{
const
char
*
path
=
status_entry
->
head_to_index
?
...
...
tests/status/status_helpers.c
View file @
243db06c
...
...
@@ -82,6 +82,9 @@ int cb_status__print(
if
(
status_flags
&
GIT_STATUS_IGNORED
)
{
wstatus
=
'I'
;
wcount
++
;
}
if
(
status_flags
&
GIT_STATUS_WT_UNREADABLE
)
{
wstatus
=
'X'
;
wcount
++
;
}
fprintf
(
stderr
,
"%c%c %s (%d/%d%s)
\n
"
,
istatus
,
wstatus
,
path
,
icount
,
wcount
,
...
...
tests/status/worktree.c
View file @
243db06c
...
...
@@ -935,3 +935,102 @@ void test_status_worktree__update_stat_cache_0(void)
git_status_list_free
(
status
);
}
void
test_status_worktree__unreadable
(
void
)
{
const
char
*
expected_paths
[]
=
{
"no_permission/foo"
};
const
unsigned
int
expected_statuses
[]
=
{
GIT_STATUS_WT_UNREADABLE
};
git_repository
*
repo
=
cl_git_sandbox_init
(
"empty_standard_repo"
);
git_status_options
opts
=
GIT_STATUS_OPTIONS_INIT
;
status_entry_counts
counts
=
{
0
};
/* Create directory with no read permission */
cl_git_pass
(
git_futils_mkdir_r
(
"empty_standard_repo/no_permission"
,
NULL
,
0777
));
cl_git_mkfile
(
"empty_standard_repo/no_permission/foo"
,
"dummy"
);
p_chmod
(
"empty_standard_repo/no_permission"
,
0644
);
counts
.
expected_entry_count
=
1
;
counts
.
expected_paths
=
expected_paths
;
counts
.
expected_statuses
=
expected_statuses
;
opts
.
show
=
GIT_STATUS_SHOW_WORKDIR_ONLY
;
opts
.
flags
=
GIT_STATUS_OPT_DEFAULTS
|
GIT_STATUS_OPT_INCLUDE_UNREADABLE
;
cl_git_pass
(
git_status_foreach_ext
(
repo
,
&
opts
,
cb_status__normal
,
&
counts
)
);
/* Restore permissions so we can cleanup :) */
p_chmod
(
"empty_standard_repo/no_permission"
,
0777
);
cl_assert_equal_i
(
counts
.
expected_entry_count
,
counts
.
entry_count
);
cl_assert_equal_i
(
0
,
counts
.
wrong_status_flags_count
);
cl_assert_equal_i
(
0
,
counts
.
wrong_sorted_path
);
}
void
test_status_worktree__unreadable_not_included
(
void
)
{
const
char
*
expected_paths
[]
=
{
"no_permission/"
};
const
unsigned
int
expected_statuses
[]
=
{
GIT_STATUS_WT_NEW
};
git_repository
*
repo
=
cl_git_sandbox_init
(
"empty_standard_repo"
);
git_status_options
opts
=
GIT_STATUS_OPTIONS_INIT
;
status_entry_counts
counts
=
{
0
};
/* Create directory with no read permission */
cl_git_pass
(
git_futils_mkdir_r
(
"empty_standard_repo/no_permission"
,
NULL
,
0777
));
cl_git_mkfile
(
"empty_standard_repo/no_permission/foo"
,
"dummy"
);
p_chmod
(
"empty_standard_repo/no_permission"
,
0644
);
counts
.
expected_entry_count
=
1
;
counts
.
expected_paths
=
expected_paths
;
counts
.
expected_statuses
=
expected_statuses
;
opts
.
show
=
GIT_STATUS_SHOW_WORKDIR_ONLY
;
opts
.
flags
=
(
GIT_STATUS_OPT_INCLUDE_IGNORED
|
GIT_STATUS_OPT_INCLUDE_UNTRACKED
);
cl_git_pass
(
git_status_foreach_ext
(
repo
,
&
opts
,
cb_status__normal
,
&
counts
)
);
/* Restore permissions so we can cleanup :) */
p_chmod
(
"empty_standard_repo/no_permission"
,
0777
);
cl_assert_equal_i
(
counts
.
expected_entry_count
,
counts
.
entry_count
);
cl_assert_equal_i
(
0
,
counts
.
wrong_status_flags_count
);
cl_assert_equal_i
(
0
,
counts
.
wrong_sorted_path
);
}
void
test_status_worktree__unreadable_as_untracked
(
void
)
{
const
char
*
expected_paths
[]
=
{
"no_permission/foo"
};
const
unsigned
int
expected_statuses
[]
=
{
GIT_STATUS_WT_NEW
};
git_repository
*
repo
=
cl_git_sandbox_init
(
"empty_standard_repo"
);
git_status_options
opts
=
GIT_STATUS_OPTIONS_INIT
;
status_entry_counts
counts
=
{
0
};
/* Create directory with no read permission */
cl_git_pass
(
git_futils_mkdir_r
(
"empty_standard_repo/no_permission"
,
NULL
,
0777
));
cl_git_mkfile
(
"empty_standard_repo/no_permission/foo"
,
"dummy"
);
p_chmod
(
"empty_standard_repo/no_permission"
,
0644
);
counts
.
expected_entry_count
=
1
;
counts
.
expected_paths
=
expected_paths
;
counts
.
expected_statuses
=
expected_statuses
;
opts
.
show
=
GIT_STATUS_SHOW_WORKDIR_ONLY
;
opts
.
flags
=
GIT_STATUS_OPT_DEFAULTS
|
GIT_STATUS_OPT_INCLUDE_UNREADABLE
|
GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED
;
cl_git_pass
(
git_status_foreach_ext
(
repo
,
&
opts
,
cb_status__normal
,
&
counts
)
);
/* Restore permissions so we can cleanup :) */
p_chmod
(
"empty_standard_repo/no_permission"
,
0777
);
cl_assert_equal_i
(
counts
.
expected_entry_count
,
counts
.
entry_count
);
cl_assert_equal_i
(
0
,
counts
.
wrong_status_flags_count
);
cl_assert_equal_i
(
0
,
counts
.
wrong_sorted_path
);
}
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