mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-26 16:08:34 +02:00
Support for push refspecs with colon, aka master:master or :foo
This commit is contained in:
parent
748eddbd86
commit
f930bae005
8 changed files with 203 additions and 76 deletions
|
@ -11,6 +11,10 @@ var crappyUnescape = function(str) {
|
|||
return str.replace(/'/g, "'").replace(///g, "/");
|
||||
};
|
||||
|
||||
function isColonRefspec(str) {
|
||||
return str.indexOf(':') !== -1 && str.split(':').length === 2;
|
||||
}
|
||||
|
||||
var assertOriginSpecified = function(generalArgs) {
|
||||
if (generalArgs[0] !== 'origin') {
|
||||
throw new GitError({
|
||||
|
@ -283,7 +287,7 @@ var commandConfig = {
|
|||
command.validateArgBounds(names, 1, Number.MAX_VALUE, '-d');
|
||||
|
||||
_.each(names, function(name) {
|
||||
engine.deleteBranch(name);
|
||||
engine.validateAndDeleteBranch(name);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -557,15 +561,24 @@ var commandConfig = {
|
|||
assertOriginSpecified(generalArgs);
|
||||
|
||||
var tracking;
|
||||
if (generalArgs[1]) {
|
||||
tracking = assertBranchIsRemoteTracking(engine, generalArgs[1]);
|
||||
var source;
|
||||
var firstArg = generalArgs[1];
|
||||
if (firstArg) {
|
||||
if (isColonRefspec(firstArg)) {
|
||||
var refspecParts = firstArg.split(':');
|
||||
source = refspecParts[0];
|
||||
tracking = assertBranchIsRemoteTracking(engine, refspecParts[1]);
|
||||
} else {
|
||||
tracking = assertBranchIsRemoteTracking(engine, firstArg);
|
||||
}
|
||||
} else {
|
||||
var oneBefore = engine.getOneBeforeCommit('HEAD');
|
||||
tracking = assertBranchIsRemoteTracking(engine, oneBefore.get('id'));
|
||||
}
|
||||
|
||||
engine.push({
|
||||
destination: tracking
|
||||
destination: tracking,
|
||||
source: source
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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')];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue