rawGitService.ts 7.8 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import path = require('path');
J
Joao Moreno 已提交
8
import { TPromise, Promise } from 'vs/base/common/winjs.base';
E
Erich Gamma 已提交
9 10 11
import mime = require('vs/base/node/mime');
import pfs = require('vs/base/node/pfs');
import { Repository, GitError } from 'vs/workbench/parts/git/node/git.lib';
J
Joao Moreno 已提交
12
import { IRawGitService, RawServiceState, IRawStatus, IHead, GitErrorCodes, IPushOptions } from 'vs/workbench/parts/git/common/git';
E
Erich Gamma 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25

function pathsAreEqual(p1: string, p2: string): boolean {
	if (/^(win32|darwin)$/.test(process.platform)) {
		p1 = p1.toLowerCase();
		p2 = p2.toLowerCase();
	}

	return p1 === p2;
}

export class RawGitService implements IRawGitService {

	private repo: Repository;
J
Joao Moreno 已提交
26
	private _repositoryRoot: TPromise<string>;
E
Erich Gamma 已提交
27 28 29

	constructor(repo: Repository) {
		this.repo = repo;
J
Joao Moreno 已提交
30 31 32 33
	}

	private getRepositoryRoot(): TPromise<string> {
		return this._repositoryRoot || (this._repositoryRoot = pfs.realpath(this.repo.path));
E
Erich Gamma 已提交
34 35
	}

J
Joao Moreno 已提交
36 37
	public serviceState(): TPromise<RawServiceState> {
		return TPromise.as<RawServiceState>(this.repo
E
Erich Gamma 已提交
38 39 40 41 42
			? RawServiceState.OK
			: RawServiceState.GitNotFound
		);
	}

J
Joao Moreno 已提交
43
	public status(): TPromise<IRawStatus> {
J
Joao Moreno 已提交
44
		return this.repo.getStatus()
E
Erich Gamma 已提交
45 46 47 48 49 50 51 52
			.then(status => this.repo.getHEAD()
				.then(HEAD => {
					if (HEAD.name) {
						return this.repo.getBranch(HEAD.name).then(null, () => HEAD);
					} else {
						return HEAD;
					}
				}, (): IHead => null)
J
Joao Moreno 已提交
53
				.then(HEAD => Promise.join([this.getRepositoryRoot(), this.repo.getHeads(), this.repo.getTags(), this.repo.getRemotes()]).then(r => {
E
Erich Gamma 已提交
54
					return {
J
Joao Moreno 已提交
55
						repositoryRoot: r[0],
E
Erich Gamma 已提交
56 57
						status: status,
						HEAD: HEAD,
J
Joao Moreno 已提交
58
						heads: r[1],
J
Joao Moreno 已提交
59 60
						tags: r[2],
						remotes: r[3]
E
Erich Gamma 已提交
61 62 63 64
					};
				})))
			.then(null, (err) => {
				if (err.gitErrorCode === GitErrorCodes.BadConfigFile) {
J
Joao Moreno 已提交
65
					return Promise.wrapError(err);
E
Erich Gamma 已提交
66
				} else if (err.gitErrorCode === GitErrorCodes.NotAtRepositoryRoot) {
J
Joao Moreno 已提交
67
					return Promise.wrapError(err);
E
Erich Gamma 已提交
68 69 70 71 72 73
				}

				return null;
			});
	}

J
Joao Moreno 已提交
74
	public init(): TPromise<IRawStatus> {
E
Erich Gamma 已提交
75 76 77
		return this.repo.init().then(() => this.status());
	}

J
Joao Moreno 已提交
78
	public add(filePaths?: string[]): TPromise<IRawStatus> {
E
Erich Gamma 已提交
79 80 81
		return this.repo.add(filePaths).then(() => this.status());
	}

J
Joao Moreno 已提交
82
	public stage(filePath: string, content: string): TPromise<IRawStatus> {
E
Erich Gamma 已提交
83 84 85
		return this.repo.stage(filePath, content).then(() => this.status());
	}

J
Joao Moreno 已提交
86
	public branch(name: string, checkout?: boolean): TPromise<IRawStatus> {
E
Erich Gamma 已提交
87 88 89
		return this.repo.branch(name, checkout).then(() => this.status());
	}

J
Joao Moreno 已提交
90
	public checkout(treeish?: string, filePaths?: string[]): TPromise<IRawStatus> {
E
Erich Gamma 已提交
91 92 93
		return this.repo.checkout(treeish, filePaths).then(() => this.status());
	}

J
Joao Moreno 已提交
94
	public clean(filePaths: string[]): TPromise<IRawStatus> {
E
Erich Gamma 已提交
95 96 97
		return this.repo.clean(filePaths).then(() => this.status());
	}

J
Joao Moreno 已提交
98
	public undo(): TPromise<IRawStatus> {
E
Erich Gamma 已提交
99 100 101
		return this.repo.undo().then(() => this.status());
	}

J
Joao Moreno 已提交
102
	public reset(treeish: string, hard?: boolean): TPromise<IRawStatus> {
E
Erich Gamma 已提交
103 104 105
		return this.repo.reset(treeish, hard).then(() => this.status());
	}

J
Joao Moreno 已提交
106
	public revertFiles(treeish: string, filePaths?: string[]): TPromise<IRawStatus> {
E
Erich Gamma 已提交
107 108 109
		return this.repo.revertFiles(treeish, filePaths).then(() => this.status());
	}

J
Joao Moreno 已提交
110
	public fetch(): TPromise<IRawStatus> {
E
Erich Gamma 已提交
111 112
		return this.repo.fetch().then(null, (err) => {
			if (err.gitErrorCode === GitErrorCodes.NoRemoteRepositorySpecified) {
J
Joao Moreno 已提交
113
				return Promise.as(null);
E
Erich Gamma 已提交
114 115
			}

J
Joao Moreno 已提交
116
			return Promise.wrapError(err);
E
Erich Gamma 已提交
117 118 119
		}).then(() => this.status());
	}

J
Joao Moreno 已提交
120 121
	public pull(rebase?: boolean): TPromise<IRawStatus> {
		return this.repo.pull(rebase).then(() => this.status());
E
Erich Gamma 已提交
122 123
	}

J
Joao Moreno 已提交
124 125
	public push(remote?: string, name?: string, options?:IPushOptions): TPromise<IRawStatus> {
		return this.repo.push(remote, name, options).then(() => this.status());
E
Erich Gamma 已提交
126 127
	}

J
Joao Moreno 已提交
128
	public sync(): TPromise<IRawStatus> {
E
Erich Gamma 已提交
129 130 131
		return this.repo.sync().then(() => this.status());
	}

J
Joao Moreno 已提交
132 133
	public commit(message:string, amend?: boolean, stage?: boolean): TPromise<IRawStatus> {
		var promise: Promise = Promise.as(null);
E
Erich Gamma 已提交
134 135 136 137 138 139 140 141 142 143

		if (stage) {
			promise = this.repo.add(null);
		}

		return promise
			.then(() => this.repo.commit(message, stage, amend))
			.then(() => this.status());
	}

J
Joao Moreno 已提交
144
	public detectMimetypes(filePath: string, treeish?: string): TPromise<string[]> {
E
Erich Gamma 已提交
145 146
		return pfs.exists(path.join(this.repo.path, filePath)).then((exists) => {
			if (exists) {
J
Joao Moreno 已提交
147
				return new TPromise<string[]>((c, e) => {
E
Erich Gamma 已提交
148 149 150 151 152 153 154 155 156
					mime.detectMimesFromFile(path.join(this.repo.path, filePath), (err, result) => {
						if (err) { e(err); }
						else { c(result.mimes); }
					});
				});
			}

			var child = this.repo.show(treeish + ':' + filePath);

J
Joao Moreno 已提交
157
			return new TPromise<string[]>((c, e) => {
E
Erich Gamma 已提交
158 159 160 161 162 163 164 165 166
				mime.detectMimesFromStream(child.stdout, filePath, (err, result) => {
					if (err) { e(err); }
					else { c(result.mimes); }
				});
			});
		});
	}

