Add support for creating signed commits and signing commits during a rebase #626

Merged
mbfr merged 25 commits from master into master 2020-08-18 11:25:31 -05:00
mbfr commented 2020-08-12 03:59:47 -05:00 (Migrated from github.com)

This all works but I have a few questions about submitting it:

  • I'm targeting this at maser but due to package versions available in other distros I'm guessing I will still have to maintain a fork if I want this to be able to use with v29 and below (eg, pre-1.0 which a lot of distros don't have)?
  • There's no dependencies in the go.mod file, but I obviously had to add a dependency on the x/crypto module to add unit tests, note sure if that's going to be a problem?
  • In libgit2 git_commit_create_with_signature is in the 'repository' block of functions in the documentation, but practically it's very difficult to use like that (you would need to look up the commit you were using to get the commit content anyway) so I added it to the Commit struct instead. The other sensible way would possibly be to add it as a method on the Repository struct, make it take a commit ID, and make it looks up the commit to read the content, but then it's just a very roundabout way of doing it
  • The RebaseOptions.fromC does not load the function pointer for git_commit_signing_cb (there is a note about it), but I don't know if that use case would ever come up. If it was, there would need to be another bridge function in C that called that function pointer.
  • I wasn't really sure on how to actually use the commit that you get from git_commit_create_with_signature and I can't find any examples, so what I did in the tests (and what I would probably do if I was using this in the real world) is to create the signed commit, then just re-point head at that signed commit.
  • I added a utility method WithSignatureUsing to the Commit to allow passing a callback to create the signature for the commit, this isn't a 1:1 mapping with the libgit2 api obviously but I figure it's what 99% of people using this library will write themselves anyway
This all works but I have a few questions about submitting it: - I'm targeting this at maser but due to package versions available in other distros I'm guessing I will still have to maintain a fork if I want this to be able to use with v29 and below (eg, pre-1.0 which a lot of distros don't have)? - There's no dependencies in the go.mod file, but I obviously had to add a dependency on the x/crypto module to add unit tests, note sure if that's going to be a problem? - In libgit2 `git_commit_create_with_signature` is in the 'repository' block of functions in the documentation, but practically it's very difficult to use like that (you would need to look up the commit you were using to get the commit content anyway) so I added it to the `Commit` struct instead. The other sensible way would possibly be to add it as a method on the `Repository` struct, make it take a commit ID, and make it looks up the commit to read the content, but then it's just a very roundabout way of doing it - The `RebaseOptions.fromC` does not load the function pointer for `git_commit_signing_cb` (there is a note about it), but I don't know if that use case would ever come up. If it was, there would need to be another bridge function in C that called that function pointer. - I wasn't really sure on how to actually use the commit that you get from `git_commit_create_with_signature` and I can't find any examples, so what I did in the tests (and what I would probably do if I was using this in the real world) is to create the signed commit, then just re-point head at that signed commit. - I added a utility method `WithSignatureUsing` to the `Commit` to allow passing a callback to create the signature for the commit, this isn't a 1:1 mapping with the libgit2 api obviously but I figure it's what 99% of people using this library will write themselves anyway
mbfr commented 2020-08-12 04:05:16 -05:00 (Migrated from github.com)

It looks like the tests are failing because of the module dependencies, which I suppose is why there were no dependencies there already. 1.9 hasn't had any releases for over 2 years and 1.10 hasn't had a release for a year and a half, is there any reason they're still in the CI? If they do have to be supported then I'm open to suggestions on how to write tests for this functionality without adding any dependencies

It looks like the tests are failing because of the module dependencies, which I suppose is why there were no dependencies there already. 1.9 hasn't had any releases for over 2 years and 1.10 hasn't had a release for a year and a half, is there any reason they're still in the CI? If they do have to be supported then I'm open to suggestions on how to write tests for this functionality without adding any dependencies
lhchavez (Migrated from github.com) reviewed 2020-08-13 09:00:47 -05:00
lhchavez (Migrated from github.com) left a comment

I'll try to review this later today, but here are the answers to most questions:

I'm targeting this at maser but due to package versions available in other distros I'm guessing I will still have to maintain a fork if I want this to be able to use with v29 and below (eg, pre-1.0 which a lot of distros don't have)?

Once this lands, we can cherry-pick it to the older branches so that you don't need to maintain a fork.

There's no dependencies in the go.mod file, but I obviously had to add a dependency on the x/crypto module to add unit tests, note sure if that's going to be a problem?

That's totally fine.

In libgit2 git_commit_create_with_signature is in the 'repository' block of functions in the documentation, but practically it's very difficult to use like that (you would need to look up the commit you were using to get the commit content anyway) so I added it to the Commit struct instead. The other sensible way would possibly be to add it as a method on the Repository struct, make it take a commit ID, and make it looks up the commit to read the content, but then it's just a very roundabout way of doing it

huh, https://libgit2.org/libgit2/#HEAD/group/commit/git_commit_create_with_signature seems to indicate that it is in the 'commit' block. and it's defined in https://github.com/libgit2/libgit2/blob/HEAD/include/git2/commit.h#L489-494

who know what happened, but in any case, based on those two links AND the intended usage, declaring it in Commit is totally fine.

The RebaseOptions.fromC does not load the function pointer for git_commit_signing_cb (there is a note about it), but I don't know if that use case would ever come up. If it was, there would need to be another bridge function in C that called that function pointer.

We can ignore that case for the time being. As you mention, it's likely that the case won't ever come up. Even thinking how to exercise this functionality in those circumstances requires some super contrived setup.

I wasn't really sure on how to actually use the commit that you get from git_commit_create_with_signature and I can't find any examples, so what I did in the tests (and what I would probably do if I was using this in the real world) is to create the signed commit, then just re-point head at that signed commit.

TODO: answer this.

I added a utility method WithSignatureUsing to the Commit to allow passing a callback to create the signature for the commit, this isn't a 1:1 mapping with the libgit2 api obviously but I figure it's what 99% of people using this library will write themselves anyway

yeah, that makes sense. Given that the callback would need to be implemented for the RebaseOptions, that same callback can be reused for the Commit.

It looks like the tests are failing because of the module dependencies [...]

Is that fixed with

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5472f22..ebbc9b0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -35,7 +35,7 @@ jobs:
       run: |
         git submodule update --init
         make build-libgit2-static
-        go get -tags static github.com/${{ github.repository }}/...
+        go get -tags static -t github.com/${{ github.repository }}/...
         go build -tags static github.com/${{ github.repository }}/...
     - name: Test
       env:

? I think that it's only the case of telling older versions of Go to also fetch the modules needed for testing.

I'll try to review this later today, but here are the answers to most questions: > I'm targeting this at maser but due to package versions available in other distros I'm guessing I will still have to maintain a fork if I want this to be able to use with v29 and below (eg, pre-1.0 which a lot of distros don't have)? Once this lands, we can cherry-pick it to the older branches so that you don't need to maintain a fork. > There's no dependencies in the go.mod file, but I obviously had to add a dependency on the x/crypto module to add unit tests, note sure if that's going to be a problem? That's totally fine. > In libgit2 `git_commit_create_with_signature` is in the 'repository' block of functions in the documentation, but practically it's very difficult to use like that (you would need to look up the commit you were using to get the commit content anyway) so I added it to the `Commit` struct instead. The other sensible way would possibly be to add it as a method on the `Repository` struct, make it take a commit ID, and make it looks up the commit to read the content, but then it's just a very roundabout way of doing it huh, https://libgit2.org/libgit2/#HEAD/group/commit/git_commit_create_with_signature seems to indicate that it is in the 'commit' block. and it's defined in https://github.com/libgit2/libgit2/blob/HEAD/include/git2/commit.h#L489-494 who know what happened, but in any case, based on those two links AND the intended usage, declaring it in `Commit` is totally fine. > The `RebaseOptions.fromC` does not load the function pointer for `git_commit_signing_cb` (there is a note about it), but I don't know if that use case would ever come up. If it was, there would need to be another bridge function in C that called that function pointer. We can ignore that case for the time being. As you mention, it's likely that the case won't ever come up. Even thinking _how_ to exercise this functionality in those circumstances requires some super contrived setup. > I wasn't really sure on how to actually use the commit that you get from `git_commit_create_with_signature` and I can't find any examples, so what I did in the tests (and what I would probably do if I was using this in the real world) is to create the signed commit, then just re-point head at that signed commit. TODO: answer this. > I added a utility method `WithSignatureUsing` to the `Commit` to allow passing a callback to create the signature for the commit, this isn't a 1:1 mapping with the libgit2 api obviously but I figure it's what 99% of people using this library will write themselves anyway yeah, that makes sense. Given that the callback would need to be implemented for the `RebaseOptions`, that same callback can be reused for the `Commit`. > It looks like the tests are failing because of the module dependencies [...] Is that fixed with ```diff diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5472f22..ebbc9b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: run: | git submodule update --init make build-libgit2-static - go get -tags static github.com/${{ github.repository }}/... + go get -tags static -t github.com/${{ github.repository }}/... go build -tags static github.com/${{ github.repository }}/... - name: Test env: ``` ? I **think** that it's only the case of telling older versions of Go to _also_ fetch the modules needed for testing.
lhchavez (Migrated from github.com) reviewed 2020-08-14 09:20:50 -05:00
lhchavez (Migrated from github.com) left a comment

sorry for the delay

sorry for the delay
@ -37,3 +37,3 @@
make build-libgit2-static
go get -tags static github.com/${{ github.repository }}/...
go get -tags static -t github.com/${{ github.repository }}/...
go build -tags static github.com/${{ github.repository }}/...
lhchavez (Migrated from github.com) commented 2020-08-14 08:37:47 -05:00

yay! it worked :D

yay! it worked :D
lhchavez (Migrated from github.com) commented 2020-08-14 08:45:05 -05:00

these two also need to be defer C.free(...)d.

these two also need to be `defer C.free(...)`d.
@ -43,0 +73,4 @@
var csf *C.char = nil
if signatureField != "" {
csf = C.CString(signatureField)
lhchavez (Migrated from github.com) commented 2020-08-14 08:41:25 -05:00

since C.CString() makes a copy, this needs a defer C.free(unsafe.Pointer(csf)) to avoid a memory leak: https://blog.golang.org/cgo#TOC_2.

since `C.CString()` makes a copy, this needs a `defer C.free(unsafe.Pointer(csf))` to avoid a memory leak: https://blog.golang.org/cgo#TOC_2.
@ -43,0 +85,4 @@
defer C.free(unsafe.Pointer(cTotalCommit))
defer C.free(unsafe.Pointer(cSignature))
ret := C.git_commit_create_with_signature(
lhchavez (Migrated from github.com) commented 2020-08-14 08:43:24 -05:00

for consistency with Amend() would it be possible to call this variable cerr?

for consistency with [`Amend()`](https://github.com/libgit2/git2go/blob/462ebd83e0ccba9cd93c05ec12dc3d98064e3d5c/commit.go#L160) would it be possible to call this variable `cerr`?
lhchavez (Migrated from github.com) commented 2020-08-14 08:48:17 -05:00

what happens if the RebaseOptions is stored in the pointerHandles by pointer?

	opts, ok := pointerHandles.Get(_payload).(*RebaseOptions)

For consistency with all the other things stored in the HandleList, which are stored as pointer.

what happens if the `RebaseOptions` is stored in the `pointerHandles` by pointer? ```suggestion opts, ok := pointerHandles.Get(_payload).(*RebaseOptions) ``` For consistency with all the other things stored in the `HandleList`, which are stored as pointer.
lhchavez (Migrated from github.com) commented 2020-08-14 09:08:43 -05:00

git_buf_grow() internally calls git__realloc, which calls realloc(3), which says that "If the new size is larger than the old size, the added memory will not be initialized.". This means that it's not guaranteed that the very last byte in the buffer is going to be a null byte after L107.

Would it make sense to call git_buf_sanitize to ensure the null byte is there?

`git_buf_grow()` internally calls `git__realloc`, which calls [`realloc(3)`](https://linux.die.net/man/3/realloc), which says that "If the new size is larger than the old size, the added memory will _not_ be initialized.". This means that it's not guaranteed that the very last byte in the buffer is going to be a null byte after L107. Would it make sense to call [`git_buf_sanitize`](https://github.com/libgit2/libgit2/blob/c71321a099373753c22055921c8f538afed5ebb6/src/buffer.c#L143-L150) to ensure the null byte is there?
lhchavez (Migrated from github.com) commented 2020-08-14 09:09:49 -05:00

huh, [C.CString()] says it does return a NULL-terminated C-compatible string: https://blog.golang.org/cgo#TOC_2.

huh, [`C.CString()`] says it does return a NULL-terminated C-compatible string: https://blog.golang.org/cgo#TOC_2.
@ -72,0 +98,4 @@
defer C.free(cstr)
// libgit2 requires the contents of the buffer to be NULL-terminated.
// C.CString() guarantees that the returned buffer will be
lhchavez (Migrated from github.com) commented 2020-08-14 08:58:38 -05:00

in order to support callback authors being able to set a specific libgit2 error, we could do something like:

if gitError, ok := err.(*GitError); ok {
    return C.int(gitError.Code)
}
return C.int(-1)
in order to support callback authors being able to set a specific libgit2 error, we could do something like: ```go if gitError, ok := err.(*GitError); ok { return C.int(gitError.Code) } return C.int(-1) ```
@ -72,0 +103,4 @@
if int(C.git_buf_set(buf, cstr, clen+1)) != 0 {
return errors.New("could not set buffer")
}
lhchavez (Migrated from github.com) commented 2020-08-14 08:59:06 -05:00

this needs a C.free(...).

this needs a `C.free(...)`.
lhchavez (Migrated from github.com) commented 2020-08-14 09:10:54 -05:00

this can be removed!

this can be removed!
lhchavez (Migrated from github.com) commented 2020-08-14 09:11:02 -05:00
		opts.payload = pointerHandles.Track(ro)
```suggestion opts.payload = pointerHandles.Track(ro) ```
lhchavez (Migrated from github.com) commented 2020-08-14 09:14:32 -05:00

it's probably okay to always ask for the commitOpts to avoid having two flavors of the utility functions. Tests don't need to have backwards-compatibility guarantees.

it's probably okay to always ask for the `commitOpts` to avoid having two flavors of the utility functions. Tests don't need to have backwards-compatibility guarantees.
lhchavez (Migrated from github.com) commented 2020-08-14 09:16:35 -05:00

IIUC this can be simplified to:

	parent := head
IIUC this can be simplified to: ```suggestion parent := head ```
lhchavez (Migrated from github.com) commented 2020-08-14 09:18:39 -05:00
		t.Logf("No signature on commit\n%s", commit.ContentToSign())

might as well use the new function! Same in L250.

```suggestion t.Logf("No signature on commit\n%s", commit.ContentToSign()) ``` might as well use the new function! Same in L250.
lhchavez (Migrated from github.com) commented 2020-08-14 09:20:37 -05:00

given that this is only going to be used once, might as well inline this function

given that this is only going to be used once, might as well inline this function
@ -177,3 +298,3 @@
// Init rebase
rebase, err := repo.InitRebase(nil, nil, onto, nil)
rebase, err := repo.InitRebase(nil, nil, onto, opts)
if err != nil {
lhchavez (Migrated from github.com) commented 2020-08-14 09:19:21 -05:00

maybe add a

t.Helper()

as the first line of this function: https://golang.org/pkg/testing/#T.Helper

maybe add a ```go t.Helper() ``` as the first line of this function: https://golang.org/pkg/testing/#T.Helper
lhchavez (Migrated from github.com) commented 2020-08-14 09:12:59 -05:00

can this block be kept?

can this block be kept?
mbfr (Migrated from github.com) reviewed 2020-08-14 09:40:57 -05:00
@ -43,0 +85,4 @@
defer C.free(unsafe.Pointer(cTotalCommit))
defer C.free(unsafe.Pointer(cSignature))
ret := C.git_commit_create_with_signature(
mbfr (Migrated from github.com) commented 2020-08-14 09:40:57 -05:00

There isn't really a lot of consistency with other functions, sometimes it's called code, sometimes ret, sometimes, ecode, sometimes cerr, etc.

There isn't really a lot of consistency with other functions, sometimes it's called `code`, sometimes `ret`, sometimes, `ecode`, sometimes `cerr`, etc.
mbfr (Migrated from github.com) reviewed 2020-08-14 09:50:06 -05:00
@ -43,0 +73,4 @@
var csf *C.char = nil
if signatureField != "" {
csf = C.CString(signatureField)
mbfr (Migrated from github.com) commented 2020-08-14 09:50:05 -05:00

Added

Added
mbfr (Migrated from github.com) reviewed 2020-08-14 09:50:08 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 09:50:08 -05:00

Added

Added
mbfr (Migrated from github.com) reviewed 2020-08-14 09:53:17 -05:00
@ -72,0 +98,4 @@
defer C.free(cstr)
// libgit2 requires the contents of the buffer to be NULL-terminated.
// C.CString() guarantees that the returned buffer will be
mbfr (Migrated from github.com) commented 2020-08-14 09:53:17 -05:00

Good idea, added

Good idea, added
mbfr (Migrated from github.com) reviewed 2020-08-14 09:53:22 -05:00
@ -72,0 +103,4 @@
if int(C.git_buf_set(buf, cstr, clen+1)) != 0 {
return errors.New("could not set buffer")
}
mbfr (Migrated from github.com) commented 2020-08-14 09:53:21 -05:00

Fixed

Fixed
mbfr (Migrated from github.com) reviewed 2020-08-14 09:55:14 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 09:55:13 -05:00

I did have this doing memset() to null bytes but figured that it was probably done by libgit internally, apparently not...I think I'll just make it do that again to make sure that it has a null byte and to avoid any issues with sizes being incorrect

I did have this doing memset() to null bytes but figured that it was probably done by libgit internally, apparently not...I think I'll just make it do that again to make sure that it has a null byte and to avoid any issues with sizes being incorrect
mbfr (Migrated from github.com) reviewed 2020-08-14 10:14:21 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:14:21 -05:00

I suppose the easier thing to do would be to just do clen+1 in the git_buf_set as well then, fixed

I suppose the easier thing to do would be to just do clen+1 in the git_buf_set as well then, fixed
mbfr (Migrated from github.com) reviewed 2020-08-14 10:14:55 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:14:55 -05:00

Removed

Removed
mbfr (Migrated from github.com) reviewed 2020-08-14 10:15:06 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:15:05 -05:00

Oops, will accept the suggestion

Oops, will accept the suggestion
mbfr (Migrated from github.com) reviewed 2020-08-14 10:16:51 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:16:51 -05:00

It's already checked directly above, I don't think it needs to do it again?

It's already checked directly above, I don't think it needs to do it again?
mbfr (Migrated from github.com) reviewed 2020-08-14 10:24:11 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:24:11 -05:00

Done

Done
mbfr (Migrated from github.com) reviewed 2020-08-14 10:25:10 -05:00
@ -177,3 +298,3 @@
// Init rebase
rebase, err := repo.InitRebase(nil, nil, onto, nil)
rebase, err := repo.InitRebase(nil, nil, onto, opts)
if err != nil {
mbfr (Migrated from github.com) commented 2020-08-14 10:25:10 -05:00

Added, should make logs a bit nicer

Added, should make logs a bit nicer
mbfr (Migrated from github.com) reviewed 2020-08-14 10:26:02 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:26:02 -05:00

It's used in 2 places, unless you mean you want to to refactor it so both of those invocations are inside the for loop?

It's used in 2 places, unless you mean you want to to refactor it so both of those invocations are inside the for loop?
mbfr (Migrated from github.com) reviewed 2020-08-14 10:28:17 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:28:17 -05:00

Ah yes, it misses the case in which the head commit is not signed, fixed

Ah yes, it misses the case in which the head commit is not signed, fixed
mbfr (Migrated from github.com) reviewed 2020-08-14 10:32:00 -05:00
mbfr (Migrated from github.com) commented 2020-08-14 10:32:00 -05:00

Fixed this and the other similar ones

Fixed this and the other similar ones
lhchavez (Migrated from github.com) reviewed 2020-08-14 19:12:17 -05:00
lhchavez (Migrated from github.com) left a comment

just relatively minor things left.

just relatively minor things left.
lhchavez (Migrated from github.com) commented 2020-08-14 18:54:35 -05:00

can gofmt be run on the change? (i need to see if there's a way to do that automatically)

can `gofmt` be run on the change? (i need to see if there's a way to do that automatically)
lhchavez (Migrated from github.com) commented 2020-08-14 19:11:07 -05:00
// CommitSigningCb defines a function type that takes some data to sign and returns (signature, signature_field, error)
type CommitSigningCb func(string) (signature, signatureField string, err error)

welp, i missed this. it should make the godoc a bit better.

```suggestion // CommitSigningCb defines a function type that takes some data to sign and returns (signature, signature_field, error) type CommitSigningCb func(string) (signature, signatureField string, err error) ``` welp, i missed this. it should make the godoc a bit better.
@ -69,14 +71,66 @@ func newRebaseOperationFromC(c *C.git_rebase_operation) *RebaseOperation {
return operation
lhchavez (Migrated from github.com) commented 2020-08-14 19:04:33 -05:00

OK, second try:

		C.git_buf_clear(buf)
		if int(C.git_buf_put(buf, cstr, clen)) != 0 {
			return errors.New("could not set buffer")
		}

git_buf_clear() will remove whatever is in the buffer, and git_buf_put() grows the buffer AND adds the NULL byte at the end.

OK, second try: ```suggestion C.git_buf_clear(buf) if int(C.git_buf_put(buf, cstr, clen)) != 0 { return errors.New("could not set buffer") } ``` [`git_buf_clear()`](https://github.com/libgit2/libgit2/blob/c71321a099373753c22055921c8f538afed5ebb6/src/buffer.c#L152-L163) will remove whatever is in the buffer, and [`git_buf_put()`](https://github.com/libgit2/libgit2/blob/c71321a099373753c22055921c8f538afed5ebb6/src/buffer.c#L223-L238) grows the buffer AND adds the NULL byte at the end.
lhchavez (Migrated from github.com) commented 2020-08-14 18:51:38 -05:00

ah! did not expand the diff ^^;; it's fine to remove.

ah! did not expand the diff ^^;; it's fine to remove.
lhchavez (Migrated from github.com) commented 2020-08-14 19:08:19 -05:00

this should be unneeded now.

```suggestion ``` this should be unneeded now.
mbfr (Migrated from github.com) reviewed 2020-08-18 02:20:24 -05:00
mbfr (Migrated from github.com) commented 2020-08-18 02:20:23 -05:00

Fixed

Fixed
mbfr (Migrated from github.com) reviewed 2020-08-18 02:51:47 -05:00
@ -69,14 +71,66 @@ func newRebaseOperationFromC(c *C.git_rebase_operation) *RebaseOperation {
return operation
mbfr (Migrated from github.com) commented 2020-08-18 02:51:47 -05:00

It seems like those functions aren't defined in the 'buffer.h' header and are also not specified in the documentation, I tried manually adding the extern ... but got an undefined reference error. Are they intended only for internal use?

It seems like those functions aren't defined in the 'buffer.h' header and are also not specified in the [documentation](https://libgit2.org/libgit2/#HEAD/search/git_buf_), I tried manually adding the `extern ...` but got an undefined reference error. Are they intended only for internal use?
mbfr (Migrated from github.com) reviewed 2020-08-18 02:55:39 -05:00
mbfr (Migrated from github.com) commented 2020-08-18 02:55:39 -05:00

Fixed this and also changed the name of the type/field to be more appropriate (based on feedback from other PR)

Fixed this and also changed the name of the type/field to be more appropriate (based on feedback from other PR)
lhchavez (Migrated from github.com) reviewed 2020-08-18 08:52:01 -05:00
@ -41,2 +41,4 @@
}
// RawHeader gets the full raw text of the commit header.
func (c *Commit) RawHeader() string {
lhchavez (Migrated from github.com) commented 2020-08-18 08:50:58 -05:00

one more thing i forgot, can the public functions have a docstring? most of the contents can be copied from the C docs.

one more thing i forgot, can the public functions have a docstring? most of the contents can be copied from the C docs.
@ -69,14 +71,66 @@ func newRebaseOperationFromC(c *C.git_rebase_operation) *RebaseOperation {
return operation
lhchavez (Migrated from github.com) commented 2020-08-18 08:47:27 -05:00

argh, yes u_u they are not marked GIT_EXTERN.

but why is it not possible to use

		if int(C.git_buf_set(buf, cstr, clen)) != 0 {
			return errors.New("could not set buffer")
		}

? git_buf_set resizes the buffer (plus the space for the NULL byte), and adds the trailing NULL byte. That's even independent of whether the original c-string had a NULL pointer or not. (This time around I did test this suggestion locally, so I'm sure this one does definitely work).

argh, yes u_u they are not marked `GIT_EXTERN`. but why is it not possible to use ```suggestion if int(C.git_buf_set(buf, cstr, clen)) != 0 { return errors.New("could not set buffer") } ``` ? [`git_buf_set`](https://github.com/libgit2/libgit2/blob/c71321a099373753c22055921c8f538afed5ebb6/src/buffer.c#L165-L184) resizes the buffer (plus the space for the NULL byte), and adds the trailing NULL byte. That's even independent of whether the original c-string had a NULL pointer or not. (This time around I did test this suggestion locally, so I'm sure this one does definitely work).
lhchavez (Migrated from github.com) commented 2020-08-18 08:48:29 -05:00
	opts->signing_cb = (git_commit_signing_cb)commitSignCallback;

for consistency with the other entries in this file.

```suggestion opts->signing_cb = (git_commit_signing_cb)commitSignCallback; ``` for consistency with the other entries in this file.
mbfr (Migrated from github.com) reviewed 2020-08-18 09:13:15 -05:00
@ -69,14 +71,66 @@ func newRebaseOperationFromC(c *C.git_rebase_operation) *RebaseOperation {
return operation
mbfr (Migrated from github.com) commented 2020-08-18 09:13:14 -05:00

I tried this before and although it works in CI (see: github actions on that commit), when running locally I get this error

___go_test_github_com_libgit2_git2go_v30: /build/libgit2/src/libgit2-1.0.1/src/rebase.c:1007: rebase_commit__create: Assertion `git_buf_contains_nul(&commit_signature)' failed.
I tried this before and although it works in CI (see: github actions on that commit), when running locally I get this error ``` ___go_test_github_com_libgit2_git2go_v30: /build/libgit2/src/libgit2-1.0.1/src/rebase.c:1007: rebase_commit__create: Assertion `git_buf_contains_nul(&commit_signature)' failed. ```
mbfr (Migrated from github.com) reviewed 2020-08-18 09:14:12 -05:00
mbfr (Migrated from github.com) commented 2020-08-18 09:14:12 -05:00

Fixed

Fixed
mbfr (Migrated from github.com) reviewed 2020-08-18 09:18:00 -05:00
@ -41,2 +41,4 @@
}
// RawHeader gets the full raw text of the commit header.
func (c *Commit) RawHeader() string {
mbfr (Migrated from github.com) commented 2020-08-18 09:18:00 -05:00

Fixed

Fixed
lhchavez (Migrated from github.com) reviewed 2020-08-18 10:13:35 -05:00
@ -69,14 +71,66 @@ func newRebaseOperationFromC(c *C.git_rebase_operation) *RebaseOperation {
return operation
lhchavez (Migrated from github.com) commented 2020-08-18 10:13:34 -05:00

interesting, that means that we need to have at least one CI configuration where assertions are enabled.

okay, what about

		// libgit2 requires the contents of the buffer to be NULL-terminated.
		// C.CString() guarantees that the returned buffer will be
		// NULL-terminated, so we can safely copy the terminator.
		if int(C.git_buf_set(buf, cstr, clen+1)) != 0 {
			return errors.New("could not set buffer")
		}

proof of guarantee: 4149493443/src/cmd/cgo/out.go (L1709-L1716)

interesting, that means that we need to have at least one CI configuration where assertions are enabled. okay, what about ```suggestion // libgit2 requires the contents of the buffer to be NULL-terminated. // C.CString() guarantees that the returned buffer will be // NULL-terminated, so we can safely copy the terminator. if int(C.git_buf_set(buf, cstr, clen+1)) != 0 { return errors.New("could not set buffer") } ``` proof of guarantee: https://github.com/golang/go/blob/4149493443f09c14d9f0fad7030704ed57149b55/src/cmd/cgo/out.go#L1709-L1716
mbfr (Migrated from github.com) reviewed 2020-08-18 10:26:33 -05:00
@ -69,14 +71,66 @@ func newRebaseOperationFromC(c *C.git_rebase_operation) *RebaseOperation {
return operation
mbfr (Migrated from github.com) commented 2020-08-18 10:26:33 -05:00

Fixed (and removed the old wrapper)

Fixed (and removed the old wrapper)
lhchavez (Migrated from github.com) approved these changes 2020-08-18 11:21:55 -05:00
lhchavez (Migrated from github.com) left a comment

Thanks again!

Thanks again!
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: jcarr/git2go#626
No description provided.