mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Use flow-diff to resolve merge conflicts
This commit is contained in:
parent
9066cedc29
commit
6191a49ed3
@ -131,11 +131,12 @@
|
|||||||
var project = RED.projects.getActiveProject();
|
var project = RED.projects.getActiveProject();
|
||||||
var message = {
|
var message = {
|
||||||
"change-branch":"Change to local branch '"+project.git.branches.local+"'",
|
"change-branch":"Change to local branch '"+project.git.branches.local+"'",
|
||||||
"abort-merge":"Git merge aborted",
|
"merge-abort":"Git merge aborted",
|
||||||
"loaded":"Project '"+msg.project+"' loaded",
|
"loaded":"Project '"+msg.project+"' loaded",
|
||||||
"updated":"Project '"+msg.project+"' updated",
|
"updated":"Project '"+msg.project+"' updated",
|
||||||
"pull":"Project '"+msg.project+"' reloaded",
|
"pull":"Project '"+msg.project+"' reloaded",
|
||||||
"revert": "Project '"+msg.project+"' reloaded"
|
"revert": "Project '"+msg.project+"' reloaded",
|
||||||
|
"merge-complete":"Git merge completed"
|
||||||
}[msg.action];
|
}[msg.action];
|
||||||
RED.notify("<p>"+message+"</p>");
|
RED.notify("<p>"+message+"</p>");
|
||||||
RED.sidebar.info.refresh()
|
RED.sidebar.info.refresh()
|
||||||
@ -219,6 +220,20 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
} else if (msg.error === "git_merge_conflict") {
|
||||||
|
RED.nodes.clear();
|
||||||
|
RED.sidebar.versionControl.refresh(true);
|
||||||
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
|
options.buttons = [
|
||||||
|
{
|
||||||
|
text: "Show merge conflicts",
|
||||||
|
click: function() {
|
||||||
|
persistentNotifications[notificationId].hideNotification();
|
||||||
|
RED.sidebar.versionControl.showLocalChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
||||||
|
@ -21,17 +21,18 @@ RED.diff = (function() {
|
|||||||
RED.keyboard.add("*","ctrl-shift-f 3","core:show-test-flow-diff-3");
|
RED.keyboard.add("*","ctrl-shift-f 3","core:show-test-flow-diff-3");
|
||||||
|
|
||||||
}
|
}
|
||||||
function createDiffTable(container) {
|
function createDiffTable(container,CurrentDiff) {
|
||||||
var diffList = $('<ol class="node-dialog-view-diff-diff"></ol>').appendTo(container);
|
var diffList = $('<ol class="node-dialog-view-diff-diff"></ol>').appendTo(container);
|
||||||
diffList.editableList({
|
diffList.editableList({
|
||||||
addButton: false,
|
addButton: false,
|
||||||
|
height: "auto",
|
||||||
scrollOnAdd: false,
|
scrollOnAdd: false,
|
||||||
addItem: function(container,i,object) {
|
addItem: function(container,i,object) {
|
||||||
var localDiff = object.diff;
|
var localDiff = object.diff;
|
||||||
var remoteDiff = object.remoteDiff;
|
var remoteDiff = object.remoteDiff;
|
||||||
var tab = object.tab.n;
|
var tab = object.tab.n;
|
||||||
var def = object.def;
|
var def = object.def;
|
||||||
var conflicts = currentDiff.conflicts;
|
var conflicts = CurrentDiff.conflicts;
|
||||||
|
|
||||||
var tabDiv = $('<div>',{class:"node-diff-tab"}).appendTo(container);
|
var tabDiv = $('<div>',{class:"node-diff-tab"}).appendTo(container);
|
||||||
tabDiv.addClass('collapsed');
|
tabDiv.addClass('collapsed');
|
||||||
@ -150,10 +151,10 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
div.addClass("node-diff-node-entry-conflict");
|
div.addClass("node-diff-node-entry-conflict");
|
||||||
} else {
|
} else {
|
||||||
selectState = currentDiff.resolutions[tab.id];
|
selectState = CurrentDiff.resolutions[tab.id];
|
||||||
}
|
}
|
||||||
// Tab properties row
|
// Tab properties row
|
||||||
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!conflicts[tab.id],selectState);
|
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!conflicts[tab.id],selectState,CurrentDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// var stats = $('<span>',{class:"node-diff-tab-stats"}).appendTo(titleRow);
|
// var stats = $('<span>',{class:"node-diff-tab-stats"}).appendTo(titleRow);
|
||||||
@ -162,14 +163,14 @@ RED.diff = (function() {
|
|||||||
var seen = {};
|
var seen = {};
|
||||||
object.tab.nodes.forEach(function(node) {
|
object.tab.nodes.forEach(function(node) {
|
||||||
seen[node.id] = true;
|
seen[node.id] = true;
|
||||||
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
|
createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv)
|
||||||
});
|
});
|
||||||
if (object.newTab) {
|
if (object.newTab) {
|
||||||
localNodeCount = object.newTab.nodes.length;
|
localNodeCount = object.newTab.nodes.length;
|
||||||
object.newTab.nodes.forEach(function(node) {
|
object.newTab.nodes.forEach(function(node) {
|
||||||
if (!seen[node.id]) {
|
if (!seen[node.id]) {
|
||||||
seen[node.id] = true;
|
seen[node.id] = true;
|
||||||
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
|
createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -177,7 +178,7 @@ RED.diff = (function() {
|
|||||||
remoteNodeCount = object.remoteTab.nodes.length;
|
remoteNodeCount = object.remoteTab.nodes.length;
|
||||||
object.remoteTab.nodes.forEach(function(node) {
|
object.remoteTab.nodes.forEach(function(node) {
|
||||||
if (!seen[node.id]) {
|
if (!seen[node.id]) {
|
||||||
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
|
createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -269,12 +270,12 @@ RED.diff = (function() {
|
|||||||
if (flowStats.conflicts > 0) {
|
if (flowStats.conflicts > 0) {
|
||||||
titleRow.addClass("node-diff-node-entry-conflict");
|
titleRow.addClass("node-diff-node-entry-conflict");
|
||||||
} else {
|
} else {
|
||||||
selectState = currentDiff.resolutions[tab.id];
|
selectState = CurrentDiff.resolutions[tab.id];
|
||||||
}
|
}
|
||||||
if (tab.id) {
|
if (tab.id) {
|
||||||
var hide = !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id]));
|
var hide = !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id]));
|
||||||
// Tab parent row
|
// Tab parent row
|
||||||
createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, hide, selectState);
|
createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, hide, selectState, CurrentDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,11 +292,8 @@ RED.diff = (function() {
|
|||||||
var diffHeaders = $('<div class="node-dialog-view-diff-headers"></div>').appendTo(diffPanel);
|
var diffHeaders = $('<div class="node-dialog-view-diff-headers"></div>').appendTo(diffPanel);
|
||||||
if (options.mode === "merge") {
|
if (options.mode === "merge") {
|
||||||
diffPanel.addClass("node-dialog-view-diff-panel-merge");
|
diffPanel.addClass("node-dialog-view-diff-panel-merge");
|
||||||
var toolbar = $('<div class="node-diff-toolbar">'+
|
|
||||||
'<span><span id="node-diff-toolbar-resolved-conflicts"></span></span> '+
|
|
||||||
'</div>').prependTo(diffPanel);
|
|
||||||
}
|
}
|
||||||
var diffList = createDiffTable(diffPanel);
|
var diffList = createDiffTable(diffPanel, diff);
|
||||||
|
|
||||||
var localDiff = diff.localDiff;
|
var localDiff = diff.localDiff;
|
||||||
var remoteDiff = diff.remoteDiff;
|
var remoteDiff = diff.remoteDiff;
|
||||||
@ -512,10 +510,10 @@ RED.diff = (function() {
|
|||||||
$('<span>',{class:"node-diff-node-label"}).html(nodeLabel).appendTo(contentDiv);
|
$('<span>',{class:"node-diff-node-label"}).html(nodeLabel).appendTo(contentDiv);
|
||||||
return nodeTitleDiv;
|
return nodeTitleDiv;
|
||||||
}
|
}
|
||||||
function createNodeDiffRow(node,stats) {
|
function createNodeDiffRow(node,stats,CurrentDiff) {
|
||||||
var localDiff = currentDiff.localDiff;
|
var localDiff = CurrentDiff.localDiff;
|
||||||
var remoteDiff = currentDiff.remoteDiff;
|
var remoteDiff = CurrentDiff.remoteDiff;
|
||||||
var conflicted = currentDiff.conflicts[node.id];
|
var conflicted = CurrentDiff.conflicts[node.id];
|
||||||
|
|
||||||
var hasChanges = false; // exists in original and local/remote but with changes
|
var hasChanges = false; // exists in original and local/remote but with changes
|
||||||
var unChanged = true; // existing in original,local,remote unchanged
|
var unChanged = true; // existing in original,local,remote unchanged
|
||||||
@ -703,10 +701,10 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
div.addClass("node-diff-node-entry-conflict");
|
div.addClass("node-diff-node-entry-conflict");
|
||||||
} else {
|
} else {
|
||||||
selectState = currentDiff.resolutions[node.id];
|
selectState = CurrentDiff.resolutions[node.id];
|
||||||
}
|
}
|
||||||
// Node row
|
// Node row
|
||||||
createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState);
|
createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState,CurrentDiff);
|
||||||
row.click(function(evt) {
|
row.click(function(evt) {
|
||||||
$(this).parent().toggleClass('collapsed');
|
$(this).parent().toggleClass('collapsed');
|
||||||
});
|
});
|
||||||
@ -982,7 +980,7 @@ RED.diff = (function() {
|
|||||||
});
|
});
|
||||||
return nodePropertiesDiv;
|
return nodePropertiesDiv;
|
||||||
}
|
}
|
||||||
function createNodeConflictRadioBoxes(node,row,localDiv,remoteDiv,propertiesTable,hide,state) {
|
function createNodeConflictRadioBoxes(node,row,localDiv,remoteDiv,propertiesTable,hide,state,diff) {
|
||||||
var safeNodeId = "node-diff-selectbox-"+node.id.replace(/\./g,'-')+(propertiesTable?"-props":"");
|
var safeNodeId = "node-diff-selectbox-"+node.id.replace(/\./g,'-')+(propertiesTable?"-props":"");
|
||||||
var className = "";
|
var className = "";
|
||||||
if (node.z||propertiesTable) {
|
if (node.z||propertiesTable) {
|
||||||
@ -1019,7 +1017,7 @@ RED.diff = (function() {
|
|||||||
row.addClass("node-diff-select-remote");
|
row.addClass("node-diff-select-remote");
|
||||||
row.removeClass("node-diff-select-local");
|
row.removeClass("node-diff-select-local");
|
||||||
}
|
}
|
||||||
refreshConflictHeader();
|
refreshConflictHeader(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
var localSelectDiv = $('<label>',{class:"node-diff-selectbox",for:safeNodeId+"-local"}).click(function(e) { e.stopPropagation();}).appendTo(localDiv);
|
var localSelectDiv = $('<label>',{class:"node-diff-selectbox",for:safeNodeId+"-local"}).click(function(e) { e.stopPropagation();}).appendTo(localDiv);
|
||||||
@ -1037,7 +1035,7 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
function refreshConflictHeader() {
|
function refreshConflictHeader(currentDiff) {
|
||||||
var resolutionCount = 0;
|
var resolutionCount = 0;
|
||||||
$(".node-diff-selectbox>input:checked").each(function() {
|
$(".node-diff-selectbox>input:checked").each(function() {
|
||||||
if (currentDiff.conflicts[$(this).data('node-id')]) {
|
if (currentDiff.conflicts[$(this).data('node-id')]) {
|
||||||
@ -1053,6 +1051,7 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
if (conflictCount === resolutionCount) {
|
if (conflictCount === resolutionCount) {
|
||||||
$("#node-diff-view-diff-merge").removeClass('disabled');
|
$("#node-diff-view-diff-merge").removeClass('disabled');
|
||||||
|
$("#node-diff-view-resolve-diff").removeClass('disabled');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getRemoteDiff(callback) {
|
function getRemoteDiff(callback) {
|
||||||
@ -1231,7 +1230,7 @@ RED.diff = (function() {
|
|||||||
var localDiff = diff.localDiff;
|
var localDiff = diff.localDiff;
|
||||||
var remoteDiff = diff.remoteDiff;
|
var remoteDiff = diff.remoteDiff;
|
||||||
var conflicts = diff.conflicts;
|
var conflicts = diff.conflicts;
|
||||||
currentDiff = diff;
|
// currentDiff = diff;
|
||||||
|
|
||||||
var trayOptions = {
|
var trayOptions = {
|
||||||
title: options.title||"Review Changes", //TODO: nls
|
title: options.title||"Review Changes", //TODO: nls
|
||||||
@ -1250,7 +1249,11 @@ RED.diff = (function() {
|
|||||||
},
|
},
|
||||||
open: function(tray) {
|
open: function(tray) {
|
||||||
var trayBody = tray.find('.editor-tray-body');
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
var diffTable = buildDiffPanel(trayBody,diff,options);
|
var toolbar = $('<div class="node-diff-toolbar">'+
|
||||||
|
'<span><span id="node-diff-toolbar-resolved-conflicts"></span></span> '+
|
||||||
|
'</div>').prependTo(trayBody);
|
||||||
|
var diffContainer = $('<div class="node-diff-container"></div>').appendTo(trayBody);
|
||||||
|
var diffTable = buildDiffPanel(diffContainer,diff,options);
|
||||||
diffTable.list.hide();
|
diffTable.list.hide();
|
||||||
if (remoteDiff) {
|
if (remoteDiff) {
|
||||||
$("#node-diff-view-diff-merge").show();
|
$("#node-diff-view-diff-merge").show();
|
||||||
@ -1262,7 +1265,7 @@ RED.diff = (function() {
|
|||||||
} else {
|
} else {
|
||||||
$("#node-diff-view-diff-merge").hide();
|
$("#node-diff-view-diff-merge").hide();
|
||||||
}
|
}
|
||||||
refreshConflictHeader();
|
refreshConflictHeader(diff);
|
||||||
// console.log("--------------");
|
// console.log("--------------");
|
||||||
// console.log(localDiff);
|
// console.log(localDiff);
|
||||||
// console.log(remoteDiff);
|
// console.log(remoteDiff);
|
||||||
@ -1290,8 +1293,8 @@ RED.diff = (function() {
|
|||||||
class: "primary disabled",
|
class: "primary disabled",
|
||||||
click: function() {
|
click: function() {
|
||||||
if (!$("#node-diff-view-diff-merge").hasClass('disabled')) {
|
if (!$("#node-diff-view-diff-merge").hasClass('disabled')) {
|
||||||
refreshConflictHeader();
|
refreshConflictHeader(diff);
|
||||||
mergeDiff(currentDiff);
|
mergeDiff(diff);
|
||||||
RED.tray.close();
|
RED.tray.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1302,7 +1305,7 @@ RED.diff = (function() {
|
|||||||
RED.tray.show(trayOptions);
|
RED.tray.show(trayOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeDiff(diff) {
|
function applyDiff(diff) {
|
||||||
var currentConfig = diff.localDiff.currentConfig;
|
var currentConfig = diff.localDiff.currentConfig;
|
||||||
var localDiff = diff.localDiff;
|
var localDiff = diff.localDiff;
|
||||||
var remoteDiff = diff.remoteDiff;
|
var remoteDiff = diff.remoteDiff;
|
||||||
@ -1356,6 +1359,20 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
config: newConfig,
|
||||||
|
nodeChangedStates: nodeChangedStates,
|
||||||
|
localChangedStates: localChangedStates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeDiff(diff) {
|
||||||
|
var appliedDiff = applyDiff(diff);
|
||||||
|
|
||||||
|
var newConfig = appliedDiff.config;
|
||||||
|
var nodeChangedStates = appliedDiff.nodeChangedStates;
|
||||||
|
var localChangedStates = appliedDiff.localChangedStates;
|
||||||
|
|
||||||
var historyEvent = {
|
var historyEvent = {
|
||||||
t:"replace",
|
t:"replace",
|
||||||
config: RED.nodes.createCompleteNodeSet(),
|
config: RED.nodes.createCompleteNodeSet(),
|
||||||
@ -1417,7 +1434,7 @@ RED.diff = (function() {
|
|||||||
var trayBody = tray.find('.editor-tray-body');
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
var diffPanel = $('<div class="node-text-diff"></div>').appendTo(trayBody);
|
var diffPanel = $('<div class="node-text-diff"></div>').appendTo(trayBody);
|
||||||
|
|
||||||
var codeTable = $("<table>").appendTo(diffPanel);
|
var codeTable = $("<table>",{class:"node-text-diff-content"}).appendTo(diffPanel);
|
||||||
$('<colgroup><col width="50"><col width="50%"><col width="50"><col width="50%"></colgroup>').appendTo(codeTable);
|
$('<colgroup><col width="50"><col width="50%"><col width="50"><col width="50%"></colgroup>').appendTo(codeTable);
|
||||||
var codeBody = $('<tbody>').appendTo(codeTable);
|
var codeBody = $('<tbody>').appendTo(codeTable);
|
||||||
var diffSummary = diffText(textA||"",textB||"");
|
var diffSummary = diffText(textA||"",textB||"");
|
||||||
@ -1681,7 +1698,7 @@ RED.diff = (function() {
|
|||||||
files.forEach(function(file) {
|
files.forEach(function(file) {
|
||||||
var hunks = file.hunks;
|
var hunks = file.hunks;
|
||||||
var isBinary = file.binary;
|
var isBinary = file.binary;
|
||||||
var codeTable = $("<table>").appendTo(diffPanel);
|
var codeTable = $("<table>",{class:"node-text-diff-content"}).appendTo(diffPanel);
|
||||||
$('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable);
|
$('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable);
|
||||||
var codeBody = $('<tbody>').appendTo(codeTable);
|
var codeBody = $('<tbody>').appendTo(codeTable);
|
||||||
|
|
||||||
@ -1700,49 +1717,145 @@ RED.diff = (function() {
|
|||||||
var unresolvedConflicts = 0;
|
var unresolvedConflicts = 0;
|
||||||
var resolvedConflicts = 0;
|
var resolvedConflicts = 0;
|
||||||
var conflictResolutions = {};
|
var conflictResolutions = {};
|
||||||
|
if (commitOptions.project.files && commitOptions.project.files.flow === file.file) {
|
||||||
|
if (commitOptions.unmerged) {
|
||||||
|
$('<span style="float: right;"><span id="node-diff-toolbar-resolved-conflicts"></span></span>').appendTo(content);
|
||||||
|
}
|
||||||
|
// var tools = $('<span style="float: right;" class="button-group"></span>').appendTo(content);
|
||||||
|
// $('<button class="editor-button editor-button-small">show flow diff</button>').appendTo(tools).click(function(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// e.stopPropagation();
|
||||||
|
// var projectName = commitOptions.project.name;
|
||||||
|
// var filename = commitOptions.project.files.flow;
|
||||||
|
// var commonVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename;
|
||||||
|
// var oldVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.oldRev+"/"+filename;
|
||||||
|
// var newVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.newRev+"/"+filename;
|
||||||
|
// var promises = [];
|
||||||
|
// if (commitOptions.commonRev) {
|
||||||
|
// var commonVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename;
|
||||||
|
// promises.push($.getJSON(commonVersionUrl));
|
||||||
|
// } else {
|
||||||
|
// promises.push($.when(null));
|
||||||
|
// }
|
||||||
|
// promises.push($.getJSON(oldVersionUrl));
|
||||||
|
// promises.push($.getJSON(newVersionUrl));
|
||||||
|
// $.when.apply($,promises).done(function(commonVersion, oldVersion,newVersion) {
|
||||||
|
// var commonFlow;
|
||||||
|
// var oldFlow;
|
||||||
|
// var newFlow;
|
||||||
|
// if (commonVersion) {
|
||||||
|
// try {
|
||||||
|
// commonFlow = JSON.parse(commonVersion[0].content||"[]");
|
||||||
|
// } catch(err) {
|
||||||
|
// console.log("Common Version doesn't contain valid JSON:",commonVersionUrl);
|
||||||
|
// console.log(err);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// try {
|
||||||
|
// oldFlow = JSON.parse(oldVersion[0].content||"[]");
|
||||||
|
// } catch(err) {
|
||||||
|
// console.log("Old Version doesn't contain valid JSON:",oldVersionUrl);
|
||||||
|
// console.log(err);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (!commonFlow) {
|
||||||
|
// commonFlow = oldFlow;
|
||||||
|
// }
|
||||||
|
// try {
|
||||||
|
// newFlow = JSON.parse(newVersion[0].content||"[]");
|
||||||
|
// } catch(err) {
|
||||||
|
// console.log("New Version doesn't contain valid JSON:",newFlow);
|
||||||
|
// console.log(err);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// var localDiff = generateDiff(commonFlow,oldFlow);
|
||||||
|
// var remoteDiff = generateDiff(commonFlow,newFlow);
|
||||||
|
// var diff = resolveDiffs(localDiff,remoteDiff);
|
||||||
|
// showDiff(diff,{
|
||||||
|
// title: filename,
|
||||||
|
// mode: commitOptions.commonRev?'merge':'view',
|
||||||
|
// oldRevTitle: commitOptions.oldRevTitle,
|
||||||
|
// newRevTitle: commitOptions.newRevTitle
|
||||||
|
// });
|
||||||
|
// // var flowDiffRow = $("<tr>").insertAfter(diffRow);
|
||||||
|
// // var content = $('<td colspan="3"></td>').appendTo(flowDiffRow);
|
||||||
|
// // currentDiff = diff;
|
||||||
|
// // var diffTable = buildDiffPanel(content,diff,{mode:"view"}).finish();
|
||||||
|
// });
|
||||||
|
// })
|
||||||
|
var diffRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
|
||||||
|
var flowDiffContent = $('<td class="flow-diff" colspan="3"></td>').appendTo(diffRow);
|
||||||
|
|
||||||
if (!commitOptions.unmerged && commitOptions.project.files && commitOptions.project.files.flow === file.file) {
|
var projectName = commitOptions.project.name;
|
||||||
var tools = $('<span style="float: right;" class="button-group"></span>').appendTo(content);
|
var filename = commitOptions.project.files.flow;
|
||||||
$('<button class="editor-button editor-button-small">show flow diff</button>').appendTo(tools).click(function(e) {
|
var commonVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename;
|
||||||
e.preventDefault();
|
var oldVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.oldRev+"/"+filename;
|
||||||
e.stopPropagation();
|
var newVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.newRev+"/"+filename;
|
||||||
var projectName = commitOptions.project.name;
|
var promises = [$.Deferred(),$.Deferred(),$.Deferred()];
|
||||||
var filename = commitOptions.project.files.flow;
|
if (commitOptions.commonRev) {
|
||||||
var oldVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.oldRev+"/"+filename;
|
var commonVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename;
|
||||||
var newVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.newRev+"/"+filename;
|
$.ajax({dataType: "json",url: commonVersionUrl}).then(function(data) { promises[0].resolve(data); }).fail(function() { promises[0].resolve(null);})
|
||||||
$.when($.getJSON(oldVersionUrl),$.getJSON(newVersionUrl)).done(function(oldVersion,newVersion) {
|
} else {
|
||||||
var oldFlow;
|
promises[0].resolve(null);
|
||||||
var newFlow;
|
}
|
||||||
|
|
||||||
|
$.ajax({dataType: "json",url: oldVersionUrl}).then(function(data) { promises[1].resolve(data); }).fail(function() { promises[1].resolve({content:"[]"});})
|
||||||
|
$.ajax({dataType: "json",url: newVersionUrl}).then(function(data) { promises[2].resolve(data); }).fail(function() { promises[2].resolve({content:"[]"});})
|
||||||
|
$.when.apply($,promises).always(function(commonVersion, oldVersion,newVersion) {
|
||||||
|
var commonFlow;
|
||||||
|
var oldFlow;
|
||||||
|
var newFlow;
|
||||||
|
if (commonVersion) {
|
||||||
try {
|
try {
|
||||||
oldFlow = JSON.parse(oldVersion[0].content||"[]");
|
commonFlow = JSON.parse(commonVersion.content||"[]");
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log("Old Version doesn't contain valid JSON:",oldVersionUrl);
|
console.log("Common Version doesn't contain valid JSON:",commonVersionUrl);
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
}
|
||||||
newFlow = JSON.parse(newVersion[0].content||"[]");
|
try {
|
||||||
} catch(err) {
|
oldFlow = JSON.parse(oldVersion.content||"[]");
|
||||||
console.log("New Version doesn't contain valid JSON:",newFlow);
|
} catch(err) {
|
||||||
console.log(err);
|
console.log("Old Version doesn't contain valid JSON:",oldVersionUrl);
|
||||||
return;
|
console.log(err);
|
||||||
}
|
return;
|
||||||
var localDiff = generateDiff(oldFlow,oldFlow);
|
}
|
||||||
var remoteDiff = generateDiff(oldFlow,newFlow);
|
if (!commonFlow) {
|
||||||
var diff = resolveDiffs(localDiff,remoteDiff);
|
commonFlow = oldFlow;
|
||||||
showDiff(diff,{
|
}
|
||||||
title: filename,
|
try {
|
||||||
mode: 'view',
|
newFlow = JSON.parse(newVersion.content||"[]");
|
||||||
oldRevTitle: commitOptions.oldRevTitle,
|
} catch(err) {
|
||||||
newRevTitle: commitOptions.newRevTitle
|
console.log("New Version doesn't contain valid JSON:",newFlow);
|
||||||
});
|
console.log(err);
|
||||||
// var flowDiffRow = $("<tr>").insertAfter(diffRow);
|
return;
|
||||||
// var content = $('<td colspan="3"></td>').appendTo(flowDiffRow);
|
}
|
||||||
// currentDiff = diff;
|
var localDiff = generateDiff(commonFlow,oldFlow);
|
||||||
// var diffTable = buildDiffPanel(content,diff,{mode:"view"}).finish();
|
var remoteDiff = generateDiff(commonFlow,newFlow);
|
||||||
|
commitOptions.currentDiff = resolveDiffs(localDiff,remoteDiff);
|
||||||
|
var diffTable = buildDiffPanel(flowDiffContent,commitOptions.currentDiff,{
|
||||||
|
title: filename,
|
||||||
|
mode: commitOptions.commonRev?'merge':'view',
|
||||||
|
oldRevTitle: commitOptions.oldRevTitle,
|
||||||
|
newRevTitle: commitOptions.newRevTitle
|
||||||
});
|
});
|
||||||
})
|
diffTable.list.hide();
|
||||||
}
|
refreshConflictHeader(commitOptions.currentDiff);
|
||||||
|
setTimeout(function() {
|
||||||
|
diffTable.finish();
|
||||||
|
diffTable.list.show();
|
||||||
|
},300);
|
||||||
|
// var flowDiffRow = $("<tr>").insertAfter(diffRow);
|
||||||
|
// var content = $('<td colspan="3"></td>').appendTo(flowDiffRow);
|
||||||
|
// currentDiff = diff;
|
||||||
|
// var diffTable = buildDiffPanel(content,diff,{mode:"view"}).finish();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else
|
||||||
|
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
var diffBinaryRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
|
var diffBinaryRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
|
||||||
@ -1750,6 +1863,9 @@ RED.diff = (function() {
|
|||||||
$('<span></span>').text("Cannot show binary file contents").appendTo(binaryContent);
|
$('<span></span>').text("Cannot show binary file contents").appendTo(binaryContent);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (commitOptions.unmerged) {
|
||||||
|
conflictHeader = $('<span style="float: right;"><span>'+resolvedConflicts+'</span> of <span>'+unresolvedConflicts+'</span> conflicts resolved</span>').appendTo(content);
|
||||||
|
}
|
||||||
hunks.forEach(function(hunk) {
|
hunks.forEach(function(hunk) {
|
||||||
var diffRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
|
var diffRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
|
||||||
var content = $('<td colspan="3"></td>').appendTo(diffRow);
|
var content = $('<td colspan="3"></td>').appendTo(diffRow);
|
||||||
@ -1886,9 +2002,6 @@ RED.diff = (function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (commitOptions.unmerged) {
|
|
||||||
conflictHeader = $('<span style="float: right;"><span>'+resolvedConflicts+'</span> of <span>'+unresolvedConflicts+'</span> conflicts resolved</span>').appendTo(content);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return diffPanel;
|
return diffPanel;
|
||||||
}
|
}
|
||||||
@ -1914,7 +2027,7 @@ RED.diff = (function() {
|
|||||||
var trayBody = tray.find('.editor-tray-body');
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
var diffPanel = $('<div class="node-text-diff"></div>').appendTo(trayBody);
|
var diffPanel = $('<div class="node-text-diff"></div>').appendTo(trayBody);
|
||||||
|
|
||||||
var codeTable = $("<table>").appendTo(diffPanel);
|
var codeTable = $("<table>",{class:"node-text-diff-content"}).appendTo(diffPanel);
|
||||||
$('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable);
|
$('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable);
|
||||||
var codeBody = $('<tbody>').appendTo(codeTable);
|
var codeBody = $('<tbody>').appendTo(codeTable);
|
||||||
|
|
||||||
@ -1957,7 +2070,6 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var trayOptions = {
|
var trayOptions = {
|
||||||
title: title||"Compare Changes", //TODO: nls
|
title: title||"Compare Changes", //TODO: nls
|
||||||
width: Infinity,
|
width: Infinity,
|
||||||
@ -1996,6 +2108,15 @@ RED.diff = (function() {
|
|||||||
class: "primary disabled",
|
class: "primary disabled",
|
||||||
click: function() {
|
click: function() {
|
||||||
if (!$("#node-diff-view-resolve-diff").hasClass('disabled')) {
|
if (!$("#node-diff-view-resolve-diff").hasClass('disabled')) {
|
||||||
|
if (options.currentDiff) {
|
||||||
|
// This is a flow file. Need to apply the diff
|
||||||
|
// and generate the new flow.
|
||||||
|
var result = applyDiff(options.currentDiff);
|
||||||
|
currentResolution = {
|
||||||
|
resolutions:{}
|
||||||
|
};
|
||||||
|
currentResolution.resolutions[options.project.files.flow] = JSON.stringify(result.config,"",4);
|
||||||
|
}
|
||||||
if (options.onresolve) {
|
if (options.onresolve) {
|
||||||
options.onresolve(currentResolution);
|
options.onresolve(currentResolution);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ RED.sidebar.versionControl = (function() {
|
|||||||
var unmergedContent;
|
var unmergedContent;
|
||||||
var unmergedChangesList;
|
var unmergedChangesList;
|
||||||
var commitButton;
|
var commitButton;
|
||||||
var mergeConflictNotification;
|
|
||||||
var localChanges;
|
var localChanges;
|
||||||
|
|
||||||
var localCommitList;
|
var localCommitList;
|
||||||
@ -76,6 +75,11 @@ RED.sidebar.versionControl = (function() {
|
|||||||
options.oldRev = "@";
|
options.oldRev = "@";
|
||||||
options.newRev = ":0";
|
options.newRev = ":0";
|
||||||
} else {
|
} else {
|
||||||
|
options.oldRevTitle = "Local";
|
||||||
|
options.newRevTitle = "Remote";
|
||||||
|
options.commonRev = ":1";
|
||||||
|
options.oldRev = ":2";
|
||||||
|
options.newRev = ":3";
|
||||||
options.onresolve = function(resolution) {
|
options.onresolve = function(resolution) {
|
||||||
utils.sendRequest({
|
utils.sendRequest({
|
||||||
url: "projects/"+activeProject.name+"/resolve/"+encodeURIComponent(entry.file),
|
url: "projects/"+activeProject.name+"/resolve/"+encodeURIComponent(entry.file),
|
||||||
@ -358,6 +362,7 @@ RED.sidebar.versionControl = (function() {
|
|||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
var spinner = utils.addSpinnerOverlay(unmergedContent);
|
var spinner = utils.addSpinnerOverlay(unmergedContent);
|
||||||
var activeProject = RED.projects.getActiveProject();
|
var activeProject = RED.projects.getActiveProject();
|
||||||
|
RED.deploy.setDeployInflight(true);
|
||||||
utils.sendRequest({
|
utils.sendRequest({
|
||||||
url: "projects/"+activeProject.name+"/merge",
|
url: "projects/"+activeProject.name+"/merge",
|
||||||
type: "DELETE",
|
type: "DELETE",
|
||||||
@ -375,6 +380,10 @@ RED.sidebar.versionControl = (function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
}).always(function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
RED.deploy.setDeployInflight(false);
|
||||||
|
},500);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
unmergedChangesList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0; right:0; left:0;"}).appendTo(unmergedContent);
|
unmergedChangesList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0; right:0; left:0;"}).appendTo(unmergedContent);
|
||||||
@ -496,6 +505,7 @@ RED.sidebar.versionControl = (function() {
|
|||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
var spinner = utils.addSpinnerOverlay(submitCommitButton).addClass('projects-dialog-spinner-sidebar');
|
var spinner = utils.addSpinnerOverlay(submitCommitButton).addClass('projects-dialog-spinner-sidebar');
|
||||||
var activeProject = RED.projects.getActiveProject();
|
var activeProject = RED.projects.getActiveProject();
|
||||||
|
RED.deploy.setDeployInflight(true);
|
||||||
utils.sendRequest({
|
utils.sendRequest({
|
||||||
url: "projects/"+activeProject.name+"/commit",
|
url: "projects/"+activeProject.name+"/commit",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@ -516,10 +526,11 @@ RED.sidebar.versionControl = (function() {
|
|||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
message:commitMessage.val()
|
message:commitMessage.val()
|
||||||
});
|
}).always(function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
RED.deploy.setDeployInflight(false);
|
||||||
|
},500);
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -1108,31 +1119,9 @@ RED.sidebar.versionControl = (function() {
|
|||||||
}
|
}
|
||||||
isMerging = !!result.merging;
|
isMerging = !!result.merging;
|
||||||
if (isMerging) {
|
if (isMerging) {
|
||||||
if (!mergeConflictNotification) {
|
|
||||||
var text = "<p>Automatic merging of changes failed.</p><p>Fix the unmerged conflicts then commit the results.</p>";
|
|
||||||
var options = {
|
|
||||||
type: 'error',
|
|
||||||
fixed: true,
|
|
||||||
id: 'merge-conflict',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: "Show merge conflicts",
|
|
||||||
click: function() {
|
|
||||||
mergeConflictNotification.hideNotification();
|
|
||||||
RED.sidebar.versionControl.showLocalChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
mergeConflictNotification = RED.notify(text,options);
|
|
||||||
}
|
|
||||||
sidebarContent.addClass("sidebar-version-control-merging");
|
sidebarContent.addClass("sidebar-version-control-merging");
|
||||||
unmergedContent.show();
|
unmergedContent.show();
|
||||||
} else {
|
} else {
|
||||||
if (mergeConflictNotification) {
|
|
||||||
mergeConflictNotification.close();
|
|
||||||
mergeConflictNotification = null;
|
|
||||||
}
|
|
||||||
sidebarContent.removeClass("sidebar-version-control-merging");
|
sidebarContent.removeClass("sidebar-version-control-merging");
|
||||||
unmergedContent.hide();
|
unmergedContent.hide();
|
||||||
}
|
}
|
||||||
@ -1307,6 +1296,8 @@ RED.sidebar.versionControl = (function() {
|
|||||||
}
|
}
|
||||||
refreshInProgress = false;
|
refreshInProgress = false;
|
||||||
$('.sidebar-version-control-shade').hide();
|
$('.sidebar-version-control-shade').hide();
|
||||||
|
}).fail(function() {
|
||||||
|
refreshInProgress = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$('.sidebar-version-control-shade').show();
|
$('.sidebar-version-control-shade').show();
|
||||||
|
@ -16,17 +16,16 @@
|
|||||||
|
|
||||||
|
|
||||||
.node-dialog-view-diff-panel {
|
.node-dialog-view-diff-panel {
|
||||||
|
padding: 5px;
|
||||||
|
padding-top: 30px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.red-ui-editableList-container {
|
.red-ui-editableList-container {
|
||||||
border-radius:1px;
|
border-radius:1px;
|
||||||
padding:0;
|
padding:0;
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
}
|
}
|
||||||
.node-dialog-view-diff-diff {
|
.node-dialog-view-diff-diff {
|
||||||
position: absolute;
|
|
||||||
top:30px;
|
|
||||||
bottom:10px;
|
|
||||||
left:10px;
|
|
||||||
right:10px;
|
|
||||||
li {
|
li {
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
@ -38,21 +37,20 @@
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
// padding-bottom: 5px;
|
// padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
&.node-dialog-view-diff-panel-merge {
|
}
|
||||||
.node-dialog-view-diff-diff {
|
.node-diff-container {
|
||||||
top: 80px
|
position: absolute;
|
||||||
}
|
top: 40px;
|
||||||
.node-dialog-view-diff-headers {
|
right:0;
|
||||||
top: 55px;
|
bottom: 0;
|
||||||
}
|
left: 0;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-dialog-view-diff-headers {
|
.node-dialog-view-diff-headers {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left:237px;
|
left:232px;
|
||||||
right:18px;
|
right:12px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
div {
|
div {
|
||||||
@ -76,11 +74,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.node-diff-toolbar {
|
.node-diff-toolbar {
|
||||||
position:absolute;
|
|
||||||
top:0;
|
|
||||||
left:0;
|
|
||||||
right:0;
|
|
||||||
height: 43px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: #666;
|
color: #666;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
@ -555,129 +548,129 @@ ul.node-dialog-configm-deploy-list {
|
|||||||
.node-text-diff {
|
.node-text-diff {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y:auto;
|
overflow-y:auto;
|
||||||
table {
|
|
||||||
|
table.node-text-diff-content {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
border: 1px solid $secondary-border-color;
|
border: 1px solid $secondary-border-color;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
width: calc(100% - 20px);
|
width: calc(100% - 20px);
|
||||||
}
|
td {
|
||||||
td {
|
vertical-align: top;
|
||||||
vertical-align: top;
|
word-wrap: break-word;
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
td.lineno {
|
|
||||||
font-family: monospace;
|
|
||||||
text-align: right;
|
|
||||||
color: #aaa;
|
|
||||||
background: #f6f6f6;
|
|
||||||
padding: 1px 5px;
|
|
||||||
}
|
|
||||||
td.lineno:nth-child(3) {
|
|
||||||
border-left: 1px solid $secondary-border-color;
|
|
||||||
}
|
|
||||||
td.linetext {
|
|
||||||
font-family: monospace;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
padding: 1px 5px;
|
|
||||||
span.prefix {
|
|
||||||
width: 30px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
color: #999;
|
|
||||||
}
|
}
|
||||||
}
|
td.lineno {
|
||||||
td.blank {
|
|
||||||
background: #f6f6f6;
|
|
||||||
}
|
|
||||||
td.added {
|
|
||||||
background: #eefaee;
|
|
||||||
}
|
|
||||||
td.removed {
|
|
||||||
background: #fadddd;
|
|
||||||
}
|
|
||||||
tr.mergeHeader td {
|
|
||||||
color: #800080;
|
|
||||||
background: #e5f9ff;
|
|
||||||
height: 26px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
tr.mergeHeader-separator td {
|
|
||||||
color: #800080;
|
|
||||||
background: darken(#e5f9ff, 10%);
|
|
||||||
height: 0px;
|
|
||||||
}
|
|
||||||
tr.mergeHeader-ours td {
|
|
||||||
border-top: 2px solid darken(#e5f9ff, 10%);
|
|
||||||
}
|
|
||||||
tr.mergeHeader-theirs td {
|
|
||||||
border-bottom: 2px solid darken(#e5f9ff, 10%);
|
|
||||||
}
|
|
||||||
td.unchanged {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
tr.unchanged {
|
|
||||||
background: #fefefe;
|
|
||||||
}
|
|
||||||
tr.start-block {
|
|
||||||
border-top: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
tr.end-block {
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
tr.node-text-diff-file-header td {
|
|
||||||
.filename {
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
|
text-align: right;
|
||||||
|
color: #aaa;
|
||||||
|
background: #f6f6f6;
|
||||||
|
padding: 1px 5px;
|
||||||
}
|
}
|
||||||
background: #f3f3f3;
|
td.lineno:nth-child(3) {
|
||||||
padding: 5px 10px 5px 0;
|
border-left: 1px solid $secondary-border-color;
|
||||||
color: #333;
|
|
||||||
cursor: pointer;
|
|
||||||
i.node-diff-chevron {
|
|
||||||
width: 30px;
|
|
||||||
}
|
}
|
||||||
}
|
td.linetext {
|
||||||
tr.node-text-diff-file-header.collapsed {
|
font-family: monospace;
|
||||||
td i.node-diff-chevron {
|
white-space: pre-wrap;
|
||||||
transform: rotate(-90deg);
|
padding: 1px 5px;
|
||||||
|
span.prefix {
|
||||||
|
width: 30px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
td.blank {
|
||||||
tr.node-text-diff-commit-header td {
|
background: #f6f6f6;
|
||||||
background: #f3f3f3;
|
|
||||||
padding: 5px 10px;
|
|
||||||
color: #333;
|
|
||||||
h3 {
|
|
||||||
font-size: 1.4em;
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
.commit-summary {
|
td.added {
|
||||||
border-top: 1px solid $secondary-border-color;
|
background: #eefaee;
|
||||||
padding-top: 5px;
|
}
|
||||||
|
td.removed {
|
||||||
|
background: #fadddd;
|
||||||
|
}
|
||||||
|
tr.mergeHeader td {
|
||||||
|
color: #800080;
|
||||||
|
background: #e5f9ff;
|
||||||
|
height: 26px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
tr.mergeHeader-separator td {
|
||||||
|
color: #800080;
|
||||||
|
background: darken(#e5f9ff, 10%);
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
tr.mergeHeader-ours td {
|
||||||
|
border-top: 2px solid darken(#e5f9ff, 10%);
|
||||||
|
}
|
||||||
|
tr.mergeHeader-theirs td {
|
||||||
|
border-bottom: 2px solid darken(#e5f9ff, 10%);
|
||||||
|
}
|
||||||
|
td.unchanged {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
.commit-body {
|
tr.unchanged {
|
||||||
margin-bottom:15px;
|
background: #fefefe;
|
||||||
white-space: pre;
|
}
|
||||||
line-height: 1.2em;
|
tr.start-block {
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
tr.end-block {
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
tr.node-text-diff-file-header td {
|
||||||
|
.filename {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
background: #f3f3f3;
|
||||||
|
padding: 5px 10px 5px 0;
|
||||||
|
color: #333;
|
||||||
|
cursor: pointer;
|
||||||
|
i.node-diff-chevron {
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tr.node-text-diff-file-header.collapsed {
|
||||||
|
td i.node-diff-chevron {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tr.node-text-diff-commit-header td {
|
||||||
|
background: #f3f3f3;
|
||||||
|
padding: 5px 10px;
|
||||||
|
color: #333;
|
||||||
|
h3 {
|
||||||
|
font-size: 1.4em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.commit-summary {
|
||||||
|
border-top: 1px solid $secondary-border-color;
|
||||||
|
padding-top: 5px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.commit-body {
|
||||||
|
margin-bottom:15px;
|
||||||
|
white-space: pre;
|
||||||
|
line-height: 1.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.node-text-diff-header > td:not(.flow-diff) {
|
||||||
|
font-family: monospace;
|
||||||
|
padding: 5px 10px;
|
||||||
|
text-align: left;
|
||||||
|
color: #666;
|
||||||
|
background: #ffd;
|
||||||
|
height: 30px;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
tr.node-text-diff-expand td {
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background: #ffc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.node-text-diff-header td {
|
|
||||||
font-family: monospace;
|
|
||||||
padding: 5px 10px;
|
|
||||||
text-align: left;
|
|
||||||
color: #666;
|
|
||||||
background: #ffd;
|
|
||||||
height: 30px;
|
|
||||||
vertical-align: middle;
|
|
||||||
border-top: 1px solid #f0f0f0;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
tr.node-text-diff-expand td {
|
|
||||||
cursor: pointer;
|
|
||||||
&:hover {
|
|
||||||
background: #ffc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ module.exports = {
|
|||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
log.warn(log._("api.flows.error-save",{message:err.message}));
|
log.warn(log._("api.flows.error-save",{message:err.message}));
|
||||||
log.warn(err.stack);
|
log.warn(err.stack);
|
||||||
res.status(500).json({error:"unexpected_error", message:err.message});
|
res.status(500).json({error:err.code || "unexpected_error", message:err.message});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,8 @@
|
|||||||
"credentials_load_failed": "<p>Flows stopped as the credentials could not be decrypted.</p><p>The flow credential file is encrypted, but the project's encryption key is missing or invalid.</p>",
|
"credentials_load_failed": "<p>Flows stopped as the credentials could not be decrypted.</p><p>The flow credential file is encrypted, but the project's encryption key is missing or invalid.</p>",
|
||||||
"missing_flow_file": "<p>Project flow file not found.</p><p>The project is not configured with a flow file.</p>",
|
"missing_flow_file": "<p>Project flow file not found.</p><p>The project is not configured with a flow file.</p>",
|
||||||
"project_empty": "<p>The project is empty.</p><p>Do you want to create a default set of project files?<br/>Otherwise, you will have to manually add files to the project outside of the editor.</p>",
|
"project_empty": "<p>The project is empty.</p><p>Do you want to create a default set of project files?<br/>Otherwise, you will have to manually add files to the project outside of the editor.</p>",
|
||||||
"project_not_found": "<p>Project '__project__' not found.</p>"
|
"project_not_found": "<p>Project '__project__' not found.</p>",
|
||||||
|
"git_merge_conflict": "<p>Automatic merging of changes failed.</p><p>Fix the unmerged conflicts then commit the results.</p>"
|
||||||
},
|
},
|
||||||
|
|
||||||
"error": "<strong>Error</strong>: __message__",
|
"error": "<strong>Error</strong>: __message__",
|
||||||
|
@ -127,7 +127,7 @@ Project.prototype.load = function () {
|
|||||||
|
|
||||||
promises.push(project.loadRemotes());
|
promises.push(project.loadRemotes());
|
||||||
|
|
||||||
return when.settle(promises).then(function() {
|
return when.settle(promises).then(function(results) {
|
||||||
return project;
|
return project;
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -218,6 +218,9 @@ Project.prototype.parseRemoteBranch = function (remoteBranch) {
|
|||||||
Project.prototype.isEmpty = function () {
|
Project.prototype.isEmpty = function () {
|
||||||
return this.empty;
|
return this.empty;
|
||||||
};
|
};
|
||||||
|
Project.prototype.isMerging = function() {
|
||||||
|
return this.merging;
|
||||||
|
}
|
||||||
|
|
||||||
Project.prototype.update = function (user, data) {
|
Project.prototype.update = function (user, data) {
|
||||||
var username;
|
var username;
|
||||||
@ -374,7 +377,13 @@ Project.prototype.unstageFile = function(file) {
|
|||||||
return gitTools.unstageFile(this.path,file);
|
return gitTools.unstageFile(this.path,file);
|
||||||
}
|
}
|
||||||
Project.prototype.commit = function(user, options) {
|
Project.prototype.commit = function(user, options) {
|
||||||
return gitTools.commit(this.path,options.message,getGitUser(user));
|
var self = this;
|
||||||
|
return gitTools.commit(this.path,options.message,getGitUser(user)).then(function() {
|
||||||
|
if (self.merging) {
|
||||||
|
self.merging = false;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Project.prototype.getFileDiff = function(file,type) {
|
Project.prototype.getFileDiff = function(file,type) {
|
||||||
return gitTools.getFileDiff(this.path,file,type);
|
return gitTools.getFileDiff(this.path,file,type);
|
||||||
@ -440,6 +449,21 @@ Project.prototype.status = function(user, includeRemote) {
|
|||||||
var result = results[0];
|
var result = results[0];
|
||||||
if (results[1]) {
|
if (results[1]) {
|
||||||
result.merging = true;
|
result.merging = true;
|
||||||
|
if (!self.merging) {
|
||||||
|
self.merging = true;
|
||||||
|
runtime.events.emit("runtime-event",{
|
||||||
|
id:"runtime-state",
|
||||||
|
payload:{
|
||||||
|
type:"warning",
|
||||||
|
error:"git_merge_conflict",
|
||||||
|
project:self.name,
|
||||||
|
text:"notification.warnings.git_merge_conflict"
|
||||||
|
},
|
||||||
|
retain:true}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.merging = false;
|
||||||
}
|
}
|
||||||
self.branches.local = result.branches.local;
|
self.branches.local = result.branches.local;
|
||||||
self.branches.remote = result.branches.remote;
|
self.branches.remote = result.branches.remote;
|
||||||
@ -534,6 +558,11 @@ Project.prototype.pull = function (user,remoteBranchName,setRemote,allowUnrelate
|
|||||||
Project.prototype.resolveMerge = function (file,resolutions) {
|
Project.prototype.resolveMerge = function (file,resolutions) {
|
||||||
var filePath = fspath.join(this.path,file);
|
var filePath = fspath.join(this.path,file);
|
||||||
var self = this;
|
var self = this;
|
||||||
|
if (typeof resolutions === 'string') {
|
||||||
|
return util.writeFile(filePath, resolutions).then(function() {
|
||||||
|
return self.stageFile(file);
|
||||||
|
})
|
||||||
|
}
|
||||||
return fs.readFile(filePath,"utf8").then(function(content) {
|
return fs.readFile(filePath,"utf8").then(function(content) {
|
||||||
var lines = content.split("\n");
|
var lines = content.split("\n");
|
||||||
var result = [];
|
var result = [];
|
||||||
@ -573,7 +602,10 @@ Project.prototype.resolveMerge = function (file,resolutions) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Project.prototype.abortMerge = function () {
|
Project.prototype.abortMerge = function () {
|
||||||
return gitTools.abortMerge(this.path);
|
var self = this;
|
||||||
|
return gitTools.abortMerge(this.path).then(function() {
|
||||||
|
self.merging = false;
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
Project.prototype.getBranches = function (user, isRemote) {
|
Project.prototype.getBranches = function (user, isRemote) {
|
||||||
|
@ -454,18 +454,19 @@ module.exports = {
|
|||||||
} else {
|
} else {
|
||||||
promise = runGitCommand(args,cwd)
|
promise = runGitCommand(args,cwd)
|
||||||
}
|
}
|
||||||
return promise.catch(function(err) {
|
return promise;
|
||||||
if (/CONFLICT/.test(err.stdout)) {
|
// .catch(function(err) {
|
||||||
var e = new Error("NLS: pull failed - merge conflict");
|
// if (/CONFLICT/.test(err.stdout)) {
|
||||||
e.code = "git_pull_merge_conflict";
|
// var e = new Error("pull failed - merge conflict");
|
||||||
throw e;
|
// e.code = "git_pull_merge_conflict";
|
||||||
} else if (/Please commit your changes or stash/i.test(err.message)) {
|
// throw e;
|
||||||
var e = new Error("NLS: Pull failed - local changes would be overwritten");
|
// } else if (/Please commit your changes or stash/i.test(err.message)) {
|
||||||
e.code = "git_pull_overwrite";
|
// var e = new Error("Pull failed - local changes would be overwritten");
|
||||||
throw e;
|
// e.code = "git_pull_overwrite";
|
||||||
}
|
// throw e;
|
||||||
throw err;
|
// }
|
||||||
});
|
// throw err;
|
||||||
|
// });
|
||||||
},
|
},
|
||||||
push: function(cwd,remote,branch,setUpstream, auth) {
|
push: function(cwd,remote,branch,setUpstream, auth) {
|
||||||
var args = ["push"];
|
var args = ["push"];
|
||||||
|
@ -212,7 +212,13 @@ function unstageFile(user, project,file) {
|
|||||||
}
|
}
|
||||||
function commit(user, project,options) {
|
function commit(user, project,options) {
|
||||||
checkActiveProject(project);
|
checkActiveProject(project);
|
||||||
return activeProject.commit(user, options);
|
var isMerging = activeProject.isMerging();
|
||||||
|
return activeProject.commit(user, options).then(function() {
|
||||||
|
// The project was merging, now it isn't. Lets reload.
|
||||||
|
if (isMerging && !activeProject.isMerging()) {
|
||||||
|
return reloadActiveProject("merge-complete");
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
function getFileDiff(user, project,file,type) {
|
function getFileDiff(user, project,file,type) {
|
||||||
checkActiveProject(project);
|
checkActiveProject(project);
|
||||||
@ -258,7 +264,7 @@ function resolveMerge(user, project,file,resolution) {
|
|||||||
function abortMerge(user, project) {
|
function abortMerge(user, project) {
|
||||||
checkActiveProject(project);
|
checkActiveProject(project);
|
||||||
return activeProject.abortMerge().then(function() {
|
return activeProject.abortMerge().then(function() {
|
||||||
return reloadActiveProject("abort-merge")
|
return reloadActiveProject("merge-abort")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getBranches(user, project,isRemote) {
|
function getBranches(user, project,isRemote) {
|
||||||
@ -478,6 +484,13 @@ function getFlows() {
|
|||||||
error.code = "missing_flow_file";
|
error.code = "missing_flow_file";
|
||||||
return when.reject(error);
|
return when.reject(error);
|
||||||
}
|
}
|
||||||
|
if (activeProject.isMerging()) {
|
||||||
|
log.warn("Project has unmerged changes");
|
||||||
|
error = new Error("Project has unmerged changes. Cannot load flows");
|
||||||
|
error.code = "git_merge_conflict";
|
||||||
|
return when.reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return util.readFile(flowsFullPath,flowsFileBackup,[],'flow');
|
return util.readFile(flowsFullPath,flowsFileBackup,[],'flow');
|
||||||
}
|
}
|
||||||
@ -486,6 +499,11 @@ function saveFlows(flows) {
|
|||||||
if (settings.readOnly) {
|
if (settings.readOnly) {
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
}
|
}
|
||||||
|
if (activeProject && activeProject.isMerging()) {
|
||||||
|
var error = new Error("Project has unmerged changes. Cannot deploy new flows");
|
||||||
|
error.code = "git_merge_conflict";
|
||||||
|
return when.reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.renameSync(flowsFullPath,flowsFileBackup);
|
fs.renameSync(flowsFullPath,flowsFileBackup);
|
||||||
|
Loading…
Reference in New Issue
Block a user