<commit_before>/** @jsx etch.dom */
/* eslint react/no-unknown-property: "off" */

import etch from 'etch';

import GitPanelView from '../views/git-panel-view';
import ModelObserver from '../models/model-observer';
import {autobind} from 'core-decorators';

export default class GitPanelController {
  constructor(props) {
    this.props = props;
    this.stagingOperationInProgress = false;

    this.repositoryObserver = new ModelObserver({
      fetchData: this.fetchRepositoryData,
      didUpdate: () => etch.update(this),
    });
    this.repositoryObserver.setActiveModel(props.repository);
    etch.initialize(this);
  }

  render() {
    const modelData = this.repositoryObserver.getActiveModelData() || {fetchInProgress: true};
    return (
      <GitPanelView
        ref="gitPanel"
        {...modelData}
        repository={this.props.repository}
        workspace={this.props.workspace}
        commandRegistry={this.props.commandRegistry}
        notificationManager={this.props.notificationManager}
        didSelectFilePath={this.props.didSelectFilePath}
        didDiveIntoFilePath={this.props.didDiveIntoFilePath}
        didSelectMergeConflictFile={this.props.didSelectMergeConflictFile}
        didDiveIntoMergeConflictPath={this.props.didDiveIntoMergeConflictPath}
        focusFilePatchView={this.props.focusFilePatchView}
        stageFilePatch={this.stageFilePatch}
        unstageFilePatch={this.unstageFilePatch}
        openFiles={this.props.openFiles}
        discardWorkDirChangesForPaths={this.props.discardWorkDirChangesForPaths}
        attemptFileStageOperation={this.attemptFileStageOperation}
        prepareToCommit={this.prepareToCommit}
        commit={this.commit}
        setAmending={this.setAmending}
        isAmending={this.props.isAmending}
        abortMerge={this.abortMerge}
        push={this.push}
        pull={this.pull}
        fetch={this.fetch}
        checkout={this.checkout}
      />
    );
  }

  async update(props) {
    const oldProps = this.props;
    this.props = {...this.props, ...props};
    if (this.props.repository !== oldProps.repository) {
      await this.repositoryObserver.setActiveModel(props.repository);
    } else if (this.props.isAmending !== oldProps.isAmending) {
      await this.repositoryObserver.refreshModelData(this.getActiveRepository());
    }
    return etch.update(this);
  }

  destroy() {
    this.repositoryObserver.destroy();
  }

  getLastModelDataRefreshPromise() {
    return this.repositoryObserver.getLastModelDataRefreshPromise();
  }

  getActiveRepository() {
    return this.repositoryObserver.getActiveModel();
  }

  refreshModelData() {
    return this.repositoryObserver.refreshModelData();
  }

  @autobind
  async fetchRepositoryData(repository) {
    const dataPromises = {
      unstagedChanges: repository.getUnstagedChanges(),
      stagedChanges: this.fetchStagedChanges(repository),
      mergeConflicts: repository.getMergeConflicts(),
      lastCommit: repository.getLastCommit(),
      isMerging: repository.isMerging(),
      branchName: repository.getCurrentBranch(),
      branches: repository.getBranches(),
      remoteName: repository.getRemoteForBranch(this.branchName),
    };
    const data = {
      unstagedChanges: await dataPromises.unstagedChanges,
      stagedChanges: await dataPromises.stagedChanges,
      mergeConflicts: await dataPromises.mergeConflicts,
      lastCommit: await dataPromises.lastCommit,
      isMerging: await dataPromises.isMerging,
      branchName: await dataPromises.branchName,
      branches: await dataPromises.branches,
      mergeMessage: null,
      aheadCount: null,
      behindCount: null,
      remoteName: await dataPromises.remoteName,
    };

    if (data.remoteName) {
      data.aheadCount = await repository.getAheadCount(data.branchName);
      data.behindCount = await repository.getBehindCount(this.branchName);
    }

    if (data.isMerging) {
      data.mergeMessage = await repository.getMergeMessage();
    }

    return data;
  }

