diff options
author | Thomas Wolf | 2018-02-04 12:11:48 +0000 |
---|---|---|
committer | Matthias Sohn | 2018-02-13 00:16:10 +0000 |
commit | 5275b0cf386c8c3383b26c5e7aa25aa39281eeeb (patch) | |
tree | eafad488410faec5261d43f0b1589cd292458b8d | |
parent | 83758204267e3768c67aed2a4683f747bcffea0c (diff) | |
download | egit-5275b0cf386c8c3383b26c5e7aa25aa39281eeeb.tar.gz egit-5275b0cf386c8c3383b26c5e7aa25aa39281eeeb.tar.xz egit-5275b0cf386c8c3383b26c5e7aa25aa39281eeeb.zip |
Prevent MissingObjectException being logged in ref content proposal
If we do ref content proposal for upstream refs, it's possible that
we don't have the referenced commit locally because it wasn't fetched
yet. Logging a MissingObjectException in this case is misleading.
Check explicitly for this and produce a description that explains this.
Change-Id: I211f906ac2fe9dedb3fc86eaf804ff4f7a6ca0c0
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
10 files changed, 68 insertions, 27 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java index 75b42c262b..98c8f078eb 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java @@ -519,12 +519,16 @@ public class UIUtils { * the repository * @param refListProvider * provides the {@link Ref}s to show in the proposal + * @param upstream + * {@code true} if the candidates provided by the + * {@code refListProvider} are from an upstream repository * @return the content proposal adapter set on the {@code textField} */ public static final ExplicitContentProposalAdapter addRefContentProposalToText( Text textField, Repository repository, - IContentProposalCandidateProvider<Ref> refListProvider) { + IContentProposalCandidateProvider<Ref> refListProvider, + boolean upstream) { return UIUtils.<Ref> addContentProposalToText(textField, refListProvider, (pattern, ref) -> { String shortenedName = Repository @@ -534,7 +538,7 @@ public class UIUtils { && !pattern.matcher(shortenedName).matches()) { return null; } - return new RefContentProposal(repository, ref); + return new RefContentProposal(repository, ref, upstream); }, null, UIText.UIUtils_StartTypingForRemoteRefMessage, UIText.UIUtils_PressShortcutForRemoteRefMessage); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java index 902a667ef2..a608464580 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java @@ -1568,6 +1568,9 @@ public class UIText extends NLS { public static String RefContentProposal_unknownObject; /** */ + public static String RefContentProposal_unknownRemoteObject; + + /** */ public static String ReflogView_DateColumnHeader; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java index bffab7dcb7..d6021e0e17 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java @@ -14,6 +14,7 @@ import java.io.IOException; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.internal.UIText; import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; @@ -76,6 +77,12 @@ public class RefContentProposal implements IContentProposal { private final ObjectId objectId; /** + * Whether the ref is an upstream ref. For upstream refs, it's OK to have a + * missing object; it just means we haven't fetched yet. + */ + private final boolean upstream; + + /** * Create content proposal for specified ref. * * @param repo @@ -84,9 +91,11 @@ public class RefContentProposal implements IContentProposal { * @param ref * ref being a content proposal. May have null or locally * non-existent object id. + * @param upstream + * {@code true} if the ref comes from an upstream repository */ - public RefContentProposal(final Repository repo, final Ref ref) { - this(repo, ref.getName(), ref.getObjectId()); + public RefContentProposal(Repository repo, Ref ref, boolean upstream) { + this(repo, ref.getName(), ref.getObjectId(), upstream); } /** @@ -100,12 +109,15 @@ public class RefContentProposal implements IContentProposal { * @param objectId * object being pointed by this ref name. May be null or locally * non-existent object. + * @param upstream + * {@code true} if the ref comes from an upstream repository */ - public RefContentProposal(final Repository repo, final String refName, - final ObjectId objectId) { + public RefContentProposal(Repository repo, String refName, + ObjectId objectId, boolean upstream) { this.db = repo; this.refName = refName; this.objectId = objectId; + this.upstream = upstream; } @Override @@ -120,10 +132,21 @@ public class RefContentProposal implements IContentProposal { @Override public String getDescription() { - if (objectId == null) + if (objectId == null) { return null; + } try (ObjectReader reader = db.newObjectReader()) { - final ObjectLoader loader = reader.open(objectId); + ObjectLoader loader = null; + try { + loader = reader.open(objectId); + } catch (MissingObjectException e) { + if (upstream) { + return refName + '\n' + objectId.abbreviate(7).name() + + " - " //$NON-NLS-1$ + + UIText.RefContentProposal_unknownRemoteObject; + } + throw e; + } final StringBuilder sb = new StringBuilder(); sb.append(refName); sb.append('\n'); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java index 6375beef66..e29d69a30d 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java @@ -1736,13 +1736,15 @@ public class RefSpecPanel { } }); set.addAll(refs); - if (HEAD != null) + if (HEAD != null) { set.add(HEAD); + } final List<RefContentProposal> result = new ArrayList<>( set.size()); - for (final Ref r : set) - result.add(new RefContentProposal(localDb, r)); + for (final Ref r : set) { + result.add(new RefContentProposal(localDb, r, HEAD == null)); + } return result; } @@ -1817,27 +1819,33 @@ public class RefSpecPanel { // contents contains wildcards // check if contents can be safely added as wildcard spec - if (isValidRefExpression(contents)) - result.add(new RefContentProposal(localDb, contents, null)); + if (isValidRefExpression(contents)) { + result.add(new RefContentProposal(localDb, contents, null, + true)); + } // let's expand wildcards final String regex = ".*" //$NON-NLS-1$ + contents.replace("*", ".*").replace("?", ".?") + ".*"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ final Pattern p = Pattern.compile(regex); - for (final RefContentProposal prop : proposals) - if (p.matcher(prop.getContent()).matches()) + for (final RefContentProposal prop : proposals) { + if (p.matcher(prop.getContent()).matches()) { result.add(prop); + } + } } else { - for (final RefContentProposal prop : proposals) - if (prop.getContent().contains(contents)) + for (final RefContentProposal prop : proposals) { + if (prop.getContent().contains(contents)) { result.add(prop); + } + } if (tryResolvingLocally && result.isEmpty()) { final ObjectId id = tryResolveLocalRef(contents); - if (id != null) - result - .add(new RefContentProposal(localDb, contents, - id)); + if (id != null) { + result.add(new RefContentProposal(localDb, contents, id, + false)); + } } } return result.toArray(new IContentProposal[0]); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java index a22e9de2b8..58c849b76b 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java @@ -94,7 +94,7 @@ public class FetchDestinationPage extends WizardPage { GridDataFactory.fillDefaults().grab(true, false).applyTo( destinationText); UIUtils.addRefContentProposalToText(sourceText, repository, - () -> getRemoteRefs()); + () -> getRemoteRefs(), true); force = new Button(main, SWT.CHECK); force.setText(UIText.FetchDestinationPage_ForceCheckbox); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java index f1ff6c2cea..a78c532db2 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java @@ -89,7 +89,7 @@ public class FetchSourcePage extends WizardPage { }); GridDataFactory.fillDefaults().grab(true, false).applyTo(sourceText); UIUtils.addRefContentProposalToText(sourceText, repository, - () -> getRemoteRefs()); + () -> getRemoteRefs(), true); checkPage(); setControl(main); } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullWizardPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullWizardPage.java index 02b2eadce4..ec80bb6abc 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullWizardPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullWizardPage.java @@ -172,7 +172,7 @@ public class PullWizardPage extends WizardPage { .getRefsForContentAssist(false, true); } return Collections.emptyList(); - }); + }, true); remoteBranchNameText.setText(getSuggestedBranchName()); remoteBranchNameText.addModifyListener(new ModifyListener() { @Override diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushBranchPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushBranchPage.java index 6662edc532..39d7fb8715 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushBranchPage.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushBranchPage.java @@ -323,7 +323,7 @@ public class PushBranchPage extends WizardPage { }); candidateProvider.setContentProposalAdapter( UIUtils.addRefContentProposalToText(remoteBranchNameText, - this.repository, candidateProvider)); + this.repository, candidateProvider, true)); if (this.ref != null) { upstreamConfigComponent = new UpstreamConfigComponent(inputPanel, SWT.NONE); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java index 6eafd866d8..403aa1f28e 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java @@ -159,7 +159,8 @@ public class RefSpecDialog extends TitleAndImageDialog { }); // content assist for source UIUtils.addRefContentProposalToText(sourceText, repo, - () -> assistProvider.getRefsForContentAssist(true, pushMode)); + () -> assistProvider.getRefsForContentAssist(true, pushMode), + !pushMode); // suggest remote tracking branch if (!pushMode) { @@ -198,7 +199,8 @@ public class RefSpecDialog extends TitleAndImageDialog { }); // content assist for destination UIUtils.addRefContentProposalToText(destinationText, repo, - () -> assistProvider.getRefsForContentAssist(false, pushMode)); + () -> assistProvider.getRefsForContentAssist(false, pushMode), + pushMode); // force update forceButton = new Button(main, SWT.CHECK); diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties index 0a210085ae..29e2c0f579 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties @@ -542,6 +542,7 @@ RefContentProposal_tag=tag RefContentProposal_trackingBranch=tracking branch RefContentProposal_tree=tree RefContentProposal_unknownObject=locally unknown object +RefContentProposal_unknownRemoteObject=locally unknown object: upstream is ahead of local repository and hasn't been fetched yet ReflogView_DateColumnHeader=Date ReflogView_ErrorOnLoad=Loading the reflog encountered an error; see the Error Log for more information ReflogView_ErrorOnOpenCommit=Error opening commit |