{"thread":{"id":"17555","subject":"[PATCH JGIT] Compute the author/commiter name and email from the git configuration","startedAt":"2009-02-04T12:28:54Z","lastAt":"2009-02-04T17:36:03Z","messageCount":2,"participants":["Yann Simon","Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"103116","messageId":"49898A06.5040603@gmail.com","threadId":"17555","inReplyTo":null,"subject":"[PATCH JGIT] Compute the author/commiter name and email from the git configuration","fromName":"Yann Simon","fromEmail":"yann.simon.fr@gmail.com","sentAt":"2009-02-04T12:28:54Z","receivedAt":"2009-02-04T12:28:54Z","isPatch":true,"sender":{"key":"yann.simon.fr@gmail.com","avatar":"https://gravatar.com/avatar/2d926895d27ac988c5c8e591887e5a6a4c7036390403c74fce92519119b887a0?d=mp&s=160"},"body":"The author/commiter name and email are retrieved from the system configuration\nand the local and global git configurations.\n\nWhen the name is not available, propose one default by using the system user name.\n\nWhen the email is not available, propose one default by concatenate the\nuser name and the host name.\n\nThe author name and email are used as default value in the author field\nwhile committing with the GUI.\n\nFix issue 47 (field Author don't fill)\n\nSigned-off-by: Yann Simon <yann.simon.fr@gmail.com>\n---\nThis is the second version of the patch.\n\nThe differences are the following ones:\n- use System.getenv for environment variables\n- use canonical host name.\n- static cache the host name\n\n .../egit/ui/internal/actions/CommitAction.java     |   17 +++\n .../org/spearce/jgit/lib/RepositoryConfigTest.java |   70 ++++++++++++\n .../src/org/spearce/jgit/lib/Constants.java        |   16 +++\n .../src/org/spearce/jgit/lib/RepositoryConfig.java |  116 ++++++++++++++++++++\n .../src/org/spearce/jgit/util/SystemReader.java    |   24 ++++\n 5 files changed, 243 insertions(+), 0 deletions(-)\n create mode 100644 org.spearce.jgit/src/org/spearce/jgit/util/SystemReader.java\n\ndiff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java\nindex 17232d6..456745c 100644\n--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java\n+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java\n@@ -41,6 +41,7 @@\n import org.spearce.jgit.lib.PersonIdent;\n import org.spearce.jgit.lib.RefUpdate;\n import org.spearce.jgit.lib.Repository;\n+import org.spearce.jgit.lib.RepositoryConfig;\n import org.spearce.jgit.lib.Tree;\n import org.spearce.jgit.lib.TreeEntry;\n import org.spearce.jgit.lib.GitIndex.Entry;\n@@ -70,8 +71,10 @@ public void run(IAction act) {\n \t\t}\n \n \t\tRepository[] repos = getRepositoriesFor(getProjectsForSelectedResources());\n+\t\tRepository repository = null;\n \t\tamendAllowed = repos.length == 1;\n \t\tfor (Repository repo : repos) {\n+\t\t\trepository = repo;\n \t\t\tif (!repo.getRepositoryState().canCommit()) {\n \t\t\t\tMessageDialog.openError(getTargetPart().getSite().getShell(),\n \t\t\t\t\t\"Cannot commit now\", \"Repository state:\"\n@@ -95,12 +98,26 @@ public void run(IAction act) {\n \t\t\t}\n \t\t}\n \n+\t\tassert repository != null;\n+\t\tRepositoryConfig repositoryConfig = repository.getConfig();\n+\t\tString author = null;\n+\t\tString username = repositoryConfig.getAuthorName();\n+\t\tif (username != null && username.length() != 0) {\n+\t\t\tauthor = username;\n+\t\t\tString email = repositoryConfig.getAuthorEmail();\n+\t\t\tif (email != null && email.length() != 0) {\n+\t\t\t\tauthor = author + \" <\" + email + \">\";\n+\t\t\t}\n+\t\t}\n+\n \t\tloadPreviousCommit();\n \n \t\tCommitDialog commitDialog = new CommitDialog(getTargetPart().getSite().getShell());\n \t\tcommitDialog.setAmending(amending);\n \t\tcommitDialog.setAmendAllowed(amendAllowed);\n \t\tcommitDialog.setFileList(files);\n+\t\tcommitDialog.setAuthor(author);\n+\n \t\tif (previousCommit != null)\n \t\t\tcommitDialog.setPreviousCommitMessage(previousCommit.getMessage());\n \ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java\nindex 34ce04a..113eb1c 100644\n--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java\n@@ -43,7 +43,11 @@\n import java.io.File;\n import java.io.IOException;\n import java.util.Arrays;\n+import java.util.HashMap;\n import java.util.LinkedList;\n+import java.util.Map;\n+\n+import org.spearce.jgit.util.SystemReader;\n \n /**\n  * Test reading of git config\n@@ -116,4 +120,70 @@ public void test006_readCaseInsensitive() throws IOException {\n \t\tassertEquals(true, repositoryConfig.getBoolean(\"foo\", null, \"bar\", false));\n \t\tassertEquals(\"\", repositoryConfig.getString(\"foo\", null, \"bar\"));\n \t}\n+\n+\tprivate class FakeSystemReader implements SystemReader {\n+\t\tMap<String, String> values = new HashMap<String, String>();\n+\t\tpublic String getEnvironmentVariable(String variable) {\n+\t\t\treturn values.get(variable);\n+\t\t}\n+\t\tpublic String getProperty(String key) {\n+\t\t\treturn values.get(key);\n+\t\t}\n+\t}\n+\n+\tpublic void test007_readUserInfos() throws IOException {\n+\t\tfinal File globalConfig = writeTrashFile(\"global.config\", \"\");\n+\t\tfinal File localConfig = writeTrashFile(\"local.config\", \"\");\n+\t\tSystem.clearProperty(Constants.OS_USER_NAME_KEY);\n+\n+\t\tFakeSystemReader fakeSystemReader = new FakeSystemReader();\n+\n+\t\tRepositoryConfig globalRepositoryConfig = new RepositoryConfig(null, globalConfig);\n+\t\tRepositoryConfig localRepositoryConfig = new RepositoryConfig(globalRepositoryConfig, localConfig);\n+\t\tlocalRepositoryConfig.setSystemReader(fakeSystemReader);\n+\n+\t\tString authorName;\n+\t\tString authorEmail;\n+\n+\t\t// no values defined nowhere\n+\t\tauthorName = localRepositoryConfig.getAuthorName();\n+\t\tauthorEmail = localRepositoryConfig.getAuthorEmail();\n+\t\tassertNull(authorName);\n+\t\tassertNull(authorEmail);\n+\n+\t\t// the system user name is defined\n+\t\tfakeSystemReader.values.put(Constants.OS_USER_NAME_KEY, \"os user name\");\n+\t\tauthorName = localRepositoryConfig.getAuthorName();\n+\t\tassertEquals(\"os user name\", authorName);\n+\n+\t\tString hostname = RepositoryConfig.getHostname();\n+\t\tif (hostname != null && hostname.length() != 0) {\n+\t\t\tauthorEmail = localRepositoryConfig.getAuthorEmail();\n+\t\t\tassertEquals(\"os user name@\" + hostname, authorEmail);\n+\t\t}\n+\n+\t\t// the git environment variables are defined\n+\t\tfakeSystemReader.values.put(Constants.GIT_AUTHOR_NAME_KEY, \"git author name\");\n+\t\tfakeSystemReader.values.put(Constants.GIT_AUTHOR_EMAIL_KEY, \"author@email\");\n+\t\tauthorName = localRepositoryConfig.getAuthorName();\n+\t\tauthorEmail = localRepositoryConfig.getAuthorEmail();\n+\t\tassertEquals(\"git author name\", authorName);\n+\t\tassertEquals(\"author@email\", authorEmail);\n+\n+\t\t// the values are defined in the global configuration\n+\t\tglobalRepositoryConfig.setString(\"user\", null, \"name\", \"global username\");\n+\t\tglobalRepositoryConfig.setString(\"user\", null, \"email\", \"author@globalemail\");\n+\t\tauthorName = localRepositoryConfig.getAuthorName();\n+\t\tauthorEmail = localRepositoryConfig.getAuthorEmail();\n+\t\tassertEquals(\"global username\", authorName);\n+\t\tassertEquals(\"author@globalemail\", authorEmail);\n+\n+\t\t// the values are defined in the local configuration\n+\t\tlocalRepositoryConfig.setString(\"user\", null, \"name\", \"local username\");\n+\t\tlocalRepositoryConfig.setString(\"user\", null, \"email\", \"author@localemail\");\n+\t\tauthorName = localRepositoryConfig.getAuthorName();\n+\t\tauthorEmail = localRepositoryConfig.getAuthorEmail();\n+\t\tassertEquals(\"local username\", authorName);\n+\t\tassertEquals(\"author@localemail\", authorEmail);\n+\t}\n }\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java\nindex 8f093d6..372fba5 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java\n@@ -228,6 +228,22 @@\n \t/** Packed refs file */\n \tpublic static final String PACKED_REFS = \"packed-refs\";\n \n+\t/** The environment variable that contains the system user name */\n+\tpublic static final String OS_USER_NAME_KEY = \"user.name\";\n+\n+\t/** The environment variable that contains the author's name */\n+\tpublic static final String GIT_AUTHOR_NAME_KEY = \"GIT_AUTHOR_NAME\";\n+\n+\t/** The environment variable that contains the author's email */\n+\tpublic static final String GIT_AUTHOR_EMAIL_KEY = \"GIT_AUTHOR_EMAIL\";\n+\n+\t/** The environment variable that contains the commiter's name */\n+\tpublic static final String GIT_COMMITER_NAME_KEY = \"GIT_COMMITER_NAME\";\n+\n+\t/** The environment variable that contains the commiter's email */\n+\tpublic static final String GIT_COMMITER_EMAIL_KEY = \"GIT_COMMITER_EMAIL\";\n+\n+\n \t/**\n \t * Create a new digest function for objects.\n \t * \ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java\nindex 7df90cd..0fa4b1f 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java\n@@ -50,6 +50,8 @@\n import java.io.InputStreamReader;\n import java.io.OutputStreamWriter;\n import java.io.PrintWriter;\n+import java.net.InetAddress;\n+import java.net.UnknownHostException;\n import java.util.ArrayList;\n import java.util.Collections;\n import java.util.HashMap;\n@@ -60,6 +62,7 @@\n import java.util.Set;\n \n import org.spearce.jgit.util.FS;\n+import org.spearce.jgit.util.SystemReader;\n \n /**\n  * An object representing the Git config file.\n@@ -98,8 +101,20 @@ public static RepositoryConfig openUserConfig() {\n \n \tprivate Map<String, Object> byName;\n \n+\tprivate static String hostname;\n+\n \tprivate static final String MAGIC_EMPTY_VALUE = \"%%magic%%empty%%\";\n \n+\t// default system reader gets the value from the system\n+\tprivate static SystemReader systemReader = new SystemReader() {\n+\t\tpublic String getEnvironmentVariable(String variable) {\n+\t\t\treturn System.getenv(variable);\n+\t\t}\n+\t\tpublic String getProperty(String key) {\n+\t\t\treturn System.getProperty(key);\n+\t\t}\n+\t};\n+\n \tRepositoryConfig(final Repository repo) {\n \t\tthis(openUserConfig(), FS.resolve(repo.getDirectory(), \"config\"));\n \t}\n@@ -308,6 +323,83 @@ public String getString(final String section, String subsection, final String na\n \t\treturn result;\n \t}\n \n+\t/**\n+\t * @return the author name as defined in the git variables\n+\t *         and configurations. If no name could be found, try\n+\t *         to use the system user name instead.\n+\t */\n+\tpublic String getAuthorName() {\n+\t\treturn getUsernameInternal(Constants.GIT_AUTHOR_NAME_KEY);\n+\t}\n+\n+\t/**\n+\t * @return the commiter name as defined in the git variables\n+\t *         and configurations. If no name could be found, try\n+\t *         to use the system user name instead.\n+\t */\n+\tpublic String getCommiterName() {\n+\t\treturn getUsernameInternal(Constants.GIT_COMMITER_NAME_KEY);\n+\t}\n+\n+\tprivate String getUsernameInternal(String gitVariableKey) {\n+\t\t// try to get the user name from the local and global configurations.\n+\t\tString username = getString(\"user\", null, \"name\");\n+\n+\t\tif (username == null) {\n+\t\t\t// try to get the user name for the system property GIT_XXX_NAME\n+\t\t\tusername = systemReader.getEnvironmentVariable(gitVariableKey);\n+\t\t}\n+\t\tif (username == null) {\n+\t\t\t// get the system user name\n+\t\t\tusername = systemReader.getProperty(Constants.OS_USER_NAME_KEY);\n+\t\t}\n+\n+\t\treturn username;\n+\t}\n+\n+\t/**\n+\t * @return the author email as defined in git variables and\n+\t *         configurations. If no email could be found, try to\n+\t *         propose one default with the author name and the\n+\t *         host name.\n+\t */\n+\tpublic String getAuthorEmail() {\n+\t\treturn getUserEmailInternal(Constants.GIT_AUTHOR_EMAIL_KEY, true);\n+\t}\n+\n+\t/**\n+\t * @return the commiter email as defined in git variables and\n+\t *         configurations. If no email could be found, try to\n+\t *         propose one default with the author name and the\n+\t *         host name.\n+\t */\n+\tpublic String getCommiterEmail() {\n+\t\treturn getUserEmailInternal(Constants.GIT_COMMITER_EMAIL_KEY, false);\n+\t}\n+\n+\tprivate String getUserEmailInternal(String gitVariableKey, boolean author) {\n+\t\t// try to get the email from the local and global configurations.\n+\t\tString email = getString(\"user\", null, \"email\");\n+\n+\t\tif (email == null) {\n+\t\t\t// try to get the email for the system property GIT_XXX_EMAIL\n+\t\t\temail = systemReader.getEnvironmentVariable(gitVariableKey);\n+\t\t}\n+\n+\t\tif (email == null) {\n+\t\t\t// try to construct an email\n+\t\t\tString userName = author ? getAuthorName() : getCommiterName();\n+\t\t\tif (userName != null && userName.length() != 0) {\n+\t\t\t\tString hostnameTmp = getHostname();\n+\t\t\t\tif (hostnameTmp != null && hostnameTmp.length() != 0) {\n+\t\t\t\t\temail = userName + \"@\" + hostnameTmp;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\n+\t\treturn email;\n+\t}\n+\n \tprivate String getRawString(final String section, final String subsection,\n \t\t\tfinal String name) {\n \t\tfinal Object o = getRawEntry(section, subsection, name);\n@@ -957,4 +1049,28 @@ private static boolean eq(final String a, final String b) {\n \t\t\treturn a.equalsIgnoreCase(b);\n \t\t}\n \t}\n+\n+\t/**\n+\t * @return the canonical hostname\n+\t */\n+\tpublic static String getHostname() {\n+\t\tif (hostname == null) {\n+\t\t\ttry {\n+\t\t\t\tInetAddress localMachine = InetAddress.getLocalHost();\n+\t\t\t\thostname = localMachine.getCanonicalHostName();\n+\t\t\t} catch (UnknownHostException e) {\n+\t\t\t\t// we do nothing\n+\t\t\t}\n+\t\t}\n+\t\treturn hostname;\n+\t}\n+\n+\t/**\n+\t * Overrides the default system reader by a custom one.\n+\t * @param systemReader new system reader\n+\t */\n+\tpublic void setSystemReader(SystemReader systemReader) {\n+\t\tRepositoryConfig.systemReader = systemReader;\n+\t}\n+\n }\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/util/SystemReader.java b/org.spearce.jgit/src/org/spearce/jgit/util/SystemReader.java\nnew file mode 100644\nindex 0000000..89b4021\n--- /dev/null\n+++ b/org.spearce.jgit/src/org/spearce/jgit/util/SystemReader.java\n@@ -0,0 +1,24 @@\n+package org.spearce.jgit.util;\n+\n+/**\n+ * Interface to read values from the system.\n+ * <p>\n+ * When writing unit tests, extending this interface with a custom class\n+ * permits to simulate an access to a system variable or property.\n+ * </p>\n+ */\n+public interface SystemReader {\n+\n+\t/**\n+\t * @param variable system variable to read\n+\t * @return value of the system variable\n+\t */\n+\tString getEnvironmentVariable(String variable);\n+\n+\t/**\n+\t * @param key of the system property to read\n+\t * @return value of the system property\n+\t */\n+\tString getProperty(String key);\n+\n+}\n-- \n1.6.0.4\n"},{"id":"103171","messageId":"20090204173603.GC26880@spearce.org","threadId":"17555","inReplyTo":"49898A06.5040603@gmail.com","subject":"Re: [PATCH JGIT] Compute the author/commiter name and email from the git configuration","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-04T17:36:03Z","receivedAt":"2009-02-04T17:36:03Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Yann Simon <yann.simon.fr@gmail.com> wrote:\n> diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java\n> index 34ce04a..113eb1c 100644\n> --- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java\n> +++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java\n> @@ -116,4 +120,70 @@ public void test006_readCaseInsensitive() throws IOException {\n>  \t\tassertEquals(true, repositoryConfig.getBoolean(\"foo\", null, \"bar\", false));\n>  \t\tassertEquals(\"\", repositoryConfig.getString(\"foo\", null, \"bar\"));\n>  \t}\n> +\n> +\tprivate class FakeSystemReader implements SystemReader {\n> +\t\tMap<String, String> values = new HashMap<String, String>();\n> +\t\tpublic String getEnvironmentVariable(String variable) {\n> +\t\t\treturn values.get(variable);\n> +\t\t}\n> +\t\tpublic String getProperty(String key) {\n> +\t\t\treturn values.get(key);\n> +\t\t}\n> +\t}\n\nI like this approach.  Perhaps this should simply be done in\nRepositoryTestCase so all of our unit tests have a stable default\nidentity, no matter what.  They could change it on a test-by-test\nbasis if needed, especially if the reader is created and populated\nwith default values during the setUp() method.\n\n> diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java\n> index 8f093d6..372fba5 100644\n> --- a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java\n> +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java\n> +\n> +\t/** The environment variable that contains the commiter's name */\n> +\tpublic static final String GIT_COMMITER_NAME_KEY = \"GIT_COMMITER_NAME\";\n\nThere are 2 't's in GIT_COMMITTER_NAME.  Both the variable name\nand the value are wrong.\n\n> +\t/** The environment variable that contains the commiter's email */\n> +\tpublic static final String GIT_COMMITER_EMAIL_KEY = \"GIT_COMMITER_EMAIL\";\n\nAgain, 2 't's.\n\n> diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java\n> index 7df90cd..0fa4b1f 100644\n> --- a/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java\n> +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java\n> @@ -308,6 +323,83 @@ public String getString(final String section, String subsection, final String na\n...\n> +\tpublic String getCommiterName() {\n\n2 't's in comitter.\n\n> +\tpublic String getCommiterEmail() {\n\nThere are 2 't's in Committer.\n\n> +\tprivate String getUserEmailInternal(String gitVariableKey, boolean author) {\n...\n> +\t\t\t// try to construct an email\n> +\t\t\tString userName = author ? getAuthorName() : getCommiterName();\n> +\t\t\tif (userName != null && userName.length() != 0) {\n> +\t\t\t\tString hostnameTmp = getHostname();\n> +\t\t\t\tif (hostnameTmp != null && hostnameTmp.length() != 0) {\n> +\t\t\t\t\temail = userName + \"@\" + hostnameTmp;\n> +\t\t\t\t}\n\nIf you do what I suggest below, getHostname() will never return\nnull, so this logic will simplify out and we'll always be able to\nset email if we have a userName.\n\nAlso, I think this should be defaulting to the Java \"user.name\"\nproperty and not to the GIT_AUTHOR_NAME environment variable.  So if\nthe user.email isn't set, and the *_EMAIL env var isn't set, use the\n\"user.name\" property and the hostname to form the email address.\n\nI don't think this should ever produce null.  If we don't have a\nusername from user.name, use some generic string like \"unknown-user\".\nThen we at least still have some identity data.  Its very unlikely\nthe JVM won't have a \"user.name\" property for us, so its very\nlikely we won't get good tests in application level code for null\nreturn values.\n\n> @@ -957,4 +1049,28 @@ private static boolean eq(final String a, final String b) {\n> +\n> +\t/**\n> +\t * @return the canonical hostname\n> +\t */\n> +\tpublic static String getHostname() {\n\nI don't see a reason for this to be public.  Please make it private.\n\n> +\t\tif (hostname == null) {\n> +\t\t\ttry {\n> +\t\t\t\tInetAddress localMachine = InetAddress.getLocalHost();\n> +\t\t\t\thostname = localMachine.getCanonicalHostName();\n> +\t\t\t} catch (UnknownHostException e) {\n> +\t\t\t\t// we do nothing\n\nSet hostname = \"localhost\" so we don't incur an UHE on every attempt\nto get the hostname.  If it failed once, its very likely to fail\nagain, and again, and again.\n\n> +\t/**\n> +\t * Overrides the default system reader by a custom one.\n> +\t * @param systemReader new system reader\n> +\t */\n> +\tpublic void setSystemReader(SystemReader systemReader) {\n\nMethod should be static.\n\n> +\t\tRepositoryConfig.systemReader = systemReader;\n\nThere is no need for RepositoryConfig here.  Rename the parameter\nso it doesn't hide the field.\n\n> diff --git a/org.spearce.jgit/src/org/spearce/jgit/util/SystemReader.java b/org.spearce.jgit/src/org/spearce/jgit/util/SystemReader.java\n> new file mode 100644\n> index 0000000..89b4021\n> --- /dev/null\n> +++ b/org.spearce.jgit/src/org/spearce/jgit/util/SystemReader.java\n> @@ -0,0 +1,24 @@\n> +package org.spearce.jgit.util;\n\nMissing copyright header.\n\n> +\t/**\n> +\t * @param variable system variable to read\n> +\t * @return value of the system variable\n> +\t */\n> +\tString getEnvironmentVariable(String variable);\n\nMaybe just emulate the System class and call this getenv() ?\n\n-- \nShawn.\n"}]}