<commit_before>import * as FSE from 'fs-extra'
import * as Path from 'path'
import {
  continueRebase,
  getChangedFiles,
  getCommit,
  getCommits,
  getRebaseInternalState,
  RebaseResult,
} from '../../../src/lib/git'
import { CommitOneLine } from '../../../src/models/commit'
import { Repository } from '../../../src/models/repository'
import { setupEmptyRepositoryDefaultMain } from '../../helpers/repositories'
import { makeCommit } from '../../helpers/repository-scaffolding'
import { squash } from '../../../src/lib/git/squash'
import { GitProcess } from 'dugite'
import { getStatusOrThrow } from '../../helpers/status'
import { getTempFilePath } from '../../../src/lib/file-system'

describe('git/cherry-pick', () => {
  let repository: Repository
  let initialCommit: CommitOneLine

  beforeEach(async () => {
    repository = await setupEmptyRepositoryDefaultMain()
    initialCommit = await makeSquashCommit(repository, 'initialize')
  })

  it('squashes one commit onto the next (non-conflicting)', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    const secondCommit = await makeSquashCommit(repository, 'second')

    const result = await squash(
      repository,
      [secondCommit],
      firstCommit,
      initialCommit.sha,
      'Test Summary\n\nTest Body'
    )

    expect(result).toBe(RebaseResult.CompletedWithoutError)

    const log = await getCommits(repository, 'HEAD', 5)
    const squashed = log[0]
    expect(squashed.summary).toBe('Test Summary')
    expect(squashed.body).toBe('Test Body\n')
    expect(log.length).toBe(2)

    // verify squashed commit contains changes from squashed commits
    const squashedFiles = await getChangedFiles(repository, squashed.sha)
    const squashedFilePaths = squashedFiles.map(f => f.path).join(' ')
    expect(squashedFilePaths).toContain('first.md')
    expect(squashedFilePaths).toContain('second.md')
  })

  it('returns error when squashOnto is in the toSquash array', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    const secondCommit = await makeSquashCommit(repository, 'second')

    const result = await squash(
      repository,
      [firstCommit, secondCommit],
      firstCommit,
      initialCommit.sha,
      'Test Summary\n\nTest Body'
    )

    expect(result).toBe(RebaseResult.Error)
  })

  it('squashes multiple commit onto one (non-conflicting)', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    const secondCommit = await makeSquashCommit(repository, 'second')
    const thirdCommit = await makeSquashCommit(repository, 'third')
    const fourthCommit = await makeSquashCommit(repository, 'fourth')

    const result = await squash(
      repository,
      [secondCommit, thirdCommit, fourthCommit],
      firstCommit,
      initialCommit.sha,
      'Test Summary\n\nTest Body'
    )

    expect(result).toBe(RebaseResult.CompletedWithoutError)

    const log = await getCommits(repository, 'HEAD', 5)
    const squashed = log[0]
    expect(squashed.summary).toBe('Test Summary')
    expect(squashed.body).toBe('Test Body\n')
    expect(log.length).toBe(2)

    // verify squashed commit contains changes from squashed commits
    const squashedFiles = await getChangedFiles(repository, squashed.sha)
    const squashedFilePaths = squashedFiles.map(f => f.path).join(' ')
    expect(squashedFilePaths).toContain('first.md')
    expect(squashedFilePaths).toContain('second.md')
    expect(squashedFilePaths).toContain('third.md')
    expect(squashedFilePaths).toContain('fourth.md')
  })

  it('squashes multiple commit non-sequential commits (reorders, non-conflicting)', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    await makeSquashCommit(repository, 'second')
    const thirdCommit = await makeSquashCommit(repository, 'third')
    await makeSquashCommit(repository, 'fourth')
    const fifthCommit = await makeSquashCommit(repository, 'fifth')

    // From oldest to newest, log looks like:
    // - initial commit
    // - 'first' commit
    // - 'second' commit
    // - 'third' commit
    // - 'fourth' commit
    // - 'fifth' commit

    // Squashing 'first' and 'fifth' onto 'third'
    // Thus, reordering to 'second', 'first - third - fifth', 'fourth'
    const result = await squash(
      repository,
      [firstCommit, fifthCommit],
      thirdCommit,<commit_msg>Make test better by providing toSquash in non log order<commit_after>import * as FSE from 'fs-extra'
import * as Path from 'path'
import {
  continueRebase,
  getChangedFiles,
  getCommit,
  getCommits,
  getRebaseInternalState,
  RebaseResult,
} from '../../../src/lib/git'
import { CommitOneLine } from '../../../src/models/commit'
import { Repository } from '../../../src/models/repository'
import { setupEmptyRepositoryDefaultMain } from '../../helpers/repositories'
import { makeCommit } from '../../helpers/repository-scaffolding'
import { squash } from '../../../src/lib/git/squash'
import { GitProcess } from 'dugite'
import { getStatusOrThrow } from '../../helpers/status'
import { getTempFilePath } from '../../../src/lib/file-system'

describe('git/cherry-pick', () => {
  let repository: Repository
  let initialCommit: CommitOneLine

  beforeEach(async () => {
    repository = await setupEmptyRepositoryDefaultMain()
    initialCommit = await makeSquashCommit(repository, 'initialize')
  })

  it('squashes one commit onto the next (non-conflicting)', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    const secondCommit = await makeSquashCommit(repository, 'second')

    const result = await squash(
      repository,
      [secondCommit],
      firstCommit,
      initialCommit.sha,
      'Test Summary\n\nTest Body'
    )

    expect(result).toBe(RebaseResult.CompletedWithoutError)

    const log = await getCommits(repository, 'HEAD', 5)
    const squashed = log[0]
    expect(squashed.summary).toBe('Test Summary')
    expect(squashed.body).toBe('Test Body\n')
    expect(log.length).toBe(2)

    // verify squashed commit contains changes from squashed commits
    const squashedFiles = await getChangedFiles(repository, squashed.sha)
    const squashedFilePaths = squashedFiles.map(f => f.path).join(' ')
    expect(squashedFilePaths).toContain('first.md')
    expect(squashedFilePaths).toContain('second.md')
  })

  it('returns error when squashOnto is in the toSquash array', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    const secondCommit = await makeSquashCommit(repository, 'second')

    const result = await squash(
      repository,
      [firstCommit, secondCommit],
      firstCommit,
      initialCommit.sha,
      'Test Summary\n\nTest Body'
    )

    expect(result).toBe(RebaseResult.Error)
  })

  it('squashes multiple commit onto one (non-conflicting)', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    const secondCommit = await makeSquashCommit(repository, 'second')
    const thirdCommit = await makeSquashCommit(repository, 'third')
    const fourthCommit = await makeSquashCommit(repository, 'fourth')

    const result = await squash(
      repository,
      [secondCommit, thirdCommit, fourthCommit],
      firstCommit,
      initialCommit.sha,
      'Test Summary\n\nTest Body'
    )

    expect(result).toBe(RebaseResult.CompletedWithoutError)

    const log = await getCommits(repository, 'HEAD', 5)
    const squashed = log[0]
    expect(squashed.summary).toBe('Test Summary')
    expect(squashed.body).toBe('Test Body\n')
    expect(log.length).toBe(2)

    // verify squashed commit contains changes from squashed commits
    const squashedFiles = await getChangedFiles(repository, squashed.sha)
    const squashedFilePaths = squashedFiles.map(f => f.path).join(' ')
    expect(squashedFilePaths).toContain('first.md')
    expect(squashedFilePaths).toContain('second.md')
    expect(squashedFilePaths).toContain('third.md')
    expect(squashedFilePaths).toContain('fourth.md')
  })

  it('squashes multiple commit non-sequential commits (reorders, non-conflicting)', async () => {
    const firstCommit = await makeSquashCommit(repository, 'first')
    await makeSquashCommit(repository, 'second')
    const thirdCommit = await makeSquashCommit(repository, 'third')
    await makeSquashCommit(repository, 'fourth')
    const fifthCommit = await makeSquashCommit(repository, 'fifth')

    // From oldest to newest, log looks like:
    // - initial commit
    // - 'first' commit
    // - 'second' commit
    // - 'third' commit
    // - 'fourth' commit
    // - 'fifth' commit

    // Squashing 'first' and 'fifth' onto 'third'
    // Thus, reordering to 'second', 'first - third - fifth', 'fourth'
    const result = await squash(
      repository,
      [fifthCommit, firstCommit], // provided in opposite log order
      thirdCommit,
{'fraction_non_alphanumeric': 0.12698768197088467, 'fraction_numerical': 0.0013437849944008958, 'mean_word_length': 3.6612734864300625, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '5280298', 'n_tokens_mistral': 2654, 'n_tokens_neox': 2632, 'n_words': 629}