Skip to content

Commit

Permalink
Merge pull request #16 from davelopez/compare_clean_diff
Browse files Browse the repository at this point in the history
Compare clean/simplified workflow diff in local repository
  • Loading branch information
davelopez authored Mar 11, 2022
2 parents ce3f1ac + e57f3a4 commit fe63946
Show file tree
Hide file tree
Showing 21 changed files with 854 additions and 164 deletions.
340 changes: 340 additions & 0 deletions client/src/@types/git.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,340 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Uri, Event, Disposable, ProviderResult } from "vscode";
export { ProviderResult } from "vscode";

export interface Git {
readonly path: string;
}

export interface InputBox {
value: string;
}

export const enum ForcePushMode {
Force,
ForceWithLease,
}

export const enum RefType {
Head,
RemoteHead,
Tag,
}

export interface Ref {
readonly type: RefType;
readonly name?: string;
readonly commit?: string;
readonly remote?: string;
}

export interface UpstreamRef {
readonly remote: string;
readonly name: string;
}

export interface Branch extends Ref {
readonly upstream?: UpstreamRef;
readonly ahead?: number;
readonly behind?: number;
}

export interface Commit {
readonly hash: string;
readonly message: string;
readonly parents: string[];
readonly authorDate?: Date;
readonly authorName?: string;
readonly authorEmail?: string;
readonly commitDate?: Date;
}

export interface Submodule {
readonly name: string;
readonly path: string;
readonly url: string;
}

export interface Remote {
readonly name: string;
readonly fetchUrl?: string;
readonly pushUrl?: string;
readonly isReadOnly: boolean;
}

export const enum Status {
INDEX_MODIFIED,
INDEX_ADDED,
INDEX_DELETED,
INDEX_RENAMED,
INDEX_COPIED,

MODIFIED,
DELETED,
UNTRACKED,
IGNORED,
INTENT_TO_ADD,

ADDED_BY_US,
ADDED_BY_THEM,
DELETED_BY_US,
DELETED_BY_THEM,
BOTH_ADDED,
BOTH_DELETED,
BOTH_MODIFIED,
}

export interface Change {
/**
* Returns either `originalUri` or `renameUri`, depending
* on whether this change is a rename change. When
* in doubt always use `uri` over the other two alternatives.
*/
readonly uri: Uri;
readonly originalUri: Uri;
readonly renameUri: Uri | undefined;
readonly status: Status;
}

export interface RepositoryState {
readonly HEAD: Branch | undefined;
readonly refs: Ref[];
readonly remotes: Remote[];
readonly submodules: Submodule[];
readonly rebaseCommit: Commit | undefined;

readonly mergeChanges: Change[];
readonly indexChanges: Change[];
readonly workingTreeChanges: Change[];

readonly onDidChange: Event<void>;
}

export interface RepositoryUIState {
readonly selected: boolean;
readonly onDidChange: Event<void>;
}

/**
* Log options.
*/
export interface LogOptions {
/** Max number of log entries to retrieve. If not specified, the default is 32. */
readonly maxEntries?: number;
readonly path?: string;
}

export interface CommitOptions {
all?: boolean | "tracked";
amend?: boolean;
signoff?: boolean;
signCommit?: boolean;
empty?: boolean;
noVerify?: boolean;
requireUserConfig?: boolean;
}

export interface FetchOptions {
remote?: string;
ref?: string;
all?: boolean;
prune?: boolean;
depth?: number;
}

export interface BranchQuery {
readonly remote?: boolean;
readonly pattern?: string;
readonly count?: number;
readonly contains?: string;
}

export interface Repository {
readonly rootUri: Uri;
readonly inputBox: InputBox;
readonly state: RepositoryState;
readonly ui: RepositoryUIState;

getConfigs(): Promise<{ key: string; value: string }[]>;
getConfig(key: string): Promise<string>;
setConfig(key: string, value: string): Promise<string>;
getGlobalConfig(key: string): Promise<string>;

getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number }>;
detectObjectType(object: string): Promise<{ mimetype: string; encoding?: string }>;
buffer(ref: string, path: string): Promise<Buffer>;
show(ref: string, path: string): Promise<string>;
getCommit(ref: string): Promise<Commit>;

add(paths: string[]): Promise<void>;
clean(paths: string[]): Promise<void>;

apply(patch: string, reverse?: boolean): Promise<void>;
diff(cached?: boolean): Promise<string>;
diffWithHEAD(): Promise<Change[]>;
diffWithHEAD(path: string): Promise<string>;
diffWith(ref: string): Promise<Change[]>;
diffWith(ref: string, path: string): Promise<string>;
diffIndexWithHEAD(): Promise<Change[]>;
diffIndexWithHEAD(path: string): Promise<string>;
diffIndexWith(ref: string): Promise<Change[]>;
diffIndexWith(ref: string, path: string): Promise<string>;
diffBlobs(object1: string, object2: string): Promise<string>;
diffBetween(ref1: string, ref2: string): Promise<Change[]>;
diffBetween(ref1: string, ref2: string, path: string): Promise<string>;

hashObject(data: string): Promise<string>;

createBranch(name: string, checkout: boolean, ref?: string): Promise<void>;
deleteBranch(name: string, force?: boolean): Promise<void>;
getBranch(name: string): Promise<Branch>;
getBranches(query: BranchQuery): Promise<Ref[]>;
setBranchUpstream(name: string, upstream: string): Promise<void>;

getMergeBase(ref1: string, ref2: string): Promise<string>;

tag(name: string, upstream: string): Promise<void>;
deleteTag(name: string): Promise<void>;

status(): Promise<void>;
checkout(treeish: string): Promise<void>;

addRemote(name: string, url: string): Promise<void>;
removeRemote(name: string): Promise<void>;
renameRemote(name: string, newName: string): Promise<void>;

fetch(options?: FetchOptions): Promise<void>;
fetch(remote?: string, ref?: string, depth?: number): Promise<void>;
pull(unshallow?: boolean): Promise<void>;
push(remoteName?: string, branchName?: string, setUpstream?: boolean, force?: ForcePushMode): Promise<void>;

blame(path: string): Promise<string>;
log(options?: LogOptions): Promise<Commit[]>;

commit(message: string, opts?: CommitOptions): Promise<void>;
}

export interface RemoteSource {
readonly name: string;
readonly description?: string;
readonly url: string | string[];
}

export interface RemoteSourceProvider {
readonly name: string;
readonly icon?: string; // codicon name
readonly supportsQuery?: boolean;
getRemoteSources(query?: string): ProviderResult<RemoteSource[]>;
getBranches?(url: string): ProviderResult<string[]>;
publishRepository?(repository: Repository): Promise<void>;
}

export interface RemoteSourcePublisher {
readonly name: string;
readonly icon?: string; // codicon name
publishRepository(repository: Repository): Promise<void>;
}

export interface Credentials {
readonly username: string;
readonly password: string;
}

export interface CredentialsProvider {
getCredentials(host: Uri): ProviderResult<Credentials>;
}

export interface PushErrorHandler {
handlePushError(
repository: Repository,
remote: Remote,
refspec: string,
error: Error & { gitErrorCode: GitErrorCodes }
): Promise<boolean>;
}

export type APIState = "uninitialized" | "initialized";

export interface PublishEvent {
repository: Repository;
branch?: string;
}

export interface API {
readonly state: APIState;
readonly onDidChangeState: Event<APIState>;
readonly onDidPublish: Event<PublishEvent>;
readonly git: Git;
readonly repositories: Repository[];
readonly onDidOpenRepository: Event<Repository>;
readonly onDidCloseRepository: Event<Repository>;

toGitUri(uri: Uri, ref: string): Uri;
getRepository(uri: Uri): Repository | null;
init(root: Uri): Promise<Repository | null>;
openRepository(root: Uri): Promise<Repository | null>;

registerRemoteSourcePublisher(publisher: RemoteSourcePublisher): Disposable;
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
registerCredentialsProvider(provider: CredentialsProvider): Disposable;
registerPushErrorHandler(handler: PushErrorHandler): Disposable;
}

export interface GitExtension {
readonly enabled: boolean;
readonly onDidChangeEnablement: Event<boolean>;

/**
* Returns a specific API version.
*
* Throws error if git extension is disabled. You can listed to the
* [GitExtension.onDidChangeEnablement](#GitExtension.onDidChangeEnablement) event
* to know when the extension becomes enabled/disabled.
*
* @param version Version number.
* @returns API instance
*/
getAPI(version: 1): API;
}

export const enum GitErrorCodes {
BadConfigFile = "BadConfigFile",
AuthenticationFailed = "AuthenticationFailed",
NoUserNameConfigured = "NoUserNameConfigured",
NoUserEmailConfigured = "NoUserEmailConfigured",
NoRemoteRepositorySpecified = "NoRemoteRepositorySpecified",
NotAGitRepository = "NotAGitRepository",
NotAtRepositoryRoot = "NotAtRepositoryRoot",
Conflict = "Conflict",
StashConflict = "StashConflict",
UnmergedChanges = "UnmergedChanges",
PushRejected = "PushRejected",
RemoteConnectionError = "RemoteConnectionError",
DirtyWorkTree = "DirtyWorkTree",
CantOpenResource = "CantOpenResource",
GitNotFound = "GitNotFound",
CantCreatePipe = "CantCreatePipe",
PermissionDenied = "PermissionDenied",
CantAccessRemote = "CantAccessRemote",
RepositoryNotFound = "RepositoryNotFound",
RepositoryIsLocked = "RepositoryIsLocked",
BranchNotFullyMerged = "BranchNotFullyMerged",
NoRemoteReference = "NoRemoteReference",
InvalidBranchName = "InvalidBranchName",
BranchAlreadyExists = "BranchAlreadyExists",
NoLocalChanges = "NoLocalChanges",
NoStashFound = "NoStashFound",
LocalChangesOverwritten = "LocalChangesOverwritten",
NoUpstreamBranch = "NoUpstreamBranch",
IsInSubmodule = "IsInSubmodule",
WrongCase = "WrongCase",
CantLockRef = "CantLockRef",
CantRebaseMultipleBranches = "CantRebaseMultipleBranches",
PatchDoesNotApply = "PatchDoesNotApply",
NoPathFound = "NoPathFound",
UnknownPath = "UnknownPath",
}
34 changes: 33 additions & 1 deletion client/src/commands/common.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { commands, Disposable } from "vscode";
import { commands, Disposable, Uri } from "vscode";
import { CommonLanguageClient } from "vscode-languageclient";

/**
Expand Down Expand Up @@ -48,3 +48,35 @@ export abstract class CustomCommand extends CommandContext {
*/
abstract execute(args: any[]): Promise<void>;
}

/**
* Contains the URI and git ref of a particular workflow
* document revision.
*/
export class ComparableWorkflow {
uri: Uri;
ref: string;

public static buildFromArgs(args: any[]): ComparableWorkflow | undefined {
if (args.length >= 2) {
const firstArg = args[0];
const secondArg = args[1];
if (firstArg.hasOwnProperty("ref")) {
// Comes from source control timeline
return { uri: secondArg, ref: firstArg.ref };
} else if (firstArg.hasOwnProperty("scheme")) {
// Comes from file explorer
return { uri: firstArg, ref: undefined };
}
}
return undefined;
}
}

/**
* Interface for retrieving a previously selected workflow document
* revision.
*/
export interface ComparableWorkflowProvider {
getSelectedForCompare(): ComparableWorkflow | undefined;
}
Loading

0 comments on commit fe63946

Please sign in to comment.