Skip to content

branch: clarify documentation around branches#5300

Merged
pks-t merged 2 commits into
libgit2:masterfrom
tiennou:fix/branch-documentation
Dec 13, 2019
Merged

branch: clarify documentation around branches#5300
pks-t merged 2 commits into
libgit2:masterfrom
tiennou:fix/branch-documentation

Conversation

@tiennou
Copy link
Copy Markdown
Contributor

@tiennou tiennou commented Nov 6, 2019

This comes after looking around at #5283, just a few documentation and commentation done.

It seems there's no "create the tracking branch for that branch using that remote" function, which is the low-level operation that's missing from people workflows — right now you can use git_branch_set_upstream to do the "verifications & configuration updating", but you have to have created a reference deemed worthwhile of that code to succeed, which is 😒.

Comment thread include/git2/branch.h
Comment thread include/git2/branch.h Outdated
* @param out Pointer to the user-allocated git_buf which will be filled with the name of the remote.
* This will returns the name of the remote a remote-tracking branch belongs to.
* IOW, it extracts "test" from "refs/remotes/test/master", checks all remotes
* for a compatible refspec, and returns the first match.
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.

This one is the one I was most surprised by — I didn't expect a round-trip through the list of remotes to happen here…

I'm tempted to provide a lower-level version under that name and rename this one to be less "accessor"-y, so that you can get the name quickly-ish. Opinions ?

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.

At first this does sound weird to me, too. But you could have a remote that isn't named anything like what the refspecs will do. E.g. the remote "foobar" could definitely fetch into "barfoo" if the refspec is configured like that.

So we definitely need this roundtrip for correctness, but I wonder about extracting "test" first. Shouldn't we use the reference as-is and directly check it against refspecs, returning the first remote with a matching one?

Copy link
Copy Markdown
Member

@pks-t pks-t Nov 28, 2019

Choose a reason for hiding this comment

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

And by the way, you document the function to return GIT_EAMBIGUOUS if there are several matching refspecs, which sounds reasonable to me. But here in the description you say that we're returning the first matching remote, which directly contradicts that.

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'm not sure about the roundtrips. IIRC reading the code left me with the feeling that a branch has a "belongs to" relation to its remote (hence the "." means "the current repository's branches" comment), and that some of those roundtrips aren't actually correct. For example, you can load a branch using its underlying reference name, but a subsequent operation with it will fail because this one will notice an ambiguity, or the configuration is somehow "broken" — the "branch.*" configuration key has been renamed, or its refspecs changed; I've been guilty of doing both, and I know GitX trusts the refdb for its remote name by reading git for-each-ref instead of doing this, hence all the suspicion 😉.

Comment thread src/branch.c
Comment thread include/git2/branch.h
Comment thread include/git2/branch.h
Comment thread include/git2/branch.h Outdated
Comment thread include/git2/branch.h Outdated
Comment thread include/git2/branch.h Outdated
* @param out Pointer to the user-allocated git_buf which will be filled with the name of the remote.
* This will returns the name of the remote a remote-tracking branch belongs to.
* IOW, it extracts "test" from "refs/remotes/test/master", checks all remotes
* for a compatible refspec, and returns the first match.
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.

At first this does sound weird to me, too. But you could have a remote that isn't named anything like what the refspecs will do. E.g. the remote "foobar" could definitely fetch into "barfoo" if the refspec is configured like that.

So we definitely need this roundtrip for correctness, but I wonder about extracting "test" first. Shouldn't we use the reference as-is and directly check it against refspecs, returning the first remote with a matching one?

Comment thread include/git2/branch.h Outdated
* @param out Pointer to the user-allocated git_buf which will be filled with the name of the remote.
* This will returns the name of the remote a remote-tracking branch belongs to.
* IOW, it extracts "test" from "refs/remotes/test/master", checks all remotes
* for a compatible refspec, and returns the first match.
Copy link
Copy Markdown
Member

@pks-t pks-t Nov 28, 2019

Choose a reason for hiding this comment

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

And by the way, you document the function to return GIT_EAMBIGUOUS if there are several matching refspecs, which sounds reasonable to me. But here in the description you say that we're returning the first matching remote, which directly contradicts that.

Comment thread src/branch.c
Comment thread src/branch.c Outdated
@tiennou tiennou force-pushed the fix/branch-documentation branch from bc1837b to 8a0d2c9 Compare November 30, 2019 20:01
Comment thread include/git2/branch.h Outdated
Comment thread include/git2/branch.h Outdated
Comment thread include/git2/branch.h Outdated
* as a full reference name, ie. "feature/nice" would become
* "refs/remote/origin/feature/nice", depending on that branch's configuration.
*
* @param out The buffer into which the name will be written.
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.

"The" needs to be lower case for consistency

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.

Do we ? This isn't really enforced in any way, and actually isn't really consistent — I realize it's likely because a lot of those discrepancies are my work (ha! 🤣). My vote usually goes for "make it look good", so I try to make "full-fledged sentences" when contextually appropriate…

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.

Well, I was only referring to consistency in this single doc comment as all the other params were starting with a lower-case letter :)

Comment thread include/git2/branch.h Outdated
Comment thread include/git2/branch.h Outdated
@tiennou tiennou force-pushed the fix/branch-documentation branch 3 times, most recently from f5857d9 to 041ed20 Compare December 8, 2019 13:41
@tiennou
Copy link
Copy Markdown
Contributor Author

tiennou commented Dec 8, 2019

Rebased, I've added some tests to make sure it works correctly on the one case I've seen failing. Should be green, as hopefully the one test I've added has been working sanely here 😜.

@tiennou tiennou force-pushed the fix/branch-documentation branch from 041ed20 to a84c210 Compare December 8, 2019 14:26
Comment thread src/refs.c
git_reference *git_reference__set_name(
git_reference *ref, const char *name)
git_reference *git_reference__realloc(
git_reference **ptr_to_ref, const char *name)
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.

Wouldn't it make more sense to have it return an error code and instead let it update the pointer in-place? Feel free to leave it as-is though.

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.

Not sure. I wanted to make the call "usable, but in a safe way". If it's implementation-defined whether realloc will realloc to a smaller size, and I need to know if the old ref is now invalid, having the pointer be NULL on return signals that case, and the higher-level code can adapt.

Arguably, most of that code comes in preparation of some more work 😉, but I want to keep it public API/documentation specific there. For example, I think having a "higher" low watermark on refname lengths could help with the invalidation (something like 32 could skip quite a few reallocs).

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.

Yeah, just leave it as-is then. Your change is an improvement compared to the current code and doesn't introduce anything new that one could complain about, so it can only be a win for us.

Comment thread src/refs.c Outdated
As git_reference__name will reallocate storage to account for longer
names (it's actually allocator-dependent), it will cause all existing
pointers to the old object to become dangling, as they now point to
freed memory.

Fix the issue by renaming to a more descriptive name, and pass a pointer
to the actual reference that can safely be invalidated if the realloc
succeeds.
@tiennou tiennou force-pushed the fix/branch-documentation branch from a84c210 to 97b8491 Compare December 13, 2019 11:01
@pks-t pks-t merged commit 2f6f10b into libgit2:master Dec 13, 2019
@pks-t
Copy link
Copy Markdown
Member

pks-t commented Dec 13, 2019

Thanks a lot, @tiennou!

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.

2 participants