<commit_before>import { git, envForAuthentication, expectedAuthenticationErrors } from './core'
import { Repository } from '../../models/repository'
import { Account } from '../../models/account'

/** Push from the remote to the branch, optionally setting the upstream. */
export async function push(repository: Repository, account: Account | null, remote: string, branch: string, setUpstream: boolean): Promise<void> {
  const args = [ 'push', remote, branch ]
  if (setUpstream) {
    args.push('--set-upstream')
  }

  const options = {
    env: envForAuthentication(account),
    expectedErrors: expectedAuthenticationErrors(),
  }

  const result = await git(args, repository.path, 'push', options)

  if (result.gitErrorDescription) {
    return Promise.reject(new Error(result.gitErrorDescription))
  }

  return Promise.resolve()
}<commit_msg>Expose progress callback for push<commit_after>import { git, envForAuthentication, expectedAuthenticationErrors, IGitExecutionOptions } from './core'
import { Repository } from '../../models/repository'
import { Account } from '../../models/account'
import { ChildProcess } from 'child_process'

const byline = require('byline')

/** Push from the remote to the branch, optionally setting the upstream. */
export async function push(repository: Repository, account: Account | null, remote: string, branch: string, setUpstream: boolean, progressCallback?: (line: string) => void): Promise<void> {
  const args = [ 'push', remote, branch ]
  if (setUpstream) {
    args.push('--set-upstream')
  }

  let options: IGitExecutionOptions = {
    env: envForAuthentication(account),
    expectedErrors: expectedAuthenticationErrors(),
  }

  if (progressCallback) {
    args.push('--progress')

    options = {
      ...options,
      processCallback: (process: ChildProcess) => {
        byline(process.stderr).on('data', (chunk: string) => {
          progressCallback(chunk)
        })
      },
    }
  }

  const result = await git(args, repository.path, 'push', options)

  if (result.gitErrorDescription) {
    return Promise.reject(new Error(result.gitErrorDescription))
  }

  return Promise.resolve()
}
{'fraction_non_alphanumeric': 0.13178654292343386, 'fraction_numerical': 0.0, 'mean_word_length': 4.037383177570093, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7623365', 'n_tokens_mistral': 593, 'n_tokens_neox': 577, 'n_words': 165}