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

Add ability to switch between files in Git Diff widget #5965

Merged
merged 40 commits into from
Sep 12, 2017
Merged

Conversation

mmorhun
Copy link
Contributor

@mmorhun mmorhun commented Aug 10, 2017

What does this PR do?

  • Adds ability to switch to the next/previous file in git compare widget. The order is defined by git. The editable content is saved on Next/Previous button click.
  • Adds Save Changes button for git compare widget.
  • Performs refactoring of git-compare-related functionality.
  • Fixes compare with deleted file bug.
  • Moves Git Diff widget from iframe to IDE.
  • Adds hotkeys for next and previous diff: alt + , and alt + . correspondingly. (actually alt + < or > but without shift).

What issues does this PR fix or reference?

#5892

Changelog

Added ability to switch between files in Git Diff widget.

Release Notes

In this version, we continued to work on improving Git support in Eclipse Che. We have improved the Git diff window so that it's simpler and faster to review changes between two states of code.

git-diff-2

To view the diff, use Git->Compare-><Select-to-what> from main menu. If more than one file has changed the list of changed files will be opened first. To select a file to compare double-click on it or select a file then click the Compare button.

Your changes are displayed in the left editor and the file being compared to is on the right. The left editor can be used for editing and fixing your changes.

When you have multiple files to review you have the ability to navigate under all the files that are changed. The number of files that are reviewable is displayed in the title of the wizard. Use Next and Previous buttons to navigate to the next or previous file correspondingly. We also introduce new keyboard shortcut for those actions Alt + . for Next and Alt + , for Previous.

Docs PR

eclipse-che/che-docs#283

@mmorhun mmorhun added the kind/enhancement A feature request - must adhere to the feature request template. label Aug 10, 2017
items.put(item.substring(2, item.length()), defineStatus(item.substring(0, 1)));
}
changesListPresenter.show(items, REVISION, null, project);
changesListPresenter.show(changedItems, REVISION, null);
Copy link
Contributor

Choose a reason for hiding this comment

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

I personally don't like methods which can accept null values.

Copy link
Contributor Author

@mmorhun mmorhun Aug 10, 2017

Choose a reason for hiding this comment

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

Well, I don't like it too, but here I see no problem. It is well documented and mean undefined.

Choose a reason for hiding this comment

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

I'm a bit out of the scope however in general I agree with @tolusha. In this very example I would recommend to avoid public method calls with null values (even well documented). I think it would be nice if you could add a corresponding method so we could call changesListPresenter.show(changedItems, REVISION) and it would internally recall changesListPresenter.show(changedItems, REVISION, null) or something similar to this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good piece of advice, but not for this case, unfortunately...
Otherwise we have to make additional methods with different names (to cover two nullable parameters), which will cause additional logic on the invocations.


changedFilesStatuses = new LinkedHashMap<>();
for (String item : diff.split("\n")) {
changedFilesStatuses.put(item.substring(2, item.length()), defineStatus(item.substring(0, 1)));
Copy link
Contributor

Choose a reason for hiding this comment

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

if diff.isEmpty() then you will have an issue

Copy link
Contributor

Choose a reason for hiding this comment

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

Make sure item.length() > 2
If defineStatus(item.substring(0, 1)) throws IllegalArgumentException then catch it

Copy link
Contributor

Choose a reason for hiding this comment

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

To have clear code extract variables for item.substring(2, item.length()) and defineStatus(item.substring(0, 1))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it will end up with empty diff

}

/**
* @return number of files in the diff
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer not to use single @return annotation in javadoc, but to have something like: "Returns number of files in the diff"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok


changedFilesList = new ArrayList<>(changedFilesStatuses.keySet());

length = changedFilesList.size();
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant field

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just cached. But ok, I'll get rid of it.

private final int length;

/**
* Creates user-friendly representation of git diff.
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you mean user-frendly? How does it related to user?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well, programmer friendly)

Copy link
Contributor

Choose a reason for hiding this comment

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

realy? 😄

*
* @author Mykola Morhun
*/
public class ChangedItems {
Copy link
Contributor

Choose a reason for hiding this comment

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

ModifiedFiles ?

Copy link
Contributor Author

@mmorhun mmorhun Aug 10, 2017

Choose a reason for hiding this comment

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

What if it is added or deleted?

Copy link
Contributor

Choose a reason for hiding this comment

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

I dont think that Modified or Changed are good words for this class because such words are present in Git Status. This object can contain not only modified/changed but new or deleted
How about DiffFiles?

Copy link
Contributor Author

@mmorhun mmorhun Aug 10, 2017

Choose a reason for hiding this comment

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

I think TouchedItems is worse. But still open for discussion.

Choose a reason for hiding this comment

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

I'm not sure I understand why do we use term Item here if we're talking exactly about files only according to javadoc? What do you think about something like AlteredFiles? In general I think we can't just name this class ChangedItems as it does not reflect it's nature, personally I would split it into several classes something like ChangedItemParser, ChangedItemHolder and ChangedItem itself, what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AlteredFiles is good name, think no one will be against it.
As about splitting, I see no point to do this. Constructor just do its own work. Its logic isn't complicated to move into separate class. And according to current representation of diff, storing data into internal object will make it more complicated and add small overhead I think.

this.compareWithLatest = true;
view.setEnableSaveChangesButton(true);

setupCurrentFile(currentFile);
Copy link
Contributor

@tolusha tolusha Aug 10, 2017

Choose a reason for hiding this comment

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

You don't setup anything. Rename it respectively.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I disagree to remove it. But name could be changed, ok.

changedItems.getProject()
.getFile(changedItems.getItemByIndex(currentItemIndex))
.then(file -> {
if (file.isPresent()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if !file.isPresent() it means it has been deleted. So, we have to show diff also.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By the way, seems that this is broken in master

* Searches for project with git repository to which given file belongs.
*/
@Nullable
private Container getGitDir(final File file) {
Copy link
Contributor

Choose a reason for hiding this comment

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

getGitRootFolder

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See no logical difference here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Root means not any


if (rootProject == null) {
final Container gitDir = getGitDir(file);
if (gitDir == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we notify user with some message?

Copy link
Contributor Author

@mmorhun mmorhun Aug 10, 2017

Choose a reason for hiding this comment

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

ok


CancelCallback cancelCallback = view::hide;

dialogFactory.createConfirmDialog(locale.compareSaveTitle(), locale.compareSaveQuestion(), locale.buttonYes(), locale.buttonNo(),
confirmCallback, cancelCallback).show();
}

@Override
public void onSaveChangesClicked() {
if (compareWithLatest) {
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 we have to check if compareWithLatest ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just for case.
The Save Changes button should be disabled when compare between revisions is shown.

}

/** @return relative path of given file from specified project */
private Path getRelPath(final Container project, final File file) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like a method for File class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe, but I think it doesn't 'fit' for current File interface

@@ -29,6 +29,9 @@ button.no=No
button.fetch=Fetch
button.push=Push
button.pull=Pull
button.save_changes=Save Changes
button.next_diff=Next
button.previous_diff=Prev
Copy link
Contributor

Choose a reason for hiding this comment

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

Previous ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let be so

@codenvy-ci
Copy link

@@ -75,45 +78,106 @@ public ComparePresenter(AppContext appContext,
}

/**
* Show compare window.
* Show compare window for given set of files between given revision and latest code version.
Copy link
Contributor

Choose a reason for hiding this comment

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

latest code version is not clear enough, I think it should be HEAD

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, agree

@codenvy-ci
Copy link

@codenvy-ci
Copy link

Build # 3557 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/3557/ to view the results.

Signed-off-by: Mykola Morhun <mmorhun@redhat.com>
@codenvy-ci
Copy link

Signed-off-by: Mykola Morhun <mmorhun@redhat.com>
@codenvy-ci
Copy link

@codenvy-ci
Copy link

Signed-off-by: Mykola Morhun <mmorhun@redhat.com>
@mmorhun
Copy link
Contributor Author

mmorhun commented Sep 7, 2017

@vparfonov please review new changes

@mmorhun
Copy link
Contributor Author

mmorhun commented Sep 7, 2017

@slemeur done.
I used alt + , / . (i.e. alt + </> without shift) because alt + left/right are already used in the editor too.

@slemeur
Copy link
Contributor

slemeur commented Sep 7, 2017

@mmorhun : Great ! Where are the docs ;) ?

@codenvy-ci
Copy link

Build # 3580 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/3580/ to view the results.

@mmorhun
Copy link
Contributor Author

mmorhun commented Sep 7, 2017

@slemeur well, I wanted to add them ;) , but I failed to find appropriate place. We have some docs in Git and SVN section which mainly about how to use different types of credentials for VCSs. We do not have a page or a section about using git functionality like change branch, commit, push, pull etc. Most of them are intuitively, but some details for git diff widget, like autosave on next/prev or hotkeys combinations, probably will be useful.
So, should I create a section for git diff widget or just leave it as is?

@mmorhun
Copy link
Contributor Author

mmorhun commented Sep 7, 2017

Maybe we should create separate page in the docs for using git functionality in CHE to not to mess credentials settings and just IDE details/tips.

@slemeur
Copy link
Contributor

slemeur commented Sep 8, 2017

You should move forward and add the information about Git Diff in the user documentation - the page you found is fine.

I agree with you that the content of the page Git and SVN needs to be revisited and re-organized:

Let's start on adding the docs for this PR. If you are able to start to re-organize the content, that would be perfect, but I'll help you on that.

Thanks Mykola.

break;
case RIGHT:
button.addStyleName(resources.windowCss().buttonAlignRight());
break;
Copy link
Contributor

Choose a reason for hiding this comment

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

add default statement or replace with if..else

@codenvy-ci
Copy link

@mmorhun mmorhun merged commit c7ed1d8 into master Sep 12, 2017
@mmorhun mmorhun deleted the CHE-5892 branch September 12, 2017 11:13
@slemeur slemeur added this to the 5.18.0 milestone Sep 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement A feature request - must adhere to the feature request template.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants