diff --git a/lib/controllers/root-controller.js b/lib/controllers/root-controller.js
index 708fdc3561..a7ec4f151f 100644
--- a/lib/controllers/root-controller.js
+++ b/lib/controllers/root-controller.js
@@ -31,7 +31,7 @@ import GitTimingsView from '../views/git-timings-view';
import Conflict from '../models/conflicts/conflict';
import {getEndpoint} from '../models/endpoint';
import Switchboard from '../switchboard';
-import {WorkdirContextPoolPropType} from '../prop-types';
+import {WorkdirContextPoolPropType, WorkdirCachePropType} from '../prop-types';
import {destroyFilePatchPaneItems, destroyEmptyFilePatchPaneItems, autobind} from '../helpers';
import {GitError} from '../git-shell-out-strategy';
import {incrementCounter, addEvent} from '../reporter-proxy';
@@ -54,6 +54,7 @@ export default class RootController extends React.Component {
// Models
loginModel: PropTypes.object.isRequired,
workdirContextPool: WorkdirContextPoolPropType.isRequired,
+ workdirCache: WorkdirCachePropType.isRequired,
repository: PropTypes.object.isRequired,
resolutionProgress: PropTypes.object.isRequired,
statusBar: PropTypes.object,
@@ -164,6 +165,10 @@ export default class RootController extends React.Component {
command="github:view-staged-changes-for-current-file"
callback={this.viewStagedChangesForCurrentFile}
/>
+
{
+ const paneItem = this.props.workspace.getCenter().getActivePaneItem();
+
+ if (!paneItem) {
+ return;
+ }
+
+ let itemPath = null;
+
+ // Likely GitHub package provided pane item
+ if (typeof paneItem.getWorkingDirectory === 'function') {
+ itemPath = path.normalize(paneItem.getWorkingDirectory());
+ }
+
+ // TextEditor-like
+ if (typeof paneItem.getPath === 'function') {
+ itemPath = path.normalize(paneItem.getPath());
+ }
+
+ // Oh well
+ if (!itemPath) {
+ return;
+ }
+
+ // Find valid git working directory
+ const workdir = await this.props.workdirCache.find(itemPath);
+
+ if (workdir) {
+ this.props.changeWorkingDirectory(workdir);
+ return;
+ }
+
+ // At this point, there is no parent git working directory
+ // But, we can still assign the current context to a valid context
+ // if the file is a child of a current working directory
+ const workdirs = this.props.workdirContextPool.getCurrentWorkDirs();
+ const itemTokens = itemPath.split(path.sep);
+ for (const dir of workdirs) {
+ const tokens = path.normalize(dir).split(path.sep).filter(t => t.length);
+ if (tokens.every((t, i) => itemTokens[i] === t)) {
+ // is a child of
+ this.props.changeWorkingDirectory(dir);
+ }
+ }
+ }
+
showWaterfallDiagnostics() {
this.props.workspace.open(GitTimingsView.buildURI());
}
diff --git a/lib/github-package.js b/lib/github-package.js
index f2fb23f72d..902bc52b31 100644
--- a/lib/github-package.js
+++ b/lib/github-package.js
@@ -293,6 +293,7 @@ export default class GithubPackage {
confirm={this.confirm}
currentWindow={this.currentWindow}
workdirContextPool={this.contextPool}
+ workdirCache={this.workdirCache}
loginModel={this.loginModel}
repository={this.getActiveRepository()}
resolutionProgress={this.getActiveResolutionProgress()}
diff --git a/lib/prop-types.js b/lib/prop-types.js
index 29fc33f8e1..d28870b09d 100644
--- a/lib/prop-types.js
+++ b/lib/prop-types.js
@@ -14,6 +14,10 @@ export const WorkdirContextPoolPropType = PropTypes.shape({
getContext: PropTypes.func.isRequired,
});
+export const WorkdirCachePropType = PropTypes.shape({
+ find: PropTypes.func.isRequired,
+});
+
export const GithubLoginModelPropType = PropTypes.shape({
getToken: PropTypes.func.isRequired,
setToken: PropTypes.func.isRequired,
diff --git a/test/controllers/root-controller.test.js b/test/controllers/root-controller.test.js
index c2eb72e890..bebd26c59e 100644
--- a/test/controllers/root-controller.test.js
+++ b/test/controllers/root-controller.test.js
@@ -10,6 +10,7 @@ import {cloneRepository, buildRepository} from '../helpers';
import {multiFilePatchBuilder} from '../builder/patch';
import Repository from '../../lib/models/repository';
import WorkdirContextPool from '../../lib/models/workdir-context-pool';
+import WorkdirCache from '../../lib/models/workdir-cache';
import ResolutionProgress from '../../lib/models/conflicts/resolution-progress';
import RemoteSet from '../../lib/models/remote-set';
import Remote from '../../lib/models/remote';
@@ -33,7 +34,8 @@ import RootController from '../../lib/controllers/root-controller';
describe('RootController', function() {
let atomEnv, app;
let workspace, commands, notificationManager, tooltips, config, confirm, deserializers, grammars, project;
- let workdirContextPool;
+ let workdirContextPool, workdirCache;
+ let changeWorkingDirectory;
beforeEach(function() {
atomEnv = global.buildAtomEnvironment();
@@ -46,6 +48,7 @@ describe('RootController', function() {
config = atomEnv.config;
project = atomEnv.project;
+ workdirCache = new WorkdirCache();
workdirContextPool = new WorkdirContextPool();
const loginModel = new GithubLoginModel(InMemoryStrategy);
@@ -53,6 +56,7 @@ describe('RootController', function() {
const emptyResolutionProgress = new ResolutionProgress();
confirm = sinon.stub(atomEnv, 'confirm');
+ changeWorkingDirectory = sinon.spy();
app = (
);
});
@@ -355,6 +362,15 @@ describe('RootController', function() {
});
});
+ describe('selectActivePaneWorkDir()', function() {
+ it('does not update if there is no active pane', function() {
+ const wrapper = shallow(app);
+ wrapper.find('Command[command="github:select-active-pane-directory"]').prop('callback')();
+
+ assert.isTrue(changeWorkingDirectory.notCalled);
+ });
+ });
+
describe('openCloneDialog()', function() {
let clone;