mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-28 00:40:07 +02:00
git log now done, fixed up result rendering
This commit is contained in:
parent
543f5986ae
commit
9c7ec69e2f
10 changed files with 189 additions and 35 deletions
13
src/animationFactory.js
Normal file
13
src/animationFactory.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/******************
|
||||
* This class is responsible for a lot of the heavy lifting around creating an animation at a certain state in time.
|
||||
* The tricky thing is that when a new commit has to be "born," say in the middle of a rebase or something, it must animate
|
||||
* out from the parent position to it's birth position.
|
||||
|
||||
* These two positions though may not be where the commit finally ends up. So we actually need to take a snapshot of the tree,
|
||||
* store all those positions, take a snapshot of the tree after a layout refresh afterwards, and then animate between those two spots.
|
||||
* and then essentially animate the entire tree too.
|
||||
|
||||
* not sure if this is necessary yet, so ill hold off for now. lets do some refs
|
||||
|
||||
*/
|
||||
|
|
@ -71,3 +71,4 @@ var AnimationQueue = Backbone.Model.extend({
|
|||
}, this), duration);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -1,24 +1,52 @@
|
|||
var Command = Backbone.Model.extend({
|
||||
defaults: {
|
||||
status: 'inqueue',
|
||||
rawStr: null,
|
||||
result: '',
|
||||
|
||||
error: null,
|
||||
generalArgs: [],
|
||||
supportedMap: {},
|
||||
warnings: null,
|
||||
|
||||
generalArgs: null,
|
||||
supportedMap: null,
|
||||
options: null,
|
||||
method: null,
|
||||
createTime: null,
|
||||
rawStr: null
|
||||
|
||||
createTime: null
|
||||
},
|
||||
|
||||
validateAtInit: function() {
|
||||
// weird things happen with defaults if you dont
|
||||
// make new objects
|
||||
this.set('generalArgs', []);
|
||||
this.set('supportedMap', {});
|
||||
this.set('warnings', []);
|
||||
|
||||
if (this.get('rawStr') === null) {
|
||||
throw new Error('Give me a string!');
|
||||
}
|
||||
if (!this.get('createTime')) {
|
||||
this.set('createTime', new Date().toString());
|
||||
}
|
||||
|
||||
|
||||
this.on('change:error', this.errorChanged, this);
|
||||
// catch errors on init
|
||||
if (this.get('error')) {
|
||||
this.errorChanged();
|
||||
}
|
||||
},
|
||||
|
||||
addWarning: function(msg) {
|
||||
this.set('warnings', this.get('warnings').push(msg));
|
||||
},
|
||||
|
||||
getFormattedWarnings: function() {
|
||||
if (!this.get('warnings').length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<p>' + this.get('warnings').join('</p><p>') + '</p>';
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
|
@ -32,8 +60,9 @@ var Command = Backbone.Model.extend({
|
|||
} catch (err) {
|
||||
if (err instanceof CommandProcessError ||
|
||||
err instanceof GitError ||
|
||||
err instanceof CommandResult) {
|
||||
// erroChanged() will handle status and all of that
|
||||
err instanceof CommandResult ||
|
||||
err instanceof Warning) {
|
||||
// errorChanged() will handle status and all of that
|
||||
this.set('error', err);
|
||||
} else {
|
||||
throw err;
|
||||
|
@ -41,12 +70,15 @@ var Command = Backbone.Model.extend({
|
|||
}
|
||||
},
|
||||
|
||||
errorChanged: function(model, err) {
|
||||
errorChanged: function() {
|
||||
var err = this.get('error');
|
||||
if (err instanceof CommandProcessError ||
|
||||
err instanceof GitError) {
|
||||
this.set('status', 'error');
|
||||
} else if (err instanceof CommandResult) {
|
||||
this.set('status', 'finished');
|
||||
} else if (err instanceof Warning) {
|
||||
this.set('status', 'warning');
|
||||
}
|
||||
this.formatError();
|
||||
},
|
||||
|
@ -76,6 +108,7 @@ var Command = Backbone.Model.extend({
|
|||
reset: /^reset($|\s)/,
|
||||
branch: /^branch($|\s)/,
|
||||
revert: /^revert($|\s)/,
|
||||
log: /^log($|\s)/,
|
||||
merge: /^merge($|\s)/
|
||||
};
|
||||
},
|
||||
|
@ -204,6 +237,7 @@ OptionParser.prototype.getMasterOptionMap = function() {
|
|||
'-a': false, // warning
|
||||
'-am': false
|
||||
},
|
||||
log: {},
|
||||
add: {},
|
||||
branch: {
|
||||
'-d': false,
|
||||
|
|
|
@ -139,11 +139,11 @@ var CommandView = Backbone.View.extend({
|
|||
var json = _.extend(
|
||||
{
|
||||
resultType: '',
|
||||
result: ''
|
||||
result: '',
|
||||
warnings: ''
|
||||
},
|
||||
this.model.toJSON()
|
||||
);
|
||||
console.log('rendering', this.model.toJSON());
|
||||
|
||||
this.$el.html(this.template(json));
|
||||
return this;
|
||||
|
@ -164,6 +164,22 @@ var CommandLineHistoryView = Backbone.View.extend({
|
|||
this.collection.on('all', this.render, this);
|
||||
|
||||
this.collection.on('change', this.scrollDown, this);
|
||||
|
||||
events.on('issueWarning', this.addWarning, this);
|
||||
},
|
||||
|
||||
addWarning: function(msg) {
|
||||
console.log('here', arguments);
|
||||
var err = new Warning({
|
||||
msg: msg
|
||||
});
|
||||
|
||||
var command = new Command({
|
||||
error: err,
|
||||
rawStr: 'Warning:'
|
||||
});
|
||||
|
||||
this.collection.add(command);
|
||||
},
|
||||
|
||||
scrollDown: function() {
|
||||
|
|
|
@ -12,7 +12,7 @@ var MyError = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
toResult: function() {
|
||||
return this.get('msg').replace('\n', '</br>');
|
||||
return '<p>' + this.get('msg').replace(/\n/g, '</p><p>') + '</p>';
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -28,6 +28,12 @@ var CommandResult = MyError.extend({
|
|||
}
|
||||
});
|
||||
|
||||
var Warning = MyError.extend({
|
||||
defaults: {
|
||||
type: 'Warning'
|
||||
}
|
||||
});
|
||||
|
||||
var GitError = MyError.extend({
|
||||
defaults: {
|
||||
type: 'Git Error'
|
||||
|
|
81
src/git.js
81
src/git.js
|
@ -40,12 +40,6 @@ GitEngine.prototype.init = function() {
|
|||
|
||||
// commit once to get things going
|
||||
this.commit();
|
||||
|
||||
// update tree
|
||||
// TODO make async, not async
|
||||
setTimeout(function() {
|
||||
events.trigger('treeRefresh');
|
||||
}, 100);
|
||||
};
|
||||
|
||||
GitEngine.prototype.getDetachedHead = function() {
|
||||
|
@ -193,7 +187,7 @@ GitEngine.prototype.resetStarter = function() {
|
|||
});
|
||||
}
|
||||
if (this.commandOptions['--hard']) {
|
||||
events.trigger('commandProcessWarn',
|
||||
this.command.addWarning(
|
||||
'Nice! You are using --hard. The default behavior is a hard reset in ' +
|
||||
"this demo, so don't worry about specifying the option explicity"
|
||||
);
|
||||
|
@ -220,10 +214,10 @@ GitEngine.prototype.reset = function(target) {
|
|||
GitEngine.prototype.commitStarter = function() {
|
||||
this.acceptNoGeneralArgs();
|
||||
if (this.commandOptions['-a']) {
|
||||
events.trigger('commandProcessWarn', 'No need to add files in this demo');
|
||||
this.command.addWarning('No need to add files in this demo');
|
||||
}
|
||||
if (this.commandOptions['-am']) {
|
||||
events.trigger('commandProcessWarn', "Don't worry about adding files or commit messages in this demo");
|
||||
this.command.addWarning("Don't worry about adding files or commit messages in this demo");
|
||||
}
|
||||
this.commit();
|
||||
};
|
||||
|
@ -237,7 +231,7 @@ GitEngine.prototype.commit = function() {
|
|||
|
||||
var newCommit = this.makeCommit([targetCommit]);
|
||||
if (this.getDetachedHead()) {
|
||||
events.trigger('commandProcessWarn', 'Warning!! Detached HEAD state');
|
||||
this.command.addWarning('Warning!! Detached HEAD state');
|
||||
this.HEAD.set('target', newCommit);
|
||||
} else {
|
||||
var targetBranch = this.HEAD.get('target');
|
||||
|
@ -611,7 +605,7 @@ GitEngine.prototype.branchStarter = function() {
|
|||
// handle deletion first
|
||||
if (this.commandOptions['-d'] || this.commandOptions['-D']) {
|
||||
var names = this.commandOptions['-d'];
|
||||
names.concat(this.commandOptions['-D']);
|
||||
names = names.concat(this.commandOptions['-D']);
|
||||
if (!names.length) {
|
||||
throw new GitError({
|
||||
msg: 'I expect branch names when deleting'
|
||||
|
@ -726,9 +720,52 @@ GitEngine.prototype.dispatch = function(command, callback) {
|
|||
this.animationQueue.add(new Animation({closure: function() { console.log(Math.random()); }}));
|
||||
}
|
||||
|
||||
// animation queue will call the callback when its done
|
||||
this.animationQueue.start();
|
||||
};
|
||||
|
||||
GitEngine.prototype.logStarter = function() {
|
||||
if (this.generalArgs.length > 1) {
|
||||
throw new GitError({
|
||||
msg: "git log with more than 1 argument doesn't make sense"
|
||||
});
|
||||
}
|
||||
if (this.generalArgs.length == 0) {
|
||||
this.generalArgs.push('HEAD');
|
||||
}
|
||||
this.log(this.generalArgs[0]);
|
||||
};
|
||||
|
||||
GitEngine.prototype.log = function(ref) {
|
||||
// first get the commit we referenced
|
||||
var commit = this.getCommitFromRef(ref);
|
||||
|
||||
// then get as many far back as we can from here, order by commit date
|
||||
var toDump = [];
|
||||
var pQueue = [commit];
|
||||
|
||||
while (pQueue.length) {
|
||||
var popped = pQueue.shift(0);
|
||||
toDump.push(popped);
|
||||
|
||||
if (popped.get('parents') && popped.get('parents').length) {
|
||||
pQueue = pQueue.concat(popped.get('parents'));
|
||||
}
|
||||
pQueue.sort(this.idSortFunc);
|
||||
}
|
||||
|
||||
toDump.reverse();
|
||||
// now go through and collect logs
|
||||
var bigLogStr = '';
|
||||
_.each(toDump, function(c) {
|
||||
bigLogStr += c.getLogEntry();
|
||||
}, this);
|
||||
|
||||
throw new CommandResult({
|
||||
msg: bigLogStr
|
||||
});
|
||||
};
|
||||
|
||||
GitEngine.prototype.addStarter = function() {
|
||||
throw new CommandResult({
|
||||
msg: "This demo is meant to demonstrate git branching, so don't worry about " +
|
||||
|
@ -750,7 +787,7 @@ GitEngine.prototype.getCommonAncestor = function(ancestor, cousin) {
|
|||
if (upstreamSet[here.get('id')]) {
|
||||
return here;
|
||||
}
|
||||
queue.concat(here.get('parents'));
|
||||
queue = queue.concat(here.get('parents'));
|
||||
}
|
||||
throw new Error('something has gone very wrong... two nodes arent connected!');
|
||||
};
|
||||
|
@ -814,12 +851,32 @@ var Commit = Backbone.Model.extend({
|
|||
type: 'commit',
|
||||
children: null,
|
||||
parents: null,
|
||||
author: 'Peter Cottle',
|
||||
createTime: null,
|
||||
commitMessage: null
|
||||
},
|
||||
|
||||
getLogEntry: function() {
|
||||
// for now we are just joining all these things with newlines...
|
||||
return [
|
||||
'Author: ' + this.get('author'),
|
||||
'Date: ' + this.get('createTime'),
|
||||
this.get('commitMessage'),
|
||||
'Commit: ' + this.get('id')
|
||||
].join('\n' ) + '\n';
|
||||
},
|
||||
|
||||
validateAtInit: function() {
|
||||
if (!this.get('id')) {
|
||||
this.set('id', uniqueId('C'));
|
||||
}
|
||||
if (!this.get('createTime')) {
|
||||
this.set('createTime', new Date().toString());
|
||||
}
|
||||
if (!this.get('commitMessage')) {
|
||||
this.set('commitMessage', 'Quick Commit. Go Bears!');
|
||||
}
|
||||
|
||||
this.set('children', []);
|
||||
|
||||
// root commits have no parents
|
||||
|
|
|
@ -74,7 +74,15 @@
|
|||
</p>
|
||||
|
||||
<p class="commandLineResult <%= resultType %>">
|
||||
<div class="commandLineResultWrapper">
|
||||
<%= result %>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<p class="commandLineWarnings">
|
||||
<div class="commandLineWarningsWrapper">
|
||||
<%= warnings %>
|
||||
</div>
|
||||
</p>
|
||||
</script>
|
||||
|
||||
|
@ -92,11 +100,11 @@
|
|||
<script src="commandModel.js"></script>
|
||||
<script src="commandViews.js"></script>
|
||||
|
||||
|
||||
<!-- vis -->
|
||||
<script src="collections.js"></script>
|
||||
<script src="visuals.js"></script>
|
||||
<script src="tree.js"></script>
|
||||
<script src="animationFactory.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -195,11 +195,17 @@ p.commandLine span.icons i {
|
|||
|
||||
p.commandLine.inqueue span.icons i.icon-check-empty,
|
||||
p.commandLine.error span.icons i.icon-exclamation-sign,
|
||||
p.commandLine.warning span.icons i.icon-exclamation-sign,
|
||||
p.commandLine.processing span.icons i.icon-retweet,
|
||||
p.commandLine.finished span.icons i.icon-check {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
p.commandLine.warning span.icons {
|
||||
background-color: #E0FF00;
|
||||
color: black;
|
||||
}
|
||||
|
||||
p.commandLine.inqueue span.icons {
|
||||
background-color: #EBEB24;
|
||||
color: black;
|
||||
|
|
17
src/tree.js
17
src/tree.js
|
@ -1,6 +1,9 @@
|
|||
var VisBranch = Backbone.Model.extend({
|
||||
defaults: {
|
||||
pos: null
|
||||
pos: null,
|
||||
text: null,
|
||||
animationSpeed: GRAPHICS.defaultAnimationTime,
|
||||
animationEasing: GRAPHICS.defaultEasing
|
||||
},
|
||||
|
||||
validateAtInit: function() {
|
||||
|
@ -37,20 +40,14 @@ var VisBranch = Backbone.Model.extend({
|
|||
this.set('text', text);
|
||||
},
|
||||
|
||||
animateUpdatedPos: function(paper) {
|
||||
animateUpdatedPos: function(speed, easing) {
|
||||
var pos = this.getPosition();
|
||||
var t = this.get('text');
|
||||
if (!t) {
|
||||
this.genGraphics(paper);
|
||||
t = this.get('text');
|
||||
// TODO HACKY
|
||||
}
|
||||
this.get('text').toFront().stop().animate({
|
||||
x: pos.x,
|
||||
y: pos.y
|
||||
},
|
||||
300,
|
||||
'easeInOut'
|
||||
speed || this.get('animationSpeed'),
|
||||
easing || this.get('animationEasing')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -71,7 +71,7 @@ GitVisuals.prototype.toScreenCoords = function(pos) {
|
|||
**************************************/
|
||||
|
||||
GitVisuals.prototype.refreshTree = function() {
|
||||
if (!this.paperReady) { return; }
|
||||
if (!this.paperReady) { console.warn('called refresh tree when not ready yet'); return; }
|
||||
|
||||
this.calculateTreeCoords();
|
||||
this.animateNodePositions();
|
||||
|
@ -79,6 +79,13 @@ GitVisuals.prototype.refreshTree = function() {
|
|||
this.animateRefs();
|
||||
};
|
||||
|
||||
GitVisuals.prototype.refreshTreeHarsh = function() {
|
||||
this.calculateTreeCoords();
|
||||
|
||||
this.animateEdges();
|
||||
this.animateNodePositions();
|
||||
};
|
||||
|
||||
GitVisuals.prototype.calculateTreeCoords = function() {
|
||||
if (!this.rootCommit) {
|
||||
throw new Error('grr, no root commit!');
|
||||
|
@ -142,6 +149,13 @@ GitVisuals.prototype.assignBoundsRecursive = function(commit, min, max) {
|
|||
|
||||
GitVisuals.prototype.calcDepth = function() {
|
||||
var maxDepth = this.calcDepthRecursive(this.rootCommit, 0);
|
||||
if (maxDepth > 15) {
|
||||
// issue warning
|
||||
events.trigger('issueWarning',
|
||||
'Max Depth Exceeded! Visuals may degrade here. ' +
|
||||
'Please start fresh or use reset to reduce the max depth'
|
||||
);
|
||||
}
|
||||
|
||||
var depthIncrement = this.getDepthIncrement(maxDepth);
|
||||
_.each(this.visNodeMap, function(visNode) {
|
||||
|
@ -279,6 +293,8 @@ GitVisuals.prototype.drawTreeFirstTime = function() {
|
|||
this.visBranchCollection.each(function(visBranch) {
|
||||
visBranch.genGraphics(paper);
|
||||
}, this);
|
||||
|
||||
this.refreshTree();
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue