Skip to content

Commit 5679509

Browse files
committed
tmp
1 parent 7f3e4cc commit 5679509

File tree

5 files changed

+153
-145
lines changed

5 files changed

+153
-145
lines changed

jupyterlab_git/git.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,16 +792,27 @@ async def checkout_all(self, top_repo_path):
792792
return {"code": code, "command": " ".join(cmd), "message": error}
793793
return {"code": code}
794794

795+
async def reset_author(self, top_repo_path):
796+
"""
797+
Reset committer identity in previous commit
798+
"""
799+
cmd = ["git", "commit", "--amend", "--reset-author", "--no-edit"]
800+
code, _, error = await execute(cmd, cwd=top_repo_path)
801+
802+
if code != 0:
803+
return {"code": code, "command": " ".join(cmd), "message": error}
804+
return {"code": code}
805+
795806
async def commit(self, commit_msg, top_repo_path):
796807
"""
797808
Execute git commit <filename> command & return the result.
798809
"""
799810
cmd = ["git", "commit", "-m", commit_msg]
800-
code, _, error = await execute(cmd, cwd=top_repo_path)
811+
code, output, error = await execute(cmd, cwd=top_repo_path)
801812

802813
if code != 0:
803814
return {"code": code, "command": " ".join(cmd), "message": error}
804-
return {"code": code}
815+
return {"code": code, "output": output}
805816

806817
async def pull(self, curr_fb_path, auth=None, cancel_on_conflict=False):
807818
"""

jupyterlab_git/handlers.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,22 @@ async def post(self):
375375
self.finish(json.dumps(body))
376376

377377

378+
class GitResetAuthorHandler(GitHandler):
379+
"""
380+
Handler for 'git commit --amend --reset-author --no-edit'.
381+
"""
382+
383+
@web.authenticated
384+
async def post(self):
385+
data = self.get_json_body()
386+
top_repo_path = data["top_repo_path"]
387+
body = await self.git.reset_author(top_repo_path)
388+
389+
if body["code"] != 0:
390+
self.set_status(500)
391+
self.finish(json.dumps(body))
392+
393+
378394
class GitCommitHandler(GitHandler):
379395
"""
380396
Handler for 'git commit -m <message>'. Commits files.
@@ -711,6 +727,7 @@ def setup_handlers(web_app):
711727
("/git/changed_files", GitChangedFilesHandler),
712728
("/git/checkout", GitCheckoutHandler),
713729
("/git/clone", GitCloneHandler),
730+
("/git/reset_author", GitResetAuthorHandler),
714731
("/git/commit", GitCommitHandler),
715732
("/git/config", GitConfigHandler),
716733
("/git/delete_commit", GitDeleteCommitHandler),

src/components/GitPanel.tsx

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { PathExt } from '@jupyterlab/coreutils';
66
import { FileBrowserModel } from '@jupyterlab/filebrowser';
77
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
88
import { ISettingRegistry } from '@jupyterlab/settingregistry';
9-
import { JSONObject } from '@lumino/coreutils';
109
import { GitExtension } from '../model';
1110
import { sleep } from '../utils';
1211
import { Git, ILogMessage } from '../tokens';
@@ -28,6 +27,9 @@ import { SuspendModal } from './SuspendModal';
2827
import { Alert } from './Alert';
2928
import { CommandIDs } from '../commandsAndMenu';
3029

