Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-165: Basic Git Extension #392

Merged
merged 88 commits into from
Oct 10, 2017
Merged

GH-165: Basic Git Extension #392

merged 88 commits into from
Oct 10, 2017

Conversation

kittaakos
Copy link
Contributor

@kittaakos kittaakos commented Aug 14, 2017

See #165

/**
* Representation of an individual file change in the working directory.
*/
export interface FileChange {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to prefix such common names with Git, there is already FileChange

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we put everything into the Git namespace?


});

async function createGit(fsRoot: string = ''): Promise<DugiteGit> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to avoid module functions and prefer class methods to be able to override them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a test, did you notice that? I mean I can, but does it make sense?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant generally, I've seen unexported module functions in other modules.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for tests, it is indeed not important

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Show me, and we replace it. I personally hate writing this. when it does nothing with the class' state at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be another class then

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be even longer though :) I understand your frustration, but we don't have dependency injection for modules, but for classes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense.

export class DugiteGit implements Git {

constructor(
@inject(WorkspaceServer) private readonly workspace: WorkspaceServer) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be nice to prefer protected over private to allow subclasses to override and access the state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you prefer that, we use protected then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is just a pain, for example, to work around some bugs in JDT because everything is private.

registry.registerHandler(GIT_COMMANDS.STATUS.id, {
execute: (): any => {
this.git.repositories().then(repositories => {
const first = repositories.shift();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a global repository provider that returns the repository that is currently selected in the UI instead of always the first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what should this command do in future?
Open the git widget?

id: 'git.status',
label: 'Print Git Status'
};
export const REPOSITORIES = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how this command is useful

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was just a placeholder command to see if the interface can be called from the browser. We will get rid of this for sure.

console.info(status);
});
} else {
console.info('No repositories were found.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use an ILogger

});
return undefined;
},
isEnabled: () => true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should obtain the repository from the provider. if there is none it should be disabled.

import { KeybindingContext, Keybinding, KeybindingContribution, KeybindingRegistry, KeyCode, Key, Modifier } from "@theia/core/lib/common";

@injectable()
export class GitKeybindingContext implements KeybindingContext {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need a keybinding context?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be removed.

/**
* Representation of an individual file change in the working directory.
*/
export interface FileChange {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we put everything into the Git namespace?

*
* @param path the FS path of the root to start the discovery.
*/
export async function locateRepositories(path: string): Promise<Repository[]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async is not used in the code

return !parts[0].length ? parts.slice(1) : parts;
}

// function getOrigin(repository, cb) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove dead code


async function splitPath(path: string): Promise<string[]> {
const parts = path.split(/(\/|\\)/);
if (!parts.length) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer being more explicit about length === 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is bad anyway. We need to call path.dirname() twice.

if (!parts.length) {
return parts;
}
// When the `path` starts with a slash, the the first part is empty string.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the the

import URI from "@theia/core/lib/common/uri";

export const GIT_RESOURCE_SCHEME = 'gitrev';

export class GitResource implements Resource {

protected readonly toDispose = new DisposableCollection();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove it? doesn't seem to be used

ressource
.then(r => r.readContents())
.then(content => console.log(content));
// try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code should be deleted

@@ -0,0 +1,235 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

module can be removed, since it is not used.

@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 26, 2017

screen shot 2017-09-26 at 15 20 46

solved and verified

@@ -0,0 +1,153 @@
/*
Copy link
Contributor Author

@kittaakos kittaakos Sep 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbicker, I was unable to figure out where do we set the id of the left panel, so I just add this as a comment. The problem is the following: both the Files and the Git has the same files ID. So the browser tests are broken.

Updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, I was wrong. I have figured out what was the problem and it is unrelated to the id. The ID is just fine.

@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 27, 2017

I tested a rebase with merge conflicts.
Merge conflicts are shown twice:
screen shot 2017-09-27 at 10 33 15
One entry with a '-' one with a '+'.
Opening a diff editor on the '-' one fails and logs an error :
screen shot 2017-09-27 at 10 39 58

This is fixed with 2c5b969#diff-392c37f87fa84f7102bfb5248b4837d8R72

@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 27, 2017

Sometimes when double-clicking on a change a diff editor gets opened twice (I will take care of that).

Fixed in d1412d1

@svenefftinge svenefftinge changed the title [WIP] GH-165: Basic Git Extension GH-165: Basic Git Extension Sep 27, 2017
@svenefftinge svenefftinge requested a review from hexa00 September 27, 2017 11:06
@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 27, 2017

On huge repositories, the initial load sometimes has all changes twice:

screen shot 2017-09-27 at 13 10 29

solved with c78e5dd

@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 27, 2017

Also on huge repos, the initial status request takes multiple seconds.

@kittaakos is looking into it

We have resolved a performance issue here. The selected repository was not set properly on the frontend.

@kittaakos
Copy link
Contributor Author

Open diff editor, close, open again. A broken editor is shown with this in the browser:

6:37:06.690 console-window.ts:40 TypeScript: [Error - 4:37:06 PM] Server initialization failed.
16:37:06.690 console-window.ts:40 TypeScript: Error: Connection got disposed.
    at Object.dispose (http://localhost:3000/bundle.js:6791:25)
    at http://localhost:3000/bundle.js:64956:56
    at CallbackList.invoke (http://localhost:3000/bundle.js:12821:39)
    at Emitter.fire (http://localhost:3000/bundle.js:12885:36)
    at closeHandler (http://localhost:3000/bundle.js:6187:26)
    at CallbackList.invoke (http://localhost:3000/bundle.js:12821:39)
    at Emitter.fire (http://localhost:3000/bundle.js:12885:36)
    at WebSocketMessageReader.AbstractMessageReader.fireClose (http://localhost:3000/bundle.js:22284:27)
    at WebSocketMessageReader.fireClose (http://localhost:3000/bundle.js:33595:40)
    at http://localhost:3000/bundle.js:33552:19
16:37:06.691 main.js:129 Uncaught (in promise) Error: Connection is disposed.
    at new ConnectionError (main.js:129)
    at throwIfClosedOrDisposed (main.js:607)
    at Object.sendRequest (main.js:706)
    at Object.shutdown (connection.js:20)
    at resolveConnection.then.connection (base.js:845)
    at <anonymous>
ConnectionError @ main.js:129
throwIfClosedOrDisposed @ main.js:607
sendRequest @ main.js:706
shutdown @ connection.js:20
resolveConnection.then.connection @ base.js:845
Promise resolved (async)
stop @ base.js:844
connection.initialize.then @ base.js:831
Promise rejected (async)
initialize @ base.js:747
resolveConnection.then @ base.js:657
Promise resolved (async)
start @ base.js:624
handleConnectionClosed @ base.js:919
CallbackList.invoke @ events.js:71
Emitter.fire @ events.js:135
closeHandler @ main.js:212
CallbackList.invoke @ events.js:71
Emitter.fire @ events.js:135
AbstractMessageReader.fireClose @ messageReader.js:126
WebSocketMessageReader.fireClose @ reader.ts:72
(anonymous) @ reader.ts:31
webSocket.onclose @ connection.ts:32
16:37:06.691 main.js:816 Uncaught (in promise) Error: Connection got disposed.
    at Object.dispose (main.js:816)
    at connection.ts:14
    at CallbackList.invoke (events.js:71)
    at Emitter.fire (events.js:135)
    at closeHandler (main.js:212)
    at CallbackList.invoke (events.js:71)
    at Emitter.fire (events.js:135)
    at WebSocketMessageReader.AbstractMessageReader.fireClose (messageReader.js:126)
    at WebSocketMessageReader.fireClose (reader.ts:72)
    at reader.ts:31

@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 27, 2017

(removed, since it was due to broken build)

@kittaakos
Copy link
Contributor Author

I do not know if it is a side-effect of something else but I had this in my console, when I have tried to open an untracked file in a "diff" editor:

index.js:380 TypeError: Cannot read property 'style' of null
    at t.layout (editor.main.js:31)
    at t.layout (editor.main.js:31)
    at t._doLayout (editor.main.js:31)
    at t._measureDomElement (editor.main.js:31)
    at t.layout (editor.main.js:31)
    at MonacoDiffEditor.webpackJsonp.524.MonacoDiffEditor.resize (monaco-diff-editor.ts:78)
    at MonacoDiffEditor.webpackJsonp.505.MonacoEditor.setSize (monaco-editor.ts:232)
    at EditorWidget.onResize (editor-widget.ts:44)
    at EditorWidget.Widget.processMessage (widget.js:485)
    at invokeHandler (index.js:433)

@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 27, 2017

Open diff editor, close, open again. A broken editor is shown with this in the browser:

fixed in d02890b

@kittaakos
Copy link
Contributor Author

kittaakos commented Sep 27, 2017

Editor (not the diff one) content does not get updated after discarding all the changes:

  • Open a file in the editor.
  • Change the file content. (You do not have to save, you know...)
  • Leave the file opened in the editor.
  • Go to Git tab, discard changes.
  • File restored to its HEAD state.
  • The opened editor still shows the modified content.

This is a general problem and tracked here: #74

@kittaakos
Copy link
Contributor Author

kittaakos commented Sep 27, 2017

I will look into the windows build issue and I try to fix it.

Solved via this.

@svenefftinge
Copy link
Contributor

svenefftinge commented Sep 28, 2017

With the current state I get, the following on commit:

messages.js:46 Uncaught (in promise) Error: Request commit failed with message: Unable to find path to repository on disk.
    at new ResponseError (messages.js:46)
    at handleResponse (main.js:421)
    at processMessageQueue (main.js:249)
    at main.js:233
    at run (setImmediate.js:40)
    at runIfPresent (setImmediate.js:69)
    at onGlobalMessage (setImmediate.js:109)

Fixed with aaa9e41

branch: this.status.branch,
paths: change.uri
});
const options: Git.Options.Checkout.WorkingTreeFile = { paths: change.uri };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do I not need to specify the branch from which I want to checkout? AFAIU the HEAD will be detached when I am in a conflicting rebase situation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then please use treeish. AFAIK, branch is a treeish.

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>…​
git checkout [-p|--patch] [<tree-ish>] [--] [<paths>…​]

@@ -123,7 +164,7 @@ export class MonacoEditorProvider {
}
}

protected installQuickOpenService(editor: MonacoEditor): void {
protected installQuickOpenService(editor: MonacoEditor | MonacoDiffEditor): void {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that? As I see it is a subclass of the MonacoEditor. Is it just some leftover code?

@kittaakos
Copy link
Contributor Author

kittaakos commented Sep 28, 2017

I got this when cloned a repository inside my workspace and double clicked on the unstaged resource in the Git tab:

opener-service.ts:6 Uncaught (in promise) A resource provider for 'file:///Users/akos.kitta/git/theia/examples/browser/xtext-core/' is not registered.

#593.

@kittaakos
Copy link
Contributor Author

kittaakos commented Sep 28, 2017

I would like to see tooltips for the Git integration toolbar items:
screen shot 2017-09-28 at 18 07 14

Could be a Chrome issue, but I cannot see anything at all.

Done.

svenefftinge and others added 16 commits October 6, 2017 16:57
Signed-off-by: Sven Efftinge <sven.efftinge@typefox.io>
The frontend can still manually fetch the available repositories from
the backend.

Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Jan Bicker <jan.bicker@typefox.io>
Staged flag was not included in the comparison, hence client was not
notified when something was staged/unstaged.

Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
…ile gets deleted

Signed-off-by: Jan Bicker <jan.bicker@typefox.io>
 - selection of nested repositories did not work properly.
 - UI: the path of a file in repository root was shown as absolute path

Signed-off-by: Jan Bicker <jan.bicker@typefox.io>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Removed obsolete either type. `MDE` is a structural and nominal subtype
of `ME`, so need to keep the union type in the API.

Signed-off-by: Akos Kitta <kittaakos@gmail.com>
…k from akosyakov

Signed-off-by: Sven Efftinge <sven.efftinge@typefox.io>
Signed-off-by: Sven Efftinge <sven.efftinge@typefox.io>
Signed-off-by: Sven Efftinge <sven.efftinge@typefox.io>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
@kittaakos
Copy link
Contributor Author

I have fixed the diff editor issue. @hexa00, please review if you have time. Thank you!

cc: @svenefftinge

Repository URIs cannot be compared via the string representation of the
underlying paths, because they can differ but still, they are pointing
to the same location.

Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Signed-off-by: Akos Kitta <kittaakos@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants