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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).