Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 406
Run git commands in dedicated renderer process#688
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
c07d65b53384de519ebfcc9b2978f91e8cd8fe00d5e9aa22d169ab2072b5ccc761ff7d54c165309fdc01197b332364b086ed4c5edca3411cbc7ae773bda0a92228185325f48b2bd9e37684ca4a6494404e7074b75d2fef39b3a2880187c4bde1918bb86ad9566a1a08ff425c4bcd27228bfa4ae4557f46097714dce2bcc38e211a1e43c2716505e0423026e27b29cc7045c009103816129c36bbcd71d6877fdc0d0bb8e57d11877e80956e294e0b8b53bf5045db1010920b4ca91908e5d868091c9911575743cb3dca043efc16dd5a0df97c652459d7e7d4ceaa09a96863209dbc3073c55f98826502cbfc3b875eb7f4b205e34e0e6359895c39aaf695fb7317a954465d309d130662704084aec87270177bab3da1740e9bc3b4b23e708668File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2,14 +2,14 @@ import path from 'path'; | ||
| import os from 'os'; | ||
| import {CompositeDisposable} from 'event-kit'; | ||
| import {GitProcess} from 'dugite'; | ||
| import {parse as parseDiff} from 'what-the-diff'; | ||
| import GitPromptServer from './git-prompt-server'; | ||
| import AsyncQueue from './async-queue'; | ||
| import {getPackageRoot, getDugitePath, readFile, fileExists, writeFile, isFileExecutable} from './helpers'; | ||
| import {getPackageRoot, getDugitePath, readFile, fileExists, fsStat, writeFile, isFileExecutable} from './helpers'; | ||
| import GitTimingsView from './views/git-timings-view'; | ||
| import WorkerManager from './worker-manager'; | ||
| const LINE_ENDING_REGEX = /\r?\n/; | ||
| @@ -57,6 +57,7 @@ export default class GitShellOutStrategy { | ||
| } | ||
| this.prompt = options.prompt || (query => Promise.reject()); | ||
| this.workerManager = options.workerManager; | ||
| } | ||
| /* | ||
| @@ -131,6 +132,7 @@ export default class GitShellOutStrategy { | ||
| const options = { | ||
| env, | ||
| processCallback: child => { | ||
| // TODO: move callback to renderer process. send child.pid back to add cancel listener | ||
| child.on('error', err => { | ||
| console.warn('Error executing: ' + formattedArgs + ':'); | ||
| console.warn(err.stack); | ||
| @@ -156,51 +158,68 @@ export default class GitShellOutStrategy { | ||
| if (process.env.PRINT_GIT_TIMES) { | ||
| console.time(`git:${formattedArgs}`); | ||
| } | ||
| return new Promise(resolve => { | ||
| timingMarker.mark('nexttick'); | ||
| setImmediate(() => { | ||
| timingMarker.mark('execute'); | ||
| resolve(GitProcess.exec(args, this.workingDir, options) | ||
| .then(({stdout, stderr, exitCode}) => { | ||
| timingMarker.finalize(); | ||
| if (process.env.PRINT_GIT_TIMES) { | ||
| console.timeEnd(`git:${formattedArgs}`); | ||
| } | ||
| if (gitPromptServer) { | ||
| gitPromptServer.terminate(); | ||
| } | ||
| subscriptions.dispose(); | ||
| if (diagnosticsEnabled) { | ||
| const headerStyle = 'font-weight: bold; color: blue;'; | ||
| console.groupCollapsed(`git:${formattedArgs}`); | ||
| console.log('%cexit status%c %d', headerStyle, 'font-weight: normal; color: black;', exitCode); | ||
| console.log('%cstdout', headerStyle); | ||
| console.log(stdout); | ||
| console.log('%cstderr', headerStyle); | ||
| console.log(stderr); | ||
| console.groupEnd(); | ||
| } | ||
| if (exitCode) { | ||
| const err = new GitError( | ||
| `${formattedArgs} exited with code ${exitCode}\nstdout: ${stdout}\nstderr: ${stderr}`, | ||
| ); | ||
| err.code = exitCode; | ||
| err.stdErr = stderr; | ||
| err.stdOut = stdout; | ||
| err.command = formattedArgs; | ||
| return Promise.reject(err); | ||
| } | ||
| return stdout; | ||
| })); | ||
| }); | ||
| return new Promise(async (resolve, reject) => { | ||
| const {stdout, stderr, exitCode, timing} = await this.executeGitCommand(args, options, timingMarker); | ||
| if (timing) { | ||
| const {execTime, spawnTime, ipcTime} = timing; | ||
| const now = performance.now(); | ||
| timingMarker.mark('nexttick', now - execTime - spawnTime - ipcTime); | ||
| timingMarker.mark('execute', now - execTime - ipcTime); | ||
| timingMarker.mark('ipc', now - ipcTime); | ||
| } | ||
| timingMarker.finalize(); | ||
| if (process.env.PRINT_GIT_TIMES) { | ||
| console.timeEnd(`git:${formattedArgs}`); | ||
| } | ||
| if (gitPromptServer) { | ||
| gitPromptServer.terminate(); | ||
| } | ||
| subscriptions.dispose(); | ||
| if (diagnosticsEnabled) { | ||
| const headerStyle = 'font-weight: bold; color: blue;'; | ||
| console.groupCollapsed(`git:${formattedArgs}`); | ||
| console.log('%cexit status%c %d', headerStyle, 'font-weight: normal; color: black;', exitCode); | ||
| console.log('%cstdout', headerStyle); | ||
| console.log(stdout); | ||
| console.log('%cstderr', headerStyle); | ||
| console.log(stderr); | ||
| console.groupEnd(); | ||
| } | ||
| if (exitCode) { | ||
| const err = new GitError( | ||
| `${formattedArgs} exited with code ${exitCode}\nstdout: ${stdout}\nstderr: ${stderr}`, | ||
| ); | ||
| err.code = exitCode; | ||
| err.stdErr = stderr; | ||
| err.stdOut = stdout; | ||
| err.command = formattedArgs; | ||
| reject(err); | ||
| } | ||
| resolve(stdout); | ||
| }); | ||
| }, {parallel: !writeOperation}); | ||
| /* eslint-enable no-console */ | ||
| } | ||
| executeGitCommand(args, options, marker = null) { | ||
| if (process.env.ATOM_GITHUB_INLINE_GIT_EXEC || !WorkerManager.getInstance().isReady()) { | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 for offering an env var to opt out of the workers for when someone runs this on their Raspberry Pi 😉 If I'm reading it right it'll prevent the first worker from spawning too? ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yup 👍 . Second expression after | ||
| marker && marker.mark('nexttick'); | ||
| const promise = GitProcess.exec(args, this.workingDir, options); | ||
| marker && marker.mark('execute'); | ||
| return promise; | ||
| } else { | ||
| const workerManager = this.workerManager || WorkerManager.getInstance(); | ||
| return workerManager.request({ | ||
| args, | ||
| workingDir: this.workingDir, | ||
| options, | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Execute a git command that may create a commit. If the command fails because the GPG binary was invoked and unable | ||
| * to acquire a passphrase (because the pinentry program attempted to use a tty), retry with a `GitPromptServer`. | ||
| @@ -220,6 +239,7 @@ export default class GitShellOutStrategy { | ||
| async isGitRepository() { | ||
| try { | ||
| await fsStat(this.workingDir); // fails if folder doesn't exist | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, cool. This fixes that uncaught-exception-in-Promise from the test suite I presume. | ||
| await this.exec(['rev-parse', '--resolve-git-dir', path.join(this.workingDir, '.git')]); | ||
| return true; | ||
| } catch (e) { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title></title> | ||
| <script type="text/javascript"> | ||
| const qs = require('querystring') | ||
| const jsPath = qs.parse(window.location.search.substr(1)).js | ||
| require(jsPath) | ||
| </script> | ||
| </head> | ||
| <body> | ||
| <h1>GitHub Package Git Execution Window</h1> | ||
| <p> | ||
| Hi there! I'm a window used by the GitHub package to execute Git commands in the background. My PID is <script>document.write(process.pid)</script>. | ||
| </p> | ||
| <p>Last command: <span id='command'></span></p> | ||
| </body> | ||
| </html> |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The day I discovered how
%cworks inconsole.log()was a dangerous day.