Skip to content

ReportingProgress(sink) never receives "Receiving objects" / "Resolving deltas" from Clone, Fetch, Push or Pull: --progress is never passed, so git suppresses transfer progress on a redirected stderr #154

Description

@matt-edmondson

What's wrong

Git reports transfer progress (counting, "Receiving objects", "Resolving deltas", remote "Writing objects") only when stderr is a terminal, unless --progress is passed. RunCommand redirects stderr, and none of the network builders ever emit --progress:

  • GitIntegration/Builders/GitCloneBuilder.cs:123
  • GitFetchBuilder.cs:210
  • GitPushBuilder.cs:195
  • GitPullBuilder.cs:217
  • GitSubmoduleUpdateBuilder.cs:155

(grep -- --progress GitIntegration/ finds nothing.)

The docs promise this output. GitCloneBuilder.cs:47-57 and GitFetchBuilder.cs:68-72 say ReportingProgress "reports git's progress output as it arrives", but the network phase, which is the slow part and the reason to attach a sink at all, never arrives.

Repro

The source repo has 3000 files, about 6 MB. Each run uses the real RunCommandGitProcessRunner.

  • Clone("file://…/src", dest).ReportingProgress(sink).ExecuteAsync() sends the sink 13 chunks, 482 characters in total. The only text is "Cloning into …" and "Updating files: 89% … 100%". Contains("Receiving objects") is False.
  • The same clone from the shell without --progress writes 21 bytes to stderr. With --progress it writes 14,452 bytes, ending with Receiving objects: 100% (3002/3002), 6.02 MiB.
  • For Fetch, the sink gets 0 "Receiving objects" updates, against 102 with --progress.

Why it matters

A UI showing a progress bar for a clone or fetch sits frozen through the entire transfer and then jumps to "Updating files". That's exactly the case ReportingProgress exists for.

Suggested fix

  • In each of the five builders, emit --progress when a sink is set (Progress is not null), and only then, so stderr stays small and exception diagnostics stay short when nobody is listening.
  • Push/Fetch --porcelain output goes to stdout, so the parsers are unaffected.

Acceptance criteria

  • An integration test clones a file:// repo with a few thousand objects and a sink attached, then asserts the sink saw "Receiving objects". Add a matching test for Fetch.
  • Without a sink, the argument vector contains no --progress, which a builder unit test checks.

Related but separate: #147 (a sink that throws).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions