Git development
 help / color / mirror / Atom feed
* [PATCH 2/4] t5516: refactor oddball tests
From: Jeff King @ 2008-11-07 22:20 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Sam Vilain
In-Reply-To: <20081107220730.GA15942@coredump.intra.peff.net>

t5516 sets up some utility functions for starting each test
with a clean slate. However, there were a few tests added
that do not use these functions, but instead make their own
repositories.

Let's bring these in line with the rest of the tests. Not
only do we reduce the number of lines, but these tests will
benefit from any further enhancements to the utility
scripts.

The conversion is pretty straightforward. Most of the tests
created a parent/child clone relationship, for which we now
use 'testrepo' as the parent.  One test looked in testrepo,
but relied on previous tests to have set it up; it now sets
up testrepo explicitly, which makes it a bit more robust to
changes in the script, as well.

Signed-off-by: Jeff King <peff@peff.net>
---
This is on top of 'next' to pick up the recent test from Clemens
Buchacher.

A few oddities here while I was digging in the history:

  - I actually introduced the first of these tests for local tracking
    refs in 09fba7a59 (and the others, being related, copied the style).
    But then I reverted them in 0673c96, because Alex had added other
    similar tests in t5404.  However, these tests ended up being
    re-added by Dscho in 28391a80, which adds a totally unrelated test.
    I think it's the result of a bad patch application (IIRC, he marked
    up my tests to avoid having them chdir for the whole test script.
    During application, Junio would see them going from tweaks to whole
    creation, and presumably just resolved the conflict that way).

    So my initial thought was to simply delete these tests. But since
    then, other related tests have been added to this script, and we do
    want to keep those. So I decided to keep them all, as they form a
    logical progression related to tracking refs. So while there is some
    duplication with t5404, I don't think it is a problem.

  - One of the tests called 'pwd', and I can't see that it would do
    anything useful. I assume it was just leftover debugging cruft
    (especially since it is from that same commit by Dscho).

 t/t5516-fetch-push.sh |   50 ++++++++++++++++++++----------------------------
 1 files changed, 21 insertions(+), 29 deletions(-)

diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 598664c..3411107 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -39,6 +39,11 @@ mk_test () {
 	)
 }
 
+mk_child() {
+	rm -rf "$1" &&
+	git clone testrepo "$1"
+}
+
 check_push_result () {
 	(
 		cd testrepo &&
@@ -425,13 +430,10 @@ test_expect_success 'push with dry-run' '
 
 test_expect_success 'push updates local refs' '
 
-	rm -rf parent child &&
-	mkdir parent &&
-	(cd parent && git init &&
-		echo one >foo && git add foo && git commit -m one) &&
-	git clone parent child &&
+	mk_test heads/master &&
+	mk_child child &&
 	(cd child &&
-		echo two >foo && git commit -a -m two &&
+		git pull .. master &&
 		git push &&
 	test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
 
@@ -439,15 +441,10 @@ test_expect_success 'push updates local refs' '
 
 test_expect_success 'push updates up-to-date local refs' '
 
-	rm -rf parent child &&
-	mkdir parent &&
-	(cd parent && git init &&
-		echo one >foo && git add foo && git commit -m one) &&
-	git clone parent child1 &&
-	git clone parent child2 &&
-	(cd child1 &&
-		echo two >foo && git commit -a -m two &&
-		git push) &&
+	mk_test heads/master &&
+	mk_child child1 &&
+	mk_child child2 &&
+	(cd child1 && git pull .. master && git push) &&
 	(cd child2 &&
 		git pull ../child1 master &&
 		git push &&
@@ -457,11 +454,8 @@ test_expect_success 'push updates up-to-date local refs' '
 
 test_expect_success 'push preserves up-to-date packed refs' '
 
-	rm -rf parent child &&
-	mkdir parent &&
-	(cd parent && git init &&
-		echo one >foo && git add foo && git commit -m one) &&
-	git clone parent child &&
+	mk_test heads/master &&
+	mk_child child &&
 	(cd child &&
 		git push &&
 	! test -f .git/refs/remotes/origin/master)
@@ -470,15 +464,13 @@ test_expect_success 'push preserves up-to-date packed refs' '
 
 test_expect_success 'push does not update local refs on failure' '
 
-	rm -rf parent child &&
-	mkdir parent &&
-	(cd parent && git init &&
-		echo one >foo && git add foo && git commit -m one &&
-		echo exit 1 >.git/hooks/pre-receive &&
-		chmod +x .git/hooks/pre-receive) &&
-	git clone parent child &&
+	mk_test heads/master &&
+	mk_child child &&
+	mkdir testrepo/.git/hooks &&
+	echo exit 1 >testrepo/.git/hooks/pre-receive &&
+	chmod +x testrepo/.git/hooks/pre-receive &&
 	(cd child &&
-		echo two >foo && git commit -a -m two &&
+		git pull .. master
 		test_must_fail git push &&
 		test $(git rev-parse master) != \
 			$(git rev-parse remotes/origin/master))
@@ -487,7 +479,7 @@ test_expect_success 'push does not update local refs on failure' '
 
 test_expect_success 'allow deleting an invalid remote ref' '
 
-	pwd &&
+	mk_test heads/master &&
 	rm -f testrepo/.git/objects/??/* &&
 	git push testrepo :refs/heads/master &&
 	(cd testrepo && test_must_fail git rev-parse --verify refs/heads/master)
-- 
1.6.0.3.866.gc189b

^ permalink raw reply related

* [PATCH 1/4] t5400: expect success for denying deletion
From: Jeff King @ 2008-11-07 22:09 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Sam Vilain, Jan Krüger
In-Reply-To: <20081107220730.GA15942@coredump.intra.peff.net>

Commit a240de11 introduced this test and the code to make it
successful.

Signed-off-by: Jeff King <peff@peff.net>
---
Reading over the mailing list postings which led to a240de11, I think it
is simply a case that Jan didn't fully understand what expect_failure
meant (it means "this is a test that is currently broken, but we hope to
fix in the future", and not anything to do with the test_must_fail in
the test itself).

 t/t5400-send-pack.sh |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 6fe2f87..da69f08 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -103,7 +103,7 @@ unset GIT_CONFIG GIT_CONFIG_LOCAL
 HOME=`pwd`/no-such-directory
 export HOME ;# this way we force the victim/.git/config to be used.
 
-test_expect_failure \
+test_expect_success \
 	'pushing a delete should be denied with denyDeletes' '
 	cd victim &&
 	git config receive.denyDeletes true &&
-- 
1.6.0.3.866.gc189b

^ permalink raw reply related

* [EGIT PATCH 6/7] Add tags to the graphical history display.
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226095664-13759-6-git-send-email-robin.rosenberg@dewire.com>

Both the SWT (Eclipse) drawing and Swing versions are updated.
The coloring and shapes are intentionally not the same as for gitk.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../egit/ui/internal/history/SWTCommit.java        |    5 +-
 .../egit/ui/internal/history/SWTPlotRenderer.java  |   71 +++++++++++++++++++-
 .../spearce/egit/ui/internal/history/SWTWalk.java  |    2 +-
 .../org/spearce/jgit/awtui/AWTPlotRenderer.java    |   46 +++++++++++++
 .../spearce/jgit/revplot/AbstractPlotRenderer.java |   23 ++++++-
 .../src/org/spearce/jgit/revplot/PlotCommit.java   |    8 ++-
 .../src/org/spearce/jgit/revplot/PlotWalk.java     |   60 ++++++++++++++++-
 7 files changed, 207 insertions(+), 8 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java
index fa0d25d..2341fbd 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java
@@ -10,12 +10,13 @@
 import org.eclipse.swt.widgets.Widget;
 import org.spearce.jgit.lib.AnyObjectId;
 import org.spearce.jgit.revplot.PlotCommit;
+import org.spearce.jgit.lib.Ref;
 
 class SWTCommit extends PlotCommit<SWTCommitList.SWTLane> {
 	Widget widget;
 
-	SWTCommit(final AnyObjectId id) {
-		super(id);
+	SWTCommit(final AnyObjectId id, final Ref[] tags) {
+		super(id, tags);
 	}
 
 	@Override
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java
index c4ee282..b008df7 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java
@@ -15,7 +15,10 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.themes.ColorUtil;
 import org.spearce.egit.ui.internal.history.SWTCommitList.SWTLane;
+import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.revplot.AbstractPlotRenderer;
 import org.spearce.jgit.revplot.PlotCommit;
 
@@ -26,7 +29,13 @@
 
 	private final Color sys_gray;
 
-	private Color sys_darkblue;
+	private final Color sys_darkblue;
+
+	private final Color sys_yellow;
+
+	private final Color sys_green;
+
+	private final Color sys_white;
 
 	GC g;
 
@@ -43,6 +52,9 @@ SWTPlotRenderer(final Display d) {
 		sys_black = d.getSystemColor(SWT.COLOR_BLACK);
 		sys_gray = d.getSystemColor(SWT.COLOR_GRAY);
 		sys_darkblue = d.getSystemColor(SWT.COLOR_DARK_BLUE);
+		sys_yellow = d.getSystemColor(SWT.COLOR_YELLOW);
+		sys_green = d.getSystemColor(SWT.COLOR_GREEN);
+		sys_white = d.getSystemColor(SWT.COLOR_WHITE);
 	}
 
 	void paint(final Event event) {
@@ -92,7 +104,64 @@ protected void drawText(final String msg, final int x, final int y) {
 		g.drawString(msg, cellX + x, cellY + texty, true);
 	}
 
+	@Override
+	protected int drawLabel(int x, int y, Ref ref) {
+		String txt;
+		String name = ref.getOrigName();
+		if (name.startsWith(Constants.R_HEADS)) {
+			g.setBackground(sys_green);
+			txt = name.substring(Constants.R_HEADS.length());
+		} else if (name.startsWith(Constants.R_REMOTES)){
+			g.setBackground(sys_gray);
+			txt = name.substring(Constants.R_REMOTES.length());
+		} else if (name.startsWith(Constants.R_TAGS)){
+			g.setBackground(sys_yellow);
+			txt = name.substring(Constants.R_TAGS.length());
+		} else {
+			// Whatever this would be
+			g.setBackground(sys_white);
+			if (name.startsWith(Constants.R_REFS))
+				txt = name.substring(Constants.R_REFS.length());
+			else
+				txt = name; // HEAD and such
+		}
+
+		// Make peeled objects, i.e. via annotated tags come out in a paler color
+		Color peeledColor = null;
+		if (ref.getPeeledObjectId() == null || !ref.getPeeledObjectId().equals(ref.getObjectId())) {
+			peeledColor = new Color(g.getDevice(), ColorUtil.blend(g.getBackground().getRGB(), sys_white.getRGB()));
+			g.setBackground(peeledColor);
+		}
+
+		if (txt.length() > 12)
+			txt = txt.substring(0,11) + "\u2026"; // ellipsis "…" (in UTF-8)
+
+		Point textsz = g.stringExtent(txt);
+		int arc = textsz.y/2;
+		final int texty = (y * 2 - textsz.y) / 2;
+
+		// Draw backgrounds
+		g.fillRoundRectangle(x + 1, cellY + texty -1, textsz.x + 3, textsz.y + 1, arc, arc);
+		g.setForeground(sys_black);
+		g.drawString(txt, x + 2, cellY + texty, true);
+		g.setLineWidth(2);
+
+		// And a two color shaded border, blend with whatever background there already is
+		g.setAlpha(128);
+		g.setForeground(sys_gray);
+		g.drawRoundRectangle(x, cellY + texty -2, textsz.x + 5, textsz.y + 3, arc, arc);
+		g.setLineWidth(2);
+		g.setForeground(sys_black);
+		g.drawRoundRectangle(x + 1, cellY + texty -1, textsz.x + 3, textsz.y + 1, arc, arc);
+		g.setAlpha(255);
+
+		if (peeledColor != null)
+			peeledColor.dispose();
+		return 8 + textsz.x;
+	}
+
 	protected Color laneColor(final SWTLane myLane) {
 		return myLane != null ? myLane.color : sys_black;
 	}
+
 }
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java
index 527d284..57039b5 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java
@@ -19,6 +19,6 @@ SWTWalk(final Repository repo) {
 
 	@Override
 	protected RevCommit createCommit(final AnyObjectId id) {
-		return new SWTCommit(id);
+		return new SWTCommit(id, getTags(id));
 	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java b/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java
index b6b715c..5dcddf5 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java
@@ -44,6 +44,8 @@
 
 import org.spearce.jgit.awtui.CommitGraphPane.GraphCellRender;
 import org.spearce.jgit.awtui.SwingCommitList.SwingLane;
+import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.revplot.AbstractPlotRenderer;
 import org.spearce.jgit.revplot.PlotCommit;
 
@@ -134,4 +136,48 @@ void paintTriangleDown(final int cx, final int y, final int h) {
 		g.drawPolygon(triangle);
 	}
 
+	@Override
+	protected int drawLabel(int x, int y, Ref ref) {
+		String txt;
+		String name = ref.getOrigName();
+		if (name.startsWith(Constants.R_HEADS)) {
+			g.setBackground(Color.GREEN);
+			txt = name.substring(Constants.R_HEADS.length());
+		} else if (name.startsWith(Constants.R_REMOTES)){
+			g.setBackground(Color.LIGHT_GRAY);
+			txt = name.substring(Constants.R_REMOTES.length());
+		} else if (name.startsWith(Constants.R_TAGS)){
+			g.setBackground(Color.YELLOW);
+			txt = name.substring(Constants.R_TAGS.length());
+		} else {
+			// Whatever this would be
+			g.setBackground(Color.WHITE);
+			if (name.startsWith(Constants.R_REFS))
+				txt = name.substring(Constants.R_REFS.length());
+			else
+				txt = name; // HEAD and such
+		}
+		if (ref.getPeeledObjectId() != null) {
+			float[] colorComponents = g.getBackground().getRGBColorComponents(null);
+			colorComponents[0] *= 0.9;
+			colorComponents[1] *= 0.9;
+			colorComponents[2] *= 0.9;
+			g.setBackground(new Color(colorComponents[0],colorComponents[1],colorComponents[2]));
+		}
+		if (txt.length() > 12)
+			txt = txt.substring(0,11) + "\u2026"; // ellipsis "…" (in UTF-8)
+
+		final int texth = g.getFontMetrics().getHeight();
+		int textw = g.getFontMetrics().stringWidth(txt);
+		g.setColor(g.getBackground());
+		int arcHeight = texth/4;
+		int y0 = y - texth/2 + (cell.getHeight() - texth)/2;
+		g.fillRoundRect(x , y0, textw + arcHeight*2, texth -1, arcHeight, arcHeight);
+		g.setColor(g.getColor().darker());
+		g.drawRoundRect(x, y0, textw + arcHeight*2, texth -1 , arcHeight, arcHeight);
+		g.setColor(Color.BLACK);
+		g.drawString(txt, x + arcHeight, y0 + texth - g.getFontMetrics().getDescent());
+
+		return arcHeight * 3 + textw;
+	}
 }
\ No newline at end of file
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java
index f175c9d..911dd68 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java
@@ -37,6 +37,7 @@
 
 package org.spearce.jgit.revplot;
 
+import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.revwalk.RevFlag;
 
 /**
@@ -140,11 +141,29 @@ protected void paintCommit(final PlotCommit<TLane> commit, final int h) {
 		else
 			drawCommitDot(dotX, dotY, dotSize, dotSize);
 
+		int textx = Math.max(maxCenter + LANE_WIDTH / 2, dotX + dotSize) + 8;
+		int n = commit.refs == null ? 0 : commit.refs.length;
+		for (int i = 0; i < n; ++i) {
+			textx += drawLabel(textx + dotSize, h/2, commit.refs[i]);
+		}
+
 		final String msg = commit.getShortMessage();
-		final int textx = Math.max(maxCenter + LANE_WIDTH / 2, dotX + dotSize) + 8;
-		drawText(msg, textx, h / 2);
+		drawText(msg, textx + dotSize + n*2, h / 2);
 	}
 
+	/**
+	 * Draw a decoration for the Ref ref at x,y
+	 *
+	 * @param x
+	 *            left
+	 * @param y
+	 *            top
+	 * @param ref
+	 *            A peeled ref
+	 * @return width of label in pixels
+	 */
+	protected abstract int drawLabel(int x, int y, Ref ref);
+
 	private int computeDotSize(final int h) {
 		int d = (int) (Math.min(h, LANE_WIDTH) * 0.50f);
 		d += (d & 1);
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java
index 5a5ef1e..c885a44 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java
@@ -39,6 +39,7 @@
 
 import org.spearce.jgit.lib.AnyObjectId;
 import org.spearce.jgit.revwalk.RevCommit;
+import org.spearce.jgit.lib.Ref;
 
 /**
  * A commit reference to a commit in the DAG.
@@ -58,14 +59,19 @@
 
 	PlotCommit[] children;
 
+	final Ref[] refs;
+
 	/**
 	 * Create a new commit.
 	 * 
 	 * @param id
 	 *            the identity of this commit.
+	 * @param tags
+	 *            the tags associated with this commit, null for no tags
 	 */
-	protected PlotCommit(final AnyObjectId id) {
+	protected PlotCommit(final AnyObjectId id, final Ref[] tags) {
 		super(id);
+		this.refs = tags;
 		passingLanes = NO_LANES;
 		children = NO_CHILDREN;
 	}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java
index e5e8aba..8801850 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java
@@ -37,14 +37,33 @@
 
 package org.spearce.jgit.revplot;
 
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+
 import org.spearce.jgit.lib.AnyObjectId;
+import org.spearce.jgit.lib.Commit;
+import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.lib.Tag;
 import org.spearce.jgit.revwalk.RevCommit;
 import org.spearce.jgit.revwalk.RevSort;
 import org.spearce.jgit.revwalk.RevWalk;
 
 /** Specialized RevWalk for visualization of a commit graph. */
 public class PlotWalk extends RevWalk {
+
+	private Map<AnyObjectId, Set<Ref>> reverseRefMap;
+
+	@Override
+	public void dispose() {
+		super.dispose();
+		reverseRefMap.clear();
+	}
+
 	/**
 	 * Create a new revision walker for a given repository.
 	 * 
@@ -54,6 +73,7 @@
 	public PlotWalk(final Repository repo) {
 		super(repo);
 		super.sort(RevSort.TOPO, true);
+		reverseRefMap = repo.getAllRefsByPeeledObjectId();
 	}
 
 	@Override
@@ -65,6 +85,44 @@ public void sort(final RevSort s, final boolean use) {
 
 	@Override
 	protected RevCommit createCommit(final AnyObjectId id) {
-		return new PlotCommit(id);
+		return new PlotCommit(id, getTags(id));
+	}
+
+	protected Ref[] getTags(final AnyObjectId commitId) {
+		Collection<Ref> list = reverseRefMap.get(commitId);
+		Ref[] tags;
+		if (list == null)
+			tags = null;
+		else {
+			tags = list.toArray(new Ref[list.size()]);
+			Arrays.sort(tags, new PlotRefComparator());
+		}
+		return tags;
+	}
+
+	class PlotRefComparator implements Comparator<Ref> {
+		public int compare(Ref o1, Ref o2) {
+			try {
+				Object obj1 = getRepository().mapObject(o1.getObjectId(), o1.getName());
+				Object obj2 = getRepository().mapObject(o2.getObjectId(), o2.getName());
+				long t1 = timeof(obj1);
+				long t2 = timeof(obj2);
+				if (t1 > t2)
+					return -1;
+				if (t1 < t2)
+					return 1;
+				return 0;
+			} catch (IOException e) {
+				// ignore
+				return 0;
+			}
+		}
+		long timeof(Object o) {
+			if (o instanceof Commit)
+				return ((Commit)o).getCommitter().getWhen().getTime();
+			if (o instanceof Tag)
+				return ((Tag)o).getTagger().getWhen().getTime();
+			return 0;
+		}
 	}
 }
-- 
1.6.0.3.578.g6a50

^ permalink raw reply related

* [EGIT PATCH 5/7] Add a method to get refs by object Id
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226095664-13759-5-git-send-email-robin.rosenberg@dewire.com>

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../src/org/spearce/jgit/lib/Repository.java       |   34 ++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index 4d6e6fd..82a7454 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -47,10 +47,13 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.Vector;
 
 import org.spearce.jgit.errors.IncorrectObjectTypeException;
@@ -952,6 +955,37 @@ public Ref peel(final Ref ref) {
 	}
 
 	/**
+	 * @return a map with all objects referenced by a peeled ref.
+	 */
+	public Map<AnyObjectId, Set<Ref>> getAllRefsByPeeledObjectId() {
+		Map<String, Ref> allRefs = getAllRefs();
+		Map<AnyObjectId, Set<Ref>> ret = new HashMap<AnyObjectId, Set<Ref>>(allRefs.size());
+		for (Ref ref : allRefs.values()) {
+			if (ref == null)
+				continue;
+			if (!ref.isPeeled()) {
+				ref = peel(ref);
+				allRefs.put(ref.getOrigName(), ref);
+			}
+			AnyObjectId target = ref.getPeeledObjectId();
+			if (target == null)
+				target = ref.getObjectId();
+			// We assume most Sets here are singletons
+			Set<Ref> oset = ret.put(target, Collections.singleton(ref));
+			if (oset != null) {
+				// that was not the case (rare)
+				if (oset.size() == 1) {
+					// Was a read-only singleton, we must copy to a new Set
+					oset = new HashSet<Ref>(oset);
+				}
+				ret.put(target, oset);
+				oset.add(ref);
+			}
+		}
+		return ret;
+	}
+
+	/**
 	 * @return true if HEAD points to a StGit patch.
 	 */
 	public boolean isStGitMode() {
-- 
1.6.0.3.578.g6a50

^ permalink raw reply related

* [EGIT PATCH 3/7] Keep original ref name when reading refs
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226095664-13759-3-git-send-email-robin.rosenberg@dewire.com>

We want to know the original name of refs, not just the target name.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java |   63 +++++++++++++++++++-
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   45 +++++++++-----
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   14 ++---
 3 files changed, 94 insertions(+), 28 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
index db94875..2f102af 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
@@ -43,6 +43,11 @@
  * A ref in Git is (more or less) a variable that holds a single object
  * identifier. The object identifier can be any valid Git object (blob, tree,
  * commit, annotated tag, ...).
+ * <p>
+ * The ref name has the attributes of the ref that was asked for as well as
+ * the ref it was resolved to for symbolic refs plus the object id it points
+ * to and (for tags) the peeled target object id, i.e. the tag resolved
+ * recursively until a non-tag object is referenced.
  */
 public class Ref {
 	/** Location where a {@link Ref} is stored. */
@@ -119,19 +124,24 @@ public boolean isPacked() {
 
 	private ObjectId peeledObjectId;
 
+	private final String origName;
+
 	/**
 	 * Create a new ref pairing.
 	 * 
 	 * @param st
 	 *            method used to store this ref.
+	 * @param origName
+	 *            The name used to resolve this ref
 	 * @param refName
 	 *            name of this ref.
 	 * @param id
 	 *            current value of the ref. May be null to indicate a ref that
 	 *            does not exist yet.
 	 */
-	public Ref(final Storage st, final String refName, final ObjectId id) {
+	public Ref(final Storage st, final String origName, final String refName, final ObjectId id) {
 		storage = st;
+		this.origName = origName;
 		name = refName;
 		objectId = id;
 	}
@@ -146,19 +156,56 @@ public Ref(final Storage st, final String refName, final ObjectId id) {
 	 * @param id
 	 *            current value of the ref. May be null to indicate a ref that
 	 *            does not exist yet.
+	 */
+	public Ref(final Storage st, final String refName, final ObjectId id) {
+		this(st, refName, refName, id);
+	}
+
+	/**
+	 * Create a new ref pairing.
+	 * 
+	 * @param st
+	 *            method used to store this ref.
+	 * @param origName
+	 *            The name used to resolve this ref
+	 * @param refName
+	 *            name of this ref.
+	 * @param id
+	 *            current value of the ref. May be null to indicate a ref that
+	 *            does not exist yet.
 	 * @param peel
 	 *            peeled value of the ref's tag. May be null if this is not a
 	 *            tag or the peeled value is not known.
 	 */
-	public Ref(final Storage st, final String refName, final ObjectId id,
+	public Ref(final Storage st, final String origName, final String refName, final ObjectId id,
 			final ObjectId peel) {
 		storage = st;
+		this.origName = origName;
 		name = refName;
 		objectId = id;
 		peeledObjectId = peel;
 	}
 
 	/**
+	 * Create a new ref pairing.
+	 * 
+	 * @param st
+	 *            method used to store this ref.
+	 * @param refName
+	 *            name of this ref.
+	 * @param id
+	 *            current value of the ref. May be null to indicate a ref that
+	 *            does not exist yet.
+	 * @param peel
+	 *            peeled value of the ref's tag. May be null if this is not a
+	 *            tag or the peeled value is not known.
+	 */
+	public Ref(final Storage st, final String refName, final ObjectId id,
+			final ObjectId peel) {
+		this(st, refName, refName, id, peel);
+	}
+
+	/**
 	 * What this ref is called within the repository.
 	 * 
 	 * @return name of this ref.
@@ -168,6 +215,13 @@ public String getName() {
 	}
 
 	/**
+	 * @return the originally resolved name
+	 */
+	public String getOrigName() {
+		return origName;
+	}
+
+	/**
 	 * Cached value of this ref.
 	 * 
 	 * @return the value of this ref at the last time we read it.
@@ -200,6 +254,9 @@ public Storage getStorage() {
 	}
 
 	public String toString() {
-		return "Ref[" + name + "=" + ObjectId.toString(getObjectId()) + "]";
+		String o = "";
+		if (!origName.equals(name))
+			o = "(" + origName + ")";
+		return "Ref[" + o + name + "=" + ObjectId.toString(getObjectId()) + "]";
 	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 5c1f060..5a1b85f 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -51,6 +51,7 @@
 import java.util.Map;
 
 import org.spearce.jgit.errors.ObjectWritingException;
+import org.spearce.jgit.lib.Ref.Storage;
 import org.spearce.jgit.util.FS;
 import org.spearce.jgit.util.NB;
 
@@ -135,8 +136,8 @@ RefUpdate newUpdate(final String name) throws IOException {
 		return new RefUpdate(this, r, fileForRef(r.getName()));
 	}
 
-	void stored(final String name, final ObjectId id, final long time) {
-		looseRefs.put(name, new Ref(Ref.Storage.LOOSE, name, id));
+	void stored(final String origName, final String name, final ObjectId id, final long time) {
+		looseRefs.put(name, new Ref(Ref.Storage.LOOSE, origName, name, id));
 		looseRefsMTime.put(name, time);
 		setModified();
 		db.fireRefsMaybeChanged();
@@ -222,12 +223,12 @@ private void readLooseRefs(final Map<String, Ref> avail,
 			final String entName = ent.getName();
 			if (".".equals(entName) || "..".equals(entName))
 				continue;
-			readOneLooseRef(avail, prefix + entName, ent);
+			readOneLooseRef(avail, prefix + entName, prefix + entName, ent);
 		}
 	}
 
 	private void readOneLooseRef(final Map<String, Ref> avail,
-			final String refName, final File ent) {
+			final String origName, final String refName, final File ent) {
 		// Unchanged and cached? Don't read it again.
 		//
 		Ref ref = looseRefs.get(refName);
@@ -270,7 +271,7 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 					return;
 				}
 
-				ref = new Ref(Ref.Storage.LOOSE, refName, id);
+				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
 				looseRefs.put(ref.getName(), ref);
 				looseRefsMTime.put(ref.getName(), ent.lastModified());
 				avail.put(ref.getName(), ref);
@@ -293,27 +294,35 @@ private File fileForRef(final String name) {
 		return new File(gitDir, name);
 	}
 
-	private Ref readRefBasic(final String name, final int depth)
+	private Ref readRefBasic(final String name, final int depth) throws IOException {
+		return readRefBasic(name, name, depth);
+	}
+
+	private Ref readRefBasic(final String origName, final String name, final int depth)
 			throws IOException {
 		// Prefer loose ref to packed ref as the loose
 		// file can be more up-to-date than a packed one.
 		//
-		Ref ref = looseRefs.get(name);
+		Ref ref = looseRefs.get(origName);
 		final File loose = fileForRef(name);
 		final long mtime = loose.lastModified();
 		if (ref != null) {
 			Long cachedlastModified = looseRefsMTime.get(name);
 			if (cachedlastModified != null && cachedlastModified == mtime)
 				return ref;
-			looseRefs.remove(name);
-			looseRefsMTime.remove(name);
+			looseRefs.remove(origName);
+			looseRefsMTime.remove(origName);
 		}
 
 		if (mtime == 0) {
 			// If last modified is 0 the file does not exist.
 			// Try packed cache.
 			//
-			return packedRefs.get(name);
+			ref = packedRefs.get(name);
+			if (ref != null)
+				if (!ref.getOrigName().equals(origName))
+					ref = new Ref(Storage.LOOSE_PACKED, origName, name, ref.getObjectId());
+			return ref;
 		}
 
 		final String line;
@@ -324,7 +333,7 @@ private Ref readRefBasic(final String name, final int depth)
 		}
 
 		if (line == null || line.length() == 0)
-			return new Ref(Ref.Storage.LOOSE, name, null);
+			return new Ref(Ref.Storage.LOOSE, origName, name, null);
 
 		if (line.startsWith("ref: ")) {
 			if (depth >= 5) {
@@ -333,12 +342,16 @@ private Ref readRefBasic(final String name, final int depth)
 			}
 
 			final String target = line.substring("ref: ".length());
-			final Ref r = readRefBasic(target, depth + 1);
+			Ref r = readRefBasic(target, target, depth + 1);
 			Long cachedMtime = looseRefsMTime.get(name);
 			if (cachedMtime != null && cachedMtime != mtime)
 				setModified();
 			looseRefsMTime.put(name, mtime);
-			return r != null ? r : new Ref(Ref.Storage.LOOSE, target, null);
+			if (r == null)
+				return new Ref(Ref.Storage.LOOSE, origName, target, null);
+			if (!origName.equals(r.getName()))
+				r = new Ref(Ref.Storage.LOOSE_PACKED, origName, r.getName(), r.getObjectId(), r.getPeeledObjectId());
+			return r; 
 		}
 
 		setModified();
@@ -350,7 +363,7 @@ private Ref readRefBasic(final String name, final int depth)
 			throw new IOException("Not a ref: " + name + ": " + line);
 		}
 
-		ref = new Ref(Ref.Storage.LOOSE, name, id);
+		ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
 		looseRefs.put(name, ref);
 		looseRefsMTime.put(name, mtime);
 		return ref;
@@ -384,7 +397,7 @@ private void refreshPackedRefs() {
 
 						final ObjectId id = ObjectId.fromString(p.substring(1));
 						last = new Ref(Ref.Storage.PACKED, last.getName(), last
-								.getObjectId(), id);
+								.getName(), last.getObjectId(), id);
 						newPackedRefs.put(last.getName(), last);
 						continue;
 					}
@@ -392,7 +405,7 @@ private void refreshPackedRefs() {
 					final int sp = p.indexOf(' ');
 					final ObjectId id = ObjectId.fromString(p.substring(0, sp));
 					final String name = new String(p.substring(sp + 1));
-					last = new Ref(Ref.Storage.PACKED, name, id);
+					last = new Ref(Ref.Storage.PACKED, name, name, id);
 					newPackedRefs.put(last.getName(), last);
 				}
 			} finally {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 86b44c5..235c2fd 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -131,9 +131,6 @@
 	/** Repository the ref is stored in. */
 	private final RefDatabase db;
 
-	/** Name of the ref. */
-	private final String name;
-
 	/** Location of the loose file holding the value of this ref. */
 	private final File looseFile;
 
@@ -160,7 +157,6 @@
 	RefUpdate(final RefDatabase r, final Ref ref, final File f) {
 		db = r;
 		this.ref = ref;
-		name = ref.getName();
 		oldValue = ref.getObjectId();
 		looseFile = f;
 	}
@@ -171,7 +167,7 @@ RefUpdate(final RefDatabase r, final Ref ref, final File f) {
 	 * @return name of this ref.
 	 */
 	public String getName() {
-		return name;
+		return ref.getName();
 	}
 
 	/**
@@ -349,9 +345,9 @@ public Result delete() throws IOException {
 	 * @throws IOException
 	 */
 	public Result delete(final RevWalk walk) throws IOException {
-		if (name.startsWith(Constants.R_HEADS)) {
+		if (getName().startsWith(Constants.R_HEADS)) {
 			final Ref head = db.readRef(Constants.HEAD);
-			if (head != null && name.equals(head.getName()))
+			if (head != null && getName().equals(head.getName()))
 				return Result.REJECTED_CURRENT_BRANCH;
 		}
 
@@ -373,7 +369,7 @@ private Result updateImpl(final RevWalk walk, final Store store)
 		if (!lock.lock())
 			return Result.LOCK_FAILURE;
 		try {
-			oldValue = db.idOf(name);
+			oldValue = db.idOf(getName());
 			if (oldValue == null)
 				return store.store(lock, Result.NEW);
 
@@ -428,7 +424,7 @@ else if (status == Result.NEW)
 				getName());
 		if (!lock.commit())
 			return Result.LOCK_FAILURE;
-		db.stored(name, newValue, lock.getCommitLastModified());
+		db.stored(this.ref.getOrigName(),  ref.getName(), newValue, lock.getCommitLastModified());
 		return status;
 	}
 
-- 
1.6.0.3.578.g6a50

^ permalink raw reply related

* [EGIT PATCH 7/7] Add decorate option to log program
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226095664-13759-7-git-send-email-robin.rosenberg@dewire.com>

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../src/org/spearce/jgit/pgm/Log.java              |   33 ++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java
index e3a32c8..bb424d4 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java
@@ -40,11 +40,19 @@
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 import java.util.TimeZone;
 
+import org.kohsuke.args4j.Option;
+import org.spearce.jgit.lib.AnyObjectId;
 import org.spearce.jgit.lib.PersonIdent;
+import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.revwalk.RevCommit;
+import org.spearce.jgit.revwalk.RevWalk;
 
 @Command(common = true, usage = "View commit history")
 class Log extends RevWalkTextBuiltin {
@@ -52,14 +60,39 @@
 
 	private final DateFormat fmt;
 
+	private Map<AnyObjectId, Set<Ref>> allRefsByPeeledObjectId;
+
+	@Option(name="--decorate", usage="Show ref names matching commits")
+	private boolean decorate;
+
 	Log() {
 		fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ", Locale.US);
 	}
 
 	@Override
+	protected RevWalk createWalk() {
+		RevWalk ret = super.createWalk();
+		if (decorate)
+			allRefsByPeeledObjectId = getRepository().getAllRefsByPeeledObjectId();
+		return ret;
+	}
+
+	@Override
 	protected void show(final RevCommit c) throws Exception {
 		out.print("commit ");
 		c.getId().copyTo(outbuffer, out);
+		if (decorate) {
+			Collection<Ref> list = allRefsByPeeledObjectId.get(c.copy());
+			if (list != null) {
+				out.print(" (");
+				for (Iterator<Ref> i = list.iterator(); i.hasNext(); ) {
+					out.print(i.next().getOrigName());
+					if (i.hasNext())
+						out.print(" ");
+				}
+				out.print(")");
+			}
+		}
 		out.println();
 
 		final PersonIdent author = c.getAuthorIdent();
-- 
1.6.0.3.578.g6a50

^ permalink raw reply related

* [EGIT PATCH 4/7] Handle peeling of loose refs.
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226095664-13759-4-git-send-email-robin.rosenberg@dewire.com>

For packed refs we got peeling automatically from packed-refs,
but for loose tags we have to follow the tags and get the leaf
object in order to comply with the documentation.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java |   22 +++++++++++----
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   28 +++++++++++++++++++-
 .../src/org/spearce/jgit/lib/Repository.java       |   13 +++++++++
 3 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
index 2f102af..1a6cc4c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
@@ -140,10 +140,7 @@ public boolean isPacked() {
 	 *            does not exist yet.
 	 */
 	public Ref(final Storage st, final String origName, final String refName, final ObjectId id) {
-		storage = st;
-		this.origName = origName;
-		name = refName;
-		objectId = id;
+		this(st, origName, refName, id, ObjectId.zeroId());
 	}
 
 	/**
@@ -158,7 +155,7 @@ public Ref(final Storage st, final String origName, final String refName, final 
 	 *            does not exist yet.
 	 */
 	public Ref(final Storage st, final String refName, final ObjectId id) {
-		this(st, refName, refName, id);
+		this(st, refName, refName, id, ObjectId.zeroId());
 	}
 
 	/**
@@ -175,7 +172,7 @@ public Ref(final Storage st, final String refName, final ObjectId id) {
 	 *            does not exist yet.
 	 * @param peel
 	 *            peeled value of the ref's tag. May be null if this is not a
-	 *            tag or the peeled value is not known.
+	 *            tag or the zero id if the peeled value is not known.
 	 */
 	public Ref(final Storage st, final String origName, final String refName, final ObjectId id,
 			final ObjectId peel) {
@@ -238,10 +235,19 @@ public ObjectId getObjectId() {
 	 *         refer to an annotated tag.
 	 */
 	public ObjectId getPeeledObjectId() {
+		if (peeledObjectId == ObjectId.zeroId())
+			return null;
 		return peeledObjectId;
 	}
 
 	/**
+	 * @return whether the Ref represents a peeled tag
+	 */
+	public boolean isPeeled() {
+		return peeledObjectId != null && peeledObjectId != ObjectId.zeroId();
+	}
+
+	/**
 	 * How was this ref obtained?
 	 * <p>
 	 * The current storage model of a Ref may influence how the ref must be
@@ -259,4 +265,8 @@ public String toString() {
 			o = "(" + origName + ")";
 		return "Ref[" + o + name + "=" + ObjectId.toString(getObjectId()) + "]";
 	}
+
+	void setPeeledObjectId(final ObjectId id) {
+		peeledObjectId = id;
+	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 5a1b85f..0d73191 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -271,7 +271,8 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 					return;
 				}
 
-				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
+				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id, null); // unpeeled
+
 				looseRefs.put(ref.getName(), ref);
 				looseRefsMTime.put(ref.getName(), ent.lastModified());
 				avail.put(ref.getName(), ref);
@@ -288,6 +289,28 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 		}
 	}
 
+	Ref peel(final Ref ref) {
+		if (ref.isPeeled())
+			return ref;
+		try {
+			Object tt = db.mapObject(ref.getObjectId(), ref.getName());
+			if (tt != null && tt instanceof Tag) {
+				Tag t = (Tag)tt;
+				while (t != null && t.getType().equals(Constants.TYPE_TAG))
+					t = db.mapTag(t.getTag(), t.getObjId());
+				if (t != null)
+					ref.setPeeledObjectId(t.getObjId());
+				else
+					ref.setPeeledObjectId(null);
+			} else
+				ref.setPeeledObjectId(ref.getObjectId());
+		} catch (IOException e) {
+			// Serious error. Caller knows a ref should never be null
+			ref.setPeeledObjectId(null);
+		}
+		return ref;
+	}
+
 	private File fileForRef(final String name) {
 		if (name.startsWith(REFS_SLASH))
 			return new File(refsDir, name.substring(REFS_SLASH.length()));
@@ -364,6 +387,9 @@ private Ref readRefBasic(final String origName, final String name, final int dep
 		}
 
 		ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
+
+		looseRefs.put(origName, ref);
+		ref = new Ref(Ref.Storage.LOOSE, origName, id);
 		looseRefs.put(name, ref);
 		looseRefsMTime.put(name, mtime);
 		return ref;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index 26748e2..4d6e6fd 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -939,6 +939,19 @@ public String getBranch() throws IOException {
 	}
 
 	/**
+	 * Peel a possibly unpeeled ref and updates it. If the ref cannot be peeled
+	 * the peeled id is set to {@link ObjectId#zeroId()}
+	 * 
+	 * @param ref
+	 *            The ref to peel
+	 * @return The same, an updated ref with peeled info or a new instance with
+	 *         more information
+	 */
+	public Ref peel(final Ref ref) {
+		return refs.peel(ref);
+	}
+
+	/**
 	 * @return true if HEAD points to a StGit patch.
 	 */
 	public boolean isStGitMode() {
-- 
1.6.0.3.578.g6a50

^ permalink raw reply related

* [EGIT PATCH 1/7] Test the origName part of the key vs the ref itself
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226095664-13759-1-git-send-email-robin.rosenberg@dewire.com>

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../tst/org/spearce/jgit/lib/RefUpdateTest.java    |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java
index 6e2cfa8..12f9ada 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java
@@ -39,6 +39,8 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import org.spearce.jgit.lib.RefUpdate.Result;
 
@@ -127,4 +129,12 @@ public void testDeleteEmptyDirs() throws IOException {
 	private void assertExists(final boolean expected, final String name) {
 		assertEquals(expected, new File(db.getDirectory(), name).exists());
 	}
+
+	public void testRefKeySameAsOrigName() {
+		Map<String, Ref> allRefs = db.getAllRefs();
+		for (Entry<String, Ref> e : allRefs.entrySet()) {
+			assertEquals(e.getKey(), e.getValue().getOrigName());
+
+		}
+	}
 }
-- 
1.6.0.3.578.g6a50

^ permalink raw reply related

* [EGIT PATCH 2/7] Add constant for "refs/"
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226095664-13759-2-git-send-email-robin.rosenberg@dewire.com>

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../src/org/spearce/jgit/lib/Constants.java        |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
index f316881..9613d07 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
@@ -216,6 +216,9 @@
 	/** Prefix for tag refs */
 	public static final String R_TAGS = "refs/tags/";
 
+	/** Prefix for any ref */
+	public static final String R_REFS = "refs/";
+
 	/** Logs folder name */
 	public static final String LOGS = "logs";
 
-- 
1.6.0.3.578.g6a50

^ permalink raw reply related

* [J/E-GIT PATCH 0/7] Tag decoration v2
From: Robin Rosenberg @ 2008-11-07 22:07 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg

This is a cleaned up version of the tag decoration patch set. It
also draws the labels slightly nicer, especially when the background
has alternating colors for each row.

-- robin

Robin Rosenberg (7):
  Test the origName part of the key vs the ref itself
  Add constant for "refs/"
  Keep original ref name when reading refs
  Handle peeling of loose refs.
  Add a method to get refs by object Id
  Add tags to the graphical history display.
  Add decorate option to log program

 .../egit/ui/internal/history/SWTCommit.java        |    5 +-
 .../egit/ui/internal/history/SWTPlotRenderer.java  |   71 ++++++++++++++++++-
 .../spearce/egit/ui/internal/history/SWTWalk.java  |    2 +-
 .../src/org/spearce/jgit/pgm/Log.java              |   33 +++++++++
 .../tst/org/spearce/jgit/lib/RefUpdateTest.java    |   10 +++
 .../org/spearce/jgit/awtui/AWTPlotRenderer.java    |   46 ++++++++++++
 .../src/org/spearce/jgit/lib/Constants.java        |    3 +
 org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java |   77 ++++++++++++++++++--
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   71 ++++++++++++++----
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   14 ++---
 .../src/org/spearce/jgit/lib/Repository.java       |   47 ++++++++++++
 .../spearce/jgit/revplot/AbstractPlotRenderer.java |   23 ++++++-
 .../src/org/spearce/jgit/revplot/PlotCommit.java   |    8 ++-
 .../src/org/spearce/jgit/revplot/PlotWalk.java     |   60 +++++++++++++++-
 14 files changed, 432 insertions(+), 38 deletions(-)

^ permalink raw reply

* [RFC PATCH 0/4] deny push to current branch of non-bare repo
From: Jeff King @ 2008-11-07 22:07 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Sam Vilain

The short of it is that it's dangerous, we see people confused by it
(there was another one just yesterday), and it's a FAQ:

  http://git.or.cz/gitwiki/GitFaq#head-b96f48bc9c925074be9f95c0fce69bcece5f6e73

The FAQ even says "don't do this until you know what you are doing." So
the safety valve is configurable, so that those who know what they are
doing can switch it off.

And it's even on Sam's "UI improvements" list. :)

Patch 4/4 is the interesting one. 1/4 is a cleanup I saw while fixing
tests. 2/4 is a cleanup to prepare for 3/4. And 3/4 fixes a bunch of
tests which were inadvertently doing such a push (but didn't care
because they didn't look at the working directory).

-Peff

^ permalink raw reply

* pull --preserve-merges
From: Stephen Haberman @ 2008-11-07 22:01 UTC (permalink / raw)
  To: git

Hi,

Awhile ago I brought up wanting to have a "rebase with preserve merges"
option for `git pull`:

http://thread.gmane.org/gmane.comp.version-control.git/96513

Andreas had a patch to help by supporting manually typing out `git pull
--rebase --preserve-merges`:

http://thread.gmane.org/gmane.comp.version-control.git/96593

And then I did another small copy/paste patch on top to add a config
setting of `branch.<name>.preservemerges` much like the existing
`branch.<name>.rebase`.

The patches haven't gotten an explicit "no" that I noticed, nor have
they been applied...is there anything I can do to move them along?
Resubmit them or what not?

Thanks,
Stephen

^ permalink raw reply

* Re: Issue updating files during a checkout from a remote push
From: Jeff King @ 2008-11-07 21:59 UTC (permalink / raw)
  To: Steve Walker; +Cc: git
In-Reply-To: <09C2A669-2B99-4490-9C95-FCCD76C03D61@idibu.com>

On Thu, Nov 06, 2008 at 06:17:54PM +0100, Steve Walker wrote:

> Sorry to keep answering my own questions directly after posting...
>
> I just tried with a 'git commit -f' and the files updated.

There is no "-f" option to commit. Did you mean "checkout -f"?

If that is the case, then yes, that will "fix" your problem in that it
brings the HEAD, index, and working tree into sync. But it is dangerous
in that it throws away any local changes you might have had.

If you did really mean "commit" then that is also a bad solution. It
creates a new commit on top of the recently pushed work that reverts all
of the changes made by the recently pushed work.

-Peff

^ permalink raw reply

* Re: Issue updating files during a checkout from a remote push
From: Jeff King @ 2008-11-07 21:56 UTC (permalink / raw)
  To: Steve Walker; +Cc: git
In-Reply-To: <334B3AB1-125A-4163-BEBC-9A73C4F569B5@idibu.com>

On Thu, Nov 06, 2008 at 06:04:20PM +0100, Steve Walker wrote:

> The overall issue is that with files that have been pushed into our repo 
> on our server, when we then check out into local working copy the new 
> files appear, but the updated files dont update even though the output 
> suggests it has. The flow I'm doing:

The short answer is: don't push into the current branch of a non-bare
repo.

> 2. On my local box I change file, add it, commit, then push it from my  
> local box to our server repo:

OK, so this updates the HEAD of the receiving repository. But the index
and working tree are untouched.

> 3. It all looks good, on my server if i do a 'git log' I can see in the 
> latest update:

Right, because the HEAD has been updated.

> 4. So I check out:
>
> oneworld:/home/beta_idibu/public_html# git checkout master
> M	.gitignore
> M	steve-git-test.txt
> M	steve-git-test2.txt
> M	steve-git-test3.txt
> Already on branch "master"
> oneworld:/home/beta_idibu/public_html#

But you were already _on_ master, so git shouldn't need to touch the
index and working tree. But the contents of master have changed out from
under you, so it looks like you have modifications.

So generally you don't want to push to the current branch, but there is
no safety valve disallowing it (and I will post a patch series in a
minute which introduces one). In the past, people have suggested doing a
merge with the working tree, but that is not desirable for two reasons:

  1. you are changing the working tree out from under whoever's repo you
     push into

  2. the merge might not be clean, in which case the user needs to
     resolve conflicts. But the user isn't even doing stuff in the
     now-conflicted repository. So the suggested workflow is instead to
     go to that repo and do a 'pull'

So depending on what you want to accomplish, there are a number of
alternative workflows:

 - if you just want to publish refs, you can use a bare repo without a
   working tree at all (git --bare init, or git clone --bare).

 - if you just want to throw away working tree changes on a push (e.g.,
   you are pushing to a production server whose working tree is kept up
   to date), you can do that automatically with a post-receive hook. But
   it will never be the default, because we don't want to throw anything
   away unless the user has explicitly told us to do so.

 - if you are working in repos A and B, and you want to get changes from
   B to A, then you would generally go to A and "git pull B". But
   sometimes that is not possible (e.g., you can only make network
   connections one way). In that case, you can push to a "remote" branch
   on A, and then merge from there when you're at A. E.g.,:

     /repo/B$ git push /repo/A master:refs/remotes/B/master
     /repo/B$ cd /repo/A
     /repo/A$ git merge B/master

-Peff

^ permalink raw reply

* Re: absurdly slow git-diff
From: Linus Torvalds @ 2008-11-07 21:37 UTC (permalink / raw)
  To: Abhijit Menon-Sen, Pierre Habouzit, Davide Libenzi; +Cc: Git Mailing List
In-Reply-To: <20081107200126.GA20284@toroid.org>


On Sat, 8 Nov 2008, Abhijit Menon-Sen wrote:
>
> If anyone's interested, the files are http://toroid.org/misc/1 and
> http://toroid.org/misc/2

Btw, you can see this by just doing

	git diff 1 2

without even doing "git init" or doing any actual git repository.

> Does anyone understand why this slowdown might happen or have
> suggestions about where I should look for it?

Sure. It's actually fairly simple. You're hitting a O(n^2) thing (possibly 
higher), and it's triggered by the fact that almost all your lines are 
identical, ie you have a file that basically has 40,000 lines of each of

	xxxx: xxx, xx xxx xxxx xx:xx:xx +xxxx
	xx: xxxx xxxxxxxxxxx <xxxx@xxxx.xxx>
	xxxx: xxxx xxxxxxxxxxx <xxxx@xxxx.xxx>

and 30,000 of 

	* xxxxx xxxxx (xxxxxx.xxxx xxx xxxxx (\Xxxxxx) xxxxxx.xxxxxx {xxx}

with a smattering of others. And this is a case where the internal git 
implementation does really badly. And nobody has really cared before, 
because nobody has ever had a case that mattered.

There's a number of different 'diff' algorithms, and it looks like GNU 
diff has one that avoids the O(n^2) case for this case.

I'm adding Davide as the original author of the diff library to the cc. 
I'm also adding Pierre, since he was talking about trying to implement
another diff algorithm (although I'm not at all sure that the patience 
diff really would help this case at all).

		Linus

^ permalink raw reply

* Re: absurdly slow git-diff
From: Mike Hommey @ 2008-11-07 21:28 UTC (permalink / raw)
  To: Abhijit Menon-Sen; +Cc: git
In-Reply-To: <20081107200126.GA20284@toroid.org>

On Sat, Nov 08, 2008 at 01:31:27AM +0530, Abhijit Menon-Sen wrote:
> I have a 240k-line file, and I change one character on every sixth line.
> The resulting diff gives git serious indigestion:
> 
> $ git --version
> git version 1.6.0.3.640.g6331a
> $ mkdir a; cd a; git init
> Initialized empty Git repository in /home/ams/a/.git/
> $ cp ../1 .; git add 1; git commit -q -m 1
> $ cp ../2 1; git add 1; git commit -q -m 2 

You don't need to go that far. You can stop at cp ../2 1 and run git
diff from there.

All the time is spent in the two loops in
xdiff/xprepare.c:xdl_cleanup_records, on line 400 and 412.

I'll leave the rest of the investigation to people actually knowing this
code ;)

Mike

^ permalink raw reply

* Re: [PATCH 2/3] Introduce rename factorization in diffcore.
From: Junio C Hamano @ 2008-11-07 21:11 UTC (permalink / raw)
  To: Yann Dirson; +Cc: git
In-Reply-To: <20081107203952.GJ5158@nan92-1-81-57-214-146.fbx.proxad.net>

Yann Dirson <ydirson@altern.org> writes:

> On Fri, Nov 07, 2008 at 12:19:14PM -0800, Junio C Hamano wrote:
>> I am afraid that this is totally unacceptable, as you yourself mentioned,
>> the end result is unapplicable with any existing tool and would confuse
>> viewers like gitk and gitweb.
>
> Well, other tools will still have to be taught about a new syntax, if
> they're going to use the new flag - just like it was for --rename.

You are mistaken.  For a patch, you are dealing with two different
parties: producer and consumer.  If you are adding new feature to the
producer, the output format should be desigend to allow the consumer tell
that it is something it does not know how to handle.

Marking a non patch with "diff --git" to trigger the logic to signal the
beginning of a patch to git-apply (and perhaps other tools) is a non
starter.

And for this "we are giving a patch that your git-apply can apply and gitk
can show, but by the way we also think the whole directory foo moved to
new location bar" is merely an additional information.  You should still
be able to apply the patch with tools that are unaware of this new
directory move detection feature.

^ permalink raw reply

* Re: [minor usability suggestion] git rebase <upstream> --onto <newbase> ?
From: Junio C Hamano @ 2008-11-07 21:06 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Ingo Molnar, git
In-Reply-To: <alpine.LNX.1.00.0811071504110.19665@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> writes:

> "git log origin/master -p" works, though.

That's an accident.  Do not rely on it.

^ permalink raw reply

* Re: git-push and $GIT_DIR/branches
From: Martin Koegler @ 2008-11-07 20:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vljvvh61y.fsf@gitster.siamese.dyndns.org>

On Fri, Nov 07, 2008 at 08:08:57AM -0800, Junio C Hamano wrote:
> mkoegler@auto.tuwien.ac.at (Martin Koegler) writes:
> 
> > I think, that the git-push behaviour is a bit unlogical in conjunction
> > with $GIT_DIR/branches.
> 
> That is because it is illogical to use $GIT_DIR/branches in conjunction
> with git; the former is a backward compatibility wart with Cogito which is
> now dead.

I'm aware, that $GIT_DIR/branches origins from Cogito and are not
recommended. But eg. Documentation/urls-remotes.txt does not reflect
this.

I asume, that you [and probably many other] are not very interrested
in this feature. But would you accept a patch changing the push
refspec to HEAD:refs/heads/<head>?

mfg Martin Kögler

^ permalink raw reply

* Re: [PATCH 2/3] Introduce rename factorization in diffcore.
From: Yann Dirson @ 2008-11-07 20:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3ai3gugt.fsf@gitster.siamese.dyndns.org>

On Fri, Nov 07, 2008 at 12:19:14PM -0800, Junio C Hamano wrote:
> I am afraid that this is totally unacceptable, as you yourself mentioned,
> the end result is unapplicable with any existing tool and would confuse
> viewers like gitk and gitweb.

Well, other tools will still have to be taught about a new syntax, if
they're going to use the new flag - just like it was for --rename.

That makes me think that it could be interesting to have a header
telling which diff extensions it is using.  It could even be
interesting to come with a cross-vc convention, which would ease the
interchange of modern patch files (I suppose some other tools already
have their own extensions for file renames).

What about some hint like the following ?

|extended diff features: git:rename git:binary git:filetypes
|extended diff features: git:unixperms git:dir-rename

Maybe we could leave "filetype" and "unixperms" out, since these do
not replace an information that would otherwise be present in a
standard diff anyway, and would just be ignored by a tool not
supporting them.


> I think it would be a much better approach to emit a hint that talks about
> directory rename in a format that does not fool usual "patch" application
> tools.  E.g.
> 
> |directory moved with similarity index 82%
> |rename from ppc
> |rename from foo
> |diff --git a/ppc/sha1.h b/foo/sha1.h
> |similarity index 85%
> |rename from ppc/sha1.h
> |rename to foo/sha1.h
> |index  9b34f76..8fce4b7 100644
> |--- ppc/sha1.h
> |+++ foo/sha1.h
> |@@ ...

So you're favoring the "patch is not textually splittable approach".
Don't you think it would be good to add some sort of hint about this
as a patch header ?

> IOW, do not add anything that begins with "diff --git" if it is not a
> patch.

OK.

^ permalink raw reply

* absurdly slow git-diff
From: Abhijit Menon-Sen @ 2008-11-07 20:01 UTC (permalink / raw)
  To: git

I have a 240k-line file, and I change one character on every sixth line.
The resulting diff gives git serious indigestion:

$ git --version
git version 1.6.0.3.640.g6331a
$ mkdir a; cd a; git init
Initialized empty Git repository in /home/ams/a/.git/
$ cp ../1 .; git add 1; git commit -q -m 1
$ cp ../2 1; git add 1; git commit -q -m 2 
$ time git show HEAD > x
git show HEAD > x  309.88s user 0.46s system 97% cpu 5:17.06 total

(I use commit -q above not only for brevity; for the second commit,
calculating the diffstat takes the same five minutes that git show,
git log -p, git log --stat etc. all take.)

Note that diff(1) can handle the patch fine:

$ time diff -u ../1 ../2 >/dev/null
diff -u ../1 ../2 > /dev/null  0.30s user 0.06s system 69% cpu 0.519 total

If anyone's interested, the files are http://toroid.org/misc/1 and
http://toroid.org/misc/2

Does anyone understand why this slowdown might happen or have
suggestions about where I should look for it?

Thanks.

-- ams

^ permalink raw reply

* Re: [PATCH 2/3] Introduce rename factorization in diffcore.
From: Junio C Hamano @ 2008-11-07 20:19 UTC (permalink / raw)
  To: Yann Dirson; +Cc: git
In-Reply-To: <20081107193957.GI5158@nan92-1-81-57-214-146.fbx.proxad.net>

Yann Dirson <ydirson@altern.org> writes:

> The direct transposition of the raw output of a dir rename with a
> change would yield something like:
>
> |diff --git a/ppc/ b/foo
> |similarity index 100%
> |rename from ppc/
> |rename to foo/
> |diff --git a/ppc/sha1.h b/foo/sha1.h
> |--- ppc/sha1.h
> |+++ foo/sha1.h
> |...
>
> This would have the usefulness I'm looking for, in that the content
> modifications would not be "hidden" among a whole lot af individual
> file rename hunks.

I am afraid that this is totally unacceptable, as you yourself mentioned,
the end result is unapplicable with any existing tool and would confuse
viewers like gitk and gitweb.

I think it would be a much better approach to emit a hint that talks about
directory rename in a format that does not fool usual "patch" application
tools.  E.g.

|directory moved with similarity index 82%
|rename from ppc
|rename from foo
|diff --git a/ppc/sha1.h b/foo/sha1.h
|similarity index 85%
|rename from ppc/sha1.h
|rename to foo/sha1.h
|index  9b34f76..8fce4b7 100644
|--- ppc/sha1.h
|+++ foo/sha1.h
|@@ ...

IOW, do not add anything that begins with "diff --git" if it is not a
patch.

^ permalink raw reply

* Re: [minor usability suggestion] git rebase <upstream> --onto <newbase> ?
From: Daniel Barkalow @ 2008-11-07 20:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Ingo Molnar, git
In-Reply-To: <7vej1ngztd.fsf@gitster.siamese.dyndns.org>

On Fri, 7 Nov 2008, Junio C Hamano wrote:

> Ingo Molnar <mingo@elte.hu> writes:
> 
> >  earth4:~/tip> git rebase 685aebb --onto linus
> >  Current branch core/urgent is up to date.
> > ...
> > For example "git log" is exemplary in this area as it accepts just 
> > about any permutation of parameters thrown at it, ...
> 
> Not really.
> 
> There may be oddball commands whose parameter order have been established
> differently long before "git log" came, but almost all of them now use the
> same convention used by the "git log" family, which is flags/options then
> revs (and then paths if the operation makes sense with paths).  And rebase
> is not one of the oddball ones.
> 
> Your "rebase" example is a rev then a flag/option, which is not how any
> other git command take its command line parameters.

"git log origin/master -p" works, though. It's paths, not revisions, that 
can't appear before options (or revisions).

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [PATCH 2/3] Introduce rename factorization in diffcore.
From: Yann Dirson @ 2008-11-07 19:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy6zwgx3i.fsf@gitster.siamese.dyndns.org>

On Thu, Nov 06, 2008 at 05:10:09PM -0800, Junio C Hamano wrote:
> Yann Dirson <ydirson@altern.org> writes:
> 
> > Rename factorization tries to group together files moving from and to
> > identical directories - the most common case being directory renames.
> > We do that by first identifying groups of bulk-moved files, and then
> > hiding those of the individual renames which carry no other
> > information (further name change, or content changes).
> > This feature is activated by the new --factorize-renames diffcore
> > flag.
> 
> I have a mixed feeling about this one, primarily because I cannot
> visualize how a useful output should look like.  Unless you rename one
> directory to another without any content changes, you would have to say
> "this directory changed to that, and among the paths underneath them, this
> file have this content change in addition".

Right.  This is something I have already thought about, without taking
the time to finalize.  So let's have a try.

The direct transposition of the raw output of a dir rename with a
change would yield something like:

|diff --git a/ppc/ b/foo
|similarity index 100%
|rename from ppc/
|rename to foo/
|diff --git a/ppc/sha1.h b/foo/sha1.h
|--- ppc/sha1.h
|+++ foo/sha1.h
|...

This would have the usefulness I'm looking for, in that the content
modifications would not be "hidden" among a whole lot af individual
file rename hunks.

But if we want to make this more generally useful (eg. allow other
tools to apply such patches), we need to be careful.  A typical patch
file can usually be seen as a sequence of changes which can be applied
independently (at least in order).  It is obvious that this is not
true for the above output.  So we could also consider making this
patch output sequential with something like:

|diff --git a/ppc/ b/foo
|similarity index 100%
|rename from ppc/
|rename to foo/
|diff --git a/foo/sha1.h b/foo/sha1.h
|--- foo/sha1.h
|+++ foo/sha1.h
|...

However, such output would possibly be confusing, eg. when looking at
it from gitk and looking for commits which modify ppc/sha1.h.

A solution to this could be to add an annotation such as:

|diff --git a/ppc/ b/foo
|similarity index 100%
|rename from ppc/
|rename to foo/
|diff --git a/foo/sha1.h b/foo/sha1.h
|--- foo/sha1.h (previously ppc/sha1.h)
|+++ foo/sha1.h
|...

That would make the "git diff" format diverge a bit more from the
standard, but since a full-fledged git patch already cannot be used by
standard patch tools, it should not be a big issue - we should just be
careful about choosing a suitable format if we go that way.

But as we already change the patch format, we could also simply say
that we don't care about the patch being "litterally splittable", add
a "this is a non-splittable whole" note at the beginning of the patch
output, and go with the litteral solution shown as first example.

How do you feel wrt this ?


> A related feature that would benefit from something like your change
> without any downside/complication of output format issues is to boost
> rename similarity score of a path when its neighbouring paths are moved to
> the same location.

Yes, that could be triggered by distinct switches.

Doing this would be related to detecting "directory splits" (ie. when
some files are really not moved, or moved into several dirs instead of
being all moved to the same target dir).  We can start by detecting
dir-splits, then shift the scoring threshold and do another pass on
split dirs.

^ permalink raw reply

* Re: [PATCH v2 3/3] pack-objects: honor '.keep' files
From: Shawn O. Pearce @ 2008-11-07 19:25 UTC (permalink / raw)
  To: Andreas Ericsson
  Cc: Brandon Casey, Junio C Hamano, Git Mailing List, Nicolas Pitre
In-Reply-To: <4913F859.8070500@op5.se>

Andreas Ericsson <ae@op5.se> wrote:
>
> Only -d should honor .keep, imo. .keep-files is nothing about "don't copy
> objects from this file" and all about "never delete this file".
>
> The only muddying comes from you, who decided that .keep-files should
> have impact on anything else than deleting the protected pack. Before that,
> .keep files had a clear semantic, and repack's documentation was correct.
>
> How do you explain .keep-files now? "protects pack-files that will forever
> be used"? Then why the hell is it called ".keep" instead of "eternal"?

The _intent_ behind .keep files has always been to avoid copying
the objects into a new pack during git-repack, because the objects
are held in a pack that cannot be deleted.

Sadly the implementation has never quite worked right, which is
what led to this patch series I think.

-- 
Shawn.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox