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

Commit 46afadd

Browse files
authored
Merge pull request #1708 from atom/vy/handle-branch-names-mismatch
Fix: handle branch names mismatch
2 parents 7950c43 + a1324c5 commit 46afadd

File tree

4 files changed

+86
-6
lines changed

4 files changed

+86
-6
lines changed

lib/controllers/status-bar-tile-controller.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,28 @@ export default class StatusBarTileController extends React.Component {
177177

178178
push(data) {
179179
return ({force, setUpstream} = {}) => {
180-
return this.props.repository.push(data.currentBranch.getName(), {force, setUpstream});
180+
return this.props.repository.push(data.currentBranch.getName(), {
181+
force,
182+
setUpstream,
183+
refSpec: data.currentBranch.getRefSpec('PUSH'),
184+
});
181185
};
182186
}
183187

184188
pull(data) {
185-
return () => this.props.repository.pull(data.currentBranch.getName());
189+
return () => {
190+
return this.props.repository.pull(data.currentBranch.getName(), {
191+
refSpec: data.currentBranch.getRefSpec('PULL'),
192+
});
193+
};
186194
}
187195

188196
fetch(data) {
189-
return () => this.props.repository.fetch(data.currentBranch.getName());
197+
return () => {
198+
const upstream = data.currentBranch.getUpstream();
199+
return this.props.repository.fetch(upstream.getRemoteRef(), {
200+
remoteName: upstream.getRemoteName(),
201+
});
202+
};
190203
}
191204
}

lib/git-shell-out-strategy.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -787,15 +787,15 @@ export default class GitShellOutStrategy {
787787
}
788788

789789
pull(remoteName, branchName, options = {}) {
790-
const args = ['pull', remoteName, branchName];
790+
const args = ['pull', remoteName, options.refSpec || branchName];
791791
if (options.ffOnly) {
792792
args.push('--ff-only');
793793
}
794794
return this.gpgExec(args, {useGitPromptServer: true, writeOperation: true});
795795
}
796796

797797
push(remoteName, branchName, options = {}) {
798-
const args = ['push', remoteName || 'origin', `refs/heads/${branchName}`];
798+
const args = ['push', remoteName || 'origin', options.refSpec || `refs/heads/${branchName}`];
799799
if (options.setUpstream) { args.push('--set-upstream'); }
800800
if (options.force) { args.push('--force'); }
801801
return this.exec(args, {useGitPromptServer: true, writeOperation: true});

lib/models/branch.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,23 @@ export default class Branch {
6767
return this.getRemoteRef().replace(/^(refs\/)?((heads|remotes)\/)?/, '');
6868
}
6969

70+
getRefSpec(action) {
71+
if (this.isRemoteTracking()) {
72+
return '';
73+
}
74+
const remoteBranch = action === 'PUSH' ? this.push : this.upstream;
75+
const remoteBranchName = remoteBranch.getShortRemoteRef();
76+
const localBranchName = this.getName();
77+
if (remoteBranchName && remoteBranchName !== localBranchName) {
78+
if (action === 'PUSH') {
79+
return `${localBranchName}:${remoteBranchName}`;
80+
} else if (action === 'PULL') {
81+
return `${remoteBranchName}:${localBranchName}`;
82+
}
83+
}
84+
return localBranchName;
85+
}
86+
7087
getSha() {
7188
return this.attributes.sha || '';
7289
}
@@ -94,6 +111,7 @@ export default class Branch {
94111
isPresent() {
95112
return true;
96113
}
114+
97115
}
98116

99117
export const nullBranch = {

test/controllers/status-bar-tile-controller.test.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,56 @@ describe('StatusBarTileController', function() {
652652
});
653653
});
654654

655+
describe('when the local branch is named differently from the remote branch it\'s tracking', function() {
656+
let repository, wrapper;
657+
658+
beforeEach(async function() {
659+
const {localRepoPath} = await setUpLocalAndRemoteRepositories();
660+
repository = await buildRepository(localRepoPath);
661+
wrapper = await mountAndLoad(buildApp({repository}));
662+
await repository.git.exec(['checkout', '-b', 'another-name', '--track', 'origin/master']);
663+
repository.refresh();
664+
});
665+
666+
it('fetches with no git error', async function() {
667+
sinon.spy(repository, 'fetch');
668+
await wrapper
669+
.instance()
670+
.fetch(await wrapper.instance().fetchData(repository))();
671+
assert.isTrue(repository.fetch.calledWith('refs/heads/master', {
672+
remoteName: 'origin',
673+
}));
674+
});
675+
676+
it('pulls from the correct branch', async function() {
677+
const prePullSHA = await repository.git.exec(['rev-parse', 'HEAD']);
678+
await repository.git.exec(['reset', '--hard', 'HEAD~2']);
679+
sinon.spy(repository, 'pull');
680+
await wrapper
681+
.instance()
682+
.pull(await wrapper.instance().fetchData(repository))();
683+
const postPullSHA = await repository.git.exec(['rev-parse', 'HEAD']);
684+
assert.isTrue(repository.pull.calledWith('another-name', {
685+
refSpec: 'master:another-name',
686+
}));
687+
assert.equal(prePullSHA, postPullSHA);
688+
});
689+
690+
it('pushes to the correct branch', async function() {
691+
await repository.git.commit('new local commit', {allowEmpty: true});
692+
const localSHA = await repository.git.exec(['rev-parse', 'another-name']);
693+
sinon.spy(repository, 'push');
694+
await wrapper
695+
.instance()
696+
.push(await wrapper.instance().fetchData(repository))();
697+
const remoteSHA = await repository.git.exec(['rev-parse', 'origin/master']);
698+
assert.isTrue(repository.push.calledWith('another-name',
699+
sinon.match({refSpec: 'another-name:master'}),
700+
));
701+
assert.equal(localSHA, remoteSHA);
702+
});
703+
});
704+
655705
describe('github tile', function() {
656706
it('toggles the github panel when clicked', async function() {
657707
const workdirPath = await cloneRepository('three-files');
@@ -666,7 +716,6 @@ describe('StatusBarTileController', function() {
666716
});
667717
});
668718

669-
670719
describe('changed files', function() {
671720

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

0 commit comments

Comments
 (0)