From: "Tor Arne Vestbø" <torarnv@gmail.com>
To: "Shawn O. Pearce" <spearce@spearce.org>,
Robin Rosenberg <robin.rosenberg@dewire.com>
Cc: git@vger.kernel.org
Subject: [EGIT PATCH v2 09/12] Implement icon and text decorations of various resource states
Date: Wed, 11 Feb 2009 19:40:11 +0100 [thread overview]
Message-ID: <1234377614-23798-10-git-send-email-torarnv@gmail.com> (raw)
In-Reply-To: <1234377614-23798-9-git-send-email-torarnv@gmail.com>
- Dirty
- Staged
- Conflict
- Assume valid
Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
org.spearce.egit.ui/icons/ovr/assume_valid.gif | Bin 0 -> 85 bytes
org.spearce.egit.ui/icons/ovr/assumevalid.gif | Bin 64 -> 0 bytes
org.spearce.egit.ui/icons/ovr/conflict.gif | Bin 64 -> 194 bytes
org.spearce.egit.ui/icons/ovr/pending_add.gif | Bin 64 -> 0 bytes
org.spearce.egit.ui/icons/ovr/pending_remove.gif | Bin 111 -> 0 bytes
org.spearce.egit.ui/icons/ovr/staged.gif | Bin 0 -> 114 bytes
org.spearce.egit.ui/icons/ovr/staged_added.gif | Bin 0 -> 169 bytes
org.spearce.egit.ui/icons/ovr/staged_removed.gif | Bin 0 -> 176 bytes
.../egit/ui/PluginPreferenceInitializer.java | 3 +
.../src/org/spearce/egit/ui/UIIcons.java | 15 +-
.../src/org/spearce/egit/ui/UIPreferences.java | 6 +
.../src/org/spearce/egit/ui/UIText.java | 17 +-
.../decorators/GitLightweightDecorator.java | 299 +++++++++++++++++---
.../internal/decorators/IDecoratableResource.java | 46 +++
.../preferences/GitDecoratorPreferencePage.java | 152 +++++++++--
.../src/org/spearce/egit/ui/uitext.properties | 15 +-
16 files changed, 477 insertions(+), 76 deletions(-)
create mode 100644 org.spearce.egit.ui/icons/ovr/assume_valid.gif
delete mode 100644 org.spearce.egit.ui/icons/ovr/assumevalid.gif
delete mode 100644 org.spearce.egit.ui/icons/ovr/pending_add.gif
delete mode 100644 org.spearce.egit.ui/icons/ovr/pending_remove.gif
create mode 100644 org.spearce.egit.ui/icons/ovr/staged.gif
create mode 100644 org.spearce.egit.ui/icons/ovr/staged_added.gif
create mode 100644 org.spearce.egit.ui/icons/ovr/staged_removed.gif
diff --git a/org.spearce.egit.ui/icons/ovr/assume_valid.gif b/org.spearce.egit.ui/icons/ovr/assume_valid.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b6d7167cb38b147aa0fcc115121f3166276f6688
GIT binary patch
literal 85
zcmZ?wbhEHb<Y3@pSj5Wk|Nno6&}sGa_b)s3!M=V!hzkaaKUo+V7+4u}Ks=CI24<;<
gU94*oY!sY|O?Vb;E(m>L;^NQ~(4hBvvkHSX0J)kQGXMYp
literal 0
HcmV?d00001
diff --git a/org.spearce.egit.ui/icons/ovr/assumevalid.gif b/org.spearce.egit.ui/icons/ovr/assumevalid.gif
deleted file mode 100644
index c7262ed4e3f9437a51806f70fbc851e3a6f951d3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 64
zcmZ?wbhEHbWM|-D_{abP{~H+o{|7M?f3h$#FfcRdfH)v|1}4Ed_6CP$GF;`pupzry
Lj9oc|fx#L8z0(dE
diff --git a/org.spearce.egit.ui/icons/ovr/conflict.gif b/org.spearce.egit.ui/icons/ovr/conflict.gif
index b444be94a2d09561b212138b1514d5c07610cc07..fce456a49a0d6b19feaef4e1fb8615d8083c674c 100644
GIT binary patch
literal 194
zcmZ?wbhEHb<YwSvIKsfNSXBI}k=aul+s7VW3poWA@dz#iA)&<rB8vn>o~Y|S);7GW
zV|+_e`Ie;0T?OrX8YZiZHCF1XE!R_9uBNn9O6ro5(lQ147ctTQ!GHl3DE?$&WMGhD
z&;bd9>||iIU!ayIII}ZDEm63-?}`D3QE8g^;`e8!hE6+n_+o~G)HE-)gh(9`Kkf%@
d8(7v&JK{arFoJ8^;WC#KQvzQ|Td^=$0|4|&KIZ@c
literal 64
zcmZ?wbhEHbWM|-D_{hM}z`*dI0SXj<vM@3*Ffr(W_#k-(Cc!EF3&kHON*Qck_+rIG
KhIgS14AuZ~{td7I
diff --git a/org.spearce.egit.ui/icons/ovr/pending_add.gif b/org.spearce.egit.ui/icons/ovr/pending_add.gif
deleted file mode 100644
index f2306024b2872e50db4143a790bca93189ef8d5f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 64
zcmZ?wbhEHbWM|-Dn8?6je1?HxCd2>#{}~t<6o0a?iZC!S=m6OaAbAER!723%B?Oj5
R<v1{ie-xgi8_2+54FJ_W4pRUC
diff --git a/org.spearce.egit.ui/icons/ovr/pending_remove.gif b/org.spearce.egit.ui/icons/ovr/pending_remove.gif
deleted file mode 100644
index 4ecce038e66f904af8345f88c2c007706a4bc3d0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 111
zcmZ?wbhEHbWM|-D*v!E2;Qr&bwzj&uy5i#Ew6wIy$jG3eAU{99|Ns9pU;~OjSy)AY
sT6I8@ATt<PWC|uQx@~OiE8rFvPw;68lw@ATcdKBBRM#03Aw~vk0Ht*t9{>OV
diff --git a/org.spearce.egit.ui/icons/ovr/staged.gif b/org.spearce.egit.ui/icons/ovr/staged.gif
new file mode 100644
index 0000000000000000000000000000000000000000..dc0b8c01673b32fde0f9b11c8302ad1ca0a1e902
GIT binary patch
literal 114
zcmZ?wbhEHb<Y3@n*v!E2>(@D15q3p!E=^fpC2=k-SzZ$rK|38WV-+D!6DfNgu|P{%
zPh+VN3xogv|1&T!DE?$&WMJT9&;hc6CU7t?u*hFHX*qrG>5bPI{QDmDwl|kFq+1-m
RA=-DKlJ_A?g`5k6H30u&A6)<d
literal 0
HcmV?d00001
diff --git a/org.spearce.egit.ui/icons/ovr/staged_added.gif b/org.spearce.egit.ui/icons/ovr/staged_added.gif
new file mode 100644
index 0000000000000000000000000000000000000000..c65d16a191f259e0feb55c9244e7545c9063f2ee
GIT binary patch
literal 169
zcmZ?wbhEHb<Y3@nI3mv=<D+lc6C~rUFXwNhSM8ymWTTpFZ&2l?k?oi~MbDtt!(w8P
zX13k6n|3NGHU_nBa)HL3YfROWEiL<k^{d^EU9;|4ZK_}8(Y4mhqBp>NLa2<7LGmO+
zwPfqgH75W6|5yCU!pOiN&!EEq1Ry&ZSk)e=_dO9$3EpXP>xYb&Yrys66%*4FPo$Ud
U`8i&abQEg7#HJw7%D`X^09=zc+W-In
literal 0
HcmV?d00001
diff --git a/org.spearce.egit.ui/icons/ovr/staged_removed.gif b/org.spearce.egit.ui/icons/ovr/staged_removed.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8aaadfb9b9300594a3448986650b82841398287c
GIT binary patch
literal 176
zcmZ?wbhEHb<Y3@nI3mX2@9!TQ8ygf96c`wooSa-&SLf&FS5i_E8XDTx)|Q{29~>Oq
z-rk;)l2TY$7#SHE5D<`;mlqcoS6p2D;Qr&HqN4x*|1;nQia%Kx85qPEbU;c#b~3Q)
zE>P`DcJ&Dn4ViXC=E@Y0u&)L|A2*0x3h8BCs@CD4#4P3#=;_K}%6y8ku!Vua8UVS)
BGb{iA
literal 0
HcmV?d00001
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/PluginPreferenceInitializer.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/PluginPreferenceInitializer.java
index 7465444..a3196f4 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/PluginPreferenceInitializer.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/PluginPreferenceInitializer.java
@@ -44,6 +44,9 @@ public void initializeDefaultPreferences() {
UIText.DecoratorPreferencesPage_projectFormatDefault);
prefs.setDefault(UIPreferences.DECORATOR_SHOW_TRACKED_ICON, true);
prefs.setDefault(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON, true);
+ prefs.setDefault(UIPreferences.DECORATOR_SHOW_STAGED_ICON, true);
+ prefs.setDefault(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON, true);
+ prefs.setDefault(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON, true);
w = new int[] { 500, 500 };
UIPreferences.setDefault(prefs,
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java
index 4c0d189..952816c 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java
@@ -18,11 +18,15 @@
* Icons for the the Eclipse plugin. Mostly decorations.
*/
public class UIIcons {
+
+ /** Decoration for resource in the index but not yet committed. */
+ public static final ImageDescriptor OVR_STAGED;
+
/** Decoration for resource added to index but not yet committed. */
- public static final ImageDescriptor OVR_PENDING_ADD;
+ public static final ImageDescriptor OVR_STAGED_ADD;
/** Decoration for resource removed from the index but not commit. */
- public static final ImageDescriptor OVR_PENDING_REMOVE;
+ public static final ImageDescriptor OVR_STAGED_REMOVE;
/** Decoration for resource not being tracked by Git */
public static final ImageDescriptor OVR_UNTRACKED;
@@ -84,11 +88,12 @@
static {
base = init();
- OVR_PENDING_ADD = map("ovr/pending_add.gif");
- OVR_PENDING_REMOVE = map("ovr/pending_remove.gif");
+ OVR_STAGED = map("ovr/staged.gif");
+ OVR_STAGED_ADD = map("ovr/staged_added.gif");
+ OVR_STAGED_REMOVE = map("ovr/staged_removed.gif");
OVR_UNTRACKED = map("ovr/untracked.gif");
OVR_CONFLICT = map("ovr/conflict.gif");
- OVR_ASSUMEVALID = map("ovr/assumevalid.gif");
+ OVR_ASSUMEVALID = map("ovr/assume_valid.gif");
ELCL16_FIND = map("elcl16/find.gif");
ELCL16_NEXT = map("elcl16/next.gif");
ELCL16_PREVIOUS = map("elcl16/previous.gif");
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIPreferences.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIPreferences.java
index 7916cea..e812716 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIPreferences.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIPreferences.java
@@ -64,6 +64,12 @@
public final static String DECORATOR_SHOW_TRACKED_ICON = "decorator_show_tracked_icon";
/** */
public final static String DECORATOR_SHOW_UNTRACKED_ICON = "decorator_show_untracked_icon";
+ /** */
+ public final static String DECORATOR_SHOW_STAGED_ICON = "decorator_show_staged_icon";
+ /** */
+ public final static String DECORATOR_SHOW_CONFLICTS_ICON = "decorator_show_conflicts_icon";
+ /** */
+ public final static String DECORATOR_SHOW_ASSUME_VALID_ICON = "decorator_show_assume_valid_icon";
/**
* Get the preference values associated with a fixed integer array.
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
index 60e4eaa..7e26337 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
@@ -968,12 +968,18 @@
public static String DecoratorPreferencesPage_generalTabFolder;
/** */
- public static String DecoratorPreferencesPage_nameResourceVariable;
+ public static String DecoratorPreferencesPage_bindingResourceName;
/** */
public static String DecoratorPreferencesPage_bindingBranchName;
/** */
+ public static String DecoratorPreferencesPage_bindingDirtyFlag;
+
+ /** */
+ public static String DecoratorPreferencesPage_bindingStagedFlag;
+
+ /** */
public static String DecoratorPreferencesPage_selectFormats;
/** */
@@ -994,6 +1000,15 @@
/** */
public static String DecoratorPreferencesPage_iconsShowUntracked;
+ /** */
+ public static String DecoratorPreferencesPage_iconsShowStaged;
+
+ /** */
+ public static String DecoratorPreferencesPage_iconsShowConflicts;
+
+ /** */
+ public static String DecoratorPreferencesPage_iconsShowAssumeValid;
+
static {
initializeMessages(UIText.class.getPackage().getName() + ".uitext",
UIText.class);
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
index b20070a..c23ce24 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
@@ -60,9 +60,12 @@
import org.spearce.egit.ui.UIIcons;
import org.spearce.egit.ui.UIPreferences;
import org.spearce.egit.ui.UIText;
+import org.spearce.egit.ui.internal.decorators.IDecoratableResource.Staged;
import org.spearce.jgit.dircache.DirCache;
+import org.spearce.jgit.dircache.DirCacheEntry;
import org.spearce.jgit.dircache.DirCacheIterator;
import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.FileMode;
import org.spearce.jgit.lib.IndexChangedEvent;
import org.spearce.jgit.lib.ObjectId;
import org.spearce.jgit.lib.RefsChangedEvent;
@@ -200,6 +203,20 @@ public void decorate(Object element, IDecoration decoration) {
private boolean ignored = false;
+ private boolean dirty = false;
+
+ private boolean conflicts = false;
+
+ private boolean assumeValid = false;
+
+ private Staged staged = Staged.NOT_STAGED;
+
+ static final int T_HEAD = 0;
+
+ static final int T_INDEX = 1;
+
+ static final int T_WORKSPACE = 2;
+
public DecoratableResourceAdapter(IResource resourceToWrap)
throws IOException {
resource = resourceToWrap;
@@ -207,59 +224,162 @@ public DecoratableResourceAdapter(IResource resourceToWrap)
repository = mapping.getRepository();
headId = repository.resolve(Constants.HEAD);
- initializeValues();
+ switch (resource.getType()) {
+ case IResource.FILE:
+ extractFileProperties();
+ break;
+ case IResource.FOLDER:
+ extractContainerProperties();
+ break;
+ case IResource.PROJECT:
+ extractProjectProperties();
+ break;
+ }
}
- /**
- * Initialize the various values that are used for making decoration
- * decisions later on.
- *
- * We might as well pre-load these now, instead of using lazy
- * initialization, because they are all read by the decorator when
- * building variable bindings and computing the preferred overlay.
- *
- * @throws IOException
- */
- private void initializeValues() throws IOException {
-
- // Resolve current branch
- branch = repository.getBranch();
+ private void extractFileProperties() throws IOException {
+ TreeWalk treeWalk = createHeadVsIndexTreeWalk();
+ if (treeWalk == null)
+ return;
- // Resolve tracked state
- if (getType() == IResource.PROJECT) {
+ if (treeWalk.next())
tracked = true;
+ else
+ return;
+
+ // TODO: Also read ignores from .git/info/excludes et al.
+ if (Team.isIgnoredHint(resource)) {
+ ignored = true;
+ return;
+ }
+
+ final DirCacheIterator indexIterator = treeWalk.getTree(T_INDEX,
+ DirCacheIterator.class);
+ final DirCacheEntry indexEntry = indexIterator != null ? indexIterator
+ .getDirCacheEntry()
+ : null;
+
+ if (indexEntry == null) {
+ staged = Staged.REMOVED;
} else {
- final TreeWalk treeWalk = new TreeWalk(repository);
-
- Set<String> repositoryPaths = Collections.singleton(mapping
- .getRepoRelativePath(resource));
- if (!(repositoryPaths.isEmpty() || repositoryPaths.contains(""))) {
- treeWalk.setFilter(PathFilterGroup
- .createFromStrings(repositoryPaths));
- treeWalk.setRecursive(treeWalk.getFilter()
- .shouldBeRecursive());
- treeWalk.reset();
-
- if (headId != null)
- treeWalk.addTree(new RevWalk(repository)
- .parseTree(headId));
- else
- treeWalk.addTree(new EmptyTreeIterator());
+ if (indexEntry.isAssumeValid()) {
+ dirty = false;
+ assumeValid = true;
+ } else if (indexEntry.getStage() > 0) {
+ conflicts = true;
+ } else if (treeWalk.getRawMode(T_HEAD) == FileMode.MISSING
+ .getBits()) {
+ staged = Staged.ADDED;
+ } else {
+ long indexEntryLastModified = indexEntry.getLastModified();
+ long resourceLastModified = resource.getLocalTimeStamp();
+
+ // C-Git under Windows stores timestamps with 1-seconds
+ // resolution, so we need to check to see if this is the
+ // case here, and possibly fix the timestamp of the resource
+ // to match the resolution of the index.
+ if (indexEntryLastModified % 1000 == 0) {
+ resourceLastModified -= resourceLastModified % 1000;
+ }
+
+ if (resourceLastModified != indexEntryLastModified) {
+ // TODO: Consider doing a content check here, to rule
+ // out false positives, as we might get mismatch between
+ // timestamps, even if the content is the same
+ dirty = true;
+ }
- treeWalk.addTree(new DirCacheIterator(DirCache
- .read(repository)));
- if (treeWalk.next()) {
- tracked = true;
+ if (treeWalk.getRawMode(T_HEAD) != treeWalk
+ .getRawMode(T_INDEX)
+ || !treeWalk.idEqual(T_HEAD, T_INDEX)) {
+ staged = Staged.MODIFIED;
}
}
}
- // Resolve ignored state (currently only reads the global Eclipse
- // ignores)
+ }
+
+ private void extractContainerProperties() throws IOException {
+ TreeWalk treeWalk = createHeadVsIndexTreeWalk();
+ if (treeWalk == null)
+ return;
+
+ if (treeWalk.next())
+ tracked = true;
+ else
+ return;
+
// TODO: Also read ignores from .git/info/excludes et al.
if (Team.isIgnoredHint(resource)) {
ignored = true;
+ return;
}
+
+ // TODO: Compute dirty state for folder, using ContainerTreeIterator
+ // and ContainerDiffFilter
+
+ }
+
+ private void extractProjectProperties() throws IOException {
+ branch = repository.getBranch();
+ tracked = true;
+
+ // TODO: Compute dirty state for folder, using ContainerTreeIterator
+ // and ContainerDiffFilter
+
+ }
+
+ /**
+ * Adds a filter to the specified tree walk limiting the results to only
+ * those matching the resource specified by
+ * <code>resourceToFilterBy</code>
+ * <p>
+ * If the resource does not exists in the current repository, or it has
+ * an empty path (it is the project itself), the filter is not added,
+ * and the method returns <code>null</code>.
+ *
+ * @param treeWalk
+ * the tree walk to add the filter to
+ * @param resourceToFilterBy
+ * the resource to filter by
+ *
+ * @return <code>true</code> if the filter could be added,
+ * <code>false</code> otherwise
+ */
+ private boolean addResourceFilter(final TreeWalk treeWalk,
+ final IResource resourceToFilterBy) {
+ Set<String> repositoryPaths = Collections.singleton(mapping
+ .getRepoRelativePath(resourceToFilterBy));
+ if (repositoryPaths.isEmpty() || repositoryPaths.contains(""))
+ return false;
+
+ treeWalk.setFilter(PathFilterGroup
+ .createFromStrings(repositoryPaths));
+ return true;
+ }
+
+ /**
+ * Helper method to create a new tree walk between HEAD and the index.
+ *
+ * @return the created tree walk, or null if it could not be created
+ * @throws IOException
+ * if there were errors when creating the tree walk
+ */
+ private TreeWalk createHeadVsIndexTreeWalk() throws IOException {
+ final TreeWalk treeWalk = new TreeWalk(repository);
+ if (!addResourceFilter(treeWalk, resource))
+ return null;
+
+ treeWalk.setRecursive(treeWalk.getFilter().shouldBeRecursive());
+ treeWalk.reset();
+
+ if (headId != null)
+ treeWalk.addTree(new RevWalk(repository).parseTree(headId));
+ else
+ treeWalk.addTree(new EmptyTreeIterator());
+
+ treeWalk.addTree(new DirCacheIterator(DirCache.read(repository)));
+ return treeWalk;
}
public String getName() {
@@ -281,6 +401,22 @@ public boolean isTracked() {
public boolean isIgnored() {
return ignored;
}
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public Staged staged() {
+ return staged;
+ }
+
+ public boolean hasConflicts() {
+ return conflicts;
+ }
+
+ public boolean isAssumeValid() {
+ return assumeValid;
+ }
}
/**
@@ -298,6 +434,12 @@ public boolean isIgnored() {
/** */
public static final String BINDING_BRANCH_NAME = "branch"; //$NON-NLS-1$
+ /** */
+ public static final String BINDING_DIRTY_FLAG = "dirty"; //$NON-NLS-1$
+
+ /** */
+ public static final String BINDING_STAGED_FLAG = "staged"; //$NON-NLS-1$
+
private IPreferenceStore store;
/**
@@ -325,10 +467,26 @@ public ImageData getImageData() {
private static ImageDescriptor untrackedImage;
+ private static ImageDescriptor stagedImage;
+
+ private static ImageDescriptor stagedAddedImage;
+
+ private static ImageDescriptor stagedRemovedImage;
+
+ private static ImageDescriptor conflictImage;
+
+ private static ImageDescriptor assumeValidImage;
+
static {
trackedImage = new CachedImageDescriptor(TeamImages
.getImageDescriptor(ISharedImages.IMG_CHECKEDIN_OVR));
untrackedImage = new CachedImageDescriptor(UIIcons.OVR_UNTRACKED);
+ stagedImage = new CachedImageDescriptor(UIIcons.OVR_STAGED);
+ stagedAddedImage = new CachedImageDescriptor(UIIcons.OVR_STAGED_ADD);
+ stagedRemovedImage = new CachedImageDescriptor(
+ UIIcons.OVR_STAGED_REMOVE);
+ conflictImage = new CachedImageDescriptor(UIIcons.OVR_CONFLICT);
+ assumeValidImage = new CachedImageDescriptor(UIIcons.OVR_ASSUMEVALID);
}
/**
@@ -354,6 +512,9 @@ public DecorationHelper(IPreferenceStore preferencesStore) {
*/
public void decorate(IDecoration decoration,
IDecoratableResource resource) {
+ if (resource.isIgnored())
+ return;
+
decorateText(decoration, resource);
decorateIcons(decoration, resource);
}
@@ -379,22 +540,49 @@ private void decorateText(IDecoration decoration,
Map<String, String> bindings = new HashMap<String, String>();
bindings.put(BINDING_RESOURCE_NAME, resource.getName());
bindings.put(BINDING_BRANCH_NAME, resource.getBranch());
+ bindings.put(BINDING_DIRTY_FLAG, resource.isDirty() ? ">" : null);
+ bindings.put(BINDING_STAGED_FLAG,
+ resource.staged() != Staged.NOT_STAGED ? "*" : null);
decorate(decoration, format, bindings);
}
private void decorateIcons(IDecoration decoration,
IDecoratableResource resource) {
- if (resource.isIgnored())
- return;
+ ImageDescriptor overlay = null;
if (resource.isTracked()) {
if (store.getBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON))
- decoration.addOverlay(trackedImage);
- } else if (store
- .getBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON)) {
- decoration.addOverlay(untrackedImage);
+ overlay = trackedImage;
+
+ if (store
+ .getBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON)
+ && resource.isAssumeValid())
+ overlay = assumeValidImage;
+
+ // Staged overrides tracked
+ Staged staged = resource.staged();
+ if (store.getBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON)
+ && staged != Staged.NOT_STAGED) {
+ if (staged == Staged.ADDED)
+ overlay = stagedAddedImage;
+ else if (staged == Staged.REMOVED)
+ overlay = stagedRemovedImage;
+ else
+ overlay = stagedImage;
+ }
+
+ // Conflicts override everything
+ if (store.getBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON)
+ && resource.hasConflicts())
+ overlay = conflictImage;
+
+ } else if (store.getBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON)) {
+ overlay = untrackedImage;
}
+
+ // Overlays can only be added once, so do it at the end
+ decoration.addOverlay(overlay);
}
/**
@@ -411,7 +599,7 @@ private void decorateIcons(IDecoration decoration,
* values
*/
public static void decorate(IDecoration decoration, String format,
- Map bindings) {
+ Map<String, String> bindings) {
StringBuffer prefix = new StringBuffer();
StringBuffer suffix = new StringBuffer();
StringBuffer output = prefix;
@@ -426,6 +614,15 @@ public static void decorate(IDecoration decoration, String format,
String key = format.substring(end + 1, start);
String s;
+ // Allow users to override the binding
+ if (key.indexOf(':') > -1) {
+ String[] keyAndBinding = key.split(":", 2);
+ key = keyAndBinding[0];
+ if (keyAndBinding.length > 1
+ && bindings.get(key) != null)
+ bindings.put(key, keyAndBinding[1]);
+ }
+
// We use the BINDING_RESOURCE_NAME key to determine if
// we are doing the prefix or suffix. The name isn't
// actually part of either.
@@ -433,7 +630,7 @@ public static void decorate(IDecoration decoration, String format,
output = suffix;
s = null;
} else {
- s = (String) bindings.get(key);
+ s = bindings.get(key);
}
if (s != null) {
@@ -522,6 +719,14 @@ public void resourceChanged(IResourceChangeEvent event) {
public boolean visit(IResourceDelta delta) throws CoreException {
final IResource resource = delta.getResource();
+ // If the resource is not part of a project under Git
+ // revision control
+ final RepositoryMapping mapping = RepositoryMapping
+ .getMapping(resource);
+ if (mapping == null) {
+ // Ignore the change
+ return true;
+ }
if (resource.getType() == IResource.ROOT) {
// Continue with the delta
return true;
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/IDecoratableResource.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/IDecoratableResource.java
index f144214..b864a10 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/IDecoratableResource.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/IDecoratableResource.java
@@ -16,6 +16,22 @@
public interface IDecoratableResource {
/**
+ * Set of possible staging states for a resource
+ */
+ public enum Staged {
+ /** Represents a resource that is not staged */
+ NOT_STAGED,
+ /** Represents a resource that has been modified */
+ MODIFIED,
+ /** Represents a resource that is added to Git */
+ ADDED,
+ /** Represents a resource that is removed from Git */
+ REMOVED,
+ /** Represents a resource that has been renamed */
+ RENAMED
+ }
+
+ /**
* Gets the type of the resource as defined by {@link IResource}
*
* @return the type of the resource
@@ -51,4 +67,34 @@
* @return whether or not the resource is ignored
*/
boolean isIgnored();
+
+ /**
+ * Returns whether or not the resource has changes that are not staged
+ *
+ * @return whether or not the resource is dirty
+ */
+ boolean isDirty();
+
+ /**
+ * Returns the staged state of the resource
+ *
+ * The set of allowed values are defined by the <code>Staged</code> enum
+ *
+ * @return the staged state of the resource
+ */
+ Staged staged();
+
+ /**
+ * Returns whether or not the resource has merge conflicts
+ *
+ * @return whether or not the resource has merge conflicts
+ */
+ boolean hasConflicts();
+
+ /**
+ * Returns whether or not the resource is assumed valid
+ *
+ * @return whether or not the resource is assumed valid
+ */
+ boolean isAssumeValid();
}
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/preferences/GitDecoratorPreferencePage.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/preferences/GitDecoratorPreferencePage.java
index 7b637e3..f72ceb7 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/preferences/GitDecoratorPreferencePage.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/preferences/GitDecoratorPreferencePage.java
@@ -55,6 +55,7 @@
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
@@ -71,8 +72,9 @@
import org.spearce.egit.ui.UIPreferences;
import org.spearce.egit.ui.UIText;
import org.spearce.egit.ui.internal.SWTUtils;
-import org.spearce.egit.ui.internal.decorators.GitLightweightDecorator.DecorationHelper;
import org.spearce.egit.ui.internal.decorators.IDecoratableResource;
+import org.spearce.egit.ui.internal.decorators.GitLightweightDecorator.DecorationHelper;
+import org.spearce.egit.ui.internal.decorators.IDecoratableResource.Staged;
/**
* Preference page for customizing Git label decorations
@@ -94,22 +96,43 @@
private Preview preview;
+ private Button showStaged;
+
+ private Button showConflicts;
+
+ private Button showAssumeValid;
+
private static final Collection PREVIEW_FILESYSTEM_ROOT;
private static IPropertyChangeListener themeListener;
static {
final PreviewResource project = new PreviewResource(
- "Project", IResource.PROJECT, "master", true, false); //$NON-NLS-1$1
+ "Project", IResource.PROJECT, "master", true, false, false, Staged.NOT_STAGED, false, false); //$NON-NLS-1$1
final ArrayList<PreviewResource> children = new ArrayList<PreviewResource>();
+
+ children.add(new PreviewResource(
+ "folder", IResource.FOLDER, null, true, false, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
+ children.add(new PreviewResource(
+ "tracked.txt", IResource.FILE, null, true, false, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
children.add(new PreviewResource(
- "folder", IResource.FOLDER, null, true, false)); //$NON-NLS-1$
+ "untracked.txt", IResource.FILE, null, false, false, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
children.add(new PreviewResource(
- "file.txt", IResource.FILE, null, true, false)); //$NON-NLS-1$
+ "ignored.txt", IResource.FILE, null, false, true, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
children.add(new PreviewResource(
- "untracked.txt", IResource.FILE, null, false, false)); //$NON-NLS-1$
+ "dirty.txt", IResource.FILE, null, true, false, true, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
children.add(new PreviewResource(
- "ignored.txt", IResource.FILE, null, false, true)); //$NON-NLS-1$
+ "staged.txt", IResource.FILE, null, true, false, false, Staged.MODIFIED, false, false)); //$NON-NLS-1$
+ children.add(new PreviewResource(
+ "partially-staged.txt", IResource.FILE, null, true, false, true, Staged.MODIFIED, false, false)); //$NON-NLS-1$
+ children.add(new PreviewResource(
+ "added.txt", IResource.FILE, null, true, false, false, Staged.ADDED, false, false)); //$NON-NLS-1$
+ children.add(new PreviewResource(
+ "removed.txt", IResource.FILE, null, true, false, false, Staged.REMOVED, false, false)); //$NON-NLS-1$
+ children.add(new PreviewResource(
+ "conflict.txt", IResource.FILE, null, true, false, true, Staged.NOT_STAGED, true, false)); //$NON-NLS-1$
+ children.add(new PreviewResource(
+ "assume-valid.txt", IResource.FILE, null, true, false, false, Staged.NOT_STAGED, false, true)); //$NON-NLS-1$
project.children = children;
PREVIEW_FILESYSTEM_ROOT = Collections.singleton(project);
}
@@ -190,22 +213,29 @@ private Control createTextDecoratorPage(Composite parent) {
Composite fileTextGroup = SWTUtils.createHVFillComposite(parent,
SWTUtils.MARGINS_DEFAULT, 3);
+ int labelWidth = convertWidthInCharsToPixels(Math.max(
+ UIText.DecoratorPreferencesPage_fileFormatLabel.length(),
+ Math.max(UIText.DecoratorPreferencesPage_folderFormatLabel
+ .length(),
+ UIText.DecoratorPreferencesPage_projectFormatLabel
+ .length())));
+
TextPair format = createFormatEditorControl(fileTextGroup,
UIText.DecoratorPreferencesPage_fileFormatLabel,
UIText.DecoratorPreferencesPage_addVariablesAction,
- getFileBindingDescriptions());
+ getFileBindingDescriptions(), labelWidth);
fileTextFormat = format.t1;
format = createFormatEditorControl(fileTextGroup,
UIText.DecoratorPreferencesPage_folderFormatLabel,
UIText.DecoratorPreferencesPage_addVariablesAction,
- getFolderBindingDescriptions());
+ getFolderBindingDescriptions(), labelWidth);
folderTextFormat = format.t1;
format = createFormatEditorControl(fileTextGroup,
UIText.DecoratorPreferencesPage_projectFormatLabel,
UIText.DecoratorPreferencesPage_addVariablesAction,
- getProjectBindingDescriptions());
+ getProjectBindingDescriptions(), labelWidth);
projectTextFormat = format.t1;
return fileTextGroup;
@@ -219,17 +249,29 @@ private Control createIconDecoratorPage(Composite parent) {
UIText.DecoratorPreferencesPage_iconsShowTracked);
showUntracked = SWTUtils.createCheckBox(imageGroup,
UIText.DecoratorPreferencesPage_iconsShowUntracked);
+ showStaged = SWTUtils.createCheckBox(imageGroup,
+ UIText.DecoratorPreferencesPage_iconsShowStaged);
+ showConflicts = SWTUtils.createCheckBox(imageGroup,
+ UIText.DecoratorPreferencesPage_iconsShowConflicts);
+ showAssumeValid = SWTUtils.createCheckBox(imageGroup,
+ UIText.DecoratorPreferencesPage_iconsShowAssumeValid);
return imageGroup;
}
private TextPair createFormatEditorControl(Composite composite,
- String title, String buttonText, final Map supportedBindings) {
+ String title, String buttonText, final Map supportedBindings,
+ int labelWidth) {
- SWTUtils.createLabel(composite, title);
+ Label label = SWTUtils.createLabel(composite, title);
+ GridData labelGridData = new GridData();
+ labelGridData.widthHint = labelWidth;
+ label.setLayoutData(labelGridData);
Text format = new Text(composite, SWT.BORDER);
- format.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridData textGridData = new GridData(GridData.FILL_HORIZONTAL);
+ textGridData.widthHint = 200;
+ format.setLayoutData(textGridData);
format.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
updatePreview();
@@ -273,16 +315,25 @@ private void initializeValues() {
.getBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON));
showUntracked.setSelection(store
.getBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
+ showStaged.setSelection(store
+ .getBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
+ showConflicts.setSelection(store
+ .getBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
+ showAssumeValid.setSelection(store
+ .getBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
SelectionListener selectionListener = new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
- fPreview.refresh();
+ preview.refresh();
}
};
computeDeepDirtyState.addSelectionListener(selectionListener);
showTracked.addSelectionListener(selectionListener);
showUntracked.addSelectionListener(selectionListener);
+ showStaged.addSelectionListener(selectionListener);
+ showConflicts.addSelectionListener(selectionListener);
+ showAssumeValid.addSelectionListener(selectionListener);
setValid(true);
}
@@ -334,6 +385,12 @@ private boolean performOk(IPreferenceStore store) {
.getSelection());
store.setValue(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON,
showUntracked.getSelection());
+ store.setValue(UIPreferences.DECORATOR_SHOW_STAGED_ICON, showStaged
+ .getSelection());
+ store.setValue(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON,
+ showConflicts.getSelection());
+ store.setValue(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON,
+ showAssumeValid.getSelection());
return true;
}
@@ -363,6 +420,14 @@ protected void performDefaults() {
showUntracked
.setSelection(store
.getDefaultBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
+ showStaged.setSelection(store
+ .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
+ showConflicts
+ .setSelection(store
+ .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
+ showAssumeValid
+ .setSelection(store
+ .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
}
/**
@@ -473,7 +538,11 @@ TextPair(Text t1, Text t2) {
private Map getFileBindingDescriptions() {
Map<String, String> bindings = new HashMap<String, String>();
bindings.put(DecorationHelper.BINDING_RESOURCE_NAME,
- UIText.DecoratorPreferencesPage_nameResourceVariable);
+ UIText.DecoratorPreferencesPage_bindingResourceName);
+ bindings.put(DecorationHelper.BINDING_DIRTY_FLAG,
+ UIText.DecoratorPreferencesPage_bindingDirtyFlag);
+ bindings.put(DecorationHelper.BINDING_STAGED_FLAG,
+ UIText.DecoratorPreferencesPage_bindingStagedFlag);
return bindings;
}
@@ -486,7 +555,11 @@ private Map getFileBindingDescriptions() {
private Map getFolderBindingDescriptions() {
Map<String, String> bindings = new HashMap<String, String>();
bindings.put(DecorationHelper.BINDING_RESOURCE_NAME,
- UIText.DecoratorPreferencesPage_nameResourceVariable);
+ UIText.DecoratorPreferencesPage_bindingResourceName);
+ bindings.put(DecorationHelper.BINDING_DIRTY_FLAG,
+ UIText.DecoratorPreferencesPage_bindingDirtyFlag);
+ bindings.put(DecorationHelper.BINDING_STAGED_FLAG,
+ UIText.DecoratorPreferencesPage_bindingStagedFlag);
return bindings;
}
@@ -499,7 +572,11 @@ private Map getFolderBindingDescriptions() {
private Map getProjectBindingDescriptions() {
Map<String, String> bindings = new HashMap<String, String>();
bindings.put(DecorationHelper.BINDING_RESOURCE_NAME,
- UIText.DecoratorPreferencesPage_nameResourceVariable);
+ UIText.DecoratorPreferencesPage_bindingResourceName);
+ bindings.put(DecorationHelper.BINDING_DIRTY_FLAG,
+ UIText.DecoratorPreferencesPage_bindingDirtyFlag);
+ bindings.put(DecorationHelper.BINDING_STAGED_FLAG,
+ UIText.DecoratorPreferencesPage_bindingStagedFlag);
bindings.put(DecorationHelper.BINDING_BRANCH_NAME,
UIText.DecoratorPreferencesPage_bindingBranchName);
return bindings;
@@ -658,14 +735,28 @@ private PreviewDecoration getDecoration(Object element) {
private boolean ignored;
+ private boolean dirty;
+
+ private boolean conflicts;
+
+ private Staged staged;
+
+ private boolean assumeValid;
+
public PreviewResource(String name, int type, String branch,
- boolean tracked, boolean ignored) {
+ boolean tracked, boolean ignored, boolean dirty, Staged staged,
+ boolean conflicts, boolean assumeValid) {
+
this.name = name;
this.branch = branch;
this.type = type;
this.children = Collections.EMPTY_LIST;
this.tracked = tracked;
this.ignored = ignored;
+ this.dirty = dirty;
+ this.staged = staged;
+ this.conflicts = conflicts;
+ this.assumeValid = assumeValid;
}
public String getName() {
@@ -687,6 +778,22 @@ public boolean isTracked() {
public boolean isIgnored() {
return ignored;
}
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public Staged staged() {
+ return staged;
+ }
+
+ public boolean hasConflicts() {
+ return conflicts;
+ }
+
+ public boolean isAssumeValid() {
+ return assumeValid;
+ }
}
private class PreviewDecoration implements IDecoration {
@@ -703,12 +810,19 @@ public boolean isIgnored() {
private Color foregroundColor;
+ /**
+ * Adds an icon overlay to the decoration
+ * <p>
+ * Copies the behavior of <code>DecorationBuilder</code> of only
+ * allowing the overlay to be set once.
+ */
public void addOverlay(ImageDescriptor overlayImage) {
- overlay = overlayImage;
+ if (overlay == null)
+ overlay = overlayImage;
}
public void addOverlay(ImageDescriptor overlayImage, int quadrant) {
- overlay = overlayImage;
+ addOverlay(overlayImage);
}
public void addPrefix(String prefix) {
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties b/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
index 9940177..e9a2321 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
@@ -358,17 +358,24 @@ DecoratorPreferencesPage_preview=Preview:
DecoratorPreferencesPage_fileFormatLabel=&Files:
DecoratorPreferencesPage_folderFormatLabel=F&olders:
DecoratorPreferencesPage_projectFormatLabel=&Projects:
-DecoratorPreferencesPage_fileFormatDefault={name}
-DecoratorPreferencesPage_folderFormatDefault={name}
-DecoratorPreferencesPage_projectFormatDefault={name} [{branch}]
+DecoratorPreferencesPage_fileFormatDefault={dirty:>} {name}
+DecoratorPreferencesPage_folderFormatDefault={dirty:>} {name}
+DecoratorPreferencesPage_projectFormatDefault={dirty:>} {name} [{branch}]
DecoratorPreferencesPage_labelDecorationsLink=See <a>''{0}''</a> to enable or disable Git decorations.
DecoratorPreferencesPage_generalTabFolder=&General
-DecoratorPreferencesPage_nameResourceVariable=name of the resource being decorated
+DecoratorPreferencesPage_bindingResourceName=name of the resource being decorated
DecoratorPreferencesPage_bindingBranchName=current branch of the project
+DecoratorPreferencesPage_bindingDirtyFlag=flag indicating whether or not the resource is dirty
+DecoratorPreferencesPage_bindingStagedFlag=flag indicating whether or not the resource is staged
DecoratorPreferencesPage_selectFormats=Select the format for file, folders, and project text labels:
DecoratorPreferencesPage_selectVariablesToAdd=Select the &variables to add to the decoration format:
DecoratorPreferencesPage_textLabel=T&ext Decorations
DecoratorPreferencesPage_iconLabel=&Icon Decorations
DecoratorPreferencesPage_iconsShowTracked=Tracked resources
DecoratorPreferencesPage_iconsShowUntracked=Untracked resources
+DecoratorPreferencesPage_iconsShowStaged=Staged resources
+DecoratorPreferencesPage_iconsShowConflicts=Conflicting resources
+DecoratorPreferencesPage_iconsShowAssumeValid=Assumed unchanged resources
+
+Decorator_exceptionMessage=Errors occurred while applying Git decorations to resources.
--
1.6.1.2.309.g2ea3
next prev parent reply other threads:[~2009-02-11 18:42 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-11 18:40 [EGIT PATCH v2 00/12] Support customizable label decorations Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 01/12] Add support code to handle plugin property changes Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 02/12] Use Set instead of array to keep track of change listeners Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 03/12] Add a specialized team exception for Git Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 04/12] Add new class ExceptionCollector for grouping exceptions Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 05/12] Add new class SWTUtils with helper-methods for creating controls Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 06/12] Implement basic customizable label decorations with preferences Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 07/12] Add binding for name of the current branch Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 08/12] Add icon decoration for tracked and untracked resources Tor Arne Vestbø
2009-02-11 18:40 ` Tor Arne Vestbø [this message]
2009-02-11 18:40 ` [EGIT PATCH v2 10/12] Don't decorate every single resource on repository change Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 11/12] Expose the underlying resource entries in ContainerTreeIterator Tor Arne Vestbø
2009-02-11 18:40 ` [EGIT PATCH v2 12/12] Implement label decorations for folders and projects Tor Arne Vestbø
2009-02-12 0:02 ` Robin Rosenberg
2009-02-11 22:16 ` [EGIT PATCH v2 08/12] Add icon decoration for tracked and untracked resources Robin Rosenberg
2009-02-11 22:46 ` [EGIT PATCH 08/12 v3] " Tor Arne Vestbø
2009-02-16 20:57 ` [EGIT PATCH v2 00/12] Support customizable label decorations Robin Rosenberg
2009-02-16 22:49 ` Tor Arne Vestbø
2009-02-17 5:52 ` Robin Rosenberg
2009-02-17 17:51 ` [EGIT PATCH 13/12] Add new file tree iterator that can adapt into a ContainerTreeIterator Tor Arne Vestbø
2009-02-17 17:52 ` [EGIT PATCH 14/12] Allow project decorations regardless of repository root location Tor Arne Vestbø
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1234377614-23798-10-git-send-email-torarnv@gmail.com \
--to=torarnv@gmail.com \
--cc=git@vger.kernel.org \
--cc=robin.rosenberg@dewire.com \
--cc=spearce@spearce.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.