Skip to content

Commit

Permalink
Add implementation for git push.
Browse files Browse the repository at this point in the history
Creation/deletion of remote branches not supported yet.
  • Loading branch information
Wei Wang committed Mar 28, 2013
1 parent 4a5c8ee commit b6b7196
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 16 deletions.
46 changes: 46 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ <h4>Remote Server</h4>
<a id="open-fetch" class="openswitch" href="#">git fetch</a>
<a id="open-pull" class="openswitch" href="#">git pull</a>
</div>
<div class="twocol last">
<h4>&nbsp;</h4>
<a id="open-push" class="openswitch" href="#">git push</a>
</div>
</div>
<div class="row concept-area">
<div id="ExplainGitCommit-Container" class="twelvecol concept-container">
Expand Down Expand Up @@ -186,6 +190,18 @@ <h4>Remote Server</h4>
</p>
<div class="playground-container"></div>
</div>
<div id="ExplainGitPush-Container" class="twelvecol concept-container">
<p>
A <span class="cmd">git push</span> will find the commits you have on your local branch that the corresponding branch
on the origin server does not have, and send them to the remote repository.
</p>
<p>
By default, all pushes must cause a fast-forward merge on the remote repository. If there is any divergence between
your local branch and the remote branch, your push will be rejected. In this scenario, you need to pull first and then
you will be able to push again.
</p>
<div class="playground-container"></div>
</div>
<div id="ExplainGitFree-Container" class="twelvecol concept-container">
<p>
Do whatever you want in this free playground.
Expand Down Expand Up @@ -510,6 +526,36 @@ <h4>Free Play</h4>
});
</script>

<script type="text/javascript">
require(['explaingit'], function (explainGit) {
var openSwitch = document.getElementById('open-push'),
open;

open = function () {
explainGit.reset();
this.classList.add('selected');

explainGit.open({
name: 'Push',
height: 500,
commitData: [
{id: 'e137e9b', tags: ['origin/master']},
{id: '46d095b', parent: 'e137e9b', tags: ['master']}
],
originData: [
{id: 'e137e9b'},
{id: '7eb7654', parent: 'e137e9b', tags: ['master']}
],
initialMessage:
'Carefully compare the commit IDs between the origin and the local repository. ' +
'Then type "git pull".'
});
};

openSwitch.addEventListener('click', open, false);
});
</script>

<script type="text/javascript">
require(['explaingit'], function (explainGit) {
var openSwitch = document.getElementById('open-freeplay'),
Expand Down
89 changes: 86 additions & 3 deletions js/controlbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,15 +308,15 @@ define(['d3'], function () {
for (fb in fetchBranches) {
if (origin.branches.indexOf(fb) > -1) {
var remoteLoc = origin.getCommit(fb).id;
local._moveTag('origin/' + fb, remoteLoc);
local.moveTag('origin/' + fb, remoteLoc);
}

resultMessage += 'Fetched ' + fetchBranches[fb] + ' commits on ' + fb + '.</br>';
}

this.info(resultMessage);

local._renderCommits();
local.renderCommits();
},

pull: function (args) {
Expand Down Expand Up @@ -352,7 +352,90 @@ define(['d3'], function () {
}
}, 750);
},


push: function (args) {
var control = this,
local = this.historyView,
remoteName = args.shift() || 'origin',
remote = this[remoteName + 'View'],
branchArgs = args.pop(),
localRef = local.currentBranch,
remoteRef = local.currentBranch,
localCommit, remoteCommit,
findCommitsToPush,
isCommonCommit,
toPush = [];

if (remoteName === 'history') {
throw new Error('Sorry, you can\'t have a remote named "history" in this example.');
}

if (!remote) {
throw new Error('There is no remote server named "' + remoteName + '".');
}

if (branchArgs) {
branchArgs = /^([^:]*)(:?)(.*)$/.exec(branchArgs);

branchArgs[1] && (localRef = branchArgs[1]);
branchArgs[2] === ':' && (remoteRef = branchArgs[3]);
}

if (local.branches.indexOf(localRef) === -1) {
throw new Error('Local ref: ' + localRef + ' does not exist.');
}

if (!remoteRef) {
throw new Error('No remote branch was specified to push to.');
}

localCommit = local.getCommit(localRef);
remoteCommit = remote.getCommit(remoteRef);

findCommitsToPush = function findCommitsToPush(localCommit) {
var commitToPush,
isCommonCommit = remote.getCommit(localCommit.id) !== null;

while (!isCommonCommit) {
commitToPush = {
id: localCommit.id,
parent: localCommit.parent,
tags: []
};

if (typeof localCommit.parent2 === 'string') {
commitToPush.parent2 = localCommit.parent2;
findCommitsToPush(local.getCommit(localCommit.parent2));
}

toPush.unshift(commitToPush);
localCommit = local.getCommit(localCommit.parent);
isCommonCommit = remote.getCommit(localCommit.id) !== null;
}
};

// push to an existing branch on the remote
if (remoteCommit && remote.branches.indexOf(remoteRef) > -1) {
if (!local.isAncestor(remoteCommit.id, localCommit.id)) {
throw new Error('Push rejected. Non fast-forward.');
}

isCommonCommit = localCommit.id === remoteCommit.id;

if (isCommonCommit) {
return this.info('Everything up-to-date.');
}

findCommitsToPush(localCommit);

remote.commitData = remote.commitData.concat(toPush);
remote.moveTag(remoteRef, toPush[toPush.length - 1].id);
remote.renderCommits();
} else {
this.info('Sorry, creating new remote branches is not supported yet.');
}
},

config: function (args) {
var path = args.shift().split('.');

Expand Down
36 changes: 23 additions & 13 deletions js/historyview.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ define(['d3'], function () {
this.commitBox = svg.append('svg:g').classed('commits', true);
this.tagBox = svg.append('svg:g').classed('tags', true);

this._renderCommits();
this.renderCommits();

this._setCurrentBranch(this.currentBranch);
},
Expand All @@ -393,7 +393,7 @@ define(['d3'], function () {
}
},

_renderCommits: function () {
renderCommits: function () {
this._calculatePositionData();
this._calculatePositionData(); // do this twice to make sure
this._renderCircles();
Expand Down Expand Up @@ -605,7 +605,7 @@ define(['d3'], function () {
this.svg.selectAll('polyline.merge-pointer').call(applyBranchlessClass);
},

_renderTags: function () {
renderTags: function () {
var view = this,
tagData = this._parseTagData(),
existingTags, newTags;
Expand Down Expand Up @@ -688,7 +688,7 @@ define(['d3'], function () {
display.text(text);
},

_moveTag: function (tag, ref) {
moveTag: function (tag, ref) {
var currentLoc = this.getCommit(tag),
newLoc = this.getCommit(ref);

Expand All @@ -700,12 +700,22 @@ define(['d3'], function () {
return this;
},

/**
* @method isAncestor
* @param ref1
* @param ref2
* @return {Boolean} whether or not ref1 is an ancestor of ref2
*/
isAncestor: function isAncestor(ref1, ref2) {
var currentCommit = this.getCommit(ref1),
targetTree = this.getCommit(ref2),
inTree = false,
additionalTrees = [];

if (!currentCommit) {
return false;
}

while (targetTree) {
if (targetTree.id === currentCommit.id) {
inTree = true;
Expand Down Expand Up @@ -745,9 +755,9 @@ define(['d3'], function () {
}

this.commitData.push(commit);
this._moveTag(this.currentBranch, commit.id);
this.moveTag(this.currentBranch, commit.id);

this._renderCommits();
this.renderCommits();

this.checkout(this.currentBranch);
return this;
Expand All @@ -771,7 +781,7 @@ define(['d3'], function () {
}

this.getCommit('HEAD').tags.push(name);
this._renderTags();
this.renderTags();
return this;
},

Expand Down Expand Up @@ -801,7 +811,7 @@ define(['d3'], function () {
commit.tags.splice(branchIndex, 1);
}

this._renderTags();
this.renderTags();
},

checkout: function (ref) {
Expand All @@ -819,8 +829,8 @@ define(['d3'], function () {
}

this._setCurrentBranch(ref === commit.id ? null : ref);
this._moveTag('HEAD', commit.id);
this._renderTags();
this.moveTag('HEAD', commit.id);
this.renderTags();

newHead.classed('checked-out', true);

Expand All @@ -835,7 +845,7 @@ define(['d3'], function () {
}

if (this.currentBranch) {
this._moveTag(this.currentBranch, commit.id);
this.moveTag(this.currentBranch, commit.id);
this.checkout(this.currentBranch);
} else {
this.checkout(commit.id);
Expand All @@ -848,7 +858,7 @@ define(['d3'], function () {
var targetCommit = this.getCommit(ref);

if (this.currentBranch) {
this._moveTag(this.currentBranch, targetCommit.id);
this.moveTag(this.currentBranch, targetCommit.id);
this.checkout(this.currentBranch);
} else {
this.checkout(targetCommit.id);
Expand Down Expand Up @@ -937,7 +947,7 @@ define(['d3'], function () {
rebasedCommit.tags.push(this.currentBranch);
}

this._renderCommits();
this.renderCommits();

if (this.currentBranch) {
this.checkout(this.currentBranch);
Expand Down

0 comments on commit b6b7196

Please sign in to comment.