We store the changed submodules paths to calculate which submodule needs
fetching. This does not work for moved submodules since their paths do
not stay the same in case of a moved submodules. In case of new
submodules we do not have a path in the current checkout, since they
just appeared in this fetch.
It is more general to collect the submodule names for changes instead of
their paths to include the above cases.
With the change described above we implement 'on-demand' fetching of
changes in moved submodules.
Note: This does only work when repositories have a .gitmodules file. In
other words: It breaks if we do not get a name for a repository.
IIRC, consensus was that this is a requirement to get nice submodule
handling these days?
Signed-off-by: Heiko Voigt <redacted>
---
I updated the leftover code from my series implementing recursive fetch
for moved submodules[1] to the current master.
This breaks t5531 and t5545 because they do not use a .gitmodules file.
I also have some code leftover that does fallback on paths in case no
submodule names can be found. But I do not really like it. The question
here is how far do we support not using .gitmodules. Is it e.g.
reasonable to say: "For --recurse-submodules=on-demand you need a
.gitmodules file?"
[1] https://public-inbox.org/git/f5baa2acc09531a16f4f693eebbe60706bb8ed1e.1361751905.git.hvoigt@hvoigt.net/
submodule.c | 92 +++++++++++++++++++++++++--------------------
t/t5526-fetch-submodules.sh | 35 +++++++++++++++++
2 files changed, 86 insertions(+), 41 deletions(-)
@@ -755,39 +755,34 @@ static struct oid_array *submodule_commits(struct string_list *submodules,return(structoid_array*)item->util;}+structcollect_changed_submodules_cb_data{+structstring_list*changed;+conststructobject_id*commit_oid;+};+staticvoidcollect_changed_submodules_cb(structdiff_queue_struct*q,structdiff_options*options,void*data){+structcollect_changed_submodules_cb_data*me=data;+structstring_list*changed=me->changed;+conststructobject_id*commit_oid=me->commit_oid;inti;-structstring_list*changed=data;for(i=0;i<q->nr;i++){structdiff_filepair*p=q->queue[i];structoid_array*commits;+conststructsubmodule*submodule;+if(!S_ISGITLINK(p->two->mode))continue;-if(S_ISGITLINK(p->one->mode)){-/*-*NEEDSWORK:Weshouldhonorthenameconfiguredin-*the.gitmodulesfileofthecommitweareexamining-*heretobeabletocorrectlyfollowsubmodules-*beingmovedaround.-*/-commits=submodule_commits(changed,p->two->path);-oid_array_append(commits,&p->two->oid);-}else{-/* Submodule is new or was moved here */-/*-*NEEDSWORK:Whenthe.gitdirectoriesofsubmodules-*liveinsidethesuperprojects.gitdirectorysome-*dayweshouldfetchnewsubmodulesdirectlyinto-*thatlocationtoowhenconfigoroptionsrequest-*thatsotheycanbecheckedoutfromthere.-*/+submodule=submodule_from_path(commit_oid,p->two->path);+if(!submodule)continue;-}++commits=submodule_commits(changed,submodule->name);+oid_array_append(commits,&p->two->oid);}}
@@ -945,7 +944,7 @@ int find_unpushed_submodules(struct oid_array *commits,constchar*remotes_name,structstring_list*needs_pushing){structstring_listsubmodules=STRING_LIST_INIT_DUP;-structstring_list_item*submodule;+structstring_list_item*name;structargv_arrayargv=ARGV_ARRAY_INIT;/* argv.argv[0] will be ignored by setup_revisions */
@@ -956,12 +955,16 @@ int find_unpushed_submodules(struct oid_array *commits,collect_changed_submodules(&submodules,&argv);-for_each_string_list_item(submodule,&submodules){-structoid_array*commits=submodule->util;-constchar*path=submodule->string;+for_each_string_list_item(name,&submodules){+structoid_array*commits=name->util;+conststructsubmodule*submodule;++submodule=submodule_from_name(&null_oid,name->string);+if(!submodule)+continue;-if(submodule_needs_pushing(path,commits))-string_list_insert(needs_pushing,path);+if(submodule_needs_pushing(submodule->path,commits))+string_list_insert(needs_pushing,submodule->path);}free_submodules_oids(&submodules);
@@ -1104,7 +1107,7 @@ static void calculate_changed_submodule_paths(void){structargv_arrayargv=ARGV_ARRAY_INIT;structstring_listchanged_submodules=STRING_LIST_INIT_DUP;-conststructstring_list_item*item;+conststructstring_list_item*name;/* No need to check if there are no submodules configured */if(!submodule_from_path(NULL,NULL))
@@ -530,4 +530,39 @@ test_expect_success 'fetching submodule into a broken repository' 'test_must_failgit-Cdstfetch--recurse-submodules'+test_expect_success"fetch new commits when submodule got renamed"'+gitclone.downstream_rename&&+(+cddownstream_rename&&+gitsubmoduleupdate--init&&+# NEEDSWORK: we omitted --recursive for the submodule update here since+# that does not work. See test 7001 for mv "moving nested submodules"+# for details. Once that is fixed we should add the --recursive option+# here.+gitcheckout-brename&&+gitmvsubmodulesubmodule_renamed&&+(+cdsubmodule_renamed&&+gitcheckout-brename_sub&&+echoa>a&&+gitadda&&+gitcommit-ma&&+gitpushoriginrename_sub&&+gitrev-parseHEAD>../../expect+)&&+gitaddsubmodule_renamed&&+gitcommit-m"update renamed submodule"&&+gitpushoriginrename+)&&+(+cddownstream&&+gitfetch--recurse-submodules=on-demand&&+(+cdsubmodule&&+gitrev-parseorigin/rename_sub>../../actual+)+)&&+test_cmpexpectactual+'+ test_done
To make extending this logic later easier.
Signed-off-by: Heiko Voigt <redacted>
---
I am quite sure I replicated the same logic but a few more eyes would be
appreciated.
Cheers Heiko
submodule.c | 55 +++++++++++++++++++++++++++----------------------------
1 file changed, 27 insertions(+), 28 deletions(-)
From: Stefan Beller <hidden> Date: 2017-08-17 17:20:20
On Thu, Aug 17, 2017 at 3:53 AM, Heiko Voigt [off-list ref] wrote:
We store the changed submodules paths to calculate which submodule needs
fetching. This does not work for moved submodules since their paths do
not stay the same in case of a moved submodules. In case of new
submodules we do not have a path in the current checkout, since they
just appeared in this fetch.
It is more general to collect the submodule names for changes instead of
their paths to include the above cases.
With the change described above we implement 'on-demand' fetching of
changes in moved submodules.
This sounds as if this would also enable fetching new submodules
eventually?
Note: This does only work when repositories have a .gitmodules file. In
other words: It breaks if we do not get a name for a repository.
IIRC, consensus was that this is a requirement to get nice submodule
handling these days?
I think that should have been the consensus since ~1.7.8 (since the
submodules git dir can live inside the superprojects
<gitdir>/module/<name>).
A gitlink entry without corresponding .gitmodules entry is just a gitlink.
If we happen to have a repository at that path of the gitlink, we can
be nice and pretend like it is a functional submodule, but it really is
not. It's just another repo inside the superproject that happen to live
at the path of a gitlink.
Signed-off-by: Heiko Voigt <redacted>
---
I updated the leftover code from my series implementing recursive fetch
for moved submodules[1] to the current master.
This breaks t5531 and t5545 because they do not use a .gitmodules file.
I also have some code leftover that does fallback on paths in case no
submodule names can be found. But I do not really like it. The question
here is how far do we support not using .gitmodules. Is it e.g.
reasonable to say: "For --recurse-submodules=on-demand you need a
.gitmodules file?"
I would not intentionally break users here, but any new functionality can
safely assume (a) we have a proper .gitmodules entry or (b) it is not a
submodule, so do nothing/be extra careful.
For example in recursive diff sort of makes sense to also handle
non-submodule gitlinks, but fetch is harder to tell.
(just last night I was rereading
https://public-inbox.org/git/CAJo=hJvnAPNAdDcAAwAvU9C4RVeQdoS3Ev9WTguHx4fD0V_nOg@mail.gmail.com/
which I think is a super cute application of gitlinks. If you happen
to checkout such
a tree, you don't want to fetch all of the fake submodules)
(optional style nit, personal opinion, feel free to ignore)
I personally prefer to not name variables exactly as their type.
Also most (all) of the struct submodule uses used 'sub' as
the variable name, maybe keep it consistent?
quoted hunk
+
if (!S_ISGITLINK(p->two->mode))
continue;
- if (S_ISGITLINK(p->one->mode)) {
- /*
- * NEEDSWORK: We should honor the name configured in
- * the .gitmodules file of the commit we are examining
- * here to be able to correctly follow submodules
- * being moved around.
- */
- commits = submodule_commits(changed, p->two->path);
- oid_array_append(commits, &p->two->oid);
- } else {
- /* Submodule is new or was moved here */
- /*
- * NEEDSWORK: When the .git directories of submodules
- * live inside the superprojects .git directory some
- * day we should fetch new submodules directly into
- * that location too when config or options request
- * that so they can be checked out from there.
- */
+ submodule = submodule_from_path(commit_oid, p->two->path);
+ if (!submodule)
continue;
- }
+
+ commits = submodule_commits(changed, submodule->name);
+ oid_array_append(commits, &p->two->oid);
}
}
@@ -530,4 +530,39 @@ test_expect_success 'fetching submodule into a broken repository' 'test_must_failgit-Cdstfetch--recurse-submodules'+test_expect_success"fetch new commits when submodule got renamed"'+gitclone.downstream_rename&&+(+cddownstream_rename&&+gitsubmoduleupdate--init&&+# NEEDSWORK: we omitted --recursive for the submodule update here since+# that does not work. See test 7001 for mv "moving nested submodules"+# for details. Once that is fixed we should add the --recursive option+# here.+gitcheckout-brename&&+gitmvsubmodulesubmodule_renamed&&+(+cdsubmodule_renamed&&+gitcheckout-brename_sub&&+echoa>a&&+gitadda&&+gitcommit-ma&&+gitpushoriginrename_sub&&+gitrev-parseHEAD>../../expect+)&&+gitaddsubmodule_renamed&&+gitcommit-m"update renamed submodule"&&+gitpushoriginrename+)&&+(+cddownstream&&+gitfetch--recurse-submodules=on-demand&&+(+cdsubmodule&&+gitrev-parseorigin/rename_sub>../../actual+)+)&&+test_cmpexpectactual+'+ test_done--
From: Stefan Beller <hidden> Date: 2017-08-17 17:24:52
On Thu, Aug 17, 2017 at 4:00 AM, Heiko Voigt [off-list ref] wrote:
To make extending this logic later easier.
Signed-off-by: Heiko Voigt <redacted>
---
I am quite sure I replicated the same logic but a few more eyes would be
appreciated.
A code cleanup is appreciated!
I thought Brandon had a series in flight doing a very similar cleanup here,
but in master..pu there is nothing to be found.
From: Brandon Williams <hidden> Date: 2017-08-17 17:50:22
On 08/17, Stefan Beller wrote:
On Thu, Aug 17, 2017 at 4:00 AM, Heiko Voigt [off-list ref] wrote:
quoted
To make extending this logic later easier.
Signed-off-by: Heiko Voigt <redacted>
---
I am quite sure I replicated the same logic but a few more eyes would be
appreciated.
A code cleanup is appreciated!
I thought Brandon had a series in flight doing a very similar cleanup here,
but in master..pu there is nothing to be found.
Yeah there are 2 series in flight which will probably conflict here.
bw/grep-recurse-submodules and bw/submodule-config-cleanup
On Thu, Aug 17, 2017 at 10:50:07AM -0700, Brandon Williams wrote:
On 08/17, Stefan Beller wrote:
quoted
On Thu, Aug 17, 2017 at 4:00 AM, Heiko Voigt [off-list ref] wrote:
quoted
To make extending this logic later easier.
Signed-off-by: Heiko Voigt <redacted>
---
I am quite sure I replicated the same logic but a few more eyes would be
appreciated.
A code cleanup is appreciated!
I thought Brandon had a series in flight doing a very similar cleanup here,
but in master..pu there is nothing to be found.
Yeah there are 2 series in flight which will probably conflict here.
bw/grep-recurse-submodules and bw/submodule-config-cleanup
Ok then I will wait until those are in and then see if I can base the
cleanup on top. I think it is only necessary as a preparation for the
fully fledged fetch configuration logic mess we will get into once we
get to the full recursive submodule fetch implementation. Not
necessarily needed for the moved submodules.
On Thu, Aug 17, 2017 at 10:20:13AM -0700, Stefan Beller wrote:
On Thu, Aug 17, 2017 at 3:53 AM, Heiko Voigt [off-list ref] wrote:
quoted
We store the changed submodules paths to calculate which submodule needs
fetching. This does not work for moved submodules since their paths do
not stay the same in case of a moved submodules. In case of new
submodules we do not have a path in the current checkout, since they
just appeared in this fetch.
It is more general to collect the submodule names for changes instead of
their paths to include the above cases.
With the change described above we implement 'on-demand' fetching of
changes in moved submodules.
This sounds as if this would also enable fetching new submodules
eventually?
Yes that was the goal when starting with these changes back then. But it
took more time than I had back then. So instead of letting these changes
sit bitrot again lets see if we can get them integrated.
For new submodules we need to change the iteration somehow. Currently we
are iterating through the index. But new submodules obviously do not
have an index entry (otherwise they would not be new). So instead of the
index we will need to create another list that contains "all"
submodules. Maybe something like: all submodules from the index plus all
submodules that changed / are new? We could also go further and inspect
all submodules from all ref tips to handle submodules on other branches
configured to 'yes'. But I think we should leave that for later if need
arises.
Some merge of index and additional submodules is needed, because for
--recurse-submodules=yes or submodule.<name>.fetchRecurseSubmodules=yes
we always need to run fetch inside the submodule. That would break if we
only looked at submodules that are collected as changed.
quoted
Note: This does only work when repositories have a .gitmodules file. In
other words: It breaks if we do not get a name for a repository.
IIRC, consensus was that this is a requirement to get nice submodule
handling these days?
I think that should have been the consensus since ~1.7.8 (since the
submodules git dir can live inside the superprojects
<gitdir>/module/<name>).
I agree but since we started without it, we kind of have a mixed state.
A gitlink entry without corresponding .gitmodules entry is just a gitlink.
If we happen to have a repository at that path of the gitlink, we can
be nice and pretend like it is a functional submodule, but it really is
not. It's just another repo inside the superproject that happen to live
at the path of a gitlink.
Yeah but at the moment we are handling 'on-demand' fetches and stuff for
such just gitlink submodules. If we were firm on that requirement we
would just skip those but that is not the case with the current
implementation.
quoted
Signed-off-by: Heiko Voigt <redacted>
---
I updated the leftover code from my series implementing recursive fetch
for moved submodules[1] to the current master.
This breaks t5531 and t5545 because they do not use a .gitmodules file.
I also have some code leftover that does fallback on paths in case no
submodule names can be found. But I do not really like it. The question
here is how far do we support not using .gitmodules. Is it e.g.
reasonable to say: "For --recurse-submodules=on-demand you need a
.gitmodules file?"
I would not intentionally break users here, but any new functionality can
safely assume (a) we have a proper .gitmodules entry or (b) it is not a
submodule, so do nothing/be extra careful.
For example in recursive diff sort of makes sense to also handle
non-submodule gitlinks, but fetch is harder to tell.
Well we have a few different cases for gitlinks without .gitmodule
entry:
1. New gitlink: We can not handle since we do not know where to clone
from.
2. Removed gitlink: No need to do anything in fetch
3. Changed (but same name) gitlink: We can / and currently do run fetch
in it
4. Renamed: We currently skip those. We could probably do something to
track the rename and run fetch in case of gitlink changes.
In my current approach only the ones with a name are
handled.
So I guess I will add a fallback to paths for 3. so we do not
unnecessarily break users using the current implementation.
Here a comment would be helpful or a more concise variable name.
(What is changed?)
I'll change that to 'changed_submodules' the caller who is passing this
in called this changed. It is the list of changed submodules to be
filled.
quoted
+ const struct object_id *commit_oid;
What about this name? It is the commit_oid in the superproject of the
current revision under investigation. IMO is easy to get confused what
commits are referenced superproject or submodule. Maybe
'super_commit_oid' would be more clear?
(optional style nit, personal opinion, feel free to ignore)
I personally prefer to not name variables exactly as their type.
Also most (all) of the struct submodule uses used 'sub' as
the variable name, maybe keep it consistent?
Well I understand that and its similar for me but I personally I do not
like abbreviations for variable names since I like to be able to read
code natually. So that took precendence over naming submodule
differently than its type here :) Counting submodule vs. sub in
submodule.c I see 4 vs. 5 occurrences... I'll think about it.
quoted
+
if (!S_ISGITLINK(p->two->mode))
continue;
- if (S_ISGITLINK(p->one->mode)) {
- /*
- * NEEDSWORK: We should honor the name configured in
- * the .gitmodules file of the commit we are examining
- * here to be able to correctly follow submodules
- * being moved around.
- */
- commits = submodule_commits(changed, p->two->path);
- oid_array_append(commits, &p->two->oid);
- } else {
- /* Submodule is new or was moved here */
- /*
- * NEEDSWORK: When the .git directories of submodules
- * live inside the superprojects .git directory some
- * day we should fetch new submodules directly into
- * that location too when config or options request
- * that so they can be checked out from there.
- */
+ submodule = submodule_from_path(commit_oid, p->two->path);
+ if (!submodule)
continue;
- }
+
+ commits = submodule_commits(changed, submodule->name);
+ oid_array_append(commits, &p->two->oid);
}
}
eventually we can also migrate to name here as well.
In a later patch.
Yeah, then it would be possible to also push submodules without a
populated worktree.
There was this other thread about the is-populated-check in
push_submodules() where it was consensus that it does not make much
sense but for a maintainer integrating others work it might be useful to
not always have all submodules populated.
Cheers Heiko
We store the changed submodules paths to calculate which submodule needs
fetching. This does not work for moved submodules since their paths do
not stay the same in case of a moved submodules. In case of new
submodules we do not have a path in the current checkout, since they
just appeared in this fetch.
It is more general to collect the submodule names for changes instead of
their paths to include the above cases.
With the change described above we implement 'on-demand' fetching of
changes in moved submodules.
Note: This does only work when repositories have a .gitmodules file. In
other words: It breaks if we do not get a name for a repository.
IIRC, consensus was that this is a requirement to get nice submodule
handling these days?
NEEDSWORK: This breaks t5531 and t5545 because they do not use a
.gitmodules file. I will add a fallback to paths to help such users.
Signed-off-by: Heiko Voigt <redacted>
---
This an update of the previous series[1] to the current master. The
fallback is still missing but now it should not conflict with any topics
in flight anymore (hopefully).
Cheers Heiko
[1] https://public-inbox.org/git/20170817105349.GC52233@book.hvoigt.net/
submodule.c | 91 +++++++++++++++++++++++++--------------------
t/t5526-fetch-submodules.sh | 35 +++++++++++++++++
2 files changed, 85 insertions(+), 41 deletions(-)
@@ -680,39 +680,34 @@ static struct oid_array *submodule_commits(struct string_list *submodules,return(structoid_array*)item->util;}+structcollect_changed_submodules_cb_data{+structstring_list*changed;+conststructobject_id*commit_oid;+};+staticvoidcollect_changed_submodules_cb(structdiff_queue_struct*q,structdiff_options*options,void*data){+structcollect_changed_submodules_cb_data*me=data;+structstring_list*changed=me->changed;+conststructobject_id*commit_oid=me->commit_oid;inti;-structstring_list*changed=data;for(i=0;i<q->nr;i++){structdiff_filepair*p=q->queue[i];structoid_array*commits;+conststructsubmodule*submodule;+if(!S_ISGITLINK(p->two->mode))continue;-if(S_ISGITLINK(p->one->mode)){-/*-*NEEDSWORK:Weshouldhonorthenameconfiguredin-*the.gitmodulesfileofthecommitweareexamining-*heretobeabletocorrectlyfollowsubmodules-*beingmovedaround.-*/-commits=submodule_commits(changed,p->two->path);-oid_array_append(commits,&p->two->oid);-}else{-/* Submodule is new or was moved here */-/*-*NEEDSWORK:Whenthe.gitdirectoriesofsubmodules-*liveinsidethesuperprojects.gitdirectorysome-*dayweshouldfetchnewsubmodulesdirectlyinto-*thatlocationtoowhenconfigoroptionsrequest-*thatsotheycanbecheckedoutfromthere.-*/+submodule=submodule_from_path(commit_oid,p->two->path);+if(!submodule)continue;-}++commits=submodule_commits(changed,submodule->name);+oid_array_append(commits,&p->two->oid);}}
@@ -870,7 +868,7 @@ int find_unpushed_submodules(struct oid_array *commits,constchar*remotes_name,structstring_list*needs_pushing){structstring_listsubmodules=STRING_LIST_INIT_DUP;-structstring_list_item*submodule;+structstring_list_item*name;structargv_arrayargv=ARGV_ARRAY_INIT;/* argv.argv[0] will be ignored by setup_revisions */
@@ -881,12 +879,16 @@ int find_unpushed_submodules(struct oid_array *commits,collect_changed_submodules(&submodules,&argv);-for_each_string_list_item(submodule,&submodules){-structoid_array*commits=submodule->util;-constchar*path=submodule->string;+for_each_string_list_item(name,&submodules){+structoid_array*commits=name->util;+conststructsubmodule*submodule;++submodule=submodule_from_name(&null_oid,name->string);+if(!submodule)+continue;-if(submodule_needs_pushing(path,commits))-string_list_insert(needs_pushing,path);+if(submodule_needs_pushing(submodule->path,commits))+string_list_insert(needs_pushing,submodule->path);}free_submodules_oids(&submodules);
@@ -1041,7 +1043,7 @@ static void calculate_changed_submodule_paths(void){structargv_arrayargv=ARGV_ARRAY_INIT;structstring_listchanged_submodules=STRING_LIST_INIT_DUP;-conststructstring_list_item*item;+conststructstring_list_item*name;/* No need to check if there are no submodules configured */if(!submodule_from_path(NULL,NULL))
@@ -530,4 +530,39 @@ test_expect_success 'fetching submodule into a broken repository' 'test_must_failgit-Cdstfetch--recurse-submodules'+test_expect_success"fetch new commits when submodule got renamed"'+gitclone.downstream_rename&&+(+cddownstream_rename&&+gitsubmoduleupdate--init&&+# NEEDSWORK: we omitted --recursive for the submodule update here since+# that does not work. See test 7001 for mv "moving nested submodules"+# for details. Once that is fixed we should add the --recursive option+# here.+gitcheckout-brename&&+gitmvsubmodulesubmodule_renamed&&+(+cdsubmodule_renamed&&+gitcheckout-brename_sub&&+echoa>a&&+gitadda&&+gitcommit-ma&&+gitpushoriginrename_sub&&+gitrev-parseHEAD>../../expect+)&&+gitaddsubmodule_renamed&&+gitcommit-m"update renamed submodule"&&+gitpushoriginrename+)&&+(+cddownstream&&+gitfetch--recurse-submodules=on-demand&&+(+cdsubmodule&&+gitrev-parseorigin/rename_sub>../../actual+)+)&&+test_cmpexpectactual+'+ test_done
From: Brandon Williams <hidden> Date: 2017-09-18 16:49:49
On 09/15, Heiko Voigt wrote:
We store the changed submodules paths to calculate which submodule needs
fetching. This does not work for moved submodules since their paths do
not stay the same in case of a moved submodules. In case of new
submodules we do not have a path in the current checkout, since they
just appeared in this fetch.
It is more general to collect the submodule names for changes instead of
their paths to include the above cases.
With the change described above we implement 'on-demand' fetching of
changes in moved submodules.
Note: This does only work when repositories have a .gitmodules file. In
other words: It breaks if we do not get a name for a repository.
IIRC, consensus was that this is a requirement to get nice submodule
handling these days?
NEEDSWORK: This breaks t5531 and t5545 because they do not use a
.gitmodules file. I will add a fallback to paths to help such users.
Signed-off-by: Heiko Voigt <redacted>
---
This an update of the previous series[1] to the current master. The
fallback is still missing but now it should not conflict with any topics
in flight anymore (hopefully).
So the idea is to collect changed submodule's name, instead of their
path, so that if they happened to moved you don't have to worry about
the path changing underneath you. This should be good once those tests
get fixed.
Thanks for working on cleaning this up! :)
@@ -680,39 +680,34 @@ static struct oid_array *submodule_commits(struct string_list *submodules,return(structoid_array*)item->util;}+structcollect_changed_submodules_cb_data{+structstring_list*changed;+conststructobject_id*commit_oid;+};+staticvoidcollect_changed_submodules_cb(structdiff_queue_struct*q,structdiff_options*options,void*data){+structcollect_changed_submodules_cb_data*me=data;+structstring_list*changed=me->changed;+conststructobject_id*commit_oid=me->commit_oid;inti;-structstring_list*changed=data;for(i=0;i<q->nr;i++){structdiff_filepair*p=q->queue[i];structoid_array*commits;+conststructsubmodule*submodule;+if(!S_ISGITLINK(p->two->mode))continue;-if(S_ISGITLINK(p->one->mode)){-/*-*NEEDSWORK:Weshouldhonorthenameconfiguredin-*the.gitmodulesfileofthecommitweareexamining-*heretobeabletocorrectlyfollowsubmodules-*beingmovedaround.-*/-commits=submodule_commits(changed,p->two->path);-oid_array_append(commits,&p->two->oid);-}else{-/* Submodule is new or was moved here */-/*-*NEEDSWORK:Whenthe.gitdirectoriesofsubmodules-*liveinsidethesuperprojects.gitdirectorysome-*dayweshouldfetchnewsubmodulesdirectlyinto-*thatlocationtoowhenconfigoroptionsrequest-*thatsotheycanbecheckedoutfromthere.-*/+submodule=submodule_from_path(commit_oid,p->two->path);+if(!submodule)continue;-}++commits=submodule_commits(changed,submodule->name);+oid_array_append(commits,&p->two->oid);}}
@@ -870,7 +868,7 @@ int find_unpushed_submodules(struct oid_array *commits,constchar*remotes_name,structstring_list*needs_pushing){structstring_listsubmodules=STRING_LIST_INIT_DUP;-structstring_list_item*submodule;+structstring_list_item*name;structargv_arrayargv=ARGV_ARRAY_INIT;/* argv.argv[0] will be ignored by setup_revisions */
@@ -881,12 +879,16 @@ int find_unpushed_submodules(struct oid_array *commits,collect_changed_submodules(&submodules,&argv);-for_each_string_list_item(submodule,&submodules){-structoid_array*commits=submodule->util;-constchar*path=submodule->string;+for_each_string_list_item(name,&submodules){+structoid_array*commits=name->util;+conststructsubmodule*submodule;++submodule=submodule_from_name(&null_oid,name->string);+if(!submodule)+continue;-if(submodule_needs_pushing(path,commits))-string_list_insert(needs_pushing,path);+if(submodule_needs_pushing(submodule->path,commits))+string_list_insert(needs_pushing,submodule->path);}free_submodules_oids(&submodules);
@@ -1041,7 +1043,7 @@ static void calculate_changed_submodule_paths(void){structargv_arrayargv=ARGV_ARRAY_INIT;structstring_listchanged_submodules=STRING_LIST_INIT_DUP;-conststructstring_list_item*item;+conststructstring_list_item*name;/* No need to check if there are no submodules configured */if(!submodule_from_path(NULL,NULL))
@@ -530,4 +530,39 @@ test_expect_success 'fetching submodule into a broken repository' 'test_must_failgit-Cdstfetch--recurse-submodules'+test_expect_success"fetch new commits when submodule got renamed"'+gitclone.downstream_rename&&+(+cddownstream_rename&&+gitsubmoduleupdate--init&&+# NEEDSWORK: we omitted --recursive for the submodule update here since+# that does not work. See test 7001 for mv "moving nested submodules"+# for details. Once that is fixed we should add the --recursive option+# here.+gitcheckout-brename&&+gitmvsubmodulesubmodule_renamed&&+(+cdsubmodule_renamed&&+gitcheckout-brename_sub&&+echoa>a&&+gitadda&&+gitcommit-ma&&+gitpushoriginrename_sub&&+gitrev-parseHEAD>../../expect+)&&+gitaddsubmodule_renamed&&+gitcommit-m"update renamed submodule"&&+gitpushoriginrename+)&&+(+cddownstream&&+gitfetch--recurse-submodules=on-demand&&+(+cdsubmodule&&+gitrev-parseorigin/rename_sub>../../actual+)+)&&+test_cmpexpectactual+'+ test_done