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
dc7efa1a
Commit
dc7efa1a
authored
Mar 26, 2014
by
Vicent Marti
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2204 from libgit2/rb/submodule-reference-counting
Make submodules externally refcounted
parents
77b699e0
591e8295
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
461 additions
and
364 deletions
+461
-364
examples/status.c
+14
-11
include/git2/submodule.h
+30
-14
src/checkout.c
+24
-16
src/diff.c
+16
-15
src/diff_file.c
+13
-4
src/submodule.c
+162
-57
src/submodule.h
+5
-3
tests/diff/submodules.c
+7
-3
tests/stash/submodules.c
+3
-0
tests/status/submodules.c
+2
-0
tests/submodule/lookup.c
+33
-62
tests/submodule/modify.c
+15
-7
tests/submodule/status.c
+103
-172
tests/submodule/submodule_helpers.c
+29
-0
tests/submodule/submodule_helpers.h
+5
-0
No files found.
examples/status.c
View file @
dc7efa1a
...
...
@@ -363,18 +363,21 @@ static void print_short(git_repository *repo, git_status_list *status)
unsigned
int
smstatus
=
0
;
if
(
!
git_submodule_lookup
(
&
sm
,
repo
,
s
->
index_to_workdir
->
new_file
.
path
)
&&
!
git_submodule_status
(
&
smstatus
,
sm
))
{
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
extra
=
" (new commits)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
)
extra
=
" (modified content)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
)
extra
=
" (modified content)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_UNTRACKED
)
extra
=
" (untracked content)"
;
&
sm
,
repo
,
s
->
index_to_workdir
->
new_file
.
path
))
{
if
(
!
git_submodule_status
(
&
smstatus
,
sm
))
{
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
extra
=
" (new commits)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
)
extra
=
" (modified content)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
)
extra
=
" (modified content)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_UNTRACKED
)
extra
=
" (untracked content)"
;
}
}
git_submodule_free
(
sm
);
}
/**
...
...
include/git2/submodule.h
View file @
dc7efa1a
...
...
@@ -123,22 +123,28 @@ typedef enum {
* There may or may not be anything else at that path, but nothing that
* looks like a submodule. In this case, this returns GIT_ENOTFOUND.
*
* The submodule object is owned by the containing repo and will be freed
* when the repo is freed. The caller need not free the submodule.
* You must call `git_submodule_free` when done with the submodule.
*
* @param
submodule Pointer to submodule description object pointer..
* @param repo The
repository.
* @param name The name of
the submodule. Trailing slashes will be ignored.
* @param
out Output ptr to submodule; pass NULL to just get return code
* @param repo The
parent repository
* @param name The name of
or path to the submodule; trailing slashes okay
* @return 0 on success, GIT_ENOTFOUND if submodule does not exist,
* GIT_EEXISTS if submodule exists in working directory only,
-1 on
* other errors.
* GIT_EEXISTS if submodule exists in working directory only,
*
-1 on
other errors.
*/
GIT_EXTERN
(
int
)
git_submodule_lookup
(
git_submodule
**
submodule
,
git_submodule
**
out
,
git_repository
*
repo
,
const
char
*
name
);
/**
* Release a submodule
*
* @param submodule Submodule object
*/
GIT_EXTERN
(
void
)
git_submodule_free
(
git_submodule
*
submodule
);
/**
* Iterate over all tracked submodules of a repository.
*
* See the note on `git_submodule` above. This iterates over the tracked
...
...
@@ -175,9 +181,11 @@ GIT_EXTERN(int) git_submodule_foreach(
* `git_submodule_add_finalize()` to wrap up adding the new submodule and
* .gitmodules to the index to be ready to commit.
*
* @param submodule The newly created submodule ready to open for clone
* @param repo Superproject repository to contain the new submodule
* @param url URL for the submodules remote
* You must call `git_submodule_free` on the submodule object when done.
*
* @param out The newly created submodule ready to open for clone
* @param repo The repository in which you want to create the submodule
* @param url URL for the submodule's remote
* @param path Path at which the submodule should be created
* @param use_gitlink Should workdir contain a gitlink to the repo in
* .git/modules vs. repo directly in workdir.
...
...
@@ -185,7 +193,7 @@ GIT_EXTERN(int) git_submodule_foreach(
* -1 on other errors.
*/
GIT_EXTERN
(
int
)
git_submodule_add_setup
(
git_submodule
**
submodule
,
git_submodule
**
out
,
git_repository
*
repo
,
const
char
*
url
,
const
char
*
path
,
...
...
@@ -493,15 +501,23 @@ GIT_EXTERN(int) git_submodule_open(
*
* Call this to reread cached submodule information for this submodule if
* you have reason to believe that it has changed.
*
* @param submodule The submodule to reload
* @param force Force reload even if the data doesn't seem out of date
* @return 0 on success, <0 on error
*/
GIT_EXTERN
(
int
)
git_submodule_reload
(
git_submodule
*
submodule
);
GIT_EXTERN
(
int
)
git_submodule_reload
(
git_submodule
*
submodule
,
int
force
);
/**
* Reread all submodule info.
*
* Call this to reload all cached submodule information for the repo.
*
* @param repo The repository to reload submodule data for
* @param force Force full reload even if the data doesn't seem out of date
* @return 0 on success, <0 on error
*/
GIT_EXTERN
(
int
)
git_submodule_reload_all
(
git_repository
*
repo
);
GIT_EXTERN
(
int
)
git_submodule_reload_all
(
git_repository
*
repo
,
int
force
);
/**
* Get the status for a submodule.
...
...
src/checkout.c
View file @
dc7efa1a
...
...
@@ -147,19 +147,23 @@ static bool checkout_is_workdir_modified(
git_submodule
*
sm
;
unsigned
int
sm_status
=
0
;
const
git_oid
*
sm_oid
=
NULL
;
bool
rval
=
false
;
if
(
git_submodule_lookup
(
&
sm
,
data
->
repo
,
wditem
->
path
)
<
0
||
git_submodule_status
(
&
sm_status
,
sm
)
<
0
)
return
true
;
if
(
GIT_SUBMODULE_STATUS_IS_WD_DIRTY
(
sm_status
))
if
(
git_submodule_lookup
(
&
sm
,
data
->
repo
,
wditem
->
path
)
<
0
)
{
giterr_clear
();
return
true
;
}
sm_oid
=
git_submodule_wd_id
(
sm
);
if
(
!
sm_oid
)
return
false
;
if
(
git_submodule_status
(
&
sm_status
,
sm
)
<
0
||
GIT_SUBMODULE_STATUS_IS_WD_DIRTY
(
sm_status
))
rval
=
true
;
else
if
((
sm_oid
=
git_submodule_wd_id
(
sm
))
==
NULL
)
rval
=
false
;
else
rval
=
(
git_oid__cmp
(
&
baseitem
->
id
,
sm_oid
)
!=
0
);
return
(
git_oid__cmp
(
&
baseitem
->
id
,
sm_oid
)
!=
0
);
git_submodule_free
(
sm
);
return
rval
;
}
/* Look at the cache to decide if the workdir is modified. If not,
...
...
@@ -324,12 +328,17 @@ static bool submodule_is_config_only(
{
git_submodule
*
sm
=
NULL
;
unsigned
int
sm_loc
=
0
;
bool
rval
=
false
;
if
(
git_submodule_lookup
(
&
sm
,
data
->
repo
,
path
)
<
0
||
git_submodule_location
(
&
sm_loc
,
sm
)
<
0
||
sm_loc
==
GIT_SUBMODULE_STATUS_IN_CONFIG
)
if
(
git_submodule_lookup
(
&
sm
,
data
->
repo
,
path
)
<
0
)
return
true
;
if
(
git_submodule_location
(
&
sm_loc
,
sm
)
<
0
||
sm_loc
==
GIT_SUBMODULE_STATUS_IN_CONFIG
)
rval
=
true
;
git_submodule_free
(
sm
);
return
false
;
}
...
...
@@ -1258,7 +1267,6 @@ static int checkout_submodule(
const
git_diff_file
*
file
)
{
int
error
=
0
;
git_submodule
*
sm
;
/* Until submodules are supported, UPDATE_ONLY means do nothing here */
if
((
data
->
strategy
&
GIT_CHECKOUT_UPDATE_ONLY
)
!=
0
)
...
...
@@ -1269,7 +1277,7 @@ static int checkout_submodule(
data
->
opts
.
dir_mode
,
GIT_MKDIR_PATH
))
<
0
)
return
error
;
if
((
error
=
git_submodule_lookup
(
&
sm
,
data
->
repo
,
file
->
path
))
<
0
)
{
if
((
error
=
git_submodule_lookup
(
NULL
,
data
->
repo
,
file
->
path
))
<
0
)
{
/* I've observed repos with submodules in the tree that do not
* have a .gitmodules - core Git just makes an empty directory
*/
...
...
@@ -1510,7 +1518,7 @@ static int checkout_create_submodules(
/* initial reload of submodules if .gitmodules was changed */
if
(
data
->
reload_submodules
&&
(
error
=
git_submodule_reload_all
(
data
->
repo
))
<
0
)
(
error
=
git_submodule_reload_all
(
data
->
repo
,
1
))
<
0
)
return
error
;
git_vector_foreach
(
&
data
->
diff
->
deltas
,
i
,
delta
)
{
...
...
@@ -1534,7 +1542,7 @@ static int checkout_create_submodules(
}
/* final reload once submodules have been updated */
return
git_submodule_reload_all
(
data
->
repo
);
return
git_submodule_reload_all
(
data
->
repo
,
1
);
}
static
int
checkout_lookup_head_tree
(
git_tree
**
out
,
git_repository
*
repo
)
...
...
src/diff.c
View file @
dc7efa1a
...
...
@@ -528,12 +528,15 @@ int git_diff__oid_for_file(
/* calculate OID for file if possible */
if
(
S_ISGITLINK
(
mode
))
{
git_submodule
*
sm
;
const
git_oid
*
sm_oid
;
if
(
!
git_submodule_lookup
(
&
sm
,
repo
,
path
)
&&
(
sm_oid
=
git_submodule_wd_id
(
sm
))
!=
NULL
)
git_oid_cpy
(
oid
,
sm_oid
);
else
{
memset
(
oid
,
0
,
sizeof
(
*
oid
));
if
(
!
git_submodule_lookup
(
&
sm
,
repo
,
path
))
{
const
git_oid
*
sm_oid
=
git_submodule_wd_id
(
sm
);
if
(
sm_oid
)
git_oid_cpy
(
oid
,
sm_oid
);
git_submodule_free
(
sm
);
}
else
{
/* if submodule lookup failed probably just in an intermediate
* state where some init hasn't happened, so ignore the error
*/
...
...
@@ -615,24 +618,24 @@ static int maybe_modified_submodule(
}
if
(
ign
<=
0
&&
git_submodule_ignore
(
sub
)
==
GIT_SUBMODULE_IGNORE_ALL
)
return
0
;
if
((
error
=
git_submodule__status
(
/* ignore it */
;
else
if
((
error
=
git_submodule__status
(
&
sm_status
,
NULL
,
NULL
,
found_oid
,
sub
,
ign
))
<
0
)
return
error
;
/* return error below */
;
/* check IS_WD_UNMODIFIED because this case is only used
* when the new side of the diff is the working directory
*/
if
(
!
GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED
(
sm_status
))
else
if
(
!
GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED
(
sm_status
))
*
status
=
GIT_DELTA_MODIFIED
;
/* now that we have a HEAD OID, check if HEAD moved */
if
((
sm_status
&
GIT_SUBMODULE_STATUS_IN_WD
)
!=
0
&&
else
if
((
sm_status
&
GIT_SUBMODULE_STATUS_IN_WD
)
!=
0
&&
!
git_oid_equal
(
&
info
->
oitem
->
id
,
found_oid
))
*
status
=
GIT_DELTA_MODIFIED
;
return
0
;
git_submodule_free
(
sub
);
return
error
;
}
static
int
maybe_modified
(
...
...
@@ -960,10 +963,8 @@ static int handle_unmatched_new_item(
delta_type
=
GIT_DELTA_ADDED
;
else
if
(
nitem
->
mode
==
GIT_FILEMODE_COMMIT
)
{
git_submodule
*
sm
;
/* ignore things that are not actual submodules */
if
(
git_submodule_lookup
(
&
sm
,
info
->
repo
,
nitem
->
path
)
!=
0
)
{
if
(
git_submodule_lookup
(
NULL
,
info
->
repo
,
nitem
->
path
)
!=
0
)
{
giterr_clear
();
delta_type
=
GIT_DELTA_IGNORED
;
}
...
...
src/diff_file.c
View file @
dc7efa1a
...
...
@@ -177,11 +177,17 @@ static int diff_file_content_commit_to_str(
unsigned
int
sm_status
=
0
;
const
git_oid
*
sm_head
;
if
((
error
=
git_submodule_lookup
(
&
sm
,
fc
->
repo
,
fc
->
file
->
path
))
<
0
||
(
error
=
git_submodule_status
(
&
sm_status
,
sm
))
<
0
)
{
if
((
error
=
git_submodule_lookup
(
&
sm
,
fc
->
repo
,
fc
->
file
->
path
))
<
0
)
{
/* GIT_EEXISTS means a "submodule" that has not been git added */
if
(
error
==
GIT_EEXISTS
)
if
(
error
==
GIT_EEXISTS
)
{
giterr_clear
();
error
=
0
;
}
return
error
;
}
if
((
error
=
git_submodule_status
(
&
sm_status
,
sm
))
<
0
)
{
git_submodule_free
(
sm
);
return
error
;
}
...
...
@@ -196,6 +202,8 @@ static int diff_file_content_commit_to_str(
if
(
GIT_SUBMODULE_STATUS_IS_WD_DIRTY
(
sm_status
))
status
=
"-dirty"
;
git_submodule_free
(
sm
);
}
git_oid_tostr
(
oid
,
sizeof
(
oid
),
&
fc
->
file
->
id
);
...
...
@@ -312,7 +320,8 @@ static int diff_file_content_load_workdir_file(
error
=
git_filter_list_apply_to_data
(
&
out
,
fl
,
&
raw
);
git_buf_free
(
&
raw
);
if
(
out
.
ptr
!=
raw
.
ptr
)
git_buf_free
(
&
raw
);
if
(
!
error
)
{
fc
->
map
.
len
=
out
.
size
;
...
...
src/submodule.c
View file @
dc7efa1a
...
...
@@ -77,12 +77,12 @@ __KHASH_IMPL(
str
,
static
kh_inline
,
const
char
*
,
void
*
,
1
,
str_hash_no_trailing_slash
,
str_equal_no_trailing_slash
);
static
int
load_submodule_config
(
git_repository
*
repo
);
static
int
load_submodule_config
(
git_repository
*
repo
,
bool
reload
);
static
git_config_backend
*
open_gitmodules
(
git_repository
*
,
bool
,
const
git_oid
*
);
static
int
lookup_head_remote
(
git_buf
*
url
,
git_repository
*
repo
);
static
int
submodule_get
(
git_submodule
**
,
git_repository
*
,
const
char
*
,
const
char
*
);
static
int
submodule_load_from_config
(
const
git_config_entry
*
,
void
*
);
static
int
submodule_load_from_wd_lite
(
git_submodule
*
,
const
char
*
,
void
*
);
static
int
submodule_load_from_wd_lite
(
git_submodule
*
);
static
int
submodule_update_config
(
git_submodule
*
,
const
char
*
,
const
char
*
,
bool
,
bool
);
static
void
submodule_get_index_status
(
unsigned
int
*
,
git_submodule
*
);
static
void
submodule_get_wd_status
(
unsigned
int
*
,
git_submodule
*
,
git_repository
*
,
git_submodule_ignore_t
);
...
...
@@ -99,27 +99,55 @@ static int submodule_config_key_trunc_puts(git_buf *key, const char *suffix)
return
git_buf_puts
(
key
,
suffix
);
}
/* lookup submodule or return ENOTFOUND if it doesn't exist */
static
int
submodule_lookup
(
git_submodule
**
out
,
git_strmap
*
cache
,
const
char
*
name
,
const
char
*
alternate
)
{
khiter_t
pos
;
/* lock cache */
pos
=
git_strmap_lookup_index
(
cache
,
name
);
if
(
!
git_strmap_valid_index
(
cache
,
pos
)
&&
alternate
)
pos
=
git_strmap_lookup_index
(
cache
,
alternate
);
if
(
!
git_strmap_valid_index
(
cache
,
pos
))
{
/* unlock cache */
return
GIT_ENOTFOUND
;
/* don't set error - caller will cope */
}
if
(
out
!=
NULL
)
{
git_submodule
*
sm
=
git_strmap_value_at
(
cache
,
pos
);
GIT_REFCOUNT_INC
(
sm
);
*
out
=
sm
;
}
/* unlock cache */
return
0
;
}
/*
* PUBLIC APIS
*/
int
git_submodule_lookup
(
git_submodule
**
sm_ptr
,
/* NULL if user only wants to test existence */
git_submodule
**
out
,
/* NULL if user only wants to test existence */
git_repository
*
repo
,
const
char
*
name
)
/* trailing slash is allowed */
const
char
*
name
)
/* trailing slash is allowed */
{
int
error
;
khiter_t
pos
;
assert
(
repo
&&
name
);
if
((
error
=
load_submodule_config
(
repo
))
<
0
)
if
((
error
=
load_submodule_config
(
repo
,
false
))
<
0
)
return
error
;
pos
=
git_strmap_lookup_index
(
repo
->
submodules
,
name
);
if
(
!
git_strmap_valid_index
(
repo
->
submodules
,
pos
))
{
error
=
GIT_ENOTFOUND
;
if
((
error
=
submodule_lookup
(
out
,
repo
->
submodules
,
name
,
NULL
))
<
0
)
{
/* check if a plausible submodule exists at path */
if
(
git_repository_workdir
(
repo
))
{
...
...
@@ -137,14 +165,9 @@ int git_submodule_lookup(
giterr_set
(
GITERR_SUBMODULE
,
(
error
==
GIT_ENOTFOUND
)
?
"No submodule named '%s'"
:
"Submodule '%s' has not been added yet"
,
name
);
return
error
;
}
if
(
sm_ptr
)
*
sm_ptr
=
git_strmap_value_at
(
repo
->
submodules
,
pos
);
return
0
;
return
error
;
}
int
git_submodule_foreach
(
...
...
@@ -159,7 +182,7 @@ int git_submodule_foreach(
assert
(
repo
&&
callback
);
if
((
error
=
load_submodule_config
(
repo
))
<
0
)
if
((
error
=
load_submodule_config
(
repo
,
true
))
<
0
)
return
error
;
git_strmap_foreach_value
(
repo
->
submodules
,
sm
,
{
...
...
@@ -198,12 +221,15 @@ void git_submodule_config_free(git_repository *repo)
if
(
smcfg
==
NULL
)
return
;
git_strmap_foreach_value
(
smcfg
,
sm
,
{
git_submodule_free
(
sm
);
});
git_strmap_foreach_value
(
smcfg
,
sm
,
{
sm
->
repo
=
NULL
;
/* disconnect from repo */
;
git_submodule_free
(
sm
);
});
git_strmap_free
(
smcfg
);
}
int
git_submodule_add_setup
(
git_submodule
**
submodule
,
git_submodule
**
out
,
git_repository
*
repo
,
const
char
*
url
,
const
char
*
path
,
...
...
@@ -211,7 +237,7 @@ int git_submodule_add_setup(
{
int
error
=
0
;
git_config_backend
*
mods
=
NULL
;
git_submodule
*
sm
;
git_submodule
*
sm
=
NULL
;
git_buf
name
=
GIT_BUF_INIT
,
real_url
=
GIT_BUF_INIT
;
git_repository_init_options
initopt
=
GIT_REPOSITORY_INIT_OPTIONS_INIT
;
git_repository
*
subrepo
=
NULL
;
...
...
@@ -223,6 +249,7 @@ int git_submodule_add_setup(
if
(
git_submodule_lookup
(
&
sm
,
repo
,
path
)
<
0
)
giterr_clear
();
else
{
git_submodule_free
(
sm
);
giterr_set
(
GITERR_SUBMODULE
,
"Attempt to add a submodule that already exists"
);
return
GIT_EEXISTS
;
...
...
@@ -307,12 +334,16 @@ int git_submodule_add_setup(
/* add submodule to hash and "reload" it */
if
(
!
(
error
=
submodule_get
(
&
sm
,
repo
,
path
,
NULL
))
&&
!
(
error
=
git_submodule_reload
(
sm
)))
!
(
error
=
git_submodule_reload
(
sm
,
false
)))
error
=
git_submodule_init
(
sm
,
false
);
cleanup:
if
(
submodule
!=
NULL
)
*
submodule
=
!
error
?
sm
:
NULL
;
if
(
error
&&
sm
)
{
git_submodule_free
(
sm
);
sm
=
NULL
;
}
if
(
out
!=
NULL
)
*
out
=
sm
;
if
(
mods
!=
NULL
)
git_config_file_free
(
mods
);
...
...
@@ -775,11 +806,60 @@ int git_submodule_open(git_repository **subrepo, git_submodule *sm)
return
git_submodule__open
(
subrepo
,
sm
,
false
);
}
int
git_submodule_reload_all
(
git_repository
*
repo
)
static
void
submodule_cache_remove_item
(
git_strmap
*
cache
,
const
char
*
name
,
git_submodule
*
expected
,
bool
free_after_remove
)
{
khiter_t
pos
;
git_submodule
*
found
;
if
(
!
cache
)
return
;
pos
=
git_strmap_lookup_index
(
cache
,
name
);
if
(
!
git_strmap_valid_index
(
cache
,
pos
))
return
;
found
=
git_strmap_value_at
(
cache
,
pos
);
if
(
expected
&&
found
!=
expected
)
return
;
git_strmap_set_value_at
(
cache
,
pos
,
NULL
);
git_strmap_delete_at
(
cache
,
pos
);
if
(
free_after_remove
)
git_submodule_free
(
found
);
}
int
git_submodule_reload_all
(
git_repository
*
repo
,
int
force
)
{
int
error
=
0
;
git_submodule
*
sm
;
GIT_UNUSED
(
force
);
assert
(
repo
);
git_submodule_config_free
(
repo
);
return
load_submodule_config
(
repo
);
if
(
repo
->
submodules
)
git_strmap_foreach_value
(
repo
->
submodules
,
sm
,
{
sm
->
flags
=
0
;
});
error
=
load_submodule_config
(
repo
,
true
);
git_strmap_foreach_value
(
repo
->
submodules
,
sm
,
{
git_strmap
*
cache
=
repo
->
submodules
;
if
((
sm
->
flags
&
GIT_SUBMODULE_STATUS__IN_FLAGS
)
==
0
)
{
submodule_cache_remove_item
(
cache
,
sm
->
name
,
sm
,
true
);
if
(
sm
->
path
!=
sm
->
name
)
submodule_cache_remove_item
(
cache
,
sm
->
path
,
sm
,
true
);
}
});
return
error
;
}
static
void
submodule_update_from_index_entry
(
...
...
@@ -855,11 +935,14 @@ static int submodule_update_head(git_submodule *submodule)
return
0
;
}
int
git_submodule_reload
(
git_submodule
*
submodule
)
int
git_submodule_reload
(
git_submodule
*
submodule
,
int
force
)
{
int
error
=
0
;
git_config_backend
*
mods
;
GIT_UNUSED
(
force
);
assert
(
submodule
);
/* refresh index data */
...
...
@@ -870,6 +953,10 @@ int git_submodule_reload(git_submodule *submodule)
if
((
error
=
submodule_update_head
(
submodule
))
<
0
)
return
error
;
/* done if bare */
if
(
git_repository_is_bare
(
submodule
->
repo
))
return
error
;
/* refresh config data */
mods
=
open_gitmodules
(
submodule
->
repo
,
false
,
NULL
);
if
(
mods
!=
NULL
)
{
...
...
@@ -893,11 +980,9 @@ int git_submodule_reload(git_submodule *submodule)
}
/* refresh wd data */
submodule
->
flags
=
submodule
->
flags
&
~
(
GIT_SUBMODULE_STATUS_IN_WD
|
GIT_SUBMODULE_STATUS__WD_OID_VALID
);
submodule
->
flags
&=
~
GIT_SUBMODULE_STATUS__ALL_WD_FLAGS
;
return
submodule_load_from_wd_lite
(
submodule
,
submodule
->
path
,
submodule
->
repo
);
return
submodule_load_from_wd_lite
(
submodule
);
}
static
void
submodule_copy_oid_maybe
(
...
...
@@ -1026,6 +1111,13 @@ static void submodule_release(git_submodule *sm)
if
(
!
sm
)
return
;
if
(
sm
->
repo
)
{
git_strmap
*
cache
=
sm
->
repo
->
submodules
;
submodule_cache_remove_item
(
cache
,
sm
->
name
,
sm
,
false
);
if
(
sm
->
path
!=
sm
->
name
)
submodule_cache_remove_item
(
cache
,
sm
->
path
,
sm
,
false
);
}
if
(
sm
->
path
!=
sm
->
name
)
git__free
(
sm
->
path
);
git__free
(
sm
->
name
);
...
...
@@ -1042,17 +1134,15 @@ void git_submodule_free(git_submodule *sm)
}
static
int
submodule_get
(
git_submodule
**
sm_ptr
,
git_submodule
**
out
,
git_repository
*
repo
,
const
char
*
name
,
const
char
*
alternate
)
{
int
error
=
0
;
git_strmap
*
smcfg
=
repo
->
submodules
;
khiter_t
pos
;
git_submodule
*
sm
;
int
error
;
assert
(
repo
&&
name
);
pos
=
git_strmap_lookup_index
(
smcfg
,
name
);
...
...
@@ -1068,22 +1158,28 @@ static int submodule_get(
*/
pos
=
kh_put
(
str
,
smcfg
,
sm
->
name
,
&
error
);
if
(
error
<
0
)
{
git_submodule_free
(
sm
);
sm
=
NULL
;
}
else
if
(
error
==
0
)
{
if
(
error
<
0
)
goto
done
;
else
if
(
error
==
0
)
{
git_submodule_free
(
sm
);
sm
=
git_strmap_value_at
(
smcfg
,
pos
);
}
else
{
error
=
0
;
git_strmap_set_value_at
(
smcfg
,
pos
,
sm
);
}
}
else
{
sm
=
git_strmap_value_at
(
smcfg
,
pos
);
}
*
sm_ptr
=
sm
;
done:
if
(
error
<
0
)
git_submodule_free
(
sm
);
else
if
(
out
)
{
GIT_REFCOUNT_INC
(
sm
);
*
out
=
sm
;
}
return
(
sm
!=
NULL
)
?
0
:
-
1
;
return
error
;
}
static
int
submodule_config_error
(
const
char
*
property
,
const
char
*
value
)
...
...
@@ -1143,7 +1239,7 @@ static int submodule_load_from_config(
const
char
*
namestart
,
*
property
,
*
alternate
=
NULL
;
const
char
*
key
=
entry
->
name
,
*
value
=
entry
->
value
,
*
path
;
git_buf
name
=
GIT_BUF_INIT
;
git_submodule
*
sm
;
git_submodule
*
sm
=
NULL
;
int
error
=
0
;
if
(
git__prefixcmp
(
key
,
"submodule."
)
!=
0
)
...
...
@@ -1230,8 +1326,8 @@ static int submodule_load_from_config(
sm
->
update_default
=
sm
->
update
;
}
else
if
(
strcasecmp
(
property
,
"fetchRecurseSubmodules"
)
==
0
)
{
if
(
git_submodule_parse_recurse
(
&
sm
->
fetch_recurse
,
value
)
<
0
)
return
-
1
;
if
(
(
error
=
git_submodule_parse_recurse
(
&
sm
->
fetch_recurse
,
value
)
)
<
0
)
goto
done
;
sm
->
fetch_recurse_default
=
sm
->
fetch_recurse
;
}
else
if
(
strcasecmp
(
property
,
"ignore"
)
==
0
)
{
...
...
@@ -1242,20 +1338,15 @@ static int submodule_load_from_config(
/* ignore other unknown submodule properties */
done:
git_submodule_free
(
sm
);
/* offset refcount inc from submodule_get() */
git_buf_free
(
&
name
);
return
error
;
}
static
int
submodule_load_from_wd_lite
(
git_submodule
*
sm
,
const
char
*
name
,
void
*
payload
)
static
int
submodule_load_from_wd_lite
(
git_submodule
*
sm
)
{
git_buf
path
=
GIT_BUF_INIT
;
GIT_UNUSED
(
name
);
GIT_UNUSED
(
payload
);
if
(
git_repository_is_bare
(
sm
->
repo
))
return
0
;
if
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
sm
->
repo
),
sm
->
path
)
<
0
)
return
-
1
;
...
...
@@ -1293,8 +1384,10 @@ static int load_submodule_config_from_index(
else
sm
->
flags
|=
GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE
;
}
else
if
(
S_ISGITLINK
(
entry
->
mode
))
{
if
(
!
submodule_get
(
&
sm
,
repo
,
entry
->
path
,
NULL
))
if
(
!
submodule_get
(
&
sm
,
repo
,
entry
->
path
,
NULL
))
{
submodule_update_from_index_entry
(
sm
,
entry
);
git_submodule_free
(
sm
);
}
}
else
if
(
strcmp
(
entry
->
path
,
GIT_MODULES_FILE
)
==
0
)
git_oid_cpy
(
gitmodules_oid
,
&
entry
->
id
);
}
...
...
@@ -1339,9 +1432,11 @@ static int load_submodule_config_from_head(
else
sm
->
flags
|=
GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE
;
}
else
if
(
S_ISGITLINK
(
entry
->
mode
))
{
if
(
!
submodule_get
(
&
sm
,
repo
,
entry
->
path
,
NULL
))
if
(
!
submodule_get
(
&
sm
,
repo
,
entry
->
path
,
NULL
))
{
submodule_update_from_head_data
(
sm
,
entry
->
mode
,
&
entry
->
id
);
git_submodule_free
(
sm
);
}
}
else
if
(
strcmp
(
entry
->
path
,
GIT_MODULES_FILE
)
==
0
&&
git_oid_iszero
(
gitmodules_oid
))
{
git_oid_cpy
(
gitmodules_oid
,
&
entry
->
id
);
...
...
@@ -1395,13 +1490,13 @@ static git_config_backend *open_gitmodules(
return
mods
;
}
static
int
load_submodule_config
(
git_repository
*
repo
)
static
int
load_submodule_config
(
git_repository
*
repo
,
bool
reload
)
{
int
error
;
git_oid
gitmodules_oid
;
git_config_backend
*
mods
=
NULL
;
if
(
repo
->
submodules
)
if
(
!
reload
&&
repo
->
submodules
)
return
0
;
memset
(
&
gitmodules_oid
,
0
,
sizeof
(
gitmodules_oid
));
...
...
@@ -1414,6 +1509,8 @@ static int load_submodule_config(git_repository *repo)
GITERR_CHECK_ALLOC
(
repo
->
submodules
);
}
/* TODO: only do the following if the sources appear modified */
/* add submodule information from index */
if
((
error
=
load_submodule_config_from_index
(
repo
,
&
gitmodules_oid
))
<
0
)
...
...
@@ -1433,8 +1530,16 @@ static int load_submodule_config(git_repository *repo)
/* shallow scan submodules in work tree */
if
(
!
git_repository_is_bare
(
repo
))
error
=
git_submodule_foreach
(
repo
,
submodule_load_from_wd_lite
,
NULL
);
if
(
!
git_repository_is_bare
(
repo
))
{
git_submodule
*
sm
;
git_strmap_foreach_value
(
repo
->
submodules
,
sm
,
{
sm
->
flags
&=
~
GIT_SUBMODULE_STATUS__ALL_WD_FLAGS
;
});
git_strmap_foreach_value
(
repo
->
submodules
,
sm
,
{
submodule_load_from_wd_lite
(
sm
);
});
}
cleanup:
if
(
mods
!=
NULL
)
...
...
src/submodule.h
View file @
dc7efa1a
...
...
@@ -111,6 +111,11 @@ enum {
GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES
=
(
1u
<<
27
),
};
#define GIT_SUBMODULE_STATUS__ALL_WD_FLAGS \
(GIT_SUBMODULE_STATUS_IN_WD | \
GIT_SUBMODULE_STATUS__WD_OID_VALID | \
GIT_SUBMODULE_STATUS__WD_FLAGS)
#define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \
((S) & ~(0xFFFFFFFFu << 20))
...
...
@@ -128,9 +133,6 @@ extern int git_submodule_open_bare(
git_repository
**
repo
,
git_submodule
*
submodule
);
/* Release reference to submodule object - not currently for external use */
extern
void
git_submodule_free
(
git_submodule
*
sm
);
extern
int
git_submodule_parse_ignore
(
git_submodule_ignore_t
*
out
,
const
char
*
value
);
extern
int
git_submodule_parse_update
(
...
...
tests/diff/submodules.c
View file @
dc7efa1a
...
...
@@ -131,7 +131,7 @@ void test_diff_submodules__dirty_submodule_2(void)
g_repo
=
setup_fixture_submodules
();
cl_git_pass
(
git_submodule_reload_all
(
g_repo
));
cl_git_pass
(
git_submodule_reload_all
(
g_repo
,
1
));
opts
.
flags
=
GIT_DIFF_INCLUDE_UNTRACKED
|
GIT_DIFF_SHOW_UNTRACKED_CONTENT
|
...
...
@@ -165,7 +165,7 @@ void test_diff_submodules__dirty_submodule_2(void)
git_diff_free
(
diff
);
cl_git_pass
(
git_submodule_reload_all
(
g_repo
));
cl_git_pass
(
git_submodule_reload_all
(
g_repo
,
1
));
cl_git_pass
(
git_diff_index_to_workdir
(
&
diff
,
g_repo
,
NULL
,
&
opts
));
check_diff_patches
(
diff
,
expected_dirty
);
...
...
@@ -291,7 +291,9 @@ void test_diff_submodules__invalid_cache(void)
check_diff_patches
(
diff
,
expected_dirty
);
git_diff_free
(
diff
);
cl_git_pass
(
git_submodule_reload_all
(
g_repo
));
git_submodule_free
(
sm
);
cl_git_pass
(
git_submodule_reload_all
(
g_repo
,
1
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
smpath
));
cl_git_pass
(
git_diff_index_to_workdir
(
&
diff
,
g_repo
,
NULL
,
&
opts
));
...
...
@@ -344,6 +346,8 @@ void test_diff_submodules__invalid_cache(void)
p_unlink
(
"submod2/sm_changed_head/new_around_here"
);
git_submodule_free
(
sm
);
cl_git_pass
(
git_diff_index_to_workdir
(
&
diff
,
g_repo
,
NULL
,
&
opts
));
check_diff_patches
(
diff
,
expected_moved
);
git_diff_free
(
diff
);
...
...
tests/stash/submodules.c
View file @
dc7efa1a
...
...
@@ -19,6 +19,9 @@ void test_stash_submodules__initialize(void)
void
test_stash_submodules__cleanup
(
void
)
{
git_submodule_free
(
sm
);
sm
=
NULL
;
git_signature_free
(
signature
);
signature
=
NULL
;
}
...
...
tests/status/submodules.c
View file @
dc7efa1a
...
...
@@ -29,6 +29,7 @@ void test_status_submodules__api(void)
cl_assert
(
sm
!=
NULL
);
cl_assert_equal_s
(
"testrepo"
,
git_submodule_name
(
sm
));
cl_assert_equal_s
(
"testrepo"
,
git_submodule_path
(
sm
));
git_submodule_free
(
sm
);
}
void
test_status_submodules__0
(
void
)
...
...
@@ -136,6 +137,7 @@ void test_status_submodules__moved_head(void)
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"testrepo"
));
cl_git_pass
(
git_submodule_open
(
&
smrepo
,
sm
));
git_submodule_free
(
sm
);
/* move submodule HEAD to c47800c7266a2be04c571c04d5a6614691ea99bd */
cl_git_pass
(
...
...
tests/submodule/lookup.c
View file @
dc7efa1a
...
...
@@ -12,31 +12,25 @@ void test_submodule_lookup__initialize(void)
void
test_submodule_lookup__simple_lookup
(
void
)
{
git_submodule
*
sm
;
/* lookup existing */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_assert
(
sm
);
assert_submodule_exists
(
g_repo
,
"sm_unchanged"
);
/* lookup pending change in .gitmodules that is not in HEAD */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_assert
(
sm
);
assert_submodule_exists
(
g_repo
,
"sm_added_and_uncommited"
);
/* lookup pending change in .gitmodules that is neither in HEAD nor index */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_gitmodules_only"
));
cl_assert
(
sm
);
/* lookup pending change in .gitmodules that is not in HEAD nor index */
assert_submodule_exists
(
g_repo
,
"sm_gitmodules_only"
);
/* lookup git repo subdir that is not added as submodule */
cl_assert
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"not-submodule"
)
==
GIT_EEXISTS
);
refute_submodule_exists
(
g_repo
,
"not-submodule"
,
GIT_EEXISTS
);
/* lookup existing directory that is not a submodule */
cl_assert
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_dir"
)
==
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"just_a_dir"
,
GIT_ENOTFOUND
);
/* lookup existing file that is not a submodule */
cl_assert
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_file"
)
==
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"just_a_file"
,
GIT_ENOTFOUND
);
/* lookup non-existent item */
cl_assert
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"no_such_file"
)
==
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"no_such_file"
,
GIT_ENOTFOUND
);
}
void
test_submodule_lookup__accessors
(
void
)
...
...
@@ -57,6 +51,9 @@ void test_submodule_lookup__accessors(void)
cl_assert
(
git_submodule_ignore
(
sm
)
==
GIT_SUBMODULE_IGNORE_NONE
);
cl_assert
(
git_submodule_update
(
sm
)
==
GIT_SUBMODULE_UPDATE_CHECKOUT
);
git_submodule_free
(
sm
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_assert_equal_s
(
"sm_changed_head"
,
git_submodule_name
(
sm
));
...
...
@@ -65,6 +62,9 @@ void test_submodule_lookup__accessors(void)
cl_assert
(
git_oid_streq
(
git_submodule_wd_id
(
sm
),
"3d9386c507f6b093471a3e324085657a3c2b4247"
)
==
0
);
git_submodule_free
(
sm
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_assert_equal_s
(
"sm_added_and_uncommited"
,
git_submodule_name
(
sm
));
...
...
@@ -72,6 +72,9 @@ void test_submodule_lookup__accessors(void)
cl_assert
(
git_submodule_head_id
(
sm
)
==
NULL
);
cl_assert
(
git_oid_streq
(
git_submodule_wd_id
(
sm
),
oid
)
==
0
);
git_submodule_free
(
sm
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_missing_commits"
));
cl_assert_equal_s
(
"sm_missing_commits"
,
git_submodule_name
(
sm
));
...
...
@@ -79,6 +82,8 @@ void test_submodule_lookup__accessors(void)
cl_assert
(
git_oid_streq
(
git_submodule_head_id
(
sm
),
oid
)
==
0
);
cl_assert
(
git_oid_streq
(
git_submodule_wd_id
(
sm
),
"5e4963595a9774b90524d35a807169049de8ccad"
)
==
0
);
git_submodule_free
(
sm
);
}
typedef
struct
{
...
...
@@ -104,69 +109,35 @@ void test_submodule_lookup__foreach(void)
void
test_submodule_lookup__lookup_even_with_unborn_head
(
void
)
{
git_reference
*
head
;
git_submodule
*
sm
;
/* put us on an unborn branch */
cl_git_pass
(
git_reference_symbolic_create
(
&
head
,
g_repo
,
"HEAD"
,
"refs/heads/garbage"
,
1
,
NULL
,
NULL
));
git_reference_free
(
head
);
/* lookup existing */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_assert
(
sm
);
/* lookup pending change in .gitmodules that is not in HEAD */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_assert
(
sm
);
/* lookup pending change in .gitmodules that is neither in HEAD nor index */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_gitmodules_only"
));
cl_assert
(
sm
);
/* lookup git repo subdir that is not added as submodule */
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not-submodule"
));
/* lookup existing directory that is not a submodule */
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_dir"
));
/* lookup existing file that is not a submodule */
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_file"
));
/* lookup non-existent item */
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"no_such_file"
));
assert_submodule_exists
(
g_repo
,
"sm_unchanged"
);
assert_submodule_exists
(
g_repo
,
"sm_added_and_uncommited"
);
assert_submodule_exists
(
g_repo
,
"sm_gitmodules_only"
);
refute_submodule_exists
(
g_repo
,
"not-submodule"
,
GIT_EEXISTS
);
refute_submodule_exists
(
g_repo
,
"just_a_dir"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"just_a_file"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"no_such_file"
,
GIT_ENOTFOUND
);
}
void
test_submodule_lookup__lookup_even_with_missing_index
(
void
)
{
git_index
*
idx
;
git_submodule
*
sm
;
/* give the repo an empty index */
cl_git_pass
(
git_index_new
(
&
idx
));
git_repository_set_index
(
g_repo
,
idx
);
git_index_free
(
idx
);
/* lookup existing */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_assert
(
sm
);
/* lookup pending change in .gitmodules that is not in HEAD */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_assert
(
sm
);
/* lookup pending change in .gitmodules that is neither in HEAD nor index */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_gitmodules_only"
));
cl_assert
(
sm
);
/* lookup git repo subdir that is not added as submodule */
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not-submodule"
));
/* lookup existing directory that is not a submodule */
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_dir"
));
/* lookup existing file that is not a submodule */
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_file"
));
/* lookup non-existent item */
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"no_such_file"
));
assert_submodule_exists
(
g_repo
,
"sm_unchanged"
);
assert_submodule_exists
(
g_repo
,
"sm_added_and_uncommited"
);
assert_submodule_exists
(
g_repo
,
"sm_gitmodules_only"
);
refute_submodule_exists
(
g_repo
,
"not-submodule"
,
GIT_EEXISTS
);
refute_submodule_exists
(
g_repo
,
"just_a_dir"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"just_a_file"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"no_such_file"
,
GIT_ENOTFOUND
);
}
tests/submodule/modify.c
View file @
dc7efa1a
...
...
@@ -21,15 +21,16 @@ void test_submodule_modify__add(void)
const
char
*
s
;
/* re-add existing submodule */
cl_assert
(
git_submodule_add_setup
(
NULL
,
g_repo
,
"whatever"
,
"sm_unchanged"
,
1
)
==
GIT_EEXISTS
);
cl_assert
_equal_i
(
GIT_EEXISTS
,
git_submodule_add_setup
(
NULL
,
g_repo
,
"whatever"
,
"sm_unchanged"
,
1
)
);
/* add a submodule using a gitlink */
cl_git_pass
(
git_submodule_add_setup
(
&
sm
,
g_repo
,
SM_LIBGIT2_URL
,
SM_LIBGIT2
,
1
)
);
git_submodule_free
(
sm
);
cl_assert
(
git_path_isfile
(
"submod2/"
SM_LIBGIT2
"/.git"
));
...
...
@@ -48,6 +49,7 @@ void test_submodule_modify__add(void)
cl_git_pass
(
git_submodule_add_setup
(
&
sm
,
g_repo
,
SM_LIBGIT2_URL
,
SM_LIBGIT2B
,
0
)
);
git_submodule_free
(
sm
);
cl_assert
(
git_path_isdir
(
"submod2/"
SM_LIBGIT2B
"/.git"
));
cl_assert
(
git_path_isfile
(
"submod2/"
SM_LIBGIT2B
"/.git/HEAD"
));
...
...
@@ -95,7 +97,7 @@ void test_submodule_modify__init(void)
/* call init and see that settings are copied */
cl_git_pass
(
git_submodule_foreach
(
g_repo
,
init_one_submodule
,
NULL
));
git_submodule_reload_all
(
g_repo
);
git_submodule_reload_all
(
g_repo
,
1
);
/* confirm submodule data in config */
cl_git_pass
(
git_repository_config
(
&
cfg
,
g_repo
));
...
...
@@ -159,6 +161,10 @@ void test_submodule_modify__sync(void)
cl_git_pass
(
git_config_get_string
(
&
str
,
cfg
,
"submodule."
SM3
".url"
));
cl_assert_equal_s
(
git_submodule_url
(
sm3
),
str
);
git_config_free
(
cfg
);
git_submodule_free
(
sm1
);
git_submodule_free
(
sm2
);
git_submodule_free
(
sm3
);
}
void
test_submodule_modify__edit_and_save
(
void
)
...
...
@@ -231,7 +237,7 @@ void test_submodule_modify__edit_and_save(void)
cl_assert_equal_i
(
GIT_SUBMODULE_RECURSE_YES
,
git_submodule_fetch_recurse_submodules
(
sm1
));
/* call reload and check that the new values are loaded */
cl_git_pass
(
git_submodule_reload
(
sm1
));
cl_git_pass
(
git_submodule_reload
(
sm1
,
0
));
cl_assert_equal_s
(
SM_LIBGIT2_URL
,
git_submodule_url
(
sm1
));
cl_assert_equal_i
(
...
...
@@ -253,16 +259,18 @@ void test_submodule_modify__edit_and_save(void)
GIT_SUBMODULE_RECURSE_NO
,
git_submodule_fetch_recurse_submodules
(
sm2
));
/* set fetchRecurseSubmodules on-demand */
cl_git_pass
(
git_submodule_reload
(
sm1
));
cl_git_pass
(
git_submodule_reload
(
sm1
,
0
));
git_submodule_set_fetch_recurse_submodules
(
sm1
,
GIT_SUBMODULE_RECURSE_ONDEMAND
);
cl_assert_equal_i
(
GIT_SUBMODULE_RECURSE_ONDEMAND
,
git_submodule_fetch_recurse_submodules
(
sm1
));
/* call save */
cl_git_pass
(
git_submodule_save
(
sm1
));
cl_git_pass
(
git_submodule_reload
(
sm1
));
cl_git_pass
(
git_submodule_reload
(
sm1
,
0
));
cl_assert_equal_i
(
GIT_SUBMODULE_RECURSE_ONDEMAND
,
git_submodule_fetch_recurse_submodules
(
sm1
));
git_submodule_free
(
sm1
);
git_submodule_free
(
sm2
);
git_repository_free
(
r2
);
git__free
(
old_url
);
}
tests/submodule/status.c
View file @
dc7efa1a
...
...
@@ -18,19 +18,43 @@ void test_submodule_status__cleanup(void)
void
test_submodule_status__unchanged
(
void
)
{
unsigned
int
status
,
expected
;
git_submodule
*
sm
;
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
expected
=
GIT_SUBMODULE_STATUS_IN_HEAD
|
unsigned
int
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
unsigned
int
expected
=
GIT_SUBMODULE_STATUS_IN_HEAD
|
GIT_SUBMODULE_STATUS_IN_INDEX
|
GIT_SUBMODULE_STATUS_IN_CONFIG
|
GIT_SUBMODULE_STATUS_IN_WD
;
cl_assert
(
status
==
expected
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_assert
(
expected
==
status
);
}
static
void
rm_submodule
(
const
char
*
name
)
{
git_buf
path
=
GIT_BUF_INIT
;
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
g_repo
),
name
));
cl_git_pass
(
git_futils_rmdir_r
(
path
.
ptr
,
NULL
,
GIT_RMDIR_REMOVE_FILES
));
git_buf_free
(
&
path
);
}
static
void
add_submodule_to_index
(
const
char
*
name
)
{
git_submodule
*
sm
;
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
name
));
cl_git_pass
(
git_submodule_add_to_index
(
sm
,
true
));
git_submodule_free
(
sm
);
}
static
void
rm_submodule_from_index
(
const
char
*
name
)
{
git_index
*
index
;
size_t
pos
;
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
cl_assert
(
!
git_index_find
(
&
pos
,
index
,
name
));
cl_git_pass
(
git_index_remove
(
index
,
name
,
0
));
cl_git_pass
(
git_index_write
(
index
));
git_index_free
(
index
);
}
/* 4 values of GIT_SUBMODULE_IGNORE to check */
...
...
@@ -38,81 +62,49 @@ void test_submodule_status__unchanged(void)
void
test_submodule_status__ignore_none
(
void
)
{
unsigned
int
status
;
git_submodule
*
sm
;
git_buf
path
=
GIT_BUF_INIT
;
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
g_repo
),
"sm_unchanged"
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
NULL
,
GIT_RMDIR_REMOVE_FILES
));
rm_submodule
(
"sm_unchanged"
);
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_dir"
));
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not-submodule"
));
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not"
));
refute_submodule_exists
(
g_repo
,
"just_a_dir"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"not-submodule"
,
GIT_EEXISTS
);
refute_submodule_exists
(
g_repo
,
"not"
,
GIT_EEXISTS
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_index"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_index"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_file"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_untracked_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_untracked_file"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_UNTRACKED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_missing_commits"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_missing_commits"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_added_and_uncommited"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_INDEX_ADDED
)
!=
0
);
/* removed sm_unchanged for deleted workdir */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_DELETED
)
!=
0
);
/* now mkdir sm_unchanged to test uninitialized */
cl_git_pass
(
git_futils_mkdir
(
git_buf_cstr
(
&
path
),
NULL
,
0755
,
0
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_reload
(
sm
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
cl_git_pass
(
git_futils_mkdir
(
"sm_unchanged"
,
"submod2"
,
0755
,
0
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_UNINITIALIZED
)
!=
0
);
/* update sm_changed_head in index */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_add_to_index
(
sm
,
true
));
/* reload is not needed because add_to_index updates the submodule data */
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
add_submodule_to_index
(
"sm_changed_head"
);
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_INDEX_MODIFIED
)
!=
0
);
/* remove sm_changed_head from index */
{
git_index
*
index
;
size_t
pos
;
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
cl_assert
(
!
git_index_find
(
&
pos
,
index
,
"sm_changed_head"
));
cl_git_pass
(
git_index_remove
(
index
,
"sm_changed_head"
,
0
));
cl_git_pass
(
git_index_write
(
index
));
git_index_free
(
index
);
}
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_reload
(
sm
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
rm_submodule_from_index
(
"sm_changed_head"
);
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_INDEX_DELETED
)
!=
0
);
git_buf_free
(
&
path
);
}
static
int
set_sm_ignore
(
git_submodule
*
sm
,
const
char
*
name
,
void
*
payload
)
...
...
@@ -126,191 +118,136 @@ static int set_sm_ignore(git_submodule *sm, const char *name, void *payload)
void
test_submodule_status__ignore_untracked
(
void
)
{
unsigned
int
status
;
git_submodule
*
sm
;
git_buf
path
=
GIT_BUF_INIT
;
git_submodule_ignore_t
ign
=
GIT_SUBMODULE_IGNORE_UNTRACKED
;
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
g_repo
),
"sm_unchanged"
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
NULL
,
GIT_RMDIR_REMOVE_FILES
));
rm_submodule
(
"sm_unchanged"
);
cl_git_pass
(
git_submodule_foreach
(
g_repo
,
set_sm_ignore
,
&
ign
));
cl_git_fail
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"not-submodule"
));
refute_submodule_exists
(
g_repo
,
"just_a_dir"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"not-submodule"
,
GIT_EEXISTS
);
refute_submodule_exists
(
g_repo
,
"not"
,
GIT_EEXISTS
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_index"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_index"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_file"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_untracked_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_untracked_file"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_missing_commits"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_missing_commits"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_added_and_uncommited"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_INDEX_ADDED
)
!=
0
);
/* removed sm_unchanged for deleted workdir */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_DELETED
)
!=
0
);
/* now mkdir sm_unchanged to test uninitialized */
cl_git_pass
(
git_futils_mkdir
(
git_buf_cstr
(
&
path
),
NULL
,
0755
,
0
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_reload
(
sm
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
cl_git_pass
(
git_futils_mkdir
(
"sm_unchanged"
,
"submod2"
,
0755
,
0
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_UNINITIALIZED
)
!=
0
);
/* update sm_changed_head in index */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_add_to_index
(
sm
,
true
));
/* reload is not needed because add_to_index updates the submodule data */
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
add_submodule_to_index
(
"sm_changed_head"
);
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_INDEX_MODIFIED
)
!=
0
);
git_buf_free
(
&
path
);
}
void
test_submodule_status__ignore_dirty
(
void
)
{
unsigned
int
status
;
git_submodule
*
sm
;
git_buf
path
=
GIT_BUF_INIT
;
git_submodule_ignore_t
ign
=
GIT_SUBMODULE_IGNORE_DIRTY
;
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
g_repo
),
"sm_unchanged"
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
NULL
,
GIT_RMDIR_REMOVE_FILES
));
rm_submodule
(
"sm_unchanged"
);
cl_git_pass
(
git_submodule_foreach
(
g_repo
,
set_sm_ignore
,
&
ign
));
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_dir"
));
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not-submodule"
));
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not"
));
refute_submodule_exists
(
g_repo
,
"just_a_dir"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"not-submodule"
,
GIT_EEXISTS
);
refute_submodule_exists
(
g_repo
,
"not"
,
GIT_EEXISTS
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_index"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_index"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_file"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_untracked_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_untracked_file"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_missing_commits"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_missing_commits"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
!=
0
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_added_and_uncommited"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_INDEX_ADDED
)
!=
0
);
/* removed sm_unchanged for deleted workdir */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_DELETED
)
!=
0
);
/* now mkdir sm_unchanged to test uninitialized */
cl_git_pass
(
git_futils_mkdir
(
git_buf_cstr
(
&
path
),
NULL
,
0755
,
0
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_reload
(
sm
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
cl_git_pass
(
git_futils_mkdir
(
"sm_unchanged"
,
"submod2"
,
0755
,
0
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_WD_UNINITIALIZED
)
!=
0
);
/* update sm_changed_head in index */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_add_to_index
(
sm
,
true
));
/* reload is not needed because add_to_index updates the submodule data */
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
add_submodule_to_index
(
"sm_changed_head"
);
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
((
status
&
GIT_SUBMODULE_STATUS_INDEX_MODIFIED
)
!=
0
);
git_buf_free
(
&
path
);
}
void
test_submodule_status__ignore_all
(
void
)
{
unsigned
int
status
;
git_submodule
*
sm
;
git_buf
path
=
GIT_BUF_INIT
;
git_submodule_ignore_t
ign
=
GIT_SUBMODULE_IGNORE_ALL
;
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
g_repo
),
"sm_unchanged"
));
cl_git_pass
(
git_futils_rmdir_r
(
git_buf_cstr
(
&
path
),
NULL
,
GIT_RMDIR_REMOVE_FILES
));
rm_submodule
(
"sm_unchanged"
);
cl_git_pass
(
git_submodule_foreach
(
g_repo
,
set_sm_ignore
,
&
ign
));
cl_assert_equal_i
(
GIT_ENOTFOUND
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"just_a_dir"
));
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not-submodule"
));
cl_assert_equal_i
(
GIT_EEXISTS
,
git_submodule_lookup
(
&
sm
,
g_repo
,
"not"
));
refute_submodule_exists
(
g_repo
,
"just_a_dir"
,
GIT_ENOTFOUND
);
refute_submodule_exists
(
g_repo
,
"not-submodule"
,
GIT_EEXISTS
);
refute_submodule_exists
(
g_repo
,
"not"
,
GIT_EEXISTS
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_index"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_index"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_file"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_untracked_file"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_changed_untracked_file"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_missing_commits"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_missing_commits"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_added_and_uncommited"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_added_and_uncommited"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
/* removed sm_unchanged for deleted workdir */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
/* now mkdir sm_unchanged to test uninitialized */
cl_git_pass
(
git_futils_mkdir
(
git_buf_cstr
(
&
path
),
NULL
,
0755
,
0
));
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_reload
(
sm
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
cl_git_pass
(
git_futils_mkdir
(
"sm_unchanged"
,
"submod2"
,
0755
,
0
));
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
/* update sm_changed_head in index */
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_changed_head"
));
cl_git_pass
(
git_submodule_add_to_index
(
sm
,
true
));
/* reload is not needed because add_to_index updates the submodule data */
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
add_submodule_to_index
(
"sm_changed_head"
);
status
=
get_submodule_status
(
g_repo
,
"sm_changed_head"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
git_buf_free
(
&
path
);
}
typedef
struct
{
...
...
@@ -401,29 +338,23 @@ void test_submodule_status__iterator(void)
void
test_submodule_status__untracked_dirs_containing_ignored_files
(
void
)
{
git_buf
path
=
GIT_BUF_INIT
;
unsigned
int
status
,
expected
;
git_submodule
*
sm
;
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_path
(
g_repo
),
"modules/sm_unchanged/info/exclude"
));
cl_git_append2file
(
git_buf_cstr
(
&
path
),
"
\n
*.ignored
\n
"
);
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_repository_workdir
(
g_repo
),
"sm_unchanged/directory"
));
cl_git_pass
(
git_futils_mkdir
(
git_buf_cstr
(
&
path
),
NULL
,
0755
,
0
));
cl_git_pass
(
git_buf_joinpath
(
&
path
,
git_buf_cstr
(
&
path
),
"i_am.ignored"
));
cl_git_mkfile
(
git_buf_cstr
(
&
path
),
"ignored this file, please
\n
"
);
cl_git_append2file
(
"submod2/.git/modules/sm_unchanged/info/exclude"
,
"
\n
*.ignored
\n
"
);
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
g_repo
,
"sm_unchanged"
));
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
cl_git_pass
(
git_futils_mkdir
(
"sm_unchanged/directory"
,
"submod2"
,
0755
,
0
));
cl_git_mkfile
(
"submod2/sm_unchanged/directory/i_am.ignored"
,
"ignore this file, please
\n
"
);
status
=
get_submodule_status
(
g_repo
,
"sm_unchanged"
);
cl_assert
(
GIT_SUBMODULE_STATUS_IS_UNMODIFIED
(
status
));
expected
=
GIT_SUBMODULE_STATUS_IN_HEAD
|
GIT_SUBMODULE_STATUS_IN_INDEX
|
GIT_SUBMODULE_STATUS_IN_CONFIG
|
GIT_SUBMODULE_STATUS_IN_WD
;
cl_assert
(
status
==
expected
);
git_buf_free
(
&
path
);
}
tests/submodule/submodule_helpers.c
View file @
dc7efa1a
...
...
@@ -125,3 +125,32 @@ git_repository *setup_fixture_submod2(void)
return
repo
;
}
void
assert_submodule_exists
(
git_repository
*
repo
,
const
char
*
name
)
{
git_submodule
*
sm
;
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
repo
,
name
));
cl_assert
(
sm
);
git_submodule_free
(
sm
);
}
void
refute_submodule_exists
(
git_repository
*
repo
,
const
char
*
name
,
int
expected_error
)
{
git_submodule
*
sm
;
cl_assert_equal_i
(
expected_error
,
git_submodule_lookup
(
&
sm
,
repo
,
name
));
}
unsigned
int
get_submodule_status
(
git_repository
*
repo
,
const
char
*
name
)
{
git_submodule
*
sm
=
NULL
;
unsigned
int
status
=
0
;
cl_git_pass
(
git_submodule_lookup
(
&
sm
,
repo
,
name
));
cl_assert
(
sm
);
cl_git_pass
(
git_submodule_status
(
&
status
,
sm
));
git_submodule_free
(
sm
);
return
status
;
}
tests/submodule/submodule_helpers.h
View file @
dc7efa1a
...
...
@@ -3,3 +3,8 @@ extern void rewrite_gitmodules(const char *workdir);
/* these will automatically set a cleanup callback */
extern
git_repository
*
setup_fixture_submodules
(
void
);
extern
git_repository
*
setup_fixture_submod2
(
void
);
extern
unsigned
int
get_submodule_status
(
git_repository
*
,
const
char
*
);
extern
void
assert_submodule_exists
(
git_repository
*
,
const
char
*
);
extern
void
refute_submodule_exists
(
git_repository
*
,
const
char
*
,
int
err
);
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