diff --git a/extensions/git/npm-shrinkwrap.json b/extensions/git/npm-shrinkwrap.json index d757c142e96..9239e6181fe 100644 --- a/extensions/git/npm-shrinkwrap.json +++ b/extensions/git/npm-shrinkwrap.json @@ -7,13 +7,18 @@ "from": "applicationinsights@0.18.0", "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz" }, + "byline": { + "version": "5.0.0", + "from": "byline@latest", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz" + }, "iconv-lite": { "version": "0.4.15", "from": "iconv-lite@0.4.15", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz" }, "vscode-extension-telemetry": { - "version": "0.0.7", + "version": "0.0.8", "from": "vscode-extension-telemetry@>=0.0.8 <0.0.9", "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz" }, diff --git a/extensions/git/package.json b/extensions/git/package.json index d4b341b4451..3175cc55c2a 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -806,6 +806,7 @@ } }, "dependencies": { + "byline": "^5.0.0", "iconv-lite": "0.4.15", "vscode-extension-telemetry": "0.0.8", "vscode-nls": "2.0.2" diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 58decf3724b..fc66825d924 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -10,6 +10,7 @@ import { Ref, RefType, Git, GitErrorCodes, Branch } from './git'; import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository'; import { Model } from './model'; import { toGitUri, fromGitUri } from './uri'; +import { grep } from './util'; import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange } from './staging'; import * as path from 'path'; import * as os from 'os'; @@ -486,12 +487,20 @@ export class CommandCenter { } const selection = resourceStates.filter(s => s instanceof Resource) as Resource[]; - const mergeConflicts = selection.filter(s => s.resourceGroupType === ResourceGroupType.Merge); + const merge = selection.filter(s => s.resourceGroupType === ResourceGroupType.Merge); + const bothModified = merge.filter(s => s.type === Status.BOTH_MODIFIED); + const promises = bothModified.map(s => grep(s.resourceUri.fsPath, /^<{7}|^={7}|^>{7}/)); + const unresolvedBothModified = await Promise.all(promises); + const resolvedConflicts = bothModified.filter((s, i) => !unresolvedBothModified[i]); + const unresolvedConflicts = [ + ...merge.filter(s => s.type !== Status.BOTH_MODIFIED), + ...bothModified.filter((s, i) => unresolvedBothModified[i]) + ]; - if (mergeConflicts.length > 0) { - const message = mergeConflicts.length > 1 - ? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", mergeConflicts.length) - : localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(mergeConflicts[0].resourceUri.fsPath)); + if (unresolvedConflicts.length > 0) { + const message = unresolvedConflicts.length > 1 + ? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", unresolvedConflicts.length) + : localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(unresolvedConflicts[0].resourceUri.fsPath)); const yes = localize('yes', "Yes"); const pick = await window.showWarningMessage(message, { modal: true }, yes); @@ -501,10 +510,8 @@ export class CommandCenter { } } - const workingTree = selection - .filter(s => s.resourceGroupType === ResourceGroupType.WorkingTree); - - const scmResources = [...workingTree, ...mergeConflicts]; + const workingTree = selection.filter(s => s.resourceGroupType === ResourceGroupType.WorkingTree); + const scmResources = [...workingTree, ...resolvedConflicts, ...unresolvedConflicts]; if (!scmResources.length) { return; diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts index 632fd5a0a86..6e1dc139340 100644 --- a/extensions/git/src/util.ts +++ b/extensions/git/src/util.ts @@ -8,6 +8,7 @@ import { Event } from 'vscode'; import { dirname } from 'path'; import * as fs from 'fs'; +import * as byline from 'byline'; export function log(...args: any[]): void { console.log.apply(console, ['git:', ...args]); @@ -188,4 +189,20 @@ export function find(array: T[], fn: (t: T) => boolean): T | undefined { }); return result; +} + +export async function grep(filename: string, pattern: RegExp): Promise { + return new Promise((c, e) => { + const fileStream = fs.createReadStream(filename, { encoding: 'utf8' }); + const stream = byline(fileStream); + stream.on('data', (line: string) => { + if (pattern.test(line)) { + fileStream.close(); + c(true); + } + }); + + stream.on('error', e); + stream.on('end', () => c(false)); + }); } \ No newline at end of file