-
Notifications
You must be signed in to change notification settings - Fork 534
Support cancellation of long-running repository operations (with context.Context) #483
Description
Right now all of the Repository
and Remote
operations including Clone
, Fetch
, Pull
and Push
run until completion or until an error occurs. I propose adding a context.Context
argument to each operation that could be long-running, so that these operations can be cancelled if the caller deems it necessary.
Here are some circumstances that such a change would allow the caller to deal with:
- A bug in
go-git
causes an operation to stall and not make progress - A bug in the remote server causes it to stall and not make progress
- The remote server is malfunctioning or overburdened and is taking too long to make progress
- The network between the client and server is malfunctioning or in a poor operating condition
Adding a new argument to these operations is a breaking change, so this would be a v5
feature.
Adding a simple Timeout
field to CloneOptions
, FetchOptions
, PullOptions
and PushOptions
would be insufficient. The caller may want to allow a long-running operation that is slowly making progress to continue, even though it exceeds an absolute timeout. The addition of context.Context
, in combination with the existing Options.Progress
, allows the caller to handle such cases.
The superficial changes to Repository
are not difficult, but fully implementing context.Context
throughout the plumbing
and internal
packages will take some effort. I propose making these changes in an iterative process with a series of pull requests, starting with the superficial changes to Repository
and propagating context.Context
throughout the library one step at a time.
If a context.Context
is cancelled, go-git
should make every effort to leave storage.Storage
in a functional and uncorrupted state. I expect that this will be the most difficult part of these changes and require the most thought.
This work is a prerequisite for using go-git
internally in the new dep tool.
Here's what the Remote
methods would look like:
func (r *Remote) Fetch(ctx context.Context, o *FetchOptions) error
func (r *Remote) Push(ctx context.Context, o *PushOptions) (err error)
Here's what the Repository
methods would look like:
func Clone(ctx context.Context, s storage.Storer, worktree billy.Filesystem, o *CloneOptions) (*Repository, error)
func (r *Repository) Fetch(ctx context.Context, o *FetchOptions) error
func (r *Repository) Pull(ctx context.Context, o *PullOptions) error
func (r *Repository) Push(ctx context.Context, o *PushOptions) error