From 6cac14328fcd23e893b17c9d9f5fd4dc0c9cde21 Mon Sep 17 00:00:00 2001 From: Sjur Bakka Date: Tue, 30 Jul 2024 14:29:21 +0200 Subject: [PATCH 1/3] Support label, reset and merge --- lib/rebase-file.js | 4 ++-- lib/reducer.js | 12 ++++++++---- test/rebase-file.spec.js | 18 ++++++++++++++++++ test/reducer.spec.js | 35 +++++++++++++++++++---------------- 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/lib/rebase-file.js b/lib/rebase-file.js index d46312d..b5aeda1 100644 --- a/lib/rebase-file.js +++ b/lib/rebase-file.js @@ -39,7 +39,7 @@ function editorCommands(keyBindings) { function toState(data) { let readingCommits = true; const lines = data.split('\n'); - if (!lines[0].match(/^(noop|(# )?(pick|break|update-ref))/)) { + if (!lines[0].match(/^(noop|pick|break|update-ref|label|# pick)/)) { throw 'Not a proper rebase file: \n' + lines.slice(0, 5).join('\n') + '\n ...'; } return lines @@ -47,7 +47,7 @@ function toState(data) { line = line.trim(); if (line.length > 0) { let parts = line.split(' '); - if (parts[0] === '#' && parts[1] !== 'pick') { + if (parts[0] === '#' && parts[1] !== 'pick' && parts[1] !== 'Branch:') { state.info.push(line); } else { if (parts[0] === '#') { diff --git a/lib/reducer.js b/lib/reducer.js index 34aa60c..7983c07 100644 --- a/lib/reducer.js +++ b/lib/reducer.js @@ -84,7 +84,7 @@ function getAction(state, action) { const [from, to] = getSelection(state); return { lines: state.lines.map((line, idx) => { - if (from <= idx && idx <= to && line.hash && line.action !== 'update-ref') { + if (from <= idx && idx <= to && isEditable(line.action)) { line = set(line, { action: action }); @@ -148,6 +148,11 @@ function getLineAction(state, pos = state.cursor.pos) { return state.lines[pos]?.action } +function isEditable(action) { + const nonEditableActions = ['break', 'update-ref', 'label', 'reset', 'merge'] + return !action.startsWith('#') && !nonEditableActions.includes(action) +} + module.exports = function reducer(state, action, param) { const pos = state.cursor.pos; const from = state.cursor.from; @@ -204,9 +209,8 @@ module.exports = function reducer(state, action, param) { if (state.lines.slice(from, to + 1).some((line) => line.action !== action && line.hash)) { newState = getAction(state, action); } - const lineTypesToBeRemovedOnDrop = ['break', 'update-ref'] - if (action === 'drop' && state.lines.slice(from, to + 1).some(line=>lineTypesToBeRemovedOnDrop.includes(line.action))) { - const newLines = newState.lines.filter((line, idx)=> idx < from || idx > to || !lineTypesToBeRemovedOnDrop.includes(line.action)); + if (action === 'drop' && state.lines.slice(from, to + 1).some(line=>!isEditable(line.action))) { + const newLines = newState.lines.filter((line, idx)=> idx < from || idx > to || isEditable(line.action)); const removedLines = newState.lines.length - newLines.length; newState = { lines: newLines, diff --git a/test/rebase-file.spec.js b/test/rebase-file.spec.js index 0bbae78..31b3b9c 100644 --- a/test/rebase-file.spec.js +++ b/test/rebase-file.spec.js @@ -61,6 +61,24 @@ describe('Rebase file', function () { expect(state.lines[0].action).to.equal('# pick'); }); + it('should parse --rebase-merges', function () { + const file = trim(` + label onto + # Branch: merge + reset onto + pick 345 Last + label branch + pick 123 First + label merge + reset branch + merge -C 234 merge # Merge branch 'merge' into first + + # Info here`); + const state = rebaseFile.toState(file); + expect(rebaseFile.toFile(state)).to.equal(file); + }); + + it('should print key bindings as help', function () { const state = rebaseFile.toState('pick ad3d434 Hello message'); expect(state.extraInfo(keyBindings())).to.deep.equal([ diff --git a/test/reducer.spec.js b/test/reducer.spec.js index 9db6664..1191d92 100644 --- a/test/reducer.spec.js +++ b/test/reducer.spec.js @@ -333,23 +333,26 @@ describe('Reducer', function () { expect(newState).to.equal(state); }); - it('should do nothing if update-ref line', function () { - const state = getState([{ - action: 'update-ref', - hash: 'refs/heads/my-branch' - }], 0); - const newState = reduce(state, 'pick'); - expect(newState.lines[0]).to.equal(state.lines[0]); - }); + ['break', 'update-ref', 'label', 'reset', 'merge', '# Comment'].forEach(function (action) { + it(`should not allow pick if ${action} line`, function () { + const state = getState([{ + action: action, + hash: 'some text' + }], 0); + const newState = reduce(state, 'pick'); + expect(newState.lines[0]).to.equal(state.lines[0]); + }); + + it(`should delete ${action} line`, function () { + const state = getState([{ + action: action, + hash: 'some text' + }], 0); + const newState = reduce(state, 'drop'); + expect(newState.lines).to.be.empty; + }); + }) - it('should delete update-ref line', function () { - const state = getState([{ - action: 'update-ref', - hash: 'refs/heads/my-branch' - }], 0); - const newState = reduce(state, 'drop'); - expect(newState.lines).to.be.empty; - }); it('should change on fixup', function () { const state = getState(3, 1); From aec1d7a7edf75b2f361e8d3f6523cf4d72c09a94 Mon Sep 17 00:00:00 2001 From: Sjur Bakka Date: Tue, 30 Jul 2024 14:38:25 +0200 Subject: [PATCH 2/3] Fix info texts --- lib/rebase-file.js | 7 +++++-- test/rebase-file.spec.js | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/rebase-file.js b/lib/rebase-file.js index b5aeda1..fd2944d 100644 --- a/lib/rebase-file.js +++ b/lib/rebase-file.js @@ -16,12 +16,15 @@ const actionDescriptions = { 'undo': 'Undo', 'redo': 'Redo', 'quit': 'Save and quit', - 'abort': 'Abort' + 'abort': 'Abort', + 'fixup -c': 'fixup -c', + 'fixup -C': 'fixup -C' }; function editorCommands(keyBindings) { let extraInfo = [ - '# NOTE: x, l, t, m is not supported by rebase editor', + '# NOTE: execute (x) is not supported by rebase editor', + '# You cannot add update-ref (u), label (l), reset (t) or merge (m), but you can move them around', '#', '# Rebase Editor Commands:', ]; diff --git a/test/rebase-file.spec.js b/test/rebase-file.spec.js index 31b3b9c..866b5ad 100644 --- a/test/rebase-file.spec.js +++ b/test/rebase-file.spec.js @@ -82,7 +82,8 @@ describe('Rebase file', function () { it('should print key bindings as help', function () { const state = rebaseFile.toState('pick ad3d434 Hello message'); expect(state.extraInfo(keyBindings())).to.deep.equal([ - '# NOTE: x, l, t, m is not supported by rebase editor', + '# NOTE: execute (x) is not supported by rebase editor', + '# You cannot add update-ref (u), label (l), reset (t) or merge (m), but you can move them around', '#', '# Rebase Editor Commands:', '# UP = Moves cursor up', @@ -95,6 +96,8 @@ describe('Rebase file', function () { '# Z, CTRL_SHIFT_Z = Redo', '# q, ENTER = Save and quit', '# CTRL_C, ESCAPE = Abort', + "# ALT_F = fixup -c", + "# CTRL_F = fixup -C", '# HOME, END, PAGE_UP, PAGE_DOWN = Moves cursor and selects with SHIFT' ]); }); From d8e6ed6add1e396d40e658c7f9fbdcb271d34187 Mon Sep 17 00:00:00 2001 From: Sjur Bakka Date: Tue, 30 Jul 2024 14:39:12 +0200 Subject: [PATCH 3/3] Fix warning --- lib/rebase-file.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/rebase-file.js b/lib/rebase-file.js index fd2944d..d22cbe9 100644 --- a/lib/rebase-file.js +++ b/lib/rebase-file.js @@ -40,7 +40,6 @@ function editorCommands(keyBindings) { } function toState(data) { - let readingCommits = true; const lines = data.split('\n'); if (!lines[0].match(/^(noop|pick|break|update-ref|label|# pick)/)) { throw 'Not a proper rebase file: \n' + lines.slice(0, 5).join('\n') + '\n ...';