1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Benjamin Muskalla and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License 2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-2.0/
8 * SPDX-License-Identifier: EPL-2.0
11 * Benjamin Muskalla <bmuskalla@tasktop.com> - initial API and implementation
12 *******************************************************************************/
13 package org
.eclipse
.egit
.ui
.internal
;
15 import java
.io
.IOException
;
17 import org
.eclipse
.egit
.core
.RepositoryUtil
;
18 import org
.eclipse
.egit
.ui
.Activator
;
19 import org
.eclipse
.egit
.ui
.internal
.clone
.ProjectRecord
;
20 import org
.eclipse
.egit
.ui
.internal
.repository
.tree
.RefNode
;
21 import org
.eclipse
.egit
.ui
.internal
.synchronize
.model
.GitModelObject
;
22 import org
.eclipse
.egit
.ui
.internal
.synchronize
.model
.GitModelRepository
;
23 import org
.eclipse
.jface
.viewers
.StyledString
;
24 import org
.eclipse
.jgit
.annotations
.NonNull
;
25 import org
.eclipse
.jgit
.lib
.BranchTrackingStatus
;
26 import org
.eclipse
.jgit
.lib
.Constants
;
27 import org
.eclipse
.jgit
.lib
.Ref
;
28 import org
.eclipse
.jgit
.lib
.Repository
;
29 import org
.eclipse
.jgit
.lib
.RepositoryState
;
30 import org
.eclipse
.osgi
.util
.NLS
;
33 * Various methods to compute label for different Git repository elements.
35 public class GitLabels
{
41 * @return a description of the ref, or null if the ref does not have a
44 public static String
getRefDescription(Ref ref
) {
45 String name
= ref
.getName();
46 if (name
.equals(Constants
.HEAD
)) {
48 return UIText
.GitLabelProvider_RefDescriptionHeadSymbolic
;
50 return UIText
.GitLabelProvider_RefDescriptionHead
;
51 } else if (name
.equals(Constants
.ORIG_HEAD
))
52 return UIText
.GitLabelProvider_RefDescriptionOrigHead
;
53 else if (name
.equals(Constants
.FETCH_HEAD
))
54 return UIText
.GitLabelProvider_RefDescriptionFetchHead
;
55 else if (name
.equals(Constants
.R_STASH
))
56 return UIText
.GitLabelProvider_RefDescriptionStash
;
62 * Format the branch tracking status suitable for displaying in decorations
66 * @return the branch tracking status as a string
68 public static String
formatBranchTrackingStatus(BranchTrackingStatus status
) {
69 StringBuilder sb
= new StringBuilder();
70 int ahead
= status
.getAheadCount();
71 int behind
= status
.getBehindCount();
82 sb
.append(status
.getBehindCount());
88 * Returns a {@link StyledString} that is initialized with "> " if the
89 * repository has any changes, empty otherwise.
92 * to get the string for
93 * @return the {@link StyledString}
95 public static @NonNull StyledString
getChangedPrefix(
96 @NonNull Repository repository
) {
97 StyledString string
= new StyledString();
98 if (RepositoryUtil
.hasChanges(repository
)) {
99 string
.append('>', StyledString
.DECORATIONS_STYLER
);
106 * Computes detailed repository label that consists of repository name,
107 * state, checked-out branch and it's status (returned by
108 * {@linkplain #formatBranchTrackingStatus(BranchTrackingStatus)})
111 * @return a styled string for the repository
112 * @throws IOException
114 public static @NonNull StyledString
getStyledLabel(
115 @NonNull Repository repository
)
117 StyledString string
= getChangedPrefix(repository
);
119 string
.append(RepositoryUtil
.INSTANCE
.getRepositoryName(repository
));
121 String branch
= RepositoryUtil
.INSTANCE
.getShortBranch(repository
);
122 if (branch
!= null) {
124 string
.append('[', StyledString
.DECORATIONS_STYLER
);
125 string
.append(branch
, StyledString
.DECORATIONS_STYLER
);
127 BranchTrackingStatus trackingStatus
= BranchTrackingStatus
.of(
129 if (trackingStatus
!= null
130 && (trackingStatus
.getAheadCount() != 0 || trackingStatus
131 .getBehindCount() != 0)) {
132 String formattedTrackingStatus
= GitLabels
133 .formatBranchTrackingStatus(trackingStatus
);
135 string
.append(formattedTrackingStatus
,
136 StyledString
.DECORATIONS_STYLER
);
139 RepositoryState repositoryState
= repository
.getRepositoryState();
140 if (repositoryState
!= RepositoryState
.SAFE
) {
141 string
.append(" - ", StyledString
.DECORATIONS_STYLER
); //$NON-NLS-1$
142 string
.append(repositoryState
.getDescription(),
143 StyledString
.DECORATIONS_STYLER
);
145 string
.append(']', StyledString
.DECORATIONS_STYLER
);
152 * Tries to return label produced by
153 * {@linkplain #getStyledLabel(Repository)}. If
154 * {@linkplain #getStyledLabel(Repository)} throws <code>Exception</code>
155 * then logs it and falls back to {@linkplain #getPlainShortLabel(Object)}
159 * @return repository label
161 public static @NonNull StyledString
getStyledLabelSafe(
162 @NonNull Repository repository
) {
164 return getStyledLabel(repository
);
165 } catch (IOException e
) {
166 logLabelRetrievalFailure(repository
, e
);
168 return new StyledString(getPlainShortLabel(repository
));
173 * If the <code>element</code> represents a repository then tries to return
174 * it's styled label (created by {@link #getStyledLabel(Repository)}). If
175 * the <code>element</code> is not a repository or if
176 * {@link #getStyledLabel(Repository)} threw <code>IOException</code> then
177 * this method returns element's simple label (
178 * {@link #getPlainShortLabel(Object)}). If the element is a repository then
179 * the returned label is appended with absolute path to this repository.
182 * IOException thrown by {@link #getStyledLabel(Repository)} is logged.
186 * @return element's label
188 public static @NonNull StyledString
getStyledLabelExtendedSafe(
190 Repository repo
= asRepository(element
);
194 StyledString text
= getStyledLabel(repo
);
195 text
.append(getLabelExtension(repo
),
196 StyledString
.QUALIFIER_STYLER
);
198 } catch (IOException e
) {
199 logLabelRetrievalFailure(element
, e
);
202 return new StyledString(getPlainShortLabelExtended(element
));
207 * @return label computed by {@linkplain #getPlainShortLabel(Object)} with
208 * appended path to the repository if element represents a
211 public static String
getPlainShortLabelExtended(Object element
) {
212 return getPlainShortLabel(element
) + getLabelExtension(element
);
215 private static void logLabelRetrievalFailure(Object element
, IOException e
) {
217 NLS
.bind(UIText
.GitLabelProvider_UnableToRetrieveLabel
,
218 element
.toString()), e
);
221 private static String
getLabelExtension(Object element
) {
222 Repository repo
= asRepository(element
);
225 return " - " + getRepositoryAbsolutePath(repo
); //$NON-NLS-1$
227 return ""; //$NON-NLS-1$
232 * @return simple short label of the Git element (repository, reference,
235 public static String
getPlainShortLabel(Object element
) {
236 if (element
instanceof Repository
)
237 return getRepositorySimpleLabel((Repository
) element
);
239 if (element
instanceof RefNode
)
240 return getRefNodeSimpleLabel((RefNode
) element
);
242 if (element
instanceof Ref
)
243 return ((Ref
) element
).getName();
245 if (element
instanceof ProjectRecord
)
246 return ((ProjectRecord
) element
).getProjectLabel();
248 if (element
instanceof GitModelObject
)
249 return ((GitModelObject
) element
).getName();
251 return (element
!= null ? element
.toString() : ""); //$NON-NLS-1$
254 private static String
getRefNodeSimpleLabel(RefNode refNode
) {
255 return refNode
.getObject().getName();
258 private static String
getRepositorySimpleLabel(Repository repository
) {
259 return RepositoryUtil
.INSTANCE
.getRepositoryName(repository
);
262 private static String
getRepositoryAbsolutePath(Repository repository
) {
263 return repository
.getDirectory().getAbsolutePath();
266 private static Repository
asRepository(Object element
) {
267 if (element
instanceof Repository
)
268 return (Repository
) element
;
269 else if (element
instanceof GitModelRepository
)
270 return ((GitModelRepository
) element
).getRepository();