WUT could it be that easy? awesome

This commit is contained in:
Peter Cottle 2013-06-10 20:01:49 -07:00
parent 30fe255c88
commit d18633c608
5 changed files with 266 additions and 1203 deletions

View file

@ -116,4 +116,5 @@ Or reported an issue that was successfully closed!
* "Goodwine" * "Goodwine"
* Brandon McCaig * Brandon McCaig
* Borislav Kosharov * Borislav Kosharov
* Ben Heavner

View file

@ -5401,6 +5401,10 @@ require.define("/src/js/intl/strings.js",function(require,module,exports,__dirna
'en_US': 'Quick commit. Go Bears!', 'en_US': 'Quick commit. Go Bears!',
'zh_CN': '快速提交。上啊月熊!' 'zh_CN': '快速提交。上啊月熊!'
}, },
'git-error-origin-fetch-no-ff': {
'__desc__': 'One of the error messages for git',
'en_US': 'Your origin branch is out of sync with the remote branch and fetch cannot be performed. try using --force'
},
'git-error-remote-branch': { 'git-error-remote-branch': {
'__desc__': 'One of the error messages for git', '__desc__': 'One of the error messages for git',
'en_US': 'You cannot execute that command on a remote branch' 'en_US': 'You cannot execute that command on a remote branch'
@ -7789,59 +7793,111 @@ GitEngine.prototype.checkUpstreamOfSource = function(
var targetLocationID = target.getCommitFromRef(targetBranch).get('id'); var targetLocationID = target.getCommitFromRef(targetBranch).get('id');
if (!upstream[targetLocationID]) { if (!upstream[targetLocationID]) {
throw new GitError({ throw new GitError({
msg: 'no no' msg: intl.str('git-error-origin-fetch-no-ff')
}); });
} }
}; };
GitEngine.prototype.getTargetGraphDifference = function(
target,
source,
targetBranch,
sourceBranch
) {
sourceBranch = source.resolveID(sourceBranch);
var targetSet = target.getUpstreamSet(targetBranch);
var sourceStartCommit = source.getCommitFromRef(sourceBranch);
var sourceTree = source.exportTree();
var sourceStartCommitJSON = sourceTree.commits[sourceStartCommit.get('id')];
// ok great, we have our starting point and our stopping set. lets go ahead
// and traverse upwards and keep track of depth manually
sourceStartCommitJSON.depth = 0;
var difference = [];
var toExplore = [sourceStartCommitJSON];
while (toExplore.length) {
var here = toExplore.pop();
difference.push(here);
_.each(here.parents, function(parentID) {
if (targetSet[parentID]) {
// we already have this commit, lets bounce
return;
}
var parentJSON = sourceTree.commits[parentID];
parentJSON.depth = here.depth + 1;
toExplore.push(parentJSON);
}, this);
}
return difference.sort(function(cA, cB) {
// reverse sort by depth
return cB.depth - cA.depth;
});
};
GitEngine.prototype.fetch = function() { GitEngine.prototype.fetch = function() {
var localBranch = this.refs['o/master'];
var remoteBranch = this.origin.refs['master'];
// first check if this is even allowed by checking the sync between // first check if this is even allowed by checking the sync between
this.checkUpstreamOfSource( this.checkUpstreamOfSource(
this, this,
this.origin, this.origin,
this.refs['o/master'], localBranch,
this.origin.refs['master'] remoteBranch
); );
var oldCommits = this.exportTree().commits; // then we get the difference in commits between these two graphs, ordered by
// HAX HAX omg we will abuse our tree instantiation here :D // depth
var originTree = this.origin.exportTree(); var commitsToMake = this.getTargetGraphDifference(
_.each(originTree.commits, function(commit, id) { this,
// if we have it, no worries this.origin,
if (this.refs[id]) { localBranch,
return; remoteBranch
} );
// go make it!
var downloadedCommit = this.getOrMakeRecursive(originTree, this.refs, id); var makeCommit = _.bind(function(id, parentIDs) {
this.commitCollection.add(downloadedCommit); // need to get the parents first. since we order by depth, we know
// the dependencies are there already
var parents = _.map(parentIDs, function(parentID) {
return this.refs[parentID];
}, this);
return this.makeCommit(parents, id);
}, this); }, this);
// since we now might have many commits more than before, lets // now make the promise chain to make each commit
// check all the ones that didn't use to exist and make animations var chainStep = _.bind(function(id, parents) {
var newCommits = this.exportTree().commits; var newCommit = makeCommit(id, parents);
var commitsToAnimate = []; return AnimationFactory.playCommitBirthPromiseAnimation(
_.each(newCommits, function(commit, id) {
if (oldCommits[id]) {
return;
}
commitsToAnimate.push(this.refs[id]);
}, this);
// now sort by id...
commitsToAnimate.sort(_.bind(this.idSortFunc, this));
_.each(commitsToAnimate, function(newCommit) {
AnimationFactory.genCommitBirthAnimation(
this.animationQueue,
newCommit, newCommit,
this.gitVisuals this.gitVisuals
); );
}, this); }, this);
var originLocation = this.origin.exportTree().branches.master.target; var deferred = Q.defer();
// yay! now we just set o/master and do a simple refresh var chain = deferred.promise;
this.setTargetLocation(this.refs['o/master'], this.refs[originLocation]);
AnimationFactory.refreshTree(this.animationQueue, this.gitVisuals); _.each(commitsToMake, function(commitJSON) {
chain = chain.then(function() {
return chainStep(
commitJSON.id,
commitJSON.parents
);
});
});
chain = chain.then(_.bind(function() {
var originLocationID = remoteBranch.get('target').get('id');
var localCommit = this.refs[originLocationID];
this.setTargetLocation(localBranch, localCommit);
return AnimationFactory.playRefreshAnimation(this.gitVisuals);
}, this));
this.animationQueue.thenFinish(chain, deferred);
}; };
GitEngine.prototype.pullStarter = function() { GitEngine.prototype.pullStarter = function() {
@ -8626,7 +8682,7 @@ GitEngine.prototype.checkout = function(idOrTarget) {
var type = target.get('type'); var type = target.get('type');
// check if this is an origin branch, and if so go to the commit referenced // check if this is an origin branch, and if so go to the commit referenced
if (type === 'branch' && target.getIsRemote()) { if (type === 'branch' && target.getIsRemote()) {
//target = this.getCommitFromRef(target.get('id')); target = this.getCommitFromRef(target.get('id'));
} }
if (type !== 'branch' && type !== 'commit') { if (type !== 'branch' && type !== 'commit') {
@ -23644,59 +23700,111 @@ GitEngine.prototype.checkUpstreamOfSource = function(
var targetLocationID = target.getCommitFromRef(targetBranch).get('id'); var targetLocationID = target.getCommitFromRef(targetBranch).get('id');
if (!upstream[targetLocationID]) { if (!upstream[targetLocationID]) {
throw new GitError({ throw new GitError({
msg: 'no no' msg: intl.str('git-error-origin-fetch-no-ff')
}); });
} }
}; };
GitEngine.prototype.getTargetGraphDifference = function(
target,
source,
targetBranch,
sourceBranch
) {
sourceBranch = source.resolveID(sourceBranch);
var targetSet = target.getUpstreamSet(targetBranch);
var sourceStartCommit = source.getCommitFromRef(sourceBranch);
var sourceTree = source.exportTree();
var sourceStartCommitJSON = sourceTree.commits[sourceStartCommit.get('id')];
// ok great, we have our starting point and our stopping set. lets go ahead
// and traverse upwards and keep track of depth manually
sourceStartCommitJSON.depth = 0;
var difference = [];
var toExplore = [sourceStartCommitJSON];
while (toExplore.length) {
var here = toExplore.pop();
difference.push(here);
_.each(here.parents, function(parentID) {
if (targetSet[parentID]) {
// we already have this commit, lets bounce
return;
}
var parentJSON = sourceTree.commits[parentID];
parentJSON.depth = here.depth + 1;
toExplore.push(parentJSON);
}, this);
}
return difference.sort(function(cA, cB) {
// reverse sort by depth
return cB.depth - cA.depth;
});
};
GitEngine.prototype.fetch = function() { GitEngine.prototype.fetch = function() {
var localBranch = this.refs['o/master'];
var remoteBranch = this.origin.refs['master'];
// first check if this is even allowed by checking the sync between // first check if this is even allowed by checking the sync between
this.checkUpstreamOfSource( this.checkUpstreamOfSource(
this, this,
this.origin, this.origin,
this.refs['o/master'], localBranch,
this.origin.refs['master'] remoteBranch
); );
var oldCommits = this.exportTree().commits; // then we get the difference in commits between these two graphs, ordered by
// HAX HAX omg we will abuse our tree instantiation here :D // depth
var originTree = this.origin.exportTree(); var commitsToMake = this.getTargetGraphDifference(
_.each(originTree.commits, function(commit, id) { this,
// if we have it, no worries this.origin,
if (this.refs[id]) { localBranch,
return; remoteBranch
} );
// go make it!
var downloadedCommit = this.getOrMakeRecursive(originTree, this.refs, id); var makeCommit = _.bind(function(id, parentIDs) {
this.commitCollection.add(downloadedCommit); // need to get the parents first. since we order by depth, we know
// the dependencies are there already
var parents = _.map(parentIDs, function(parentID) {
return this.refs[parentID];
}, this);
return this.makeCommit(parents, id);
}, this); }, this);
// since we now might have many commits more than before, lets // now make the promise chain to make each commit
// check all the ones that didn't use to exist and make animations var chainStep = _.bind(function(id, parents) {
var newCommits = this.exportTree().commits; var newCommit = makeCommit(id, parents);
var commitsToAnimate = []; return AnimationFactory.playCommitBirthPromiseAnimation(
_.each(newCommits, function(commit, id) {
if (oldCommits[id]) {
return;
}
commitsToAnimate.push(this.refs[id]);
}, this);
// now sort by id...
commitsToAnimate.sort(_.bind(this.idSortFunc, this));
_.each(commitsToAnimate, function(newCommit) {
AnimationFactory.genCommitBirthAnimation(
this.animationQueue,
newCommit, newCommit,
this.gitVisuals this.gitVisuals
); );
}, this); }, this);
var originLocation = this.origin.exportTree().branches.master.target; var deferred = Q.defer();
// yay! now we just set o/master and do a simple refresh var chain = deferred.promise;
this.setTargetLocation(this.refs['o/master'], this.refs[originLocation]);
AnimationFactory.refreshTree(this.animationQueue, this.gitVisuals); _.each(commitsToMake, function(commitJSON) {
chain = chain.then(function() {
return chainStep(
commitJSON.id,
commitJSON.parents
);
});
});
chain = chain.then(_.bind(function() {
var originLocationID = remoteBranch.get('target').get('id');
var localCommit = this.refs[originLocationID];
this.setTargetLocation(localBranch, localCommit);
return AnimationFactory.playRefreshAnimation(this.gitVisuals);
}, this));
this.animationQueue.thenFinish(chain, deferred);
}; };
GitEngine.prototype.pullStarter = function() { GitEngine.prototype.pullStarter = function() {
@ -24481,7 +24589,7 @@ GitEngine.prototype.checkout = function(idOrTarget) {
var type = target.get('type'); var type = target.get('type');
// check if this is an origin branch, and if so go to the commit referenced // check if this is an origin branch, and if so go to the commit referenced
if (type === 'branch' && target.getIsRemote()) { if (type === 'branch' && target.getIsRemote()) {
//target = this.getCommitFromRef(target.get('id')); target = this.getCommitFromRef(target.get('id'));
} }
if (type !== 'branch' && type !== 'commit') { if (type !== 'branch' && type !== 'commit') {
@ -25528,6 +25636,10 @@ require.define("/src/js/intl/strings.js",function(require,module,exports,__dirna
'en_US': 'Quick commit. Go Bears!', 'en_US': 'Quick commit. Go Bears!',
'zh_CN': '快速提交。上啊月熊!' 'zh_CN': '快速提交。上啊月熊!'
}, },
'git-error-origin-fetch-no-ff': {
'__desc__': 'One of the error messages for git',
'en_US': 'Your origin branch is out of sync with the remote branch and fetch cannot be performed. try using --force'
},
'git-error-remote-branch': { 'git-error-remote-branch': {
'__desc__': 'One of the error messages for git', '__desc__': 'One of the error messages for git',
'en_US': 'You cannot execute that command on a remote branch' 'en_US': 'You cannot execute that command on a remote branch'

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@
<meta property="og:image" content="http://pcottle.github.io/learnGitBranching/assets/learnGitBranching.png"/> <meta property="og:image" content="http://pcottle.github.io/learnGitBranching/assets/learnGitBranching.png"/>
<meta property="og:description" content="A interactive Git visualization tool to educate and challenge!"/> <meta property="og:description" content="A interactive Git visualization tool to educate and challenge!"/>
<link rel="stylesheet" href="build/main.053c68bc.css" type="text/css" charset="utf-8"> <link rel="stylesheet" href="build/main.80cc7f4d.css" type="text/css" charset="utf-8">
<link rel="stylesheet" href="src/style/font-awesome.css" type="text/css" charset="utf-8"> <link rel="stylesheet" href="src/style/font-awesome.css" type="text/css" charset="utf-8">
</head> </head>
<body> <body>

View file

@ -762,34 +762,104 @@ GitEngine.prototype.checkUpstreamOfSource = function(
GitEngine.prototype.getTargetGraphDifference = function( GitEngine.prototype.getTargetGraphDifference = function(
target, target,
targetBranch,
source, source,
targetBranch,
sourceBranch sourceBranch
) = { ) {
sourceBranch = source.resolveID(sourceBranch); sourceBranch = source.resolveID(sourceBranch);
var targetSet = target.getUpstreamSet(targetBranch); var targetSet = target.getUpstreamSet(targetBranch);
var sourceStartCommit = source.getCommitFromRef(sourceBranch);
var sourceTree = source.exportTree(); var sourceTree = source.exportTree();
var startCommit = sourceTree.commits[ var sourceStartCommitJSON = sourceTree.commits[sourceStartCommit.get('id')];
// ok great, we have our starting point and our stopping set. lets go ahead
// and traverse upwards and keep track of depth manually
sourceStartCommitJSON.depth = 0;
var difference = [];
var toExplore = [sourceStartCommitJSON];
while (toExplore.length) {
var here = toExplore.pop();
difference.push(here);
_.each(here.parents, function(parentID) {
if (targetSet[parentID]) {
// we already have this commit, lets bounce
return;
}
var parentJSON = sourceTree.commits[parentID];
parentJSON.depth = here.depth + 1;
toExplore.push(parentJSON);
}, this);
}
return difference.sort(function(cA, cB) {
// reverse sort by depth
return cB.depth - cA.depth;
});
}; };
GitEngine.prototype.fetch = function() { GitEngine.prototype.fetch = function() {
var localBranch = this.refs['o/master'];
var remoteBranch = this.origin.refs['master'];
// first check if this is even allowed by checking the sync between // first check if this is even allowed by checking the sync between
this.checkUpstreamOfSource( this.checkUpstreamOfSource(
this, this,
this.origin, this.origin,
this.refs['o/master'], localBranch,
this.origin.refs['master'] remoteBranch
); );
// then we get the difference in commits between these two graphs, ordered by // then we get the difference in commits between these two graphs, ordered by
// depth // depth
var commitsToMake = this.getTargetGraphDifference(
this,
this.origin,
localBranch,
remoteBranch
);
// this.commitCollection.add(downloadedCommit); var makeCommit = _.bind(function(id, parentIDs) {
var originLocation = this.origin.exportTree().branches.master.target; // need to get the parents first. since we order by depth, we know
// yay! now we just set o/master and do a simple refresh // the dependencies are there already
this.setTargetLocation(this.refs['o/master'], this.refs[originLocation]); var parents = _.map(parentIDs, function(parentID) {
AnimationFactory.refreshTree(this.animationQueue, this.gitVisuals); return this.refs[parentID];
}, this);
return this.makeCommit(parents, id);
}, this);
// now make the promise chain to make each commit
var chainStep = _.bind(function(id, parents) {
var newCommit = makeCommit(id, parents);
return AnimationFactory.playCommitBirthPromiseAnimation(
newCommit,
this.gitVisuals
);
}, this);
var deferred = Q.defer();
var chain = deferred.promise;
_.each(commitsToMake, function(commitJSON) {
chain = chain.then(function() {
return chainStep(
commitJSON.id,
commitJSON.parents
);
});
});
chain = chain.then(_.bind(function() {
var originLocationID = remoteBranch.get('target').get('id');
var localCommit = this.refs[originLocationID];
this.setTargetLocation(localBranch, localCommit);
return AnimationFactory.playRefreshAnimation(this.gitVisuals);
}, this));
this.animationQueue.thenFinish(chain, deferred);
}; };
GitEngine.prototype.pullStarter = function() { GitEngine.prototype.pullStarter = function() {