Skip to content

Commit

Permalink
Merge pull request #41 from sjurba/rebase-merges
Browse files Browse the repository at this point in the history
Rebase merges
  • Loading branch information
sjurba authored Jul 30, 2024
2 parents 8f6856a + d8e6ed6 commit afde5c6
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 26 deletions.
12 changes: 7 additions & 5 deletions lib/rebase-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -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:',
];
Expand All @@ -37,17 +40,16 @@ 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
.reduce((state, line) => {
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] === '#') {
Expand Down
12 changes: 8 additions & 4 deletions lib/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
23 changes: 22 additions & 1 deletion test/rebase-file.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,29 @@ 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([
'# 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',
Expand All @@ -77,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'
]);
});
Expand Down
35 changes: 19 additions & 16 deletions test/reducer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit afde5c6

Please sign in to comment.