more argument and test progress

This commit is contained in:
Peter Cottle 2013-10-17 11:33:41 -07:00
parent 246d86e7e6
commit b9ebaca62b
3 changed files with 73 additions and 24 deletions

View file

@ -213,12 +213,18 @@ describe('Git Remotes', function() {
}); });
it('will not fetch if ref does not exist on remote', function() { it('will not fetch if ref does not exist on remote', function() {
expectTreeAsync( expectTreeAsync(
'git clone; git fakeTeamwork; git fetch foo:master', 'git clone; git fakeTeamwork; git fetch foo:master',
'{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}'
); );
}); });
it('does not fetch if ref does not exist on remote with one arg', function() {
expectTreeAsync(
'git clone; git fakeTeamwork; git fetch foo',
'{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}'
);
});
}); });

View file

@ -253,14 +253,14 @@ var commandConfig = {
fetch: { fetch: {
regex: /^git +fetch($|\s)/, regex: /^git +fetch($|\s)/,
execute: function(engine, command) { execute: function(engine, command) {
var options = {};
if (!engine.hasOrigin()) { if (!engine.hasOrigin()) {
throw new GitError({ throw new GitError({
msg: intl.str('git-error-origin-required') msg: intl.str('git-error-origin-required')
}); });
} }
var source;
var destination;
var generalArgs = command.getGeneralArgs(); var generalArgs = command.getGeneralArgs();
command.twoArgsImpliedOrigin(generalArgs); command.twoArgsImpliedOrigin(generalArgs);
assertOriginSpecified(generalArgs); assertOriginSpecified(generalArgs);
@ -268,21 +268,28 @@ var commandConfig = {
var firstArg = generalArgs[1]; var firstArg = generalArgs[1];
if (firstArg && isColonRefspec(firstArg)) { if (firstArg && isColonRefspec(firstArg)) {
var refspecParts = firstArg.split(':'); var refspecParts = firstArg.split(':');
options.source = refspecParts[0]; source = refspecParts[0];
options.destination = refspecParts[1]; destination = validateBranchName(engine, refspecParts[1]);
// destination will be created by fetch, but check source // destination will be created by fetch, but check source
assertIsRef(engine.origin, options.source);
} else if (firstArg) { } else if (firstArg) {
// here is the deal -- its JUST like git push. the first arg // here is the deal -- its JUST like git push. the first arg
// is used as both the destination and the source, so we need // is used as both the destination and the source, so we need
// to make sure it exists as the source on REMOTE and then // to make sure it exists as the source on REMOTE and then
// the destination will be created locally // the destination will be created locally
var tracking = assertBranchIsRemoteTracking(engine, firstArg); source = firstArg;
options.branches = [engine.refs[tracking]]; destination = firstArg;
//var tracking = assertBranchIsRemoteTracking(engine, firstArg);
//options.branches = [engine.refs[tracking]];
}
if (source) { // empty string fails this check
assertIsRef(engine.origin, source);
} }
engine.fetch(options); engine.fetch({
source: source,
destination: destination
});
} }
}, },

View file

@ -357,13 +357,9 @@ GitEngine.prototype.makeOrigin = function(treeString) {
return; return;
} }
var originTarget = branchJSON.target; var originTarget = this.findCommonAncestorWithRemote(
// now this is tricky -- our remote could have commits that we do branchJSON.target
// not have. so lets go upwards until we find one that we have );
while (!this.refs[originTarget]) {
var parents = originTree.commits[originTarget].parents;
originTarget = parents[0];
}
// now we have something in common, lets make the tracking branch // now we have something in common, lets make the tracking branch
var remoteBranch = this.makeBranch( var remoteBranch = this.makeBranch(
@ -375,6 +371,27 @@ GitEngine.prototype.makeOrigin = function(treeString) {
}, this); }, this);
}; };
GitEngine.prototype.makeRemoteBranchForRemote = function(branchName) {
var target = this.origin.refs[branchName].get('target');
var originTarget = this.findCommonAncestorWithRemote(
target.get('id');
);
return this.makeBranch(
ORIGIN_PREFIX + branchName,
this.getCommitFromRef(originTarget)
);
};
GitEngine.prototype.findCommonAncestorWithRemote = function(originTarget) {
// now this is tricky -- our remote could have commits that we do
// not have. so lets go upwards until we find one that we have
while (!this.refs[originTarget]) {
var parents = this.origin.refs[originTarget].get('parents');
originTarget = parents[0].get('id');
}
return originTarget;
};
GitEngine.prototype.makeBranchOnOriginAndTrack = function(branchName, target) { GitEngine.prototype.makeBranchOnOriginAndTrack = function(branchName, target) {
var remoteBranch = this.makeBranch( var remoteBranch = this.makeBranch(
ORIGIN_PREFIX + branchName, ORIGIN_PREFIX + branchName,
@ -1018,11 +1035,30 @@ GitEngine.prototype.pushDeleteRemoteBranch = function(
GitEngine.prototype.fetch = function(options) { GitEngine.prototype.fetch = function(options) {
options = options || {}; options = options || {};
// get all remotes // ok this is just like git push -- if the destination does not exist,
var allRemotes = this.branchCollection.filter(function(branch) { // we need to make it
return branch.getIsRemote(); if (options.destination) {
}); // its just like creating a branch, we will merge (if pulling) later
var branchesToFetch = options.branches || allRemotes; this.validateAndMakeBranch(
options.destination,
this.getCommitFromRef('HEAD')
);
}
// now we need to know which remotes to fetch. lets do this by either checking our source
// option or just getting all of them
var branchesToFetch;
if (options.source) {
// gah -- first we have to check that we even have a remote branch
// for this source (we know its on the remote based on validation)
if (!this.refs[ORIGIN_PREFX + options.source]) {
this.makeRemoteBranchForRemote(options.source);
}
} else {
branchesToFetch = this.branchCollection.filter(function(branch) {
return branch.getIsRemote();
});
}
// first check if our local remote branch is upstream of the origin branch set. // first check if our local remote branch is upstream of the origin branch set.
// this check essentially pretends the local remote branch is in origin and // this check essentially pretends the local remote branch is in origin and