git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[JGIT PATCH 7/8] Pack jgit into a portable single file command line utility

From
Shawn O. Pearce <spearce@spearce.org>
Date
Jul 1, 2008, 03:04 UTC
Message-ID
<1214881445-3931-8-git-send-email-spearce@spearce.org>
In-Reply-To
<1214881445-3931-7-git-send-email-spearce@spearce.org>

On UNIX (and even Cygwin) we can package the entire jgit library into a single JAR file and prefix that JAR with a shell script to start the JVM, passing in the script/JAR file as the only classpath. This trick works because the table of contents for the ZIP file is at the end of the stream, and the JVM tends to only do random access through that table when it looks up classes for loading.

A tiny shell script called make_jgit.sh compiles everything with the command line javac and packages it into the portable jgit shell script, making it possible to build and use jgit without touching either Eclipse or Maven.

Currently this is quite easy to implement as we have only one support library (JSch), but things may get more complicated if we add another JAR to our classpath.

With this I can install JGit into my personal account and make use of it on a daily basis from the command line:

	./make_jgit.sh
	mv jgit ~/bin
	jgit push ...
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .gitignore   |    1 +
 jgit         |   37 -------------------------------------
 jgit.sh      |   45 +++++++++++++++++++++++++++++++++++++++++++++
 make_jgit.sh |   26 ++++++++++++++++++++++++++
 4 files changed, 72 insertions(+), 37 deletions(-)
 create mode 100644 .gitignore
 delete mode 100755 jgit
 create mode 100755 jgit.sh
 create mode 100755 make_jgit.sh
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0763732
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/jgit
diff --git a/jgit b/jgit
deleted file mode 100755
index be7df7e..0000000
--- a/jgit
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-
-jgit_home=`dirname $0`
-cp="$jgit_home/org.spearce.jgit/bin"
-cp="$cp:$jgit_home/org.spearce.jgit/lib/jsch-0.1.37.jar"
-unset jgit_home
-java_args=
-
-# Cleanup paths for Cygwin.
-#
-case "`uname`" in
-CYGWIN*)
-	cp=`cygpath --windows --mixed --path "$cp"`
-	;;
-Darwin)
-	if test -e /System/Library/Frameworks/JavaVM.framework
-	then
-		java_args='
-			-Dcom.apple.mrj.application.apple.menu.about.name=JGit
-			-Dcom.apple.mrj.application.growbox.intrudes=false
-			-Dapple.laf.useScreenMenuBar=true
-			-Xdock:name=JGit
-		'
-	fi
-	;;
-esac
-
-CLASSPATH="$cp"
-export CLASSPATH
-
-java=java
-if test -n "$JAVA_HOME"
-then
-	java="$JAVA_HOME/bin/java"
-fi
-
-exec "$java" $java_args org.spearce.jgit.pgm.Main "$@"
diff --git a/jgit.sh b/jgit.sh
new file mode 100755
index 0000000..84927bc
--- /dev/null
+++ b/jgit.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+if [ "@@use_self@@" = "1" ]
+then
+	this_script=`which "$0" 2>/dev/null`
+	[ $? -gt 0 -a -f "$0" ] && this_script="$0"
+	cp=$this_script
+else
+	jgit_home=`dirname $0`
+	cp="$jgit_home/org.spearce.jgit/bin"
+	cp="$cp:$jgit_home/org.spearce.jgit/lib/jsch-0.1.37.jar"
+	unset jgit_home
+	java_args=
+fi
+
+# Cleanup paths for Cygwin.
+#
+case "`uname`" in
+CYGWIN*)
+	cp=`cygpath --windows --mixed --path "$cp"`
+	;;
+Darwin)
+	if test -e /System/Library/Frameworks/JavaVM.framework
+	then
+		java_args='
+			-Dcom.apple.mrj.application.apple.menu.about.name=JGit
+			-Dcom.apple.mrj.application.growbox.intrudes=false
+			-Dapple.laf.useScreenMenuBar=true
+			-Xdock:name=JGit
+		'
+	fi
+	;;
+esac
+
+CLASSPATH="$cp"
+export CLASSPATH
+
+java=java
+if test -n "$JAVA_HOME"
+then
+	java="$JAVA_HOME/bin/java"
+fi
+
+exec "$java" $java_args org.spearce.jgit.pgm.Main "$@"
+exit 1
diff --git a/make_jgit.sh b/make_jgit.sh
new file mode 100755
index 0000000..3889dca
--- /dev/null
+++ b/make_jgit.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+PATH=$JAVA_HOME/bin:$PATH
+O=jgit
+T=".temp$$.$O"
+
+rm -f $O
+rm -rf $T $O+ org.spearce.jgit/bin2
+cp org.spearce.jgit/lib/jsch-0.1.37.jar $T &&
+mkdir org.spearce.jgit/bin2 &&
+(cd org.spearce.jgit/src &&
+ find . -name \*.java -type f |
+ xargs javac \
+	-source 1.5 \
+	-target 1.5 \
+	-g \
+	-d ../bin2 \
+	-cp ../lib/jsch-0.1.37.jar) &&
+jar uf $T -C org.spearce.jgit/bin2 . &&
+jar uf $T -C org.spearce.jgit META-INF &&
+sed s/@@use_self@@/1/ jgit.sh >$O+ &&
+cat $T >>$O+ &&
+chmod 555 $O+ &&
+mv $O+ $O &&
+echo "Created $O." &&
+rm -rf $T $O+ org.spearce.jgit/bin2
-- 
1.5.6.74.g8a5e
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 8 of 9 in “Minor push fixups”
  1. 0/8 Minor push fixupsShawn O. Pearce, Jul 1, 2008
  2. 1/8 Correct thin pack completion in IndexPack to handle some bundlesShawn O. Pearce, Jul 1, 2008
  3. 2/8 Delete reflog when deleting ref during dumb transport pushShawn O. Pearce, Jul 1, 2008
  4. 3/8 Refuse to create or delete funny ref names over dumb transportsShawn O. Pearce, Jul 1, 2008
  5. 4/8 Shorten progress message text from PackWriterShawn O. Pearce, Jul 1, 2008
  6. 5/8 Correctly name the stderr redirection thread for local transportShawn O. Pearce, Jul 1, 2008
  7. 6/8 Support 'git upload-pack' and 'git receive-pack' over SSHShawn O. Pearce, Jul 1, 2008
  8. 7/8 Pack jgit into a portable single file command line utilityShawn O. Pearce, Jul 1, 2008
  9. 8/8 Don't try to pack 0{40} during push of delete and updateShawn O. Pearce, Jul 1, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.