1/*---------------------------------------------------------------------------------------------
2 *  Copyright (c) Microsoft Corporation. All rights reserved.
3 *  Licensed under the MIT License. See License.txt in the project root for license information.
4 *--------------------------------------------------------------------------------------------*/
5
6import { Uri, Event, Disposable, ProviderResult } from 'vscode';
7export { ProviderResult } from 'vscode';
8
9export interface Git {
10	readonly path: string;
11}
12
13export interface InputBox {
14	value: string;
15}
16
17export const enum RefType {
18	Head,
19	RemoteHead,
20	Tag
21}
22
23export interface Ref {
24	readonly type: RefType;
25	readonly name?: string;
26	readonly commit?: string;
27	readonly remote?: string;
28}
29
30export interface UpstreamRef {
31	readonly remote: string;
32	readonly name: string;
33}
34
35export interface Branch extends Ref {
36	readonly upstream?: UpstreamRef;
37	readonly ahead?: number;
38	readonly behind?: number;
39}
40
41export interface Commit {
42	readonly hash: string;
43	readonly message: string;
44	readonly parents: string[];
45	readonly authorDate?: Date;
46	readonly authorName?: string;
47	readonly authorEmail?: string;
48	readonly commitDate?: Date;
49}
50
51export interface Submodule {
52	readonly name: string;
53	readonly path: string;
54	readonly url: string;
55}
56
57export interface Remote {
58	readonly name: string;
59	readonly fetchUrl?: string;
60	readonly pushUrl?: string;
61	readonly isReadOnly: boolean;
62}
63
64export const enum Status {
65	INDEX_MODIFIED,
66	INDEX_ADDED,
67	INDEX_DELETED,
68	INDEX_RENAMED,
69	INDEX_COPIED,
70
71	MODIFIED,
72	DELETED,
73	UNTRACKED,
74	IGNORED,
75	INTENT_TO_ADD,
76
77	ADDED_BY_US,
78	ADDED_BY_THEM,
79	DELETED_BY_US,
80	DELETED_BY_THEM,
81	BOTH_ADDED,
82	BOTH_DELETED,
83	BOTH_MODIFIED
84}
85
86export interface Change {
87
88	/**
89	 * Returns either `originalUri` or `renameUri`, depending
90	 * on whether this change is a rename change. When
91	 * in doubt always use `uri` over the other two alternatives.
92	 */
93	readonly uri: Uri;
94	readonly originalUri: Uri;
95	readonly renameUri: Uri | undefined;
96	readonly status: Status;
97}
98
99export interface RepositoryState {
100	readonly HEAD: Branch | undefined;
101	readonly refs: Ref[];
102	readonly remotes: Remote[];
103	readonly submodules: Submodule[];
104	readonly rebaseCommit: Commit | undefined;
105
106	readonly mergeChanges: Change[];
107	readonly indexChanges: Change[];
108	readonly workingTreeChanges: Change[];
109
110	readonly onDidChange: Event<void>;
111}
112
113export interface RepositoryUIState {
114	readonly selected: boolean;
115	readonly onDidChange: Event<void>;
116}
117
118/**
119 * Log options.
120 */
121export interface LogOptions {
122	/** Max number of log entries to retrieve. If not specified, the default is 32. */
123	readonly maxEntries?: number;
124	readonly path?: string;
125}
126
127export interface CommitOptions {
128	all?: boolean | 'tracked';
129	amend?: boolean;
130	signoff?: boolean;
131	signCommit?: boolean;
132	empty?: boolean;
133}
134
135export interface BranchQuery {
136	readonly remote?: boolean;
137	readonly contains?: string;
138}
139
140export interface Repository {
141
142	readonly rootUri: Uri;
143	readonly inputBox: InputBox;
144	readonly state: RepositoryState;
145	readonly ui: RepositoryUIState;
146
147	getConfigs(): Promise<{ key: string; value: string; }[]>;
148	getConfig(key: string): Promise<string>;
149	setConfig(key: string, value: string): Promise<string>;
150	getGlobalConfig(key: string): Promise<string>;
151
152	getObjectDetails(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }>;
153	detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }>;
154	buffer(ref: string, path: string): Promise<Buffer>;
155	show(ref: string, path: string): Promise<string>;
156	getCommit(ref: string): Promise<Commit>;
157
158	clean(paths: string[]): Promise<void>;
159
160	apply(patch: string, reverse?: boolean): Promise<void>;
161	diff(cached?: boolean): Promise<string>;
162	diffWithHEAD(): Promise<Change[]>;
163	diffWithHEAD(path: string): Promise<string>;
164	diffWith(ref: string): Promise<Change[]>;
165	diffWith(ref: string, path: string): Promise<string>;
166	diffIndexWithHEAD(): Promise<Change[]>;
167	diffIndexWithHEAD(path: string): Promise<string>;
168	diffIndexWith(ref: string): Promise<Change[]>;
169	diffIndexWith(ref: string, path: string): Promise<string>;
170	diffBlobs(object1: string, object2: string): Promise<string>;
171	diffBetween(ref1: string, ref2: string): Promise<Change[]>;
172	diffBetween(ref1: string, ref2: string, path: string): Promise<string>;
173
174	hashObject(data: string): Promise<string>;
175
176	createBranch(name: string, checkout: boolean, ref?: string): Promise<void>;
177	deleteBranch(name: string, force?: boolean): Promise<void>;
178	getBranch(name: string): Promise<Branch>;
179	getBranches(query: BranchQuery): Promise<Ref[]>;
180	setBranchUpstream(name: string, upstream: string): Promise<void>;
181
182	getMergeBase(ref1: string, ref2: string): Promise<string>;
183
184	status(): Promise<void>;
185	checkout(treeish: string): Promise<void>;
186
187	addRemote(name: string, url: string): Promise<void>;
188	removeRemote(name: string): Promise<void>;
189	renameRemote(name: string, newName: string): Promise<void>;
190
191	fetch(remote?: string, ref?: string, depth?: number): Promise<void>;
192	pull(unshallow?: boolean): Promise<void>;
193	push(remoteName?: string, branchName?: string, setUpstream?: boolean): Promise<void>;
194
195	blame(path: string): Promise<string>;
196	log(options?: LogOptions): Promise<Commit[]>;
197
198	commit(message: string, opts?: CommitOptions): Promise<void>;
199}
200
201export interface RemoteSource {
202	readonly name: string;
203	readonly description?: string;
204	readonly url: string | string[];
205}
206
207export interface RemoteSourceProvider {
208	readonly name: string;
209	readonly icon?: string; // codicon name
210	readonly supportsQuery?: boolean;
211	getRemoteSources(query?: string): ProviderResult<RemoteSource[]>;
212	publishRepository?(repository: Repository): Promise<void>;
213}
214
215export interface Credentials {
216	readonly username: string;
217	readonly password: string;
218}
219
220export interface CredentialsProvider {
221	getCredentials(host: Uri): ProviderResult<Credentials>;
222}
223
224export type APIState = 'uninitialized' | 'initialized';
225
226export interface API {
227	readonly state: APIState;
228	readonly onDidChangeState: Event<APIState>;
229	readonly git: Git;
230	readonly repositories: Repository[];
231	readonly onDidOpenRepository: Event<Repository>;
232	readonly onDidCloseRepository: Event<Repository>;
233
234	toGitUri(uri: Uri, ref: string): Uri;
235	getRepository(uri: Uri): Repository | null;
236	init(root: Uri): Promise<Repository | null>;
237
238	registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
239	registerCredentialsProvider(provider: CredentialsProvider): Disposable;
240}
241
242export interface GitExtension {
243
244	readonly enabled: boolean;
245	readonly onDidChangeEnablement: Event<boolean>;
246
247	/**
248	 * Returns a specific API version.
249	 *
250	 * Throws error if git extension is disabled. You can listed to the
251	 * [GitExtension.onDidChangeEnablement](#GitExtension.onDidChangeEnablement) event
252	 * to know when the extension becomes enabled/disabled.
253	 *
254	 * @param version Version number.
255	 * @returns API instance
256	 */
257	getAPI(version: 1): API;
258}
259
260export const enum GitErrorCodes {
261	BadConfigFile = 'BadConfigFile',
262	AuthenticationFailed = 'AuthenticationFailed',
263	NoUserNameConfigured = 'NoUserNameConfigured',
264	NoUserEmailConfigured = 'NoUserEmailConfigured',
265	NoRemoteRepositorySpecified = 'NoRemoteRepositorySpecified',
266	NotAGitRepository = 'NotAGitRepository',
267	NotAtRepositoryRoot = 'NotAtRepositoryRoot',
268	Conflict = 'Conflict',
269	StashConflict = 'StashConflict',
270	UnmergedChanges = 'UnmergedChanges',
271	PushRejected = 'PushRejected',
272	RemoteConnectionError = 'RemoteConnectionError',
273	DirtyWorkTree = 'DirtyWorkTree',
274	CantOpenResource = 'CantOpenResource',
275	GitNotFound = 'GitNotFound',
276	CantCreatePipe = 'CantCreatePipe',
277	CantAccessRemote = 'CantAccessRemote',
278	RepositoryNotFound = 'RepositoryNotFound',
279	RepositoryIsLocked = 'RepositoryIsLocked',
280	BranchNotFullyMerged = 'BranchNotFullyMerged',
281	NoRemoteReference = 'NoRemoteReference',
282	InvalidBranchName = 'InvalidBranchName',
283	BranchAlreadyExists = 'BranchAlreadyExists',
284	NoLocalChanges = 'NoLocalChanges',
285	NoStashFound = 'NoStashFound',
286	LocalChangesOverwritten = 'LocalChangesOverwritten',
287	NoUpstreamBranch = 'NoUpstreamBranch',
288	IsInSubmodule = 'IsInSubmodule',
289	WrongCase = 'WrongCase',
290	CantLockRef = 'CantLockRef',
291	CantRebaseMultipleBranches = 'CantRebaseMultipleBranches',
292	PatchDoesNotApply = 'PatchDoesNotApply',
293	NoPathFound = 'NoPathFound',
294	UnknownPath = 'UnknownPath',
295}
296