Support for push refspecs with colon, aka master:master or :foo

This commit is contained in:
Peter Cottle 2013-10-09 22:29:05 -07:00
parent 748eddbd86
commit f930bae005
8 changed files with 203 additions and 76 deletions

View file

@ -860,16 +860,22 @@ GitEngine.prototype.descendSortDepth = function(objects) {
GitEngine.prototype.push = function(options) {
options = options || {};
var localBranch = this.getOneBeforeCommit('HEAD');
var remoteBranch = this.refs[options.destination];
var branchOnRemote = this.origin.refs[remoteBranch.getBaseID()];
if (options.source === "") {
// delete case
this.pushDeleteRemoteBranch(remoteBranch, branchOnRemote);
return;
}
var sourceLocation = this.getOneBeforeCommit(options.source || 'HEAD');
// first check if this is even allowed by checking the sync between
this.checkUpstreamOfSource(
this,
this.origin,
branchOnRemote,
localBranch,
sourceLocation,
intl.str('git-error-origin-push-no-ff')
);
@ -877,7 +883,7 @@ GitEngine.prototype.push = function(options) {
this.origin,
this,
branchOnRemote,
localBranch
sourceLocation
);
// now here is the tricky part -- the difference between local master
@ -926,7 +932,7 @@ GitEngine.prototype.push = function(options) {
}, this);
chain = chain.then(_.bind(function() {
var localLocationID = localBranch.get('target').get('id');
var localLocationID = sourceLocation.get('target').get('id');
var remoteCommit = this.origin.refs[localLocationID];
this.origin.setTargetLocation(branchOnRemote, remoteCommit);
// unhighlight local
@ -936,7 +942,7 @@ GitEngine.prototype.push = function(options) {
// HAX HAX update master and remote tracking for master
chain = chain.then(_.bind(function() {
var localCommit = this.getCommitFromRef(localBranch);
var localCommit = this.getCommitFromRef(sourceLocation);
this.setTargetLocation(remoteBranch, localCommit);
return this.animationFactory.playRefreshAnimation(this.gitVisuals);
}, this));
@ -946,6 +952,32 @@ GitEngine.prototype.push = function(options) {
}
};
GitEngine.prototype.pushDeleteRemoteBranch = function(
remoteBranch,
branchOnRemote
) {
if (branchOnRemote.get('id') === 'master') {
throw new GitError({
msg: intl.todo('You cannot delete master branch on remote!')
});
}
// ok so this isn't too bad -- we basically just:
// 1) instruct the remote to delete the branch
// 2) kill off the remote branch locally
// 3) find any branches tracking this remote branch and set them to not track
var id = remoteBranch.get('id');
this.origin.deleteBranch(branchOnRemote);
this.deleteBranch(remoteBranch);
this.branchCollection.each(function(branch) {
if (branch.getRemoteTrackingBranchID() === id) {
branch.setRemoteTrackingBranchID(null);
}
}, this);
// animation needs to be triggered on origin directly
this.origin.externalRefresh();
};
GitEngine.prototype.fetch = function(options) {
options = options || {};
@ -2147,7 +2179,7 @@ GitEngine.prototype.isRemoteBranchRef = function(ref) {
return resolved.getIsRemote();
};
GitEngine.prototype.deleteBranch = function(name) {
GitEngine.prototype.validateAndDeleteBranch = function(name) {
// trying to delete, lets check our refs
var target = this.resolveID(name);
@ -2167,7 +2199,10 @@ GitEngine.prototype.deleteBranch = function(name) {
msg: intl.str('git-error-remote-branch')
});
}
this.deleteBranch(branch);
};
GitEngine.prototype.deleteBranch = function(branch) {
this.branchCollection.remove(branch);
this.refs[branch.get('id')] = undefined;
delete this.refs[branch.get('id')];