Skip to content

Commit a78cac8

Browse files
authored
Merge pull request #448 from telamonian/simple_staging_refactored
Simplify the staging UI to make it easier for git beginners
2 parents 50952c9 + 6d1d70a commit a78cac8

20 files changed

+812
-207
lines changed

babel.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module.exports = {
2+
"sourceMap": "inline",
23
presets: [
34
[
45
'@babel/preset-env',

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var tsConfig = require ('./tsconfig.json');
33
var tsOptions = tsConfig["compilerOptions"];
44
// Need as the test folder is not visible from the src folder
55
tsOptions["rootDir"] = null;
6+
tsOptions["inlineSourceMap"] = true;
67

78
module.exports = {
89
automock: false,

jupyterlab_git/git.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ def branch(self, current_path):
377377
return remotes
378378

379379
# all's good; concatenate results and return
380-
return {"code": 0, "branches": heads["branches"] + remotes["branches"]}
380+
return {"code": 0, "branches": heads["branches"] + remotes["branches"], "current_branch": heads["current_branch"]}
381381

382382
def branch_heads(self, current_path):
383383
"""
@@ -393,37 +393,43 @@ def branch_heads(self, current_path):
393393
)
394394
output, error = p.communicate()
395395
if p.returncode == 0:
396-
current_branch_seen = False
396+
current_branch = None
397397
results = []
398398
try:
399399
for name,commit_sha,upstream_name,is_current_branch in (line.split('\t') for line in output.decode("utf-8").splitlines()):
400400
# Format reference : https://git-scm.com/docs/git-for-each-ref#_field_names
401401
is_current_branch = bool(is_current_branch.strip())
402-
current_branch_seen |= is_current_branch
403402

404-
results.append({
403+
branch = {
405404
"is_current_branch": is_current_branch,
406405
"is_remote_branch": False,
407406
"name": name,
408407
"upstream": upstream_name if upstream_name else None,
409408
"top_commit": commit_sha,
410409
"tag": None,
411-
})
410+
}
411+
results.append(branch)
412+
if is_current_branch:
413+
current_branch = branch
412414

413415
# Remote branch is seleted use 'git branch -a' as fallback machanism
414416
# to get add detached head on remote branch to preserve older functionality
415417
# TODO : Revisit this to checkout new local branch with same name as remote
416418
# when the remote branch is seleted, VS Code git does the same thing.
417-
if not current_branch_seen and self.get_current_branch(current_path) == "HEAD":
418-
results.append({
419+
if not current_branch and self.get_current_branch(current_path) == "HEAD":
420+
branch = {
419421
"is_current_branch": True,
420422
"is_remote_branch": False,
421423
"name": self._get_detached_head_name(current_path),
422424
"upstream": None,
423425
"top_commit": None,
424426
"tag": None,
425-
})
426-
return {"code": p.returncode, "branches": results}
427+
}
428+
results.append(branch)
429+
current_branch = branch
430+
431+
return {"code": p.returncode, "branches": results, "current_branch": current_branch}
432+
427433
except Exception as downstream_error:
428434
return {
429435
"code": -1,
@@ -529,6 +535,10 @@ def add(self, filename, top_repo_path):
529535
"""
530536
Execute git add<filename> command & return the result.
531537
"""
538+
if not isinstance(filename, str):
539+
# assume filename is a sequence
540+
filename = ' '.join(filename)
541+
532542
my_output = subprocess.check_output(["git", "add", filename], cwd=top_repo_path)
533543
return my_output
534544

@@ -584,8 +594,12 @@ def reset_to_commit(self, commit_id, top_repo_path):
584594
"""
585595
Reset the current branch to a specific past commit.
586596
"""
597+
cmd = ["git", "reset", "--hard"]
598+
if commit_id:
599+
cmd.append(commit_id)
600+
587601
my_output = subprocess.check_output(
588-
["git", "reset", "--hard", commit_id], cwd=top_repo_path
602+
cmd, cwd=top_repo_path
589603
)
590604
return my_output
591605

jupyterlab_git/tests/test_branch.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,15 @@ def test_branch_success(mock_subproc_popen):
710710
'top_commit': 'abcdefghijklmnopqrstuvwxyz01234567890123',
711711
'tag': None,
712712
}
713-
]
713+
],
714+
'current_branch': {
715+
'is_current_branch': True,
716+
'is_remote_branch': False,
717+
'name': 'feature-foo',
718+
'upstream': 'origin/feature-foo',
719+
'top_commit': 'abcdefghijklmnopqrstuvwxyz01234567890123',
720+
'tag': None,
721+
}
714722
}
715723

716724
# When
@@ -832,7 +840,15 @@ def test_branch_success_detached_head(mock_subproc_popen):
832840
'top_commit': 'abcdefghijklmnopqrstuvwxyz01234567890123',
833841
'tag': None,
834842
}
835-
]
843+
],
844+
'current_branch': {
845+
'is_current_branch': True,
846+
'is_remote_branch': False,
847+
'name': '(HEAD detached at origin/feature-foo)',
848+
'upstream': None,
849+
'top_commit': None,
850+
'tag': None,
851+
}
836852
}
837853

838854
# When

schema/plugin.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
"title": "History count",
1111
"description": "Number of (most recent) commits shown in the history log",
1212
"default": 25
13+
},
14+
"simpleStaging": {
15+
"type": "boolean",
16+
"title": "Simple staging flag",
17+
"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",
18+
"default": false
1319
}
1420
}
1521
}

src/components/CommitBox.tsx

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ import {
1010
} from '../style/BranchHeaderStyle';
1111

1212
export interface ICommitBoxProps {
13-
hasStagedFiles: boolean;
14-
commitAllStagedFiles: (message: string) => Promise<void>;
13+
hasFiles: boolean;
14+
commitFunc: (message: string) => Promise<void>;
1515
}
1616

1717
export interface ICommitBoxState {
1818
/**
1919
* Commit message
2020
*/
2121
value: string;
22-
disableSubmit: boolean;
2322
}
2423

2524
export class CommitBox extends React.Component<
@@ -29,8 +28,7 @@ export class CommitBox extends React.Component<
2928
constructor(props: ICommitBoxProps) {
3029
super(props);
3130
this.state = {
32-
value: '',
33-
disableSubmit: true
31+
value: ''
3432
};
3533
}
3634

@@ -45,28 +43,19 @@ export class CommitBox extends React.Component<
4543
/** Initalize commit message input box */
4644
initializeInput = (): void => {
4745
this.setState({
48-
value: '',
49-
disableSubmit: true
46+
value: ''
5047
});
5148
};
5249

5350
/** Handle input inside commit message box */
5451
handleChange = (event: any): void => {
55-
if (event.target.value && event.target.value !== '') {
56-
this.setState({
57-
value: event.target.value,
58-
disableSubmit: false
59-
});
60-
} else {
61-
this.setState({
62-
value: event.target.value,
63-
disableSubmit: true
64-
});
65-
}
52+
this.setState({
53+
value: event.target.value
54+
});
6655
};
6756

6857
/** Update state of commit message input box */
69-
checkReadyForSubmit = (hasStagedFiles: boolean) => {
58+
commitButtonStyle = (hasStagedFiles: boolean) => {
7059
if (hasStagedFiles) {
7160
if (this.state.value.length === 0) {
7261
return classes(stagedCommitButtonStyle, stagedCommitButtonReadyStyle);
@@ -86,22 +75,22 @@ export class CommitBox extends React.Component<
8675
>
8776
<textarea
8877
className={classes(textInputStyle, stagedCommitMessageStyle)}
89-
disabled={!this.props.hasStagedFiles}
78+
disabled={!this.props.hasFiles}
9079
placeholder={
91-
this.props.hasStagedFiles
80+
this.props.hasFiles
9281
? 'Input message to commit staged changes'
9382
: 'Stage your changes before commit'
9483
}
9584
value={this.state.value}
9685
onChange={this.handleChange}
9786
/>
9887
<input
99-
className={this.checkReadyForSubmit(this.props.hasStagedFiles)}
88+
className={this.commitButtonStyle(this.props.hasFiles)}
10089
type="button"
10190
title="Commit"
102-
disabled={this.state.disableSubmit}
91+
disabled={!(this.props.hasFiles && this.state.value)}
10392
onClick={() => {
104-
this.props.commitAllStagedFiles(this.state.value);
93+
this.props.commitFunc(this.state.value);
10594
this.initializeInput();
10695
}}
10796
/>

src/components/FileItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export class FileItem extends React.Component<IFileItemProps, {}> {
123123
}
124124
}
125125

126-
getFileLableIconClass() {
126+
getFileLabelIconClass() {
127127
if (this.showDiscardWarning()) {
128128
return classes(fileIconStyle, parseFileExtension(this.props.file.to));
129129
} else {
@@ -248,7 +248,7 @@ export class FileItem extends React.Component<IFileItemProps, {}> {
248248
this.props.moveFile(this.props.file.to);
249249
}}
250250
/>
251-
<span className={this.getFileLableIconClass()} />
251+
<span className={this.getFileLabelIconClass()} />
252252
<span
253253
className={this.getFileLabelClass()}
254254
onContextMenu={e => {

0 commit comments

Comments
 (0)