Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Fix: handle branch names mismatch #1708

Merged
merged 13 commits into from
Oct 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions lib/controllers/status-bar-tile-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,28 @@ export default class StatusBarTileController extends React.Component {

push(data) {
return ({force, setUpstream} = {}) => {
return this.props.repository.push(data.currentBranch.getName(), {force, setUpstream});
return this.props.repository.push(data.currentBranch.getName(), {
force,
setUpstream,
refSpec: data.currentBranch.getRefSpec('PUSH'),
});
};
}

pull(data) {
return () => this.props.repository.pull(data.currentBranch.getName());
return () => {
return this.props.repository.pull(data.currentBranch.getName(), {
refSpec: data.currentBranch.getRefSpec('PULL'),
});
};
}

fetch(data) {
return () => this.props.repository.fetch(data.currentBranch.getName());
return () => {
const upstream = data.currentBranch.getUpstream();
return this.props.repository.fetch(upstream.getRemoteRef(), {
remoteName: upstream.getRemoteName(),
});
};
}
}
4 changes: 2 additions & 2 deletions lib/git-shell-out-strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -787,15 +787,15 @@ export default class GitShellOutStrategy {
}

pull(remoteName, branchName, options = {}) {
const args = ['pull', remoteName, branchName];
const args = ['pull', remoteName, options.refSpec || branchName];
if (options.ffOnly) {
args.push('--ff-only');
}
return this.gpgExec(args, {useGitPromptServer: true, writeOperation: true});
}

push(remoteName, branchName, options = {}) {
const args = ['push', remoteName || 'origin', `refs/heads/${branchName}`];
const args = ['push', remoteName || 'origin', options.refSpec || `refs/heads/${branchName}`];
if (options.setUpstream) { args.push('--set-upstream'); }
if (options.force) { args.push('--force'); }
return this.exec(args, {useGitPromptServer: true, writeOperation: true});
Expand Down
18 changes: 18 additions & 0 deletions lib/models/branch.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,23 @@ export default class Branch {
return this.getRemoteRef().replace(/^(refs\/)?((heads|remotes)\/)?/, '');
}

getRefSpec(action) {
if (this.isRemoteTracking()) {
return '';
}
const remoteBranch = action === 'PUSH' ? this.push : this.upstream;
const remoteBranchName = remoteBranch.getShortRemoteRef();
const localBranchName = this.getName();
if (remoteBranchName && remoteBranchName !== localBranchName) {
if (action === 'PUSH') {
return `${localBranchName}:${remoteBranchName}`;
} else if (action === 'PULL') {
return `${remoteBranchName}:${localBranchName}`;
}
}
return localBranchName;
}

getSha() {
return this.attributes.sha || '';
}
Expand Down Expand Up @@ -94,6 +111,7 @@ export default class Branch {
isPresent() {
return true;
}

}

export const nullBranch = {
Expand Down
51 changes: 50 additions & 1 deletion test/controllers/status-bar-tile-controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,56 @@ describe('StatusBarTileController', function() {
});
});

describe('when the local branch is named differently from the remote branch it\'s tracking', function() {
let repository, wrapper;

beforeEach(async function() {
const {localRepoPath} = await setUpLocalAndRemoteRepositories();
repository = await buildRepository(localRepoPath);
wrapper = await mountAndLoad(buildApp({repository}));
await repository.git.exec(['checkout', '-b', 'another-name', '--track', 'origin/master']);
repository.refresh();
});

it('fetches with no git error', async function() {
sinon.spy(repository, 'fetch');
await wrapper
.instance()
.fetch(await wrapper.instance().fetchData(repository))();
assert.isTrue(repository.fetch.calledWith('refs/heads/master', {
remoteName: 'origin',
}));
});

it('pulls from the correct branch', async function() {
const prePullSHA = await repository.git.exec(['rev-parse', 'HEAD']);
await repository.git.exec(['reset', '--hard', 'HEAD~2']);
sinon.spy(repository, 'pull');
await wrapper
.instance()
.pull(await wrapper.instance().fetchData(repository))();
const postPullSHA = await repository.git.exec(['rev-parse', 'HEAD']);
assert.isTrue(repository.pull.calledWith('another-name', {
refSpec: 'master:another-name',
}));
assert.equal(prePullSHA, postPullSHA);
});

it('pushes to the correct branch', async function() {
await repository.git.commit('new local commit', {allowEmpty: true});
const localSHA = await repository.git.exec(['rev-parse', 'another-name']);
sinon.spy(repository, 'push');
await wrapper
.instance()
.push(await wrapper.instance().fetchData(repository))();
const remoteSHA = await repository.git.exec(['rev-parse', 'origin/master']);
assert.isTrue(repository.push.calledWith('another-name',
sinon.match({refSpec: 'another-name:master'}),
));
assert.equal(localSHA, remoteSHA);
});
});

describe('github tile', function() {
it('toggles the github panel when clicked', async function() {
const workdirPath = await cloneRepository('three-files');
Expand All @@ -666,7 +716,6 @@ describe('StatusBarTileController', function() {
});
});


describe('changed files', function() {

it('toggles the git panel when clicked', async function() {
Expand Down