  fetchStagedChanges(repository) {
    if (this.props.isAmending) {
      return repository.getStagedChangesSinceParentCommit();<commit_msg>Experiment with optimizing Git calls<commit_after>/** @jsx etch.dom */
/* eslint react/no-unknown-property: "off" */

import etch from 'etch';

import GitPanelView from '../views/git-panel-view';
import ModelObserver from '../models/model-observer';
import {autobind} from 'core-decorators';

export default class GitPanelController {
  constructor(props) {
    this.props = props;
    this.stagingOperationInProgress = false;

    this.repositoryObserver = new ModelObserver({
      fetchData: this.fetchRepositoryData,
      didUpdate: () => etch.update(this),
    });
    this.repositoryObserver.setActiveModel(props.repository);
    etch.initialize(this);
  }

  render() {
    const modelData = this.repositoryObserver.getActiveModelData() || {fetchInProgress: true};
    return (
      <GitPanelView
        ref="gitPanel"
        {...modelData}
        repository={this.props.repository}
        workspace={this.props.workspace}
        commandRegistry={this.props.commandRegistry}
        notificationManager={this.props.notificationManager}
        didSelectFilePath={this.props.didSelectFilePath}
        didDiveIntoFilePath={this.props.didDiveIntoFilePath}
        didSelectMergeConflictFile={this.props.didSelectMergeConflictFile}
        didDiveIntoMergeConflictPath={this.props.didDiveIntoMergeConflictPath}
        focusFilePatchView={this.props.focusFilePatchView}
        stageFilePatch={this.stageFilePatch}
        unstageFilePatch={this.unstageFilePatch}
        openFiles={this.props.openFiles}
        discardWorkDirChangesForPaths={this.props.discardWorkDirChangesForPaths}
        attemptFileStageOperation={this.attemptFileStageOperation}
        prepareToCommit={this.prepareToCommit}
        commit={this.commit}
        setAmending={this.setAmending}
        isAmending={this.props.isAmending}
        abortMerge={this.abortMerge}
        push={this.push}
        pull={this.pull}
        fetch={this.fetch}
        checkout={this.checkout}
      />
    );
  }

  async update(props) {
    const oldProps = this.props;
    this.props = {...this.props, ...props};
    if (this.props.repository !== oldProps.repository) {
      await this.repositoryObserver.setActiveModel(props.repository);
    } else if (this.props.isAmending !== oldProps.isAmending) {
      await this.repositoryObserver.refreshModelData(this.getActiveRepository());
    }
    return etch.update(this);
  }

  destroy() {
    this.repositoryObserver.destroy();
  }

  getLastModelDataRefreshPromise() {
    return this.repositoryObserver.getLastModelDataRefreshPromise();
  }

  getActiveRepository() {
    return this.repositoryObserver.getActiveModel();
  }

  refreshModelData() {
    return this.repositoryObserver.refreshModelData();
  }

  @autobind
  async fetchRepositoryData(repository) {
    const dataPromises = {
      mergeConflicts: repository.getMergeConflicts(),
      lastCommit: repository.getLastCommit(),
      isMerging: repository.isMerging(),
      branchName: repository.getCurrentBranch(),
      branches: repository.getBranches(),
      remoteName: repository.getRemoteForBranch(this.branchName),
      unstagedChanges: repository.getUnstagedChanges(),
      stagedChanges: this.fetchStagedChanges(repository),
    };
    const data = {
      unstagedChanges: await dataPromises.unstagedChanges,
      stagedChanges: await dataPromises.stagedChanges,
      mergeConflicts: await dataPromises.mergeConflicts,
      lastCommit: await dataPromises.lastCommit,
      isMerging: await dataPromises.isMerging,
      branchName: await dataPromises.branchName,
      branches: await dataPromises.branches,
      mergeMessage: null,
      aheadCount: null,
      behindCount: null,
      remoteName: await dataPromises.remoteName,
    };

    if (data.remoteName) {
      data.aheadCount = await repository.getAheadCount(data.branchName);
      data.behindCount = await repository.getBehindCount(this.branchName);
    }

    if (data.isMerging) {
      data.mergeMessage = await repository.getMergeMessage();
    }

    return data;
  }

  fetchStagedChanges(repository) {
    if (this.props.isAmending) {
      return repository.getStagedChangesSinceParentCommit();
{'fraction_non_alphanumeric': 0.10555355643516852, 'fraction_numerical': 0.0, 'mean_word_length': 3.609176340519624, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '1199709', 'n_tokens_mistral': 2361, 'n_tokens_neox': 2345, 'n_words': 359}