30+
const MISSING_IDENTITY =
31+
'Your name and email address were configured automatically';
32+
3133
/**
3234
* Interface describing component properties.
3335
*/
@@ -227,35 +229,20 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
227229
* @returns a promise which commits the files
228230
*/
229231
commitStagedFiles = async (message: string): Promise<void> => {
230-
let res: boolean;
232+
let res: Response;
231233
if (!message) {
232234
return;
233235
}
234-
try {
235-
res = await this._hasIdentity(this.props.model.pathRepository);
236-
} catch (err) {
237-
this._log({
238-
severity: 'error',
239-
message: 'Failed to commit changes.'
240-
});
241-
console.error(err);
242-
showErrorMessage('Fail to commit', err);
243-
return;
244-
}
245-
if (!res) {
246-
this._log({
247-
severity: 'error',
248-
message: 'Failed to commit changes.'
249-
});
250-
return;
251-
}
252236
this._log({
253237
severity: 'info',
254238
message: 'Committing changes...'
255239
});
256240
this._suspend(true);
257241
try {
258-
await Promise.all([sleep(1000), this.props.model.commit(message)]);
242+
[, res] = await Promise.all<any, Response>([
243+
sleep(1000),
244+
this.props.model.commit(message)
245+
]);
259246
} catch (err) {
260247
this._suspend(false);
261248
this._log({
@@ -271,6 +258,10 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
271258
severity: 'success',
272259
message: 'Committed changes.'
273260
});
261+
const { output } = await res.json();
262+
if (output.indexOf(MISSING_IDENTITY) !== -1) {
263+
await this._setIdentity(this.props.model.pathRepository);
264+
}
274265
};
275266

276267
/**
@@ -570,37 +561,36 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
570561
* @param path - repository path
571562
* @returns a promise which returns a success status
572563
*/
573-
private async _hasIdentity(path: string): Promise<boolean> {
564+
private async _setIdentity(path: string): Promise<boolean> {
574565
// If the repository path changes, check the user identity
575566
if (path !== this._previousRepoPath) {
576567
try {
577-
let res = await this.props.model.config();
578-
if (res.ok) {
579-
const options: JSONObject = (await res.json()).options;
580-
const keys = Object.keys(options);
581-
582-
// If the user name or e-mail is unknown, ask the user to set it
583-
if (keys.indexOf('user.name') < 0 || keys.indexOf('user.email') < 0) {
584-
const result = await showDialog({
585-
title: 'Who is committing?',
586-
body: new GitAuthorForm()
587-
});
588-
if (!result.button.accept) {
589-
console.log('User refuses to set identity.');
590-
return false;
591-
}
592-
const identity = result.value;
593-
res = await this.props.model.config({
594-
'user.name': identity.name,
595-
'user.email': identity.email
596-
});
597-
if (!res.ok) {
598-
console.log(await res.text());
599-
return false;
600-
}
601-
}
602-
this._previousRepoPath = path;
568+
const result = await showDialog({
569+
title: 'Who is committing?',
570+
body: new GitAuthorForm()
571+
});
572+
if (!result.button.accept) {
573+
console.log('User refuses to set identity.');
574+
return false;
575+
}
576+
const identity = result.value;
577+
let res = await this.props.model.config({
578+
'user.name': identity.name,
579+
'user.email': identity.email
580+
});
581+
if (!res.ok) {
582+
console.log(await res.text());
583+
return false;
584+
}
585+
this._suspend(true);
586+
res = await this.props.model.resetAuthor();
587+
if (!res.ok) {
588+
this._suspend(false);
589+
console.log(await res.text());
590+
return false;
603591
}
592+
this._suspend(false);
593+
this._previousRepoPath = path;
604594
} catch (error) {
605595
throw new Error('Failed to set your identity. ' + error.message);
606596
}

src/model.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,40 @@ export class GitExtension implements IGitExtension {
529529
return data;
530530
}
531531

532+
async resetAuthor(): Promise<Response> {
533+
await this.ready;
534+
const path = this.pathRepository;
535+
536+
if (path === null) {
537+
return Promise.resolve(
538+
new Response(
539+
JSON.stringify({
540+
code: -1,
541+
message: 'Not in a git repository.'
542+
})
543+
)
544+
);
545+
}
546+
547+
try {
548+
const response = await httpGitRequest('/git/reset_author', 'POST', {
549+
top_repo_path: path
550+
});
551+
if (!response.ok) {
552+
return response.json().then((data: any) => {
553+
throw new ServerConnection.ResponseError(response, data.message);
554+
});
555+
}
556+
557+
this.refreshStatus();
558+
this._headChanged.emit();
559+
560+
return response;
561+
} catch (err) {
562+
throw new ServerConnection.NetworkError(err);
563+
}
564+
}
565+
532566
/**
533567
* Commit all staged file changes.
534568
*

0 commit comments

Comments
 (0)