Skip to content

[Submodule] Git submodule dup - #5890

Merged
ethomson merged 8 commits into
libgit2:mainfrom
lolgear:git_submodule_dup
Jul 22, 2021
Merged

[Submodule] Git submodule dup#5890
ethomson merged 8 commits into
libgit2:mainfrom
lolgear:git_submodule_dup

Conversation

@lolgear

@lolgear lolgear commented May 16, 2021

Copy link
Copy Markdown
Contributor

@lolgear lolgear changed the title [Submodule] Git submodule dup. [Submodule] Git submodule dup May 16, 2021

@neithernut neithernut left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disclaimer: not a maintainer.

Comment thread src/submodule.c Outdated
git_submodule* git_submodule_dup(git_submodule *sm)
{
if (!sm)
return;

Copy link
Copy Markdown
Contributor

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?

Copy link
Copy Markdown
Contributor Author

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)?

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethomson

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);
}

@lolgear
lolgear requested a review from ethomson May 22, 2021 16:57
Comment thread src/submodule.c Outdated

int git_submodule_dup(git_submodule **out, git_submodule *source)
{
return git_object_dup((git_object **)out, (git_object *)source);

Copy link
Copy Markdown
Contributor

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.

@lolgear lolgear May 26, 2021

Copy link
Copy Markdown
Contributor Author

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;
}

Copy link
Copy Markdown
Contributor

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.

@lolgear lolgear May 26, 2021

Copy link
Copy Markdown
Contributor Author

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?

Copy link
Copy Markdown
Contributor

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.

@lolgear
lolgear requested a review from tiennou May 26, 2021 12:34
Comment thread src/submodule.c Outdated
{
GIT_ASSERT_ARG(out);

if (source != NULL)

@tiennou tiennou May 26, 2021

Copy link
Copy Markdown
Contributor

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…

Copy link
Copy Markdown
Contributor Author

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?

@lolgear
lolgear requested a review from tiennou May 26, 2021 19:17
@lolgear

lolgear commented May 31, 2021

Copy link
Copy Markdown
Contributor Author

Could anybody check this PR?

@tiennou tiennou left a comment

Copy link
Copy Markdown
Contributor

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.

Comment thread 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param out Pointer to store the copy of the submodule
* @param out Pointer to store the copy of the submodule. Cannot be NULL.

Comment thread 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param source Original tag to copy
* @param source Original submodule to copy.

@lolgear

lolgear commented Jun 1, 2021

Copy link
Copy Markdown
Contributor Author

@tiennou
Could you show me an example of this test?
This function is so common that I can't figure out whether I should add test in separate file or add it in one of the existed files.

@tiennou

tiennou commented Jun 2, 2021

Copy link
Copy Markdown
Contributor

Sure, I'd put it as test_submodule_lookup__can_be_dupped, which would git_submodule_lookup(), dup that, check that one of the "basic" properties work (name/owner/url, IIRC any one of them, as it's just about accessing the underlying storage), then free the first and assert whatever you checked at the beginning is still what we expect. In case anything goes wrong with memory in the future, the test would cause a segfault.

@lolgear

lolgear commented Jun 3, 2021

Copy link
Copy Markdown
Contributor Author

@tiennou
Could you check latest changes?
I guess that it is done, but I can't run tests.
A lot of errors at "configure" phase.

@lolgear
lolgear requested a review from tiennou June 7, 2021 10:48

@ethomson ethomson left a comment

Copy link
Copy Markdown
Member

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.

Comment thread src/submodule.c
Comment on lines +1860 to +1863

if (source != NULL)
GIT_REFCOUNT_INC(source);

Copy link
Copy Markdown
Member

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.

Suggested change
if (source != NULL)
GIT_REFCOUNT_INC(source);
GIT_ASSERT_ARG(source);
GIT_REFCOUNT_INC(source);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethomson
Fixed

Comment thread 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.

Copy link
Copy Markdown
Member

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.

Suggested change
* @param out Pointer to store the copy of the submodule. Cannot be NULL.
* @param out Pointer to store the copy of the submodule.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethomson
Fixed

Comment thread tests/submodule/lookup.c Outdated
git_submodule *sm_duplicate;
const char *oid = "480095882d281ed676fe5b863569520e54a7d5c0";

// Check original

Copy link
Copy Markdown
Member

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...

Suggested change
// Check original
/* Check original */

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethomson
Fixed

Comment thread 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Duplicate and free original
/* Duplicate and free original */

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethomson
Fixed

Comment thread tests/submodule/lookup.c Outdated
cl_assert(git_submodule_dup(&sm_duplicate, sm) == 0);
git_submodule_free(sm);

// Check duplicate

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Check duplicate
/* Check duplicate */

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethomson
Fixed

@lolgear
lolgear requested a review from ethomson June 15, 2021 14:34
@lolgear

lolgear commented Jun 15, 2021

Copy link
Copy Markdown
Contributor Author

@ethomson Fixed.

@ethomson

Copy link
Copy Markdown
Member

Thanks @lolgear!

@ethomson

Copy link
Copy Markdown
Member

Oops, I didn't hit merge - my bad! Thanks again @lolgear!

@ethomson
ethomson merged commit 43b5075 into libgit2:main Jul 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants