Skip to content

Commit

Permalink
Merge pull request #887 from ktaletsk/commit-and-push
Browse files Browse the repository at this point in the history
Allow `commit & push`
  • Loading branch information
fcollonval authored Apr 3, 2021
2 parents df81263 + 4444de0 commit 6b95bc9
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 40 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Once installed, extension behavior can be modified via the following settings wh

- **blockWhileCommandExecutes**: suspend JupyterLab user interaction until Git commands (e.g., `commit`, `pull`, `reset`, `revert`) finish executing. Setting this to `true` helps mitigate potential race conditions leading to data loss, conflicts, and a broken Git history. Unless running a slow network, UI suspension should not interfere with standard workflows. Setting this to `false` allows for actions to trigger multiple concurrent Git actions.
- **cancelPullMergeConflict**: cancel pulling changes from a remote repository if there exists a merge conflict. If set to `true`, when fetching and integrating changes from a remote repository, a conflicting merge is canceled and the working tree left untouched.
- **commitAndPush**: Whether to trigger or not a push for each commit; default is `true`.
- **disableBranchWithChanges**: disable all branch operations, such as creating a new branch or switching to a different branch, when there are changed/staged files. When set to `true`, this setting guards against overwriting and/or losing uncommitted changes.
- **displayStatus**: display Git extension status updates in the JupyterLab status bar. If `true`, the extension displays status updates in the JupyterLab status bar, such as when pulling and pushing changes, switching branches, and polling for changes. Depending on the level of extension activity, some users may find the status updates distracting. In which case, setting this to `false` should reduce visual noise.
- **doubleClickDiff**: double click a file in the Git extension panel to open a diff of the file instead of opening the file for editing.
Expand Down
6 changes: 6 additions & 0 deletions schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
"title": "Simple staging flag",
"description": "If true, use a simplified concept of staging. Only files with changes are shown (instead of showing staged/changed/untracked), and all files with changes will be automatically staged",
"default": false
},
"commitAndPush": {
"type": "boolean",
"title": "Trigger push on commit",
"description": "Whether to trigger or not a push for each commit.",
"default": true
}
},
"jupyter.lab.shortcuts": [
Expand Down
21 changes: 14 additions & 7 deletions src/components/CommitBox.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { TranslationBundle } from '@jupyterlab/translation';
import { CommandRegistry } from '@lumino/commands';
import * as React from 'react';
import TextareaAutosize from 'react-textarea-autosize';
import {
commitFormClass,
commitSummaryClass,
commitButtonClass,
commitDescriptionClass,
commitButtonClass
commitFormClass,
commitSummaryClass
} from '../style/CommitBox';
import { TranslationBundle } from '@jupyterlab/translation';
import { CommandRegistry } from '@lumino/commands';
import { CommandIDs } from '../tokens';

/**
Expand All @@ -23,10 +23,17 @@ export interface ICommitBoxProps {
* Boolean indicating whether files currently exist which have changes to commit.
*/
hasFiles: boolean;

/**
* Commit button label
*/
label: string;

/**
* The application language translator.
*/
trans: TranslationBundle;

/**
* Callback to invoke in order to commit changes.
*
Expand Down Expand Up @@ -91,7 +98,7 @@ export class CommitBox extends React.Component<
? this.props.trans.__('Disabled: No files are staged for commit')
: !this.state.summary
? this.props.trans.__('Disabled: No commit message summary')
: this.props.trans.__('Commit');
: this.props.label;

const shortcutHint = CommandRegistry.formatKeystroke(
this._getSubmitKeystroke()
Expand Down Expand Up @@ -125,7 +132,7 @@ export class CommitBox extends React.Component<
className={commitButtonClass}
type="button"
title={title}
value={this.props.trans.__('Commit')}
value={this.props.label}
disabled={disabled}
onClick={this._onCommitSubmit}
/>
Expand Down
23 changes: 20 additions & 3 deletions src/components/GitPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { showDialog } from '@jupyterlab/apputils';
import { PathExt } from '@jupyterlab/coreutils';
import { FileBrowserModel } from '@jupyterlab/filebrowser';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { TranslationBundle } from '@jupyterlab/translation';
import { CommandRegistry } from '@lumino/commands';
import { JSONObject } from '@lumino/coreutils';
import { Signal } from '@lumino/signaling';
import Tab from '@material-ui/core/Tab';
import Tabs from '@material-ui/core/Tabs';
import { TranslationBundle } from '@jupyterlab/translation';
import * as React from 'react';
import { Logger } from '../logger';
import { GitExtension } from '../model';
Expand Down Expand Up @@ -260,6 +260,13 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
console.error(error);
this.props.logger.log({ ...errorLog, error });
}
const hasRemote = this.props.model.branches.some(
branch => branch.is_remote_branch
);
// If enabled commit and push, push here
if (this.props.settings.composite['commitAndPush'] && hasRemote) {
await this.props.commands.execute(CommandIDs.gitPush);
}
};

/**
Expand Down Expand Up @@ -367,6 +374,14 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
* @returns React element
*/
private _renderChanges(): React.ReactElement {
const hasRemote = this.props.model.branches.some(
branch => branch.is_remote_branch
);
const commitAndPush =
(this.props.settings.composite['commitAndPush'] as boolean) && hasRemote;
const buttonLabel = commitAndPush
? this.props.trans.__('Commit and Push')
: this.props.trans.__('Commit');
return (
<React.Fragment>
<FileList
Expand All @@ -378,17 +393,19 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
/>
{this.props.settings.composite['simpleStaging'] ? (
<CommitBox
commands={this.props.commands}
hasFiles={this._markedFiles.length > 0}
trans={this.props.trans}
label={buttonLabel}
onCommit={this.commitMarkedFiles}
commands={this.props.commands}
/>
) : (
<CommitBox
commands={this.props.commands}
hasFiles={this._hasStagedFile()}
trans={this.props.trans}
label={buttonLabel}
onCommit={this.commitStagedFiles}
commands={this.props.commands}
/>
)}
</React.Fragment>
Expand Down
66 changes: 41 additions & 25 deletions tests/test-components/CommitBox.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import * as React from 'react';
import 'jest';
import { shallow } from 'enzyme';
import { CommitBox} from '../../src/components/CommitBox';
import { CommandRegistry } from '@lumino/commands';
import { nullTranslator } from '@jupyterlab/translation';
import { CommandRegistry } from '@lumino/commands';
import { shallow } from 'enzyme';
import 'jest';
import * as React from 'react';
import { CommitBox } from '../../src/components/CommitBox';
import { CommandIDs } from '../../src/tokens';

describe('CommitBox', () => {

const defaultCommands = new CommandRegistry()
const defaultCommands = new CommandRegistry();
defaultCommands.addKeyBinding({
keys: ['Accel Enter'],
command: CommandIDs.gitSubmitCommand,
selector: '.jp-git-CommitBox'
})
});

const trans = nullTranslator.load('jupyterlab-git');

Expand All @@ -23,7 +22,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
});
expect(box).toBeInstanceOf(CommitBox);
});
Expand All @@ -33,7 +33,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
});
expect(box.state.summary).toEqual('');
});
Expand All @@ -43,7 +44,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
});
expect(box.state.description).toEqual('');
});
Expand All @@ -55,37 +57,44 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('input[type="text"]').first();
expect(node.prop('placeholder')).toEqual('Summary (Ctrl+Enter to commit)');
expect(node.prop('placeholder')).toEqual(
'Summary (Ctrl+Enter to commit)'
);
});

it('should adjust placeholder text for the commit message summary when keybinding changes', () => {
const adjustedCommands = new CommandRegistry()
const adjustedCommands = new CommandRegistry();
adjustedCommands.addKeyBinding({
keys: ['Shift Enter'],
command: CommandIDs.gitSubmitCommand,
selector: '.jp-git-CommitBox'
})
});
const props = {
onCommit: async () => {},
hasFiles: false,
commands: adjustedCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('input[type="text"]').first();
expect(node.prop('placeholder')).toEqual('Summary (Shift+Enter to commit)');
expect(node.prop('placeholder')).toEqual(
'Summary (Shift+Enter to commit)'
);
});

it('should set a `title` attribute on the input element to provide a commit message summary', () => {
const props = {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('input[type="text"]').first();
Expand All @@ -97,7 +106,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('TextareaAutosize').first();
Expand All @@ -109,7 +119,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('TextareaAutosize').first();
Expand All @@ -121,7 +132,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('input[type="button"]').first();
Expand All @@ -133,7 +145,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('input[type="button"]').first();
Expand All @@ -145,7 +158,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: false,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('input[type="button"]').first();
Expand All @@ -158,7 +172,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: true,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
const node = component.find('input[type="button"]').first();
Expand All @@ -171,7 +186,8 @@ describe('CommitBox', () => {
onCommit: async () => {},
hasFiles: true,
commands: defaultCommands,
trans: trans
trans: trans,
label: 'Commit'
};
const component = shallow(<CommitBox {...props} />);
component.setState({
Expand Down
Loading

0 comments on commit 6b95bc9

Please sign in to comment.