forked from atom/github
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrepository-conflict-controller.js
112 lines (96 loc) · 3.28 KB
/
repository-conflict-controller.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import path from 'path';
import React from 'react';
import PropTypes from 'prop-types';
import yubikiri from 'yubikiri';
import {CompositeDisposable} from 'event-kit';
import ObserveModel from '../views/observe-model';
import ResolutionProgress from '../models/conflicts/resolution-progress';
import EditorConflictController from './editor-conflict-controller';
const DEFAULT_REPO_DATA = {
mergeConflictPaths: [],
isRebasing: false,
};
/**
* Render an `EditorConflictController` for each `TextEditor` open on a file that contains git conflict markers.
*/
export default class RepositoryConflictController extends React.Component {
static propTypes = {
workspace: PropTypes.object.isRequired,
commands: PropTypes.object.isRequired,
config: PropTypes.object.isRequired,
resolutionProgress: PropTypes.object.isRequired,
repository: PropTypes.object.isRequired,
refreshResolutionProgress: PropTypes.func,
};
static defaultProps = {
refreshResolutionProgress: () => {},
resolutionProgress: new ResolutionProgress(),
};
constructor(props, context) {
super(props, context);
this.state = {openEditors: this.props.workspace.getTextEditors()};
this.subscriptions = new CompositeDisposable();
}
componentDidMount() {
const updateState = () => {
this.setState({
openEditors: this.props.workspace.getTextEditors(),
});
};
this.subscriptions.add(
this.props.workspace.observeTextEditors(updateState),
this.props.workspace.onDidDestroyPaneItem(updateState),
this.props.config.observe('github.graphicalConflictResolution', () => this.forceUpdate()),
);
}
fetchData = repository => {
return yubikiri({
workingDirectoryPath: repository.getWorkingDirectoryPath(),
mergeConflictPaths: repository.getMergeConflicts().then(conflicts => {
return conflicts.map(conflict => conflict.filePath);
}),
isRebasing: repository.isRebasing(),
});
}
render() {
return (
<ObserveModel model={this.props.repository} fetchData={this.fetchData}>
{data => this.renderWithData(data || DEFAULT_REPO_DATA)}
</ObserveModel>
);
}
renderWithData(repoData) {
const conflictingEditors = this.getConflictingEditors(repoData);
return (
<div>
{conflictingEditors.map(editor => (
<EditorConflictController
key={editor.id}
commands={this.props.commands}
resolutionProgress={this.props.resolutionProgress}
editor={editor}
isRebase={repoData.isRebasing}
refreshResolutionProgress={this.props.refreshResolutionProgress}
/>
))}
</div>
);
}
getConflictingEditors(repoData) {
if (
repoData.mergeConflictPaths.length === 0 ||
this.state.openEditors.length === 0 ||
!this.props.config.get('github.graphicalConflictResolution')
) {
return [];
}
const commonBasePath = this.props.repository.getWorkingDirectoryPath();
const fullMergeConflictPaths = new Set(
repoData.mergeConflictPaths.map(relativePath => path.join(commonBasePath, relativePath)),
);
return this.state.openEditors.filter(editor => fullMergeConflictPaths.has(editor.getPath()));
}
componentWillUnmount() {
this.subscriptions.dispose();
}
}