Git development
 help / color / mirror / Atom feed
* [JGIT PATCH 21/28] Convert ls-remote program to args4j
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-21-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/LsRemote.java         |   23 +++++--------------
 1 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsRemote.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsRemote.java
index 921bcff..391a04d 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsRemote.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsRemote.java
@@ -37,30 +37,19 @@
 
 package org.spearce.jgit.pgm;
 
+import org.kohsuke.args4j.Argument;
 import org.spearce.jgit.lib.AnyObjectId;
 import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.transport.FetchConnection;
 import org.spearce.jgit.transport.Transport;
 
 class LsRemote extends TextBuiltin {
-	@Override
-	public void execute(final String[] args) throws Exception {
-		int argi = 0;
-		for (; argi < args.length; argi++) {
-			final String a = args[argi];
-			if ("--".equals(a)) {
-				argi++;
-				break;
-			} else
-				break;
-		}
+	@Argument(index = 0, metaVar = "uri-ish", required = true)
+	private String remote;
 
-		if (argi == args.length)
-			throw die("usage: url");
-		else if (argi + 1 < args.length)
-			throw die("too many arguments");
-
-		final Transport tn = Transport.open(db, args[argi]);
+	@Override
+	protected void run() throws Exception {
+		final Transport tn = Transport.open(db, remote);
 		final FetchConnection c = tn.openFetch();
 		try {
 			for (final Ref r : c.getRefs()) {
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* [JGIT PATCH 22/28] Convert ls-tree program to args4j
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-22-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/LsTree.java           |   42 ++++++--------------
 1 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsTree.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsTree.java
index a0a7216..8d4937f 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsTree.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/LsTree.java
@@ -37,40 +37,26 @@
 
 package org.spearce.jgit.pgm;
 
-import java.io.File;
-
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
 import org.spearce.jgit.lib.Constants;
 import org.spearce.jgit.lib.FileMode;
-import org.spearce.jgit.treewalk.FileTreeIterator;
+import org.spearce.jgit.treewalk.AbstractTreeIterator;
 import org.spearce.jgit.treewalk.TreeWalk;
 
 class LsTree extends TextBuiltin {
-	@Override
-	public void execute(final String[] args) throws Exception {
-		final TreeWalk walk = new TreeWalk(db);
-		int argi = 0;
-		for (; argi < args.length; argi++) {
-			final String a = args[argi];
-			if ("--".equals(a)) {
-				argi++;
-				break;
-			} else if ("-r".equals(a))
-				walk.setRecursive(true);
-			else
-				break;
-		}
+	@Option(name = "--recursive", usage = "recurse into subtrees", aliases = { "-r" })
+	private boolean recursive;
 
-		if (argi == args.length)
-			throw die("usage: [-r] treename");
-		else if (argi + 1 < args.length)
-			throw die("too many arguments");
+	@Argument(index = 0, required = true, metaVar = "tree-ish")
+	private AbstractTreeIterator tree;
 
+	@Override
+	protected void run() throws Exception {
+		final TreeWalk walk = new TreeWalk(db);
 		walk.reset(); // drop the first empty tree, which we do not need here
-		final String n = args[argi];
-		if (is_WorkDir(n))
-			walk.addTree(new FileTreeIterator(new File(n)));
-		else
-			walk.addTree(resolve(n));
+		walk.setRecursive(recursive);
+		walk.addTree(tree);
 
 		while (walk.next()) {
 			final FileMode mode = walk.getFileMode(0);
@@ -88,8 +74,4 @@ class LsTree extends TextBuiltin {
 			out.println();
 		}
 	}
-
-	private boolean is_WorkDir(final String name) {
-		return new File(name).isDirectory();
-	}
 }
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* [JGIT PATCH 23/28] Convert merge-base program to args4j
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-23-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/MergeBase.java        |   37 ++++++++++++--------
 1 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/MergeBase.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/MergeBase.java
index c1648a0..c0ddd3b 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/MergeBase.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/MergeBase.java
@@ -37,27 +37,34 @@
 
 package org.spearce.jgit.pgm;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
 import org.spearce.jgit.revwalk.RevCommit;
-import org.spearce.jgit.revwalk.RevWalk;
 import org.spearce.jgit.revwalk.filter.RevFilter;
 
 class MergeBase extends TextBuiltin {
-	@Override
-	public void execute(final String[] args) throws Exception {
-		final RevWalk walk = new RevWalk(db);
-		int max = 1;
-		for (final String a : args) {
-			if ("--".equals(a))
-				break;
-			else if ("--all".equals(a))
-				max = Integer.MAX_VALUE;
-			else
-				walk.markStart(walk.parseCommit(resolve(a)));
-		}
+	@Option(name = "--all", usage = "display all possible merge bases")
+	private boolean all;
 
-		walk.setRevFilter(RevFilter.MERGE_BASE);
+	@Argument(index = 0, metaVar = "commit-ish", required = true)
+	void commit_0(final RevCommit c) {
+		commits.add(c);
+	}
+
+	@Argument(index = 1, metaVar = "commit-ish", required = true)
+	private final List<RevCommit> commits = new ArrayList<RevCommit>();
+
+	@Override
+	protected void run() throws Exception {
+		for (final RevCommit c : commits)
+			argWalk.markStart(c);
+		argWalk.setRevFilter(RevFilter.MERGE_BASE);
+		int max = all ? Integer.MAX_VALUE : 1;
 		while (max-- > 0) {
-			final RevCommit b = walk.next();
+			final RevCommit b = argWalk.next();
 			if (b == null)
 				break;
 			out.println(b.getId());
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* [JGIT PATCH 25/28] Convert show-ref program to args4j
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-25-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/ShowRef.java          |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ShowRef.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ShowRef.java
index 576e342..6dfba3e 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ShowRef.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ShowRef.java
@@ -44,7 +44,7 @@ import org.spearce.jgit.lib.Ref;
 
 class ShowRef extends TextBuiltin {
 	@Override
-	public void execute(String[] args) throws Exception {
+	protected void run() throws Exception {
 		for (final Ref r : new TreeMap<String, Ref>(db.getAllRefs()).values()) {
 			show(r.getObjectId(), r.getName());
 			if (r.getPeeledObjectId() != null)
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* [JGIT PATCH 24/28] Convert push program to args4j
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-24-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/Push.java             |   95 +++++++++-----------
 1 files changed, 44 insertions(+), 51 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java
index 5671cc5..df6c664 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java
@@ -37,9 +37,12 @@
 
 package org.spearce.jgit.pgm;
 
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
 
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
 import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.lib.TextProgressMonitor;
 import org.spearce.jgit.transport.PushResult;
@@ -49,64 +52,54 @@ import org.spearce.jgit.transport.Transport;
 import org.spearce.jgit.transport.RemoteRefUpdate.Status;
 
 class Push extends TextBuiltin {
+	@Argument(index = 0, metaVar = "uri-ish")
+	private String remote = "origin";
 
+	@Argument(index = 1, metaVar = "refspec")
+	private final List<RefSpec> refSpecs = new ArrayList<RefSpec>();
+
+	@Option(name = "--all")
+	void addAll(final boolean ignored) {
+		refSpecs.add(Transport.REFSPEC_PUSH_ALL);
+	}
+
+	@Option(name = "--tags")
+	void addTags(final boolean ignored) {
+		refSpecs.add(Transport.REFSPEC_TAGS);
+	}
+
+	@Option(name = "--verbose", aliases = { "-v" })
 	private boolean verbose = false;
 
+	@Option(name = "--thin")
+	private boolean thin = Transport.DEFAULT_PUSH_THIN;
+
+	@Option(name = "--no-thin")
+	void nothin(final boolean ignored) {
+		thin = false;
+	}
+
+	@Option(name = "--force", aliases = { "-f" })
+	private boolean force;
+
+	@Option(name = "--receive-pack", metaVar = "path")
+	private String receivePack;
+
 	private boolean first = true;
 
 	@Override
-	public void execute(String[] args) throws Exception {
-		final LinkedList<RefSpec> refSpecs = new LinkedList<RefSpec>();
-		Boolean thin = null;
-		String exec = null;
-		boolean forceAll = false;
-
-		int argi = 0;
-		for (; argi < args.length; argi++) {
-			final String a = args[argi];
-			if ("--thin".equals(a))
-				thin = true;
-			else if ("--no-thin".equals(a))
-				thin = false;
-			else if ("-f".equals(a) || "--force".equals(a))
-				forceAll = true;
-			else if (a.startsWith("--exec="))
-				exec = a.substring("--exec=".length());
-			else if (a.startsWith("--receive-pack="))
-				exec = a.substring("--receive-pack=".length());
-			else if ("--tags".equals(a))
-				refSpecs.add(Transport.REFSPEC_TAGS);
-			else if ("--all".equals(a))
-				refSpecs.add(Transport.REFSPEC_PUSH_ALL);
-			else if ("-v".equals(a))
-				verbose = true;
-			else if ("--".equals(a)) {
-				argi++;
-				break;
-			} else if (a.startsWith("-"))
-				die("usage: push [--all] [--tags] [--force] [--thin]\n"
-						+ "[--receive-pack=<git-receive-pack>] [<repository> [<refspec>]...]");
-			else
-				break;
+	protected void run() throws Exception {
+		if (force) {
+			final List<RefSpec> orig = new ArrayList<RefSpec>(refSpecs);
+			refSpecs.clear();
+			for (final RefSpec spec : orig)
+				refSpecs.add(spec.setForceUpdate(true));
 		}
 
-		final String repository;
-		if (argi == args.length)
-			repository = "origin";
-		else
-			repository = args[argi++];
-		final Transport transport = Transport.open(db, repository);
-		if (thin != null)
-			transport.setPushThin(thin);
-		if (exec != null)
-			transport.setOptionReceivePack(exec);
-
-		for (; argi < args.length; argi++) {
-			RefSpec spec = new RefSpec(args[argi]);
-			if (forceAll)
-				spec = spec.setForceUpdate(true);
-			refSpecs.add(spec);
-		}
+		final Transport transport = Transport.open(db, remote);
+		transport.setPushThin(thin);
+		if (receivePack != null)
+			transport.setOptionReceivePack(receivePack);
 		final Collection<RemoteRefUpdate> toPush = transport
 				.findRemoteRefUpdatesFor(refSpecs);
 
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* [JGIT PATCH 27/28] Convert rev-list, log, glog programs to args4j
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-27-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../org/spearce/jgit/pgm/RevWalkTextBuiltin.java   |  146 +++++++++++---------
 1 files changed, 80 insertions(+), 66 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/RevWalkTextBuiltin.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/RevWalkTextBuiltin.java
index 2aba3c5..97fe7a4 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/RevWalkTextBuiltin.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/RevWalkTextBuiltin.java
@@ -41,9 +41,14 @@ import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
 import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.ObjectId;
+import org.spearce.jgit.pgm.opt.PathTreeFilterHandler;
 import org.spearce.jgit.revwalk.ObjectWalk;
 import org.spearce.jgit.revwalk.RevCommit;
+import org.spearce.jgit.revwalk.RevFlag;
 import org.spearce.jgit.revwalk.RevObject;
 import org.spearce.jgit.revwalk.RevSort;
 import org.spearce.jgit.revwalk.RevWalk;
@@ -53,98 +58,105 @@ import org.spearce.jgit.revwalk.filter.CommitterRevFilter;
 import org.spearce.jgit.revwalk.filter.MessageRevFilter;
 import org.spearce.jgit.revwalk.filter.RevFilter;
 import org.spearce.jgit.treewalk.filter.AndTreeFilter;
-import org.spearce.jgit.treewalk.filter.PathFilter;
-import org.spearce.jgit.treewalk.filter.PathFilterGroup;
 import org.spearce.jgit.treewalk.filter.TreeFilter;
 
 abstract class RevWalkTextBuiltin extends TextBuiltin {
 	RevWalk walk;
 
+	@Option(name = "--objects")
 	boolean objects = false;
 
+	@Option(name = "--parents")
 	boolean parents = false;
 
+	@Option(name = "--total-count")
 	boolean count = false;
 
 	char[] outbuffer = new char[Constants.OBJECT_ID_LENGTH * 2];
 
-	@Override
-	public final void execute(String[] args) throws Exception {
-		final EnumSet<RevSort> sorting = EnumSet.noneOf(RevSort.class);
-		final List<String> argList = new ArrayList<String>();
-		final List<RevFilter> revLimiter = new ArrayList<RevFilter>();
-		List<PathFilter> pathLimiter = null;
-		for (final String a : args) {
-			if (pathLimiter != null)
-				pathLimiter.add(PathFilter.create(a));
-			else if ("--".equals(a))
-				pathLimiter = new ArrayList<PathFilter>();
-			else if (a.startsWith("--author="))
-				revLimiter.add(AuthorRevFilter.create(a.substring("--author="
-						.length())));
-			else if (a.startsWith("--committer="))
-				revLimiter.add(CommitterRevFilter.create(a
-						.substring("--committer=".length())));
-			else if (a.startsWith("--grep="))
-				revLimiter.add(MessageRevFilter.create(a.substring("--grep="
-						.length())));
-			else if ("--objects".equals(a))
-				objects = true;
-			else if ("--date-order".equals(a))
-				sorting.add(RevSort.COMMIT_TIME_DESC);
-			else if ("--topo-order".equals(a))
-				sorting.add(RevSort.TOPO);
-			else if ("--reverse".equals(a))
-				sorting.add(RevSort.REVERSE);
-			else if ("--boundary".equals(a))
-				sorting.add(RevSort.BOUNDARY);
-			else if ("--parents".equals(a))
-				parents = true;
-			else if ("--total-count".equals(a))
-				count = true;
-			else
-				argList.add(a);
-		}
+	private final EnumSet<RevSort> sorting = EnumSet.noneOf(RevSort.class);
+
+	private void enableRevSort(final RevSort type, final boolean on) {
+		if (on)
+			sorting.add(type);
+		else
+			sorting.remove(type);
+	}
+
+	@Option(name = "--date-order")
+	void enableDateOrder(final boolean on) {
+		enableRevSort(RevSort.COMMIT_TIME_DESC, on);
+	}
+
+	@Option(name = "--topo-order")
+	void enableTopoOrder(final boolean on) {
+		enableRevSort(RevSort.TOPO, on);
+	}
+
+	@Option(name = "--reverse")
+	void enableReverse(final boolean on) {
+		enableRevSort(RevSort.REVERSE, on);
+	}
+
+	@Option(name = "--boundary")
+	void enableBoundary(final boolean on) {
+		enableRevSort(RevSort.BOUNDARY, on);
+	}
+
+	@Argument(index = 0, metaVar = "commit-ish")
+	private final List<RevCommit> commits = new ArrayList<RevCommit>();
+
+	@Option(name = "--", metaVar = "path", multiValued = true, handler = PathTreeFilterHandler.class)
+	private TreeFilter pathFilter = TreeFilter.ALL;
+
+	private final List<RevFilter> revLimiter = new ArrayList<RevFilter>();
 
+	@Option(name = "--author")
+	void addAuthorRevFilter(final String who) {
+		revLimiter.add(AuthorRevFilter.create(who));
+	}
+
+	@Option(name = "--committer")
+	void addCommitterRevFilter(final String who) {
+		revLimiter.add(CommitterRevFilter.create(who));
+	}
+
+	@Option(name = "--grep")
+	void addCMessageRevFilter(final String msg) {
+		revLimiter.add(MessageRevFilter.create(msg));
+	}
+
+	@Override
+	protected void run() throws Exception {
 		walk = createWalk();
 		for (final RevSort s : sorting)
 			walk.sort(s, true);
 
-		if (pathLimiter != null && !pathLimiter.isEmpty())
-			walk.setTreeFilter(AndTreeFilter.create(PathFilterGroup
-					.create(pathLimiter), TreeFilter.ANY_DIFF));
+		if (pathFilter != TreeFilter.ALL)
+			walk.setTreeFilter(AndTreeFilter.create(pathFilter,
+					TreeFilter.ANY_DIFF));
 
 		if (revLimiter.size() == 1)
 			walk.setRevFilter(revLimiter.get(0));
 		else if (revLimiter.size() > 1)
 			walk.setRevFilter(AndRevFilter.create(revLimiter));
 
-		final long start = System.currentTimeMillis();
-		boolean have_revision = false;
-		boolean not = false;
-		for (String a : argList) {
-			if ("--not".equals(a)) {
-				not = true;
-				continue;
-			}
-			boolean menot = false;
-			if (a.startsWith("^")) {
-				a = a.substring(1);
-				menot = true;
-			}
-			final RevCommit c = walk.parseCommit(resolve(a));
-			if (not ^ menot)
-				walk.markUninteresting(c);
-			else {
+		if (commits.isEmpty()) {
+			final ObjectId head = db.resolve(Constants.HEAD);
+			if (head == null)
+				throw die("Cannot resolve " + Constants.HEAD);
+			commits.add(walk.parseCommit(head));
+		}
+		for (final RevCommit c : commits) {
+			final RevCommit real = argWalk == walk ? c : walk.parseCommit(c);
+			if (c.has(RevFlag.UNINTERESTING))
+				walk.markUninteresting(real);
+			else
 				walk.markStart(c);
-				have_revision = true;
-			}
 		}
-		if (!have_revision)
-			walk.markStart(walk.parseCommit(resolve("HEAD")));
-
-		int n = walkLoop();
 
+		final long start = System.currentTimeMillis();
+		final int n = walkLoop();
 		if (count) {
 			final long end = System.currentTimeMillis();
 			System.err.print(n);
@@ -158,7 +170,9 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
 	protected RevWalk createWalk() {
 		if (objects)
 			return new ObjectWalk(db);
-		return new RevWalk(db);
+		if (argWalk == null)
+			argWalk = new RevWalk(db);
+		return argWalk;
 	}
 
 	protected int walkLoop() throws Exception {
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* [JGIT PATCH 28/28] Remove support for legacy style TextBuiltins
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-28-git-send-email-spearce@spearce.org>

Now that all builtins use the new automatic parsing support
we want to require that they override run() and do not try
to override execute().

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/TextBuiltin.java      |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
index c4a55f4..9f90c16 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
@@ -113,7 +113,7 @@ public abstract class TextBuiltin {
 	 *             framework will catch the exception and print a message on
 	 *             standard error.
 	 */
-	public void execute(String[] args) throws Exception {
+	public final void execute(String[] args) throws Exception {
 		parseArguments(args);
 		run();
 	}
@@ -166,9 +166,7 @@ public abstract class TextBuiltin {
 	 *             framework will catch the exception and print a message on
 	 *             standard error.
 	 */
-	protected void run() throws Exception {
-		throw die("Override either execute (legacy) or run (new style).");
-	}
+	protected abstract void run() throws Exception;
 
 	/**
 	 * @return the repository this command accesses.
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* [JGIT PATCH 26/28] Convert tag program to args4j
From: Shawn O. Pearce @ 2008-07-18  1:44 UTC (permalink / raw)
  To: Robin Rosenberg, Marek Zawirski; +Cc: git
In-Reply-To: <1216345461-59382-26-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/Tag.java              |   79 ++++++++------------
 1 files changed, 32 insertions(+), 47 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Tag.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Tag.java
index d59616b..a7bd037 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Tag.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Tag.java
@@ -37,48 +37,35 @@
 
 package org.spearce.jgit.pgm;
 
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+import org.spearce.jgit.errors.MissingObjectException;
 import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.ObjectId;
+import org.spearce.jgit.lib.ObjectLoader;
 import org.spearce.jgit.lib.PersonIdent;
 
 class Tag extends TextBuiltin {
+	@Option(name = "-f", usage = "force replacing an existing tag")
+	private boolean force;
+
+	@Option(name = "-m", metaVar = "message", usage = "tag message")
+	private String message = "";
+
+	@Argument(index = 0, required = true, metaVar = "name")
+	private String tagName;
+
+	@Argument(index = 1, metaVar = "object")
+	private ObjectId object;
+
 	@Override
-	public void execute(String[] args) throws Exception {
-		String tagName = null;
-		String message = null;
-		String ref = "HEAD";
-		boolean force = false;
-               if (args.length == 0)
-                       usage();
-		for (int i = 0; i < args.length; ++i) {
-			if (args[i].equals("-f")) {
-				force = true;
-				continue;
-			}
-			if (args[i].equals("-m")) {
-				if (i < args.length - 2)
-					message = args[i++] + "\n";
-				else
-					usage();
-				continue;
-			}
-			if (args[i].startsWith("-m")) {
-				message = args[i].substring(2) + "\n";
-				continue;
-			}
-			if (args[i].startsWith("-") && i == args.length - 1)
-				usage();
-			if (i == args.length - 2) {
-				tagName = args[i];
-				ref = args[i+1];
-				++i;
-				continue;
-			}
-			if (i == args.length - 1) {
-				tagName = args[i];
-				continue;
-			}
-			usage();
+	protected void run() throws Exception {
+		if (object == null) {
+			object = db.resolve(Constants.HEAD);
+			if (object == null)
+				throw die("Cannot resolve " + Constants.HEAD);
 		}
+
 		if (!tagName.startsWith(Constants.TAGS_PREFIX + "/"))
 			tagName = Constants.TAGS_PREFIX + "/" + tagName;
 		if (!force && db.resolve(tagName) != null) {
@@ -86,19 +73,17 @@ class Tag extends TextBuiltin {
 					+ tagName.substring(Constants.TAGS_PREFIX.length() + 1)
 					+ "' exists");
 		}
+
+		final ObjectLoader ldr = db.openObject(object);
+		if (ldr == null)
+			throw new MissingObjectException(object, "any");
+
 		org.spearce.jgit.lib.Tag tag = new org.spearce.jgit.lib.Tag(db);
-		tag.setObjId(db.resolve(ref));
-		if (message != null) {
-			message = message.replaceAll("\r", "");
-			tag.setMessage(message);
-			tag.setTagger(new PersonIdent(db));
-			tag.setType("commit");
-		}
+		tag.setObjId(object);
+		tag.setType(Constants.typeString(ldr.getType()));
+		tag.setTagger(new PersonIdent(db));
+		tag.setMessage(message.replaceAll("\r", ""));
 		tag.setTag(tagName.substring(Constants.TAGS_PREFIX.length() + 1));
 		tag.tag();
 	}
-
-	private void usage() {
-               throw die("Usage: [-m message] [-f] tag [head]");
-	}
 }
-- 
1.5.6.3.569.ga9185

^ permalink raw reply related

* git-remote SEGV on t5505 test.
From: SungHyun Nam @ 2008-07-18  1:46 UTC (permalink / raw)
  To: git

Hello,

The gdb backtrace said:
(gdb) bt
#0  0xff03455c in strlen () from /usr/lib/libc.so.1
#1  0xff087058 in _doprnt () from /usr/lib/libc.so.1
#2  0xff088c18 in printf () from /usr/lib/libc.so.1
#3  0x0007df20 in prune (argc=1556136, argv=0x139cd0) at
builtin-remote.c:590

The codes in builtin-remote.c:590,
         printf(" * [%s] %s\n", dry_run ? "would prune" : "prune",
                skip_prefix(refname, "refs/remotes/"));

And the 'skip_prefix()' returns NULL in this case.
(The old skip_prefix() never returns NULL).

It seems there is another place need to be checked:
   builtin-remote.c:464 : can pass NULL to the strdup().

Regards,
namsh

^ permalink raw reply

* Re: [PATCH] gitk - work around stderr redirection on Cygwin
From: Mark Levedahl @ 2008-07-18  2:41 UTC (permalink / raw)
  To: Eric Blake; +Cc: Junio C Hamano, paulus, git
In-Reply-To: <487EC2BB.5050503@byu.net>

Eric Blake wrote:
> Could you point me to the patch?  I need to roll the Cygwin git 
> release of
> 1.5.6.3 anyway (in part because cygwin has upgraded from perl 5.8 to
> 5.10).  This sounds like something worth me including as a vendor patch,
> if it does not get folded into the main repo.
>
The patch is at the top of this thread:
http://article.gmane.org/gmane.comp.version-control.git/85023/match=gitk+work+around+stderr+redirection

(I'll send you a patch against Junio's tree privately as a backup).

Mark

^ permalink raw reply

* git gc annoyance
From: Mike Laster @ 2008-07-18  3:30 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 412 bytes --]

Whenever I run 'git gc' all of the files in .git/logs/refs/remotes/ 
tags get touched with the current timestamp.

I use unison to sync my working directories between home and work and  
these files show up as changed unnecessarily.  Since they are all zero- 
byte files
clearly they haven't changed.  It would be more efficient to not touch  
the file if it already exists to leave the old timestamp in place.


[-- Attachment #2: git_gc_log.txt.gz --]
[-- Type: application/x-gzip, Size: 3819 bytes --]

[-- Attachment #3: Type: text/plain, Size: 1 bytes --]



^ permalink raw reply

* Re: git-remote SEGV on t5505 test.
From: Junio C Hamano @ 2008-07-18  4:25 UTC (permalink / raw)
  To: SungHyun Nam; +Cc: git
In-Reply-To: <g5osl6$4g3$1@ger.gmane.org>

SungHyun Nam <namsh@posdata.co.kr> writes:

> And the 'skip_prefix()' returns NULL in this case.
> (The old skip_prefix() never returns NULL).

Thanks.  Something like this?

 builtin-remote.c |   51 +++++++++++++++++++--------------------------------
 1 files changed, 19 insertions(+), 32 deletions(-)

diff --git a/builtin-remote.c b/builtin-remote.c
index 1491354..db12668 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -147,6 +147,15 @@ struct branch_info {
 
 static struct path_list branch_list;
 
+static const char *abbrev_ref(const char *name, const char *prefix)
+{
+	const char *abbrev = skip_prefix(name, prefix);
+	if (abbrev)
+		return abbrev;
+	return name;
+}
+#define abbrev_branch(name) abbrev_ref((name), "refs/heads/")
+
 static int config_read_branches(const char *key, const char *value, void *cb)
 {
 	if (!prefixcmp(key, "branch.")) {
@@ -176,18 +185,12 @@ static int config_read_branches(const char *key, const char *value, void *cb)
 			info->remote = xstrdup(value);
 		} else {
 			char *space = strchr(value, ' ');
-			const char *ptr = skip_prefix(value, "refs/heads/");
-			if (ptr)
-				value = ptr;
+			value = abbrev_branch(value);
 			while (space) {
 				char *merge;
 				merge = xstrndup(value, space - value);
 				path_list_append(merge, &info->merge);
-				ptr = skip_prefix(space + 1, "refs/heads/");
-				if (ptr)
-					value = ptr;
-				else
-					value = space + 1;
+				value = abbrev_branch(space + 1);
 				space = strchr(value, ' ');
 			}
 			path_list_append(xstrdup(value), &info->merge);
@@ -219,12 +222,7 @@ static int handle_one_branch(const char *refname,
 	refspec.dst = (char *)refname;
 	if (!remote_find_tracking(states->remote, &refspec)) {
 		struct path_list_item *item;
-		const char *name, *ptr;
-		ptr = skip_prefix(refspec.src, "refs/heads/");
-		if (ptr)
-			name = ptr;
-		else
-			name = refspec.src;
+		const char *name = abbrev_branch(refspec.src);
 		/* symbolic refs pointing nowhere were handled already */
 		if ((flags & REF_ISSYMREF) ||
 				unsorted_path_list_has_path(&states->tracked,
@@ -253,7 +251,6 @@ static int get_ref_states(const struct ref *ref, struct ref_states *states)
 		struct path_list *target = &states->tracked;
 		unsigned char sha1[20];
 		void *util = NULL;
-		const char *ptr;
 
 		if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
 			target = &states->new;
@@ -262,10 +259,7 @@ static int get_ref_states(const struct ref *ref, struct ref_states *states)
 			if (hashcmp(sha1, ref->new_sha1))
 				util = &states;
 		}
-		ptr = skip_prefix(ref->name, "refs/heads/");
-		if (!ptr)
-			ptr = ref->name;
-		path_list_append(ptr, target)->util = util;
+		path_list_append(abbrev_branch(ref->name), target)->util = util;
 	}
 	free_refs(fetch_map);
 
@@ -460,10 +454,8 @@ static int append_ref_to_tracked_list(const char *refname,
 
 	memset(&refspec, 0, sizeof(refspec));
 	refspec.dst = (char *)refname;
-	if (!remote_find_tracking(states->remote, &refspec)) {
-		path_list_append(skip_prefix(refspec.src, "refs/heads/"),
-			&states->tracked);
-	}
+	if (!remote_find_tracking(states->remote, &refspec))
+		path_list_append(abbrev_branch(refspec.src), &states->tracked);
 
 	return 0;
 }
@@ -530,15 +522,10 @@ static int show(int argc, const char **argv)
 					"es" : "");
 			for (i = 0; i < states.remote->push_refspec_nr; i++) {
 				struct refspec *spec = states.remote->push + i;
-				const char *p = "", *q = "";
-				if (spec->src)
-					p = skip_prefix(spec->src, "refs/heads/");
-				if (spec->dst)
-					q = skip_prefix(spec->dst, "refs/heads/");
 				printf(" %s%s%s%s", spec->force ? "+" : "",
-					p ? p : spec->src,
-					spec->dst ? ":" : "",
-					q ? q : spec->dst);
+				       abbrev_branch(spec->src),
+				       spec->dst ? ":" : "",
+				       spec->dst ? abbrev_branch(spec->dst) : "");
 			}
 			printf("\n");
 		}
@@ -588,7 +575,7 @@ static int prune(int argc, const char **argv)
 				result |= delete_ref(refname, NULL);
 
 			printf(" * [%s] %s\n", dry_run ? "would prune" : "pruned",
-			       skip_prefix(refname, "refs/remotes/"));
+			       abbrev_ref(refname, "refs/remotes/"));
 		}
 
 		/* NEEDSWORK: free remote */

^ permalink raw reply related

* [PATCH] Enable git rev-list to parse --quiet
From: Nick Andrew @ 2008-07-18  4:05 UTC (permalink / raw)
  To: git

Enable git rev-list to parse --quiet

git rev-list never sees the --quiet option because --quiet is
also an option for diff-files.

Example:

$ ./git rev-list --quiet ^HEAD~2 HEAD
1e102bf7c83281944ffd9202a7d35c514e4a5644
3bf0dd1f4e75ee1591169b687ce04dff00ae2e3e
$ echo $?
0

The fix scans the argument list to detect --quiet before passing it
to setup_revisions(). It also arranges to count the number of commits
or objects (whether sent to STDOUT or not) so --quiet can return an
appropriate exit code (1 if there were commits/objects, 0 otherwise).

After fix:

$ ./git rev-list --quiet ^HEAD~2 HEAD
$ echo $?
1
---

 builtin-rev-list.c |   28 ++++++++++++++++++++++++----
 1 files changed, 24 insertions(+), 4 deletions(-)


diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 8e1720c..e2e5e13 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -52,6 +52,11 @@ static const char rev_list_usage[] =
 
 static struct rev_info revs;
 
+/* Count of number of commits or objects noticed (even if not output).
+ * Used by --quiet option to set an appropriate exit status.
+ */
+static int seen_count;
+
 static int bisect_list;
 static int show_timestamp;
 static int hdr_termination;
@@ -167,12 +172,14 @@ static void finish_commit(struct commit *commit)
 	}
 	free(commit->buffer);
 	commit->buffer = NULL;
+	seen_count++;
 }
 
 static void finish_object(struct object_array_entry *p)
 {
 	if (p->item->type == OBJ_BLOB && !has_sha1_file(p->item->sha1))
 		die("missing blob object '%s'", sha1_to_hex(p->item->sha1));
+	seen_count++;
 }
 
 static void show_object(struct object_array_entry *p)
@@ -588,6 +595,17 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 	init_revisions(&revs, prefix);
 	revs.abbrev = 0;
 	revs.commit_format = CMIT_FMT_UNSPECIFIED;
+
+	/* Parse options which are also recognised by git-diff-files */
+	for (i = 1 ; i < argc; i++) {
+		const char *arg = argv[i];
+
+		if (!strcmp(arg, "--quiet")) {
+			quiet = 1;
+			continue;
+		}
+	}
+
 	argc = setup_revisions(argc, argv, &revs, NULL);
 
 	for (i = 1 ; i < argc; i++) {
@@ -621,10 +639,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 			read_revisions_from_stdin(&revs);
 			continue;
 		}
-		if (!strcmp(arg, "--quiet")) {
-			quiet = 1;
-			continue;
-		}
 		usage(rev_list_usage);
 
 	}
@@ -700,9 +714,15 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 		}
 	}
 
+	seen_count = 0;
+
 	traverse_commit_list(&revs,
 		quiet ? finish_commit : show_commit,
 		quiet ? finish_object : show_object);
 
+	if (quiet) {
+		return seen_count ? 1 : 0;
+	}
+
 	return 0;
 }

^ permalink raw reply related

* Re: Git bash - is this MSYS bash or something else?
From: Steffen Prohaska @ 2008-07-18  4:59 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: git
In-Reply-To: <487FE830.5000101@gmail.com>


On Jul 18, 2008, at 2:47 AM, Lennart Borgman (gmail) wrote:

> I wonder if the bash.exe that comes with GIT is MSYS bash or a  
> rewrite?

It is the MSYS bash.


> Does it follow the usual MSYS bash rules?

What does this mean?

	Steffen

^ permalink raw reply

* Re: [PATCH (GIT-GUI) 0/3] Improve gui blame usability for large repositories
From: Alexander Gavrilov @ 2008-07-18  5:39 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20080717021623.GC16740@spearce.org>

Hello,

On Thursday 17 July 2008 06:16:23 Shawn O. Pearce wrote:
> Alexander Gavrilov <angavrilov@gmail.com> wrote:
> > Full copy detection can take quite some time on large repositories, which
> > substantially decreases perceived usability of the 'git gui blame' command.
> > This set of patches tries to overcome it by:
> > 
> > 1) Allowing the user to disable '-C -C' and/or set the detection threshold.
> > 
> > 2) Explicitly killing back-end processes, which don't produce any output
> >   during copy detection, and thus normally won't receive SIGPIPE until
> >   it is finished. Runaway processes are annoying.
> > 
> > 3) To compensate for (1), adding a context menu item to manually invoke
> >   blame -C -C -C on a group of lines.
> 
> This series is nicely done.  Works well on revision.c in git.git,
> where the blame can be costly to compute with full copy detection.
> And getting the incremental from the context menu also works well.

I also thought that it would be useful to be able to specify the line range explicitly,
but couldn't invent a good UI for it. Selecting lines with the mouse also causes a
commit to be selected and recolored in green, and popping up a dialog to request
line numbers seems too lame.

Alexander

^ permalink raw reply

* Re: [PATCH] Enable git rev-list to parse --quiet
From: Junio C Hamano @ 2008-07-18  5:42 UTC (permalink / raw)
  To: Nick Andrew; +Cc: git
In-Reply-To: <20080718040459.13073.76896.stgit@marcab.local.tull.net>

Nick Andrew <nick@nick-andrew.net> writes:

> Enable git rev-list to parse --quiet
>
> git rev-list never sees the --quiet option because --quiet is
> also an option for diff-files.
>
> Example:
>
> $ ./git rev-list --quiet ^HEAD~2 HEAD
> 1e102bf7c83281944ffd9202a7d35c514e4a5644
> 3bf0dd1f4e75ee1591169b687ce04dff00ae2e3e
> $ echo $?
> 0
>
> The fix scans the argument list to detect --quiet before passing it
> to setup_revisions(). It also arranges to count the number of commits
> or objects (whether sent to STDOUT or not) so --quiet can return an
> appropriate exit code (1 if there were commits/objects, 0 otherwise).
>
> After fix:

Thanks for noticing, but this replaces one breakage with another.

Your new behaviour is a new "tell me if it is an empty set" option, and it
means quite different thing from what --quiet does.

The --quiet option is designed primarily for sanity checking after a
failed fetch by commit walkers.  Here is how it works (well, at least how
it is supposed to work).

Imagine you have this history:

	---o---o---X

and the other side has this history:

	---o---o---X---A---B---C

And you run fetch over a dumb protocol; the commit walker fetches C,
discovers you do not have its parent B and tries to fetch it, and you
somehow kill that process.  Your repository will have:

	---o---o---X           C

Now, we do not mark C with our refs, so we do not say "Ok we have
everything leading up to C" when you re-run the same commit walker.
Instead, we'll let the walker walk again starting from C.  So we will
never in corrupt state.

But you might want to see if your repository has this kind of failure.
For that, you can run rev-list starting from C and X --- it will fail
after it finds out that C's parent is B and tries to read it.  And you
will learn the failure with the exit code from the command.  --quiet was
about squelching the output of "I've seen C", "I've seen X", as the only
thing you care about in that mode of usage is if the history is well
connected which is reported by the exit code.

-- >8 --
Subject: [PATCH] rev-list: honor --quiet option

Nick Andrew noticed that rev-list lets the --quiet option to be parsed by
underlying diff_options parser but did not pick up the result.  This
resulted in --quiet option to become effectively a no-op.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-rev-list.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 8e1720c..507201e 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -589,7 +589,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 	revs.abbrev = 0;
 	revs.commit_format = CMIT_FMT_UNSPECIFIED;
 	argc = setup_revisions(argc, argv, &revs, NULL);
-
+	quiet = DIFF_OPT_TST(&revs.diffopt, QUIET);
 	for (i = 1 ; i < argc; i++) {
 		const char *arg = argv[i];
 
@@ -621,10 +621,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 			read_revisions_from_stdin(&revs);
 			continue;
 		}
-		if (!strcmp(arg, "--quiet")) {
-			quiet = 1;
-			continue;
-		}
 		usage(rev_list_usage);
 
 	}
-- 
1.5.6.3.573.gd2d2

^ permalink raw reply related

* [PATCH (GITK) 0/3] Avoid runaway processes in gitk
From: Alexander Gavrilov @ 2008-07-18  5:44 UTC (permalink / raw)
  To: git; +Cc: Paul Mackerras

As in the 'git gui blame' case, gitk back-end processes can sometimes
run for a while without producing any output, e.g. diff-files on a slow
filesystem.

These patches make gitk explicitly kill its back-end processes.

Alexander Gavrilov (3):
      gitk: Kill back-end processes on window close.
      gitk: Register diff-files & diff-index in commfd, to ensure kill.
      gitk: On Windows use a Cygwin-specific flag for kill.

 gitk |   79 ++++++++++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 53 insertions(+), 26 deletions(-)

^ permalink raw reply

* Re: git-remote SEGV on t5505 test.
From: SungHyun Nam @ 2008-07-18  5:44 UTC (permalink / raw)
  To: git
In-Reply-To: <7vsku7es3n.fsf@gitster.siamese.dyndns.org>

Junio C Hamano wrote:
> SungHyun Nam <namsh@posdata.co.kr> writes:
> 
>> And the 'skip_prefix()' returns NULL in this case.
>> (The old skip_prefix() never returns NULL).
> 
> Thanks.  Something like this?

With this patch, 'make test' passed all the tests successfully.
I ran test with GIT_SKIP_TESTS="t90?? t91?? t92?? t94??".

Regards,
namsh

P.S I skipped svn/cvs test because I don't need them (And no
     svn/cvs installed).  But, I skipped send-email test because it
     fails.  I thought I don't need to use send-email.

     And now I check what caused fail.  The problem was this test
     script generates 'fake.sendmail' which uses '/bin/sh'.

     Is it possible that we can use 'SHELL_PATH' here?  Or could
     you apply the patch below?

diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index de5b980..0320aa1 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -16,7 +16,7 @@ test_expect_success \
      '(echo "#!/bin/sh"
        echo shift
        echo output=1
-      echo "while test -f commandline\$output; do
output=\$((\$output+1)); done"
+      echo "while test -f commandline\$output; do output=\`expr
\$output + 1\`; done"
        echo for a
        echo do
        echo "  echo \"!\$a!\""

^ permalink raw reply related

* [PATCH (GITK) 1/3] gitk: Kill back-end processes on window close.
From: Alexander Gavrilov @ 2008-07-18  5:45 UTC (permalink / raw)
  To: git; +Cc: Paul Mackerras
In-Reply-To: <200807180944.48570.angavrilov@gmail.com>

When collecting commits for a rarely changed, or recently
created file or directory, rev-list may work for a noticeable
period of time without producing any output. Such processes
don't receive SIGPIPE for a while after gitk is closed, thus
becoming runaway CPU hogs.

Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
---
 gitk |   35 +++++++++++++++++++++++++----------
 1 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/gitk b/gitk
index fddcb45..29d79d6 100755
--- a/gitk
+++ b/gitk
@@ -375,19 +375,33 @@ proc start_rev_list {view} {
     return 1
 }
 
+proc stop_instance {inst} {
+    global commfd leftover
+
+    set fd $commfd($inst)
+    catch {
+	set pid [pid $fd]
+	exec kill $pid
+    }
+    catch {close $fd}
+    nukefile $fd
+    unset commfd($inst)
+    unset leftover($inst)
+}
+
+proc stop_backends {} {
+    global commfd
+
+    foreach inst [array names commfd] {
+	stop_instance $inst
+    }
+}
+
 proc stop_rev_list {view} {
-    global commfd viewinstances leftover
+    global viewinstances
 
     foreach inst $viewinstances($view) {
-	set fd $commfd($inst)
-	catch {
-	    set pid [pid $fd]
-	    exec kill $pid
-	}
-	catch {close $fd}
-	nukefile $fd
-	unset commfd($inst)
-	unset leftover($inst)
+	stop_instance $inst
     }
     set viewinstances($view) {}
 }
@@ -2103,6 +2117,7 @@ proc makewindow {} {
     bind . <$M1B-minus> {incrfont -1}
     bind . <$M1B-KP_Subtract> {incrfont -1}
     wm protocol . WM_DELETE_WINDOW doquit
+    bind . <Destroy> {stop_backends}
     bind . <Button-1> "click %W"
     bind $fstring <Key-Return> {dofind 1 1}
     bind $sha1entry <Key-Return> gotocommit
-- 
1.5.6.2.39.gd084

^ permalink raw reply related

* [PATCH (GITK) 2/3] gitk: Register diff-files & diff-index in commfd, to ensure kill.
From: Alexander Gavrilov @ 2008-07-18  5:46 UTC (permalink / raw)
  To: git; +Cc: Paul Mackerras
In-Reply-To: <200807180945.43504.angavrilov@gmail.com>

Local change analysis can take a noticeable amount of time on large
file sets, and produce no output if there are no changes. Register
the back-ends in commfd, so that they get properly killed on window
close.

Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
---
 gitk |   39 +++++++++++++++++++++++----------------
 1 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/gitk b/gitk
index 29d79d6..b523c98 100755
--- a/gitk
+++ b/gitk
@@ -90,6 +90,15 @@ proc dorunq {} {
     }
 }
 
+proc reg_instance {fd} {
+    global commfd leftover loginstance
+
+    set i [incr loginstance]
+    set commfd($i) $fd
+    set leftover($i) {}
+    return $i
+}
+
 proc unmerged_files {files} {
     global nr_unmerged
 
@@ -294,10 +303,10 @@ proc parseviewrevs {view revs} {
 # Start off a git log process and arrange to read its output
 proc start_rev_list {view} {
     global startmsecs commitidx viewcomplete curview
-    global commfd leftover tclencoding
+    global tclencoding
     global viewargs viewargscmd viewfiles vfilelimit
     global showlocalchanges commitinterest
-    global viewactive loginstance viewinstances vmergeonly
+    global viewactive viewinstances vmergeonly
     global pending_select mainheadid
     global vcanopt vflags vrevs vorigargs
 
@@ -354,10 +363,8 @@ proc start_rev_list {view} {
 	error_popup "[mc "Error executing git log:"] $err"
 	return 0
     }
-    set i [incr loginstance]
+    set i [reg_instance $fd]
     set viewinstances($view) [list $i]
-    set commfd($i) $fd
-    set leftover($i) {}
     if {$showlocalchanges && $mainheadid ne {}} {
 	lappend commitinterest($mainheadid) {dodiffindex}
     }
@@ -420,8 +427,8 @@ proc getcommits {} {
 
 proc updatecommits {} {
     global curview vcanopt vorigargs vfilelimit viewinstances
-    global viewactive viewcomplete loginstance tclencoding
-    global startmsecs commfd showneartags showlocalchanges leftover
+    global viewactive viewcomplete tclencoding
+    global startmsecs showneartags showlocalchanges
     global mainheadid pending_select
     global isworktree
     global varcid vposids vnegids vflags vrevs
@@ -482,10 +489,8 @@ proc updatecommits {} {
     if {$viewactive($view) == 0} {
 	set startmsecs [clock clicks -milliseconds]
     }
-    set i [incr loginstance]
+    set i [reg_instance $fd]
     lappend viewinstances($view) $i
-    set commfd($i) $fd
-    set leftover($i) {}
     fconfigure $fd -blocking 0 -translation lf -eofchar {}
     if {$tclencoding != {}} {
 	fconfigure $fd -encoding $tclencoding
@@ -4063,10 +4068,11 @@ proc dodiffindex {} {
     incr lserial
     set fd [open "|git diff-index --cached HEAD" r]
     fconfigure $fd -blocking 0
-    filerun $fd [list readdiffindex $fd $lserial]
+    set i [reg_instance $fd]
+    filerun $fd [list readdiffindex $fd $lserial $i]
 }
 
-proc readdiffindex {fd serial} {
+proc readdiffindex {fd serial inst} {
     global mainheadid nullid nullid2 curview commitinfo commitdata lserial
 
     set isdiff 1
@@ -4077,7 +4083,7 @@ proc readdiffindex {fd serial} {
 	set isdiff 0
     }
     # we only need to see one line and we don't really care what it says...
-    close $fd
+    stop_instance $inst
 
     if {$serial != $lserial} {
 	return 0
@@ -4086,7 +4092,8 @@ proc readdiffindex {fd serial} {
     # now see if there are any local changes not checked in to the index
     set fd [open "|git diff-files" r]
     fconfigure $fd -blocking 0
-    filerun $fd [list readdifffiles $fd $serial]
+    set i [reg_instance $fd]
+    filerun $fd [list readdifffiles $fd $serial $i]
 
     if {$isdiff && ![commitinview $nullid2 $curview]} {
 	# add the line for the changes in the index to the graph
@@ -4103,7 +4110,7 @@ proc readdiffindex {fd serial} {
     return 0
 }
 
-proc readdifffiles {fd serial} {
+proc readdifffiles {fd serial inst} {
     global mainheadid nullid nullid2 curview
     global commitinfo commitdata lserial
 
@@ -4115,7 +4122,7 @@ proc readdifffiles {fd serial} {
 	set isdiff 0
     }
     # we only need to see one line and we don't really care what it says...
-    close $fd
+    stop_instance $inst
 
     if {$serial != $lserial} {
 	return 0
-- 
1.5.6.2.39.gd084

^ permalink raw reply related

* [PATCH (GITK) 3/3] gitk: On Windows use a Cygwin-specific flag for kill.
From: Alexander Gavrilov @ 2008-07-18  5:47 UTC (permalink / raw)
  To: git; +Cc: Paul Mackerras
In-Reply-To: <200807180946.43560.angavrilov@gmail.com>

MSysGit compiles git binaries as native Windows executables,
so they cannot be killed unless a special flag is specified.

This flag is implemented by the Cygwin version of kill,
which is also included in MSysGit.

Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
---
 gitk |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/gitk b/gitk
index b523c98..d7fea26 100755
--- a/gitk
+++ b/gitk
@@ -388,7 +388,12 @@ proc stop_instance {inst} {
     set fd $commfd($inst)
     catch {
 	set pid [pid $fd]
-	exec kill $pid
+
+	if {$::tcl_platform(platform) eq {windows}} {
+	    exec kill -f $pid
+	} else {
+	    exec kill $pid
+	}
     }
     catch {close $fd}
     nukefile $fd
-- 
1.5.6.2.39.gd084

^ permalink raw reply related

* Re: [PATCH] shrink git-shell by avoiding redundant dependencies
From: Dmitry Potapov @ 2008-07-18  5:59 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <20080718002620.GE8421@leksak.fem-net>

On Fri, Jul 18, 2008 at 02:26:20AM +0200, Stephan Beyer wrote:
> 
> Dmitry Potapov wrote:
> > diff --git a/shell.c b/shell.c
> > index b27d01c..91ca7de 100644
> > --- a/shell.c
> > +++ b/shell.c
> > @@ -3,6 +3,14 @@
> >  #include "exec_cmd.h"
> >  #include "strbuf.h"
> >  
> > +/* Stubs for functions that make no sense for git-shell. These stubs
> > + * are provided here to avoid linking in external redundant modules.
> > + */
> > +void release_pack_memory(size_t need, int fd){}
> > +void trace_argv_printf(const char **argv, const char *fmt, ...){}
> > +void trace_printf(const char *fmt, ...){}
> > +
> > +
> 
> I don't really understand why this works.
> You redefine libgit.a functions here
> 
> So the linker should complain like that:
> 	libgit.a(sha1_file.o): In function `release_pack_memory':
> 	/home/sbeyer/src/git/sha1_file.c:624: multiple definition of `release_pack_memory'
> 	shell.o:/home/sbeyer/src/git/shell.c:9: first defined here
> 	collect2: ld returned 1 exit status
> 
> And, in fact, it does when I move a function from a builtin to a lib
> source file, for example launch_editor() from builtin-tag.c to strbuf.c,
> like the following one:

It works because these functions are defined in object files, so the
linker should not search for them in libraries. However, if the linker
is forced to link sha1_file.c for some other reason, you will get the
conflict.

Dmitry

^ permalink raw reply

* Re: [PATCH] Link git-shell only to a subset of libgit.a
From: Dmitry Potapov @ 2008-07-18  6:03 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <1216343070-20237-1-git-send-email-s-beyer@gmx.net>

On Fri, Jul 18, 2008 at 03:04:30AM +0200, Stephan Beyer wrote:
> Commit 5b8e6f85 introduced stubs for three functions that make no sense
> for git-shell. But those stubs defined libgit.a functions a second time
> so that a linker can complain.
> 
> Now git-shell is only linked to a subset of libgit.a.
> 
> Signed-off-by: Stephan Beyer <s-beyer@gmx.net>

I agree, it is probably better to specify explicitly what files to link
for git-shell if we want to keep it small and avoid the problem with
some linkers.

Dmitry

^ permalink raw reply

* Re: [PATCH] Remove function stubs in shell.c
From: Dmitry Potapov @ 2008-07-18  6:06 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <1216343197-20290-1-git-send-email-s-beyer@gmx.net>

On Fri, Jul 18, 2008 at 03:06:37AM +0200, Stephan Beyer wrote:
> These function stubs may be useful, but because they redefine
> functions, they provoke a linker error.
> 
> Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
> ---
> Or would you rather like this one? ;)

Unfortunately, this one will increase the size of git-shell
considerably:

   text    data     bss     dec     hex filename
  18182     824    8232   27238    6a66 git-shell
===
   text    data     bss     dec     hex filename
 146738    1376   93164  241278   3ae7e git-shell

So, personally, I don't like it.

Dmitry

^ permalink raw reply

* Re: [PATCH] Enable git rev-list to parse --quiet
From: Junio C Hamano @ 2008-07-18  6:10 UTC (permalink / raw)
  To: Nick Andrew; +Cc: git
In-Reply-To: <7v8wvzeojm.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Nick Andrew <nick@nick-andrew.net> writes:
> ...
>> After fix:
>
> Thanks for noticing, but this replaces one breakage with another.
>
> Your new behaviour is a new "tell me if it is an empty set" option, and it
> means quite different thing from what --quiet does.

And here is how I would do it if I were interested in such a feature.

-- >8 --
rev-list --check-empty

This new option squelches the output entirely and signals if the specified
set is empty by its exit status.  E.g.

    $ git rev-list --check-empty HEAD..HEAD

will exit with a non-zero status, and

    $ git rev-list --check-empty HEAD^..HEAD

will exit with zero status.

---
 builtin-rev-list.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 507201e..4f9cce9 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -52,6 +52,7 @@ static const char rev_list_usage[] =
 
 static struct rev_info revs;
 
+static int check_empty;
 static int bisect_list;
 static int show_timestamp;
 static int hdr_termination;
@@ -161,6 +162,8 @@ static void show_commit(struct commit *commit)
 
 static void finish_commit(struct commit *commit)
 {
+	if (check_empty)
+		exit(0);
 	if (commit->parents) {
 		free_commit_list(commit->parents);
 		commit->parents = NULL;
@@ -171,6 +174,8 @@ static void finish_commit(struct commit *commit)
 
 static void finish_object(struct object_array_entry *p)
 {
+	if (check_empty)
+		exit(0);
 	if (p->item->type == OBJ_BLOB && !has_sha1_file(p->item->sha1))
 		die("missing blob object '%s'", sha1_to_hex(p->item->sha1));
 }
@@ -593,6 +598,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 	for (i = 1 ; i < argc; i++) {
 		const char *arg = argv[i];
 
+		if (!strcmp(arg, "--check-empty")) {
+			check_empty = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--header")) {
 			revs.verbose_header = 1;
 			continue;
@@ -650,6 +659,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 
 	if (prepare_revision_walk(&revs))
 		die("revision walk setup failed");
+	if (check_empty)
+		quiet = 1;
+
 	if (revs.tree_objects)
 		mark_edges_uninteresting(revs.commits, &revs, show_edge);
 
@@ -699,6 +711,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 	traverse_commit_list(&revs,
 		quiet ? finish_commit : show_commit,
 		quiet ? finish_object : show_object);
-
+	if (check_empty)
+		exit(1);
 	return 0;
 }

^ permalink raw reply related


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