	// careful, this buffers the whole object into memory
J
Joao Moreno 已提交
167
	public show(filePath: string, treeish?: string): TPromise<string> {
E
Erich Gamma 已提交
168 169 170 171 172 173
		treeish = treeish === '~' ? '' : treeish;
		return this.repo.buffer(treeish + ':' + filePath).then(null, e => {
			if (e instanceof GitError) {
				return ''; // mostly untracked files end up in a git error
			}

J
Joao Moreno 已提交
174
			return TPromise.wrapError<string>(e);
E
Erich Gamma 已提交
175 176 177
		});
	}

J
Joao Moreno 已提交
178
	public onOutput(): Promise {
E
Erich Gamma 已提交
179 180
		var cancel: () => void;

J
Joao Moreno 已提交
181
		return new Promise((c, e, p) => {
E
Erich Gamma 已提交
182 183 184 185
			cancel = this.repo.onOutput(p);
		}, () => cancel());
	}
}
J
Joao Moreno 已提交
186

J
Joao Moreno 已提交
187
export class DelayedRawGitService implements IRawGitService {
J
Joao Moreno 已提交
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

	constructor(private raw: TPromise<IRawGitService>) { }

	public serviceState(): TPromise<RawServiceState> {
		return this.raw.then(raw => raw.serviceState());
	}

	public status(): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.status());
	}

	public init(): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.init());
	}

	public add(filesPaths?: string[]): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.add(filesPaths));
	}

	public stage(filePath: string, content: string): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.stage(filePath, content));
	}

	public branch(name: string, checkout?: boolean): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.branch(name, checkout));
	}

	public checkout(treeish?: string, filePaths?: string[]): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.checkout(treeish, filePaths));
	}

	public clean(filePaths: string[]): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.clean(filePaths));
	}

	public undo(): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.undo());
	}

	public reset(treeish: string, hard?: boolean): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.reset(treeish, hard));
	}

	public revertFiles(treeish: string, filePaths?: string[]): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.revertFiles(treeish, filePaths));
	}

	public fetch(): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.fetch());
	}

J
Joao Moreno 已提交
239 240
	public pull(rebase?: boolean): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.pull(rebase));
J
Joao Moreno 已提交
241 242
	}

J
Joao Moreno 已提交
243 244
	public push(origin?: string, name?: string, options?:IPushOptions): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.push(origin, name, options));
J
Joao Moreno 已提交
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
	}

	public sync(): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.sync());
	}

	public commit(message: string, amend?: boolean, stage?: boolean): TPromise<IRawStatus> {
		return this.raw.then(raw => raw.commit(message, amend, stage));
	}

	public detectMimetypes(path: string, treeish?: string): TPromise<string[]> {
		return this.raw.then(raw => raw.detectMimetypes(path, treeish));
	}

	public show(path: string, treeish?: string): TPromise<string> {
		return this.raw.then(raw => raw.show(path, treeish));
	}

	public onOutput(): Promise {
		return this.raw.then(raw => raw.onOutput());
	}
}