Submodules-API should report .gitmodules parse errors instead of ignoring them - #4522
Conversation
| static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name); | ||
| static git_config_backend *open_gitmodules(git_repository *repo, int gitmod); | ||
| static git_config *gitmodules_snapshot(git_repository *repo); | ||
| static int gitmodules_snapshot(git_repository *repo, git_config **snap); |
There was a problem hiding this comment.
The out parameter is typically first
| data.repo = repo; | ||
|
|
||
| if ((mods = gitmodules_snapshot(repo)) == NULL) | ||
| if ((error = gitmodules_snapshot(repo, &mods)) < 0 || mods == NULL) |
There was a problem hiding this comment.
I feel like this interface has become a bit more brittle by having to check for mods == NULL, as well. What about returning for example ENOTFOUND in case there are no submodules?
There was a problem hiding this comment.
I haven't done that in the first place as I then have to reset errors... First lemme see whether this approach will work at all...
| if (git_config_open_ondisk(&mods, path.ptr) < 0) | ||
| mods = NULL; | ||
| } | ||
| int error = git_config_open_ondisk(&mods, path.ptr); |
There was a problem hiding this comment.
Might be I'm misreading the diff, but isn't this introducing a declaration after instructions?
| cl_git_rewritefile("submod2/.gitmodules", | ||
| "[submodule \"Test_App\"\n" | ||
| " path = Test_App\n" | ||
| " url = ../Test_App\n"); |
| cl_git_fail(git_submodule_foreach(g_repo, foreach_cb, NULL)); | ||
| } | ||
|
|
||
| void test_submodule_lookup__fail_invalid_gitignores(void) |
There was a problem hiding this comment.
gitignores? Don't you mean gitmodules?
There was a problem hiding this comment.
Yeah a type, this is still WIP as I can't test locally ATM...
|
@pks-t All change requests should be addressed now. |
pks-t
left a comment
There was a problem hiding this comment.
Thanks for the fixups. I think the interface is a lot easier to use like this, as you can assume that mods will never be NULL in case the function returns success. The only non-stylistic thing that bothers me is the git_buf_joinpath error being ignored, which should definitly be fixed (even though you obviously just go with the previous behavior).
|
|
||
| if ((mods = gitmodules_snapshot(repo)) == NULL) | ||
| if ((error = gitmodules_snapshot(&mods, repo)) < 0) | ||
| { |
There was a problem hiding this comment.
The opening "{" is on the same line for single-line if-statements.
| if ((error = gitmodules_snapshot(&mods, repo)) < 0) | ||
| { | ||
| if (error == GIT_ENOTFOUND) | ||
| error = 0; |
There was a problem hiding this comment.
In my opinion, it looks much more readable like this
| @@ -1916,31 +1921,32 @@ static int submodule_load_from_wd_lite(git_submodule *sm) | |||
|
|
|||
| /** | |||
| * Returns a snapshot of $WORK_TREE/.gitmodules. | |||
There was a problem hiding this comment.
I'd like to see a short comment about GIT_ENOTFOUND here such that people know to expect it in case there are no submodules.
| git_config *mods = NULL; | ||
| if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0) | ||
| return NULL; | ||
| return 0; |
There was a problem hiding this comment.
Hum. Shouldn't this bubble up the error? git_buf_joinpath failing indicates that there was a memory allocation error, which definitly shouldn't be ignored.
if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) < 0)
return -1;
| git_config *mods = NULL, *snap = NULL; | ||
| git_buf path = GIT_BUF_INIT; | ||
|
|
||
| if (workdir != NULL) { |
There was a problem hiding this comment.
The whole indentation could be avoided if you return early in case workdir == NULL. That's a matter of taste, though -- your call if you want to do that instead.
There was a problem hiding this comment.
Yeah I also thought that, however, I did not want to make too big changes...
|
@pks-t All change requests should be addressed now. |
|
|
||
| if (mods) { | ||
| git_config_snapshot(&snap, mods); | ||
| git_config_snapshot(snap, mods); |
There was a problem hiding this comment.
Sorry for not catching that earlier, but now that you report errors you should definitly also check the return value of git_config_snapshot.
| git_config_snapshot(&snap, mods); | ||
| git_config_snapshot(snap, mods); | ||
| git_config_free(mods); | ||
| return 0; |
There was a problem hiding this comment.
We usually try to avoid returning early for non-trivial code. I'd rather go with something like
...
*snap = NULL;
...
if ((error = git_config_open_ondisk(...)) < 0)
goto out;
if (!mods) {
error = -1;
goto out;
}
if ((error = git_config_snapshot(mods, config)) < 0)
goto out;
out:
git_config_free(mods);
if (error)
git_config_free(*snap);
return error;
There was a problem hiding this comment.
goto is better? - Shall I change all the code for this? You asked to exit early before for !worktree.
There was a problem hiding this comment.
Sorry 😅 Seeing that your code already improves the function by quite a lot, I'm satisfied if you check the return code of git_config_snapshot, without converting the function to goto style.
|
@pks-t Any reason why lots of PRs are not merged (such as this one)? |
|
@csware because we’re busy. We appreciate your contributions but we are all volunteers and do not always have as much time to review pull requests as we would like. We appreciate your patience. |
|
Also, we’ve locked down for 0.27. This is eligible for merging to master after that release, but this is not a change we’d take before then. |
pks-t
left a comment
There was a problem hiding this comment.
v0.27.0 is finally out the door, so we're back to our usual business again.
| mods = NULL; | ||
| } | ||
| if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0) | ||
| return -1; |
There was a problem hiding this comment.
This should probably be if ((error = git_buf_joinpath(&path, workdir, GIT_MODULES_FILE)) < 0) return error;
| if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0) | ||
| return -1; | ||
|
|
||
| error = git_config_open_ondisk(&mods, path.ptr); |
There was a problem hiding this comment.
You should probably also check the return value here. While an error will cause mods to be NULL, which is catched in a few lines, it feels a bit more robust to check directly. You could avoid multiple free's by adding a goto out. Additional kudos if you also convert the other error handling branches to goto out with a unified section for freeing up memory in case error != 0.
|
|
||
| cl_git_fail(git_submodule_foreach(g_repo, sm_lookup_cb, &data)); | ||
| } | ||
|
|
Signed-off-by: Sven Strickroth <email@cs-ware.de>
|
Thanks for the contribution, @csware! |
Issue mentioned in issue #4517 and issue #4516.
Git for Windows does report parse errors in
.gitmodules, so should libgit2.