-
Notifications
You must be signed in to change notification settings - Fork 2.5k
[Submodule] Git submodule dup #5890
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disclaimer: not a maintainer.
src/submodule.c
Outdated
git_submodule* git_submodule_dup(git_submodule *sm) | ||
{ | ||
if (!sm) | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you meant to return either sm
or, explicitly, NULL
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, which one is more appropriate (in current codebase)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would be NULL
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would emulate the existing dup
functions like git_commit_dup
and return an int
and use an out parameter. This way we can change the implementation later in case we add some failure case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I just use git_object_dup
function?
int git_submodule_dup(git_submodule **out, git_submodule *source) {
return git_object_dup((git_object **)out, (git_object *)source);
}
src/submodule.c
Outdated
@@ -1854,6 +1854,11 @@ static void submodule_release(git_submodule *sm) | |||
git__free(sm); | |||
} | |||
|
|||
int git_submodule_dup(git_submodule **out, git_submodule *source) | |||
{ | |||
return git_object_dup((git_object **)out, (git_object *)source); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That won't work — git_submodule
is not a proper subtype/C "subclass" of git_object
, so this will actually clobber memory in the underlying structure when incrementing the refcount.
IIRC your previous version (using GIT_REFCOUNT_INC
) was correct but the function's prototype wasn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't figure out how to adjust *out
parameter with previous implementation.
Something like this?
int git_submodule_dup(git_submodule **out, git_submodule *source)
{
if (!out) { return -1; }
if (!source) { return -1; }
*out = source;
GIT_REFCOUNT_INC(*out);
return 0;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd (personally) go for this :
int git_submodule_dup(git_submodule **out, git_submodule *source)
{
GIT_ASSERT_ARG(out);
if (source != NULL)
GIT_REFCOUNT_INC(source);
*out = source;
return 0;
}
Assert because allowing a NULL
out
could open up the API to misuse/programmer error, only incref if source is non-NULL
so a NULL "submodule" can pass through, and always copy either an incref-ed source or NULL in out
so it's always a known value and not uninitialized memory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, project has different styles in spaces/tabs and in nullability checks.
Is there any (current) guide to look at?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's docs/coding-style.md, which is supposed to be current and seems to be. I'd maybe add something about the assertion macros (which are new-ish) and when to use them — ideally for "impossible" or "API misuse" conditions.
src/submodule.c
Outdated
{ | ||
GIT_ASSERT_ARG(out); | ||
|
||
if (source != NULL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah… if (source)
would have been fine here. Sorry, another project of mine has "all conditions must be explicit", so…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a lot of occurrences of != NULL
in this file. Should I change it to implicit check?
Could anybody check this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few minor docblock tweaks (I skimmed the header initially). A quick test that exercises the new function and check that both submodules work and can be freed separately would be ❤️, just to be sure nothing regresses.
include/git2/submodule.h
Outdated
* Create an in-memory copy of a submodule. The copy must be explicitly | ||
* free'd or it will leak. | ||
* | ||
* @param out Pointer to store the copy of the submodule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @param out Pointer to store the copy of the submodule | |
* @param out Pointer to store the copy of the submodule. Cannot be NULL. |
include/git2/submodule.h
Outdated
* free'd or it will leak. | ||
* | ||
* @param out Pointer to store the copy of the submodule | ||
* @param source Original tag to copy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @param source Original tag to copy | |
* @param source Original submodule to copy. |
@tiennou |
Sure, I'd put it as |
@tiennou |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks great, a few minor suggestions.
src/submodule.c
Outdated
|
||
if (source != NULL) | ||
GIT_REFCOUNT_INC(source); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason source
is optional? I would make it required.
if (source != NULL) | |
GIT_REFCOUNT_INC(source); | |
GIT_ASSERT_ARG(source); | |
GIT_REFCOUNT_INC(source); | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethomson
Fixed
include/git2/submodule.h
Outdated
* Create an in-memory copy of a submodule. The copy must be explicitly | ||
* free'd or it will leak. | ||
* | ||
* @param out Pointer to store the copy of the submodule. Cannot be NULL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our docs generally tell you when a param is optional, instead of when a param is required.
* @param out Pointer to store the copy of the submodule. Cannot be NULL. | |
* @param out Pointer to store the copy of the submodule. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethomson
Fixed
tests/submodule/lookup.c
Outdated
git_submodule *sm_duplicate; | ||
const char *oid = "480095882d281ed676fe5b863569520e54a7d5c0"; | ||
|
||
// Check original |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't use //
comments in this project...
// Check original | |
/* Check original */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethomson
Fixed
tests/submodule/lookup.c
Outdated
cl_assert(git_submodule_ignore(sm) == GIT_SUBMODULE_IGNORE_NONE); | ||
cl_assert(git_submodule_update_strategy(sm) == GIT_SUBMODULE_UPDATE_CHECKOUT); | ||
|
||
// Duplicate and free original |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Duplicate and free original | |
/* Duplicate and free original */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethomson
Fixed
tests/submodule/lookup.c
Outdated
cl_assert(git_submodule_dup(&sm_duplicate, sm) == 0); | ||
git_submodule_free(sm); | ||
|
||
// Check duplicate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Check duplicate | |
/* Check duplicate */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethomson
Fixed
@ethomson Fixed. |
Thanks @lolgear! |
Oops, I didn't hit merge - my bad! Thanks again @lolgear! |
git_submodule_dup
has been added.