Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Support cancellation of long-running repository operations (with context.Context) #483

@JoshuaSjoding

Description

@JoshuaSjoding

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions