Search in sources :

Example 1 with CheckoutEntry

use of org.eclipse.jgit.lib.CheckoutEntry in project egit by eclipse.

the class SwitchToMenu method createDynamicMenu.

private void createDynamicMenu(Menu menu, final Repository repository) {
    MenuItem newBranch = new MenuItem(menu, SWT.PUSH);
    newBranch.setText(UIText.SwitchToMenu_NewBranchMenuLabel);
    newBranch.setImage(newBranchImage);
    newBranch.addSelectionListener(new SelectionAdapter() {

        @Override
        public void widgetSelected(SelectionEvent e) {
            String sourceRef = repository.getConfig().getString(ConfigConstants.CONFIG_WORKFLOW_SECTION, null, ConfigConstants.CONFIG_KEY_DEFBRANCHSTARTPOINT);
            CreateBranchWizard wiz = null;
            try {
                Ref ref = null;
                if (sourceRef != null) {
                    ref = repository.findRef(sourceRef);
                }
                if (ref != null) {
                    wiz = new CreateBranchWizard(repository, ref.getName());
                } else {
                    wiz = new CreateBranchWizard(repository, repository.getFullBranch());
                }
            } catch (IOException e1) {
            // Ignore
            }
            if (wiz == null) {
                wiz = new CreateBranchWizard(repository);
            }
            WizardDialog dlg = new WizardDialog(e.display.getActiveShell(), wiz);
            dlg.setHelpAvailable(false);
            dlg.open();
        }
    });
    createSeparator(menu);
    try {
        String currentBranch = repository.getFullBranch();
        Map<String, Ref> localBranches = repository.getRefDatabase().getRefs(Constants.R_HEADS);
        TreeMap<String, Ref> sortedRefs = new TreeMap<>(CommonUtils.STRING_ASCENDING_COMPARATOR);
        // Add the MAX_NUM_MENU_ENTRIES most recently used branches first
        ReflogReader reflogReader = repository.getReflogReader(Constants.HEAD);
        List<ReflogEntry> reflogEntries;
        if (reflogReader == null) {
            reflogEntries = Collections.emptyList();
        } else {
            reflogEntries = reflogReader.getReverseEntries();
        }
        for (ReflogEntry entry : reflogEntries) {
            CheckoutEntry checkout = entry.parseCheckout();
            if (checkout != null) {
                Ref ref = localBranches.get(checkout.getFromBranch());
                if (ref != null)
                    if (sortedRefs.size() < MAX_NUM_MENU_ENTRIES)
                        sortedRefs.put(checkout.getFromBranch(), ref);
                ref = localBranches.get(checkout.getToBranch());
                if (ref != null)
                    if (sortedRefs.size() < MAX_NUM_MENU_ENTRIES)
                        sortedRefs.put(checkout.getToBranch(), ref);
            }
        }
        // Add the recently used branches to the menu, in alphabetical order
        int itemCount = 0;
        for (final Entry<String, Ref> entry : sortedRefs.entrySet()) {
            itemCount++;
            final String shortName = entry.getKey();
            final String fullName = entry.getValue().getName();
            createMenuItem(menu, repository, currentBranch, fullName, shortName);
            // Do not duplicate branch names
            localBranches.remove(shortName);
        }
        if (itemCount < MAX_NUM_MENU_ENTRIES) {
            // local branches
            if (itemCount > 0 && localBranches.size() > 0)
                createSeparator(menu);
            // Now add more other branches if we have only a few branch switches
            // Sort the remaining local branches
            sortedRefs.clear();
            sortedRefs.putAll(localBranches);
            for (final Entry<String, Ref> entry : sortedRefs.entrySet()) {
                itemCount++;
                // protect ourselves against a huge sub-menu
                if (itemCount > MAX_NUM_MENU_ENTRIES)
                    break;
                final String fullName = entry.getValue().getName();
                final String shortName = entry.getKey();
                createMenuItem(menu, repository, currentBranch, fullName, shortName);
            }
        }
        if (itemCount > 0)
            createSeparator(menu);
        MenuItem others = new MenuItem(menu, SWT.PUSH);
        others.setText(UIText.SwitchToMenu_OtherMenuLabel);
        others.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                CheckoutDialog dialog = new CheckoutDialog(e.display.getActiveShell(), repository);
                if (dialog.open() == Window.OK) {
                    BranchOperationUI.checkout(repository, dialog.getRefName()).start();
                }
            }
        });
    } catch (IOException e) {
        Activator.handleError(e.getMessage(), e, true);
    }
}
Also used : ReflogReader(org.eclipse.jgit.lib.ReflogReader) SelectionAdapter(org.eclipse.swt.events.SelectionAdapter) CheckoutDialog(org.eclipse.egit.ui.internal.dialogs.CheckoutDialog) MenuItem(org.eclipse.swt.widgets.MenuItem) IOException(java.io.IOException) TreeMap(java.util.TreeMap) CreateBranchWizard(org.eclipse.egit.ui.internal.repository.CreateBranchWizard) Ref(org.eclipse.jgit.lib.Ref) CheckoutEntry(org.eclipse.jgit.lib.CheckoutEntry) ReflogEntry(org.eclipse.jgit.lib.ReflogEntry) SelectionEvent(org.eclipse.swt.events.SelectionEvent) WizardDialog(org.eclipse.jface.wizard.WizardDialog)

Example 2 with CheckoutEntry

use of org.eclipse.jgit.lib.CheckoutEntry in project egit by eclipse.

the class RepositoryUtil method mapCommitToRef.

/**
 * Tries to map a commit to a symbolic reference.
 * <p>
 * This value will be cached for the given commit ID unless refresh is
 * specified. The return value will be the full name, e.g.
 * "refs/remotes/someBranch", "refs/tags/v.1.0"
 * <p>
 * Since this mapping is not unique, the following precedence rules are
 * used:
 * <ul>
 * <li>Tags take precedence over branches</li>
 * <li>Local branches take preference over remote branches</li>
 * <li>Newer references take precedence over older ones where time stamps
 * are available. Use commiter time stamp from commit if no stamp can be
 * found on the tag</li>
 * <li>If there are still ambiguities, the reference name with the highest
 * lexicographic value will be returned</li>
 * </ul>
 *
 * @param repository
 *            the {@link Repository}
 * @param commitId
 *            a commit
 * @param refresh
 *            if true, the cache will be invalidated
 * @return the symbolic reference, or <code>null</code> if no such reference
 *         can be found
 */
public String mapCommitToRef(Repository repository, String commitId, boolean refresh) {
    synchronized (commitMappingCache) {
        if (!ObjectId.isId(commitId)) {
            return null;
        }
        try {
            ReflogReader reflogReader = repository.getReflogReader(Constants.HEAD);
            if (reflogReader != null) {
                List<ReflogEntry> lastEntry = reflogReader.getReverseEntries();
                for (ReflogEntry entry : lastEntry) {
                    if (entry.getNewId().name().equals(commitId)) {
                        CheckoutEntry checkoutEntry = entry.parseCheckout();
                        if (checkoutEntry != null) {
                            Ref ref = repository.findRef(checkoutEntry.getToBranch());
                            if (ref != null) {
                                ObjectId objectId = ref.getObjectId();
                                if (objectId != null && objectId.getName().equals(commitId)) {
                                    return checkoutEntry.getToBranch();
                                }
                                ref = repository.peel(ref);
                            }
                            if (ref != null) {
                                ObjectId id = ref.getPeeledObjectId();
                                if (id != null && id.getName().equals(commitId)) {
                                    return checkoutEntry.getToBranch();
                                }
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
        // ignore here
        }
        Map<String, String> cacheEntry = commitMappingCache.get(repository.getDirectory().toString());
        if (!refresh && cacheEntry != null && cacheEntry.containsKey(commitId)) {
            // this may be null in fact
            return cacheEntry.get(commitId);
        }
        if (cacheEntry == null) {
            cacheEntry = new HashMap<>();
            commitMappingCache.put(repository.getDirectory().getPath(), cacheEntry);
        } else {
            cacheEntry.clear();
        }
        Map<String, Date> tagMap = new HashMap<>();
        try (RevWalk rw = new RevWalk(repository)) {
            Map<String, Ref> tags = repository.getRefDatabase().getRefs(Constants.R_TAGS);
            for (Ref tagRef : tags.values()) {
                RevObject any = rw.parseAny(repository.resolve(tagRef.getName()));
                if (any instanceof RevTag) {
                    RevTag tag = (RevTag) any;
                    if (tag.getObject().name().equals(commitId)) {
                        Date timestamp;
                        if (tag.getTaggerIdent() != null) {
                            timestamp = tag.getTaggerIdent().getWhen();
                        } else {
                            try {
                                RevCommit commit = rw.parseCommit(tag.getObject());
                                timestamp = commit.getCommitterIdent().getWhen();
                            } catch (IncorrectObjectTypeException e) {
                                // not referencing a comit.
                                timestamp = null;
                            }
                        }
                        tagMap.put(tagRef.getName(), timestamp);
                    }
                } else if (any instanceof RevCommit) {
                    RevCommit commit = ((RevCommit) any);
                    if (commit.name().equals(commitId))
                        tagMap.put(tagRef.getName(), commit.getCommitterIdent().getWhen());
                }
            // else ignore here
            }
        } catch (IOException e) {
        // ignore here
        }
        String cacheValue = null;
        if (!tagMap.isEmpty()) {
            // we try to obtain the "latest" tag
            Date compareDate = new Date(0);
            for (Map.Entry<String, Date> tagEntry : tagMap.entrySet()) {
                if (tagEntry.getValue() != null && tagEntry.getValue().after(compareDate)) {
                    compareDate = tagEntry.getValue();
                    cacheValue = tagEntry.getKey();
                }
            }
            // if we don't have time stamps, we sort
            if (cacheValue == null) {
                // $NON-NLS-1$
                String compareString = "";
                for (String tagName : tagMap.keySet()) {
                    if (tagName.compareTo(compareString) >= 0) {
                        cacheValue = tagName;
                        compareString = tagName;
                    }
                }
            }
        }
        if (cacheValue == null) {
            // we didnt't find a tag, so let's look for local branches
            Set<String> branchNames = new TreeSet<>();
            // put this into a sorted set
            try {
                Map<String, Ref> remoteBranches = repository.getRefDatabase().getRefs(Constants.R_HEADS);
                for (Ref branch : remoteBranches.values()) {
                    ObjectId objectId = branch.getObjectId();
                    if (objectId != null && objectId.name().equals(commitId)) {
                        branchNames.add(branch.getName());
                    }
                }
            } catch (IOException e) {
            // ignore here
            }
            if (!branchNames.isEmpty()) {
                // get the last (sorted) entry
                cacheValue = branchNames.toArray(new String[branchNames.size()])[branchNames.size() - 1];
            }
        }
        if (cacheValue == null) {
            // last try: remote branches
            Set<String> branchNames = new TreeSet<>();
            // put this into a sorted set
            try {
                Map<String, Ref> remoteBranches = repository.getRefDatabase().getRefs(Constants.R_REMOTES);
                for (Ref branch : remoteBranches.values()) {
                    ObjectId objectId = branch.getObjectId();
                    if (objectId != null && objectId.name().equals(commitId)) {
                        branchNames.add(branch.getName());
                    }
                }
                if (!branchNames.isEmpty()) {
                    // get the last (sorted) entry
                    cacheValue = branchNames.toArray(new String[branchNames.size()])[branchNames.size() - 1];
                }
            } catch (IOException e) {
            // ignore here
            }
        }
        cacheEntry.put(commitId, cacheValue);
        return cacheValue;
    }
}
Also used : RevTag(org.eclipse.jgit.revwalk.RevTag) ReflogReader(org.eclipse.jgit.lib.ReflogReader) ObjectId(org.eclipse.jgit.lib.ObjectId) HashMap(java.util.HashMap) RevObject(org.eclipse.jgit.revwalk.RevObject) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Date(java.util.Date) Ref(org.eclipse.jgit.lib.Ref) CheckoutEntry(org.eclipse.jgit.lib.CheckoutEntry) ReflogEntry(org.eclipse.jgit.lib.ReflogEntry) TreeSet(java.util.TreeSet) Map(java.util.Map) HashMap(java.util.HashMap) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

IOException (java.io.IOException)2 CheckoutEntry (org.eclipse.jgit.lib.CheckoutEntry)2 Ref (org.eclipse.jgit.lib.Ref)2 ReflogEntry (org.eclipse.jgit.lib.ReflogEntry)2 ReflogReader (org.eclipse.jgit.lib.ReflogReader)2 Date (java.util.Date)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 TreeSet (java.util.TreeSet)1 CheckoutDialog (org.eclipse.egit.ui.internal.dialogs.CheckoutDialog)1 CreateBranchWizard (org.eclipse.egit.ui.internal.repository.CreateBranchWizard)1 WizardDialog (org.eclipse.jface.wizard.WizardDialog)1 IncorrectObjectTypeException (org.eclipse.jgit.errors.IncorrectObjectTypeException)1 ObjectId (org.eclipse.jgit.lib.ObjectId)1 RevCommit (org.eclipse.jgit.revwalk.RevCommit)1 RevObject (org.eclipse.jgit.revwalk.RevObject)1 RevTag (org.eclipse.jgit.revwalk.RevTag)1 RevWalk (org.eclipse.jgit.revwalk.RevWalk)1 SelectionAdapter (org.eclipse.swt.events.SelectionAdapter)1