We change `Patch::latest` to always return something, because a patch is
malformed if it doesn't have at least one revision, and thus would not
load in the first place.
This also implies that there is a latest revision in the face of
concurrent updates.
Note that currently, traversal order for concurrent updates is still random.
This will be fixed in another patch.
Before this change, if a merge op referred to a commit that was not on
the default branch, the merge op and all descendant ops would be pruned.
This is a bad idea because the state of the default branch can change
*after* the merge op is created, which is out of the control of the
merge op author.
Therefore, instead of exiting, we keep processing ops (but ignore the
merge), in case the merge is invalid for this specific reason.
Previously, only one connection to the node control socket could be
handled at a time. This usually worked fine, but if one connection hangs
for whatever reason, no other process can access the node.
It turns out it's possible to create a deadlock when using
`child.wait()` with `Stdio::piped()`, if we don't read the output while
the child process is running. This is because the pipe has an internal
kernel buffer that will eventually fill up, causing the child process to
block on writing to stdout and never exit.
To remedy this situation, we read the stdout in a thread while the child
process is running.
When applying a `Merge` action, we verify that the commit is in the
history of the default branch of that user.
Since this is not the case when issuing a `rad merge`, and since that
command is no longer needed with the push-based merge, we remove the
`rad merge` command completely.
To allow third party tools read the routing table entries filtered by
rid or nid and if needed in json format.
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
Move `merges` from `Revision` to `Patch`, and key them by actor.
This ensures that only one merge is possible per actor. We also make
sure that only one revision can be merged at a time, and signal a
conflict if more than one revision is considered merged.
Finally, we make sure that merges have the same target-branch commit
to be considered equal.
Allows third party implementations to listen to the event stream of a
node.
In case of a serialization error we exit the event subscription and end
the process.
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
Allows patches to have their state updated to `Merged` with a `git push`
to the default branch.
Currently, due to the limitations of the COB store, this requires a
linear search through all patches. This will eventually become a problem
when projects have thousands of patches, so we should look into
long-term solutions.
When updating sigrefs with `storage::refs::save` we weren't checking
the `RAD_COMMIT_TIME` variable, so the sigrefs commit was using current
time, and we weren't able to reproduce a deterministic sigrefs commit.
Make `refs::save` reproducible in debug mode using `debug_assertions`
and checking the `RAD_COMMIT_TIME` environment variable.
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
'git pull' in workflow/6-pulling-contributor causes a message to be
emitted for some git versions. It asks to configure 'git pull's default
action.
Use '--ff' as a workaround as a git config file is unsupported, and no
environment variable exists for this configuration.
The `refs/tmp` namespace is used by Git for the purpose of storing
temporary refs. We use it here instead of `refs/patch` to indicate
that the refs can be safely deleted.
This adds the ability to the git-remote-helper to open and update
patches via a `git push` to the magic ref `refs/patches` and
`refs/heads/patches/<patch-id>`.
The main change is that we had to move away from offering the `connect`
capability in the remote helper, to offering `push` and `fetch`
individually.
To get a feel for how this works, see the `rad-patch-via-push.md`
example.