org.eclipse.jgit.lib;version="[2.1.0,2.2.0)",
org.eclipse.jgit.pgm;version="[2.1.0,2.2.0)",
org.eclipse.jgit.pgm.opt;version="[2.1.0,2.2.0)",
+ org.eclipse.jgit.revwalk;version="[2.1.0,2.2.0)",
org.eclipse.jgit.storage.file;version="[2.1.0,2.2.0)",
org.eclipse.jgit.util;version="[2.1.0,2.2.0)",
org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
throws IOException {
return JGitTestUtil.writeTrashFile(db, name, data);
}
+
+ protected void deleteTrashFile(final String name) throws IOException {
+ JGitTestUtil.deleteTrashFile(db, name);
+ }
}
--- /dev/null
+/*
+ * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.pgm;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.CLIRepositoryTestCase;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.Test;
+
+public class StatusTest extends CLIRepositoryTestCase {
+ @Test
+ public void testStatus() throws Exception {
+ Git git = new Git(db);
+ // Write all files
+ writeTrashFile("tracked", "tracked");
+ writeTrashFile("stagedNew", "stagedNew");
+ writeTrashFile("stagedModified", "stagedModified");
+ writeTrashFile("stagedDeleted", "stagedDeleted");
+ writeTrashFile("trackedModified", "trackedModified");
+ writeTrashFile("trackedDeleted", "trackedDeleted");
+ writeTrashFile("untracked", "untracked");
+ // Test untracked
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch master", //
+ "# Untracked files:", //
+ "# ",//
+ "# \tstagedDeleted", //
+ "# \tstagedModified", //
+ "# \tstagedNew", //
+ "# \ttracked", //
+ "# \ttrackedDeleted", //
+ "# \ttrackedModified", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Add to index
+ git.add().addFilepattern("tracked").call();
+ git.add().addFilepattern("stagedModified").call();
+ git.add().addFilepattern("stagedDeleted").call();
+ git.add().addFilepattern("trackedModified").call();
+ git.add().addFilepattern("trackedDeleted").call();
+ // Test staged count
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch master", //
+ "# Changes to be committed:", //
+ "# ", //
+ "# \tnew file: stagedDeleted", //
+ "# \tnew file: stagedModified", //
+ "# \tnew file: tracked", //
+ "# \tnew file: trackedDeleted", //
+ "# \tnew file: trackedModified", //
+ "# ", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tstagedNew", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Commit
+ git.commit().setMessage("initial commit")
+ .call();
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch master", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tstagedNew", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Make some changes and stage them
+ writeTrashFile("stagedModified", "stagedModified modified");
+ deleteTrashFile("stagedDeleted");
+ writeTrashFile("trackedModified", "trackedModified modified");
+ deleteTrashFile("trackedDeleted");
+ git.add().addFilepattern("stagedModified").call();
+ git.rm().addFilepattern("stagedDeleted").call();
+ git.add().addFilepattern("stagedNew").call();
+ // Test staged/not-staged status
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch master", //
+ "# Changes to be committed:", //
+ "# ", //
+ "# \tdeleted: stagedDeleted", //
+ "# \tmodified: stagedModified", //
+ "# \tnew file: stagedNew", //
+ "# ", //
+ "# Changes not staged for commit:", //
+ "# ", //
+ "# \tdeleted: trackedDeleted", //
+ "# \tmodified: trackedModified", //
+ "# ", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Create unmerged file
+ writeTrashFile("unmerged", "unmerged");
+ git.add().addFilepattern("unmerged").call();
+ // Commit pending changes
+ git.add().addFilepattern("trackedModified").call();
+ git.rm().addFilepattern("trackedDeleted").call();
+ git.commit().setMessage("commit before branching").call();
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch master", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Checkout new branch
+ git.checkout().setCreateBranch(true).setName("test").call();
+ // Test branch status
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch test", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Commit change and checkout master again
+ writeTrashFile("unmerged", "changed in test branch");
+ git.add().addFilepattern("unmerged").call();
+ RevCommit testBranch = git.commit()
+ .setMessage("changed unmerged in test branch").call();
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch test", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ git.checkout().setName("master").call();
+ // Change the same file and commit
+ writeTrashFile("unmerged", "changed in master branch");
+ git.add().addFilepattern("unmerged").call();
+ git.commit().setMessage("changed unmerged in master branch").call();
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch master", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Merge test branch into master
+ git.merge().include(testBranch.getId()).call();
+ // Test unmerged status
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# On branch master", //
+ "# Unmerged paths:", //
+ "# ", //
+ "# \tunmerged", //
+ "# ", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ // Test detached head
+ String commitId = db.getRef(Constants.MASTER).getObjectId().name();
+ git.checkout().setName(commitId).call();
+ assertArrayOfLinesEquals(new String[] { // git status output
+ "# Not currently on any branch.", //
+ "# Unmerged paths:", //
+ "# ", //
+ "# \tunmerged", //
+ "# ", //
+ "# Untracked files:", //
+ "# ", //
+ "# \tuntracked", //
+ "" //
+ }, execute("git status")); //
+ }
+
+ private void assertArrayOfLinesEquals(String[] expected, String[] actual) {
+ assertEquals(toText(expected), toText(actual));
+ }
+
+ private String toText(String[] lines) {
+ StringBuilder b = new StringBuilder();
+ for (String s : lines) {
+ b.append(s);
+ b.append('\n');
+ }
+ return b.toString();
+ }
+}
org.eclipse.jgit.pgm.Rm
org.eclipse.jgit.pgm.Show
org.eclipse.jgit.pgm.ShowRef
+org.eclipse.jgit.pgm.Status
org.eclipse.jgit.pgm.Tag
org.eclipse.jgit.pgm.UploadPack
org.eclipse.jgit.pgm.Version
cannotWrite=Cannot write {0}
cantFindGitDirectory=error: can't find git directory
cantWrite=Can't write {0}
+changesNotStagedForCommit=Changes not staged for commit:
+changesToBeCommitted=Changes to be committed:
commitLabel=commit
configFileNotFound=configuration file {0} not found
conflictingUsageOf_git_dir_andArguments=conflicting usage of --git-dir and arguments
initializedEmptyGitRepositoryIn=Initialized empty Git repository in {0}
invalidHttpProxyOnlyHttpSupported=Invalid http_proxy: {0}: Only http supported.
jgitVersion=jgit version {0}
+lineFormat=# {0}
listeningOn=Listening on {0}
mergeConflict=CONFLICT(content): Merge conflict in {0}
mergeFailed=Automatic merge failed; fix conflicts and then commit the result
notAnObject={0} is not an object
notFound=!! NOT FOUND !!
noteObjectTooLargeToPrint=Note object {0} too large to print
+notOnAnyBranch=Not currently on any branch.
+onBranch=On branch {0}
onBranchToBeBorn=You are on a branch yet to be born
onlyOneMetaVarExpectedIn=Only one {0} expected in {1}.
onlyOneOfIncludeOnlyAllInteractiveCanBeUsed=Only one of --include/--only/--all/--interactive can be used.
repaint=Repaint
serviceNotSupported=Service '{0}' not supported
skippingObject=skipping {0} {1}
+statusFileListFormat=\t%1$s
+statusFileListFormatWithPrefix=\t%1$-11s %2$s
+statusModified=modified:
+statusNewFile=new file:
+statusRemoved=deleted:
switchedToNewBranch=Switched to a new branch ''{0}''
switchedToBranch=Switched to branch ''{0}''
tagLabel=tag
timeInMilliSeconds={0} ms
tooManyRefsGiven=Too many refs given
unknownMergeStrategy=unknown merge strategy {0} specified
+unmergedPaths=Unmerged paths:
unsupportedOperation=Unsupported operation: {0}
+untrackedFiles=Untracked files:
usage_Blame=Show what revision and author last modified each line
usage_CommandLineClientForamazonsS3Service=Command line client for Amazon's S3 service
usage_CommitAll=commit all modified and deleted files
usage_ServerSideBackendForJgitFetch=Server side backend for 'jgit fetch'
usage_ServerSideBackendForJgitPush=Server side backend for 'jgit push'
usage_ShowDiffs=Show diffs
+usage_Status=Show the working tree status
usage_StopTrackingAFile=Stop tracking a file
usage_UpdateRemoteRepositoryFromLocalRefs=Update remote repository from local refs
usage_abbrevCommits=abbreviate commits to N + 1 digits
package org.eclipse.jgit.pgm;
+import java.text.MessageFormat;
+
import org.eclipse.jgit.nls.NLS;
import org.eclipse.jgit.nls.TranslationBundle;
return NLS.getBundleFor(CLIText.class);
}
+ /**
+ * Format the given line for using the format defined by {@link #lineFormat}
+ * ("# " by default).
+ *
+ * @param line
+ * the line to format
+ * @return the formatted line
+ */
+ public static String formatLine(String line) {
+ return MessageFormat.format(get().lineFormat, line);
+ }
+
/***/ public String IPZillaPasswordPrompt;
/***/ public String alreadyOnBranch;
/***/ public String authorInfo;
/***/ public String cannotWrite;
/***/ public String cantFindGitDirectory;
/***/ public String cantWrite;
+ /***/ public String changesNotStagedForCommit;
+ /***/ public String changesToBeCommitted;
/***/ public String commitLabel;
/***/ public String conflictingUsageOf_git_dir_andArguments;
/***/ public String couldNotCreateBranch;
/***/ public String initializedEmptyGitRepositoryIn;
/***/ public String invalidHttpProxyOnlyHttpSupported;
/***/ public String jgitVersion;
+ /***/ public String lineFormat;
/***/ public String listeningOn;
/***/ public String mergeConflict;
/***/ public String mergeFailed;
/***/ public String notAnIndexFile;
/***/ public String notAnObject;
/***/ public String notFound;
+ /***/ public String notOnAnyBranch;
/***/ public String noteObjectTooLargeToPrint;
/***/ public String onBranchToBeBorn;
+ /***/ public String onBranch;
/***/ public String onlyOneMetaVarExpectedIn;
/***/ public String onlyOneOfIncludeOnlyAllInteractiveCanBeUsed;
/***/ public String pathspecDidNotMatch;
/***/ public String repaint;
/***/ public String serviceNotSupported;
/***/ public String skippingObject;
- /***/ public String switchedToNewBranch;
- /***/ public String switchedToBranch;
+ /***/ public String statusFileListFormat;
+ /***/ public String statusFileListFormatWithPrefix;
+ /***/ public String statusModified;
+ /***/ public String statusNewFile;
+ /***/ public String statusRemoved;
+
+ /***/
+ public String switchedToNewBranch;
+
+ /***/
+ public String switchedToBranch;
/***/ public String tagLabel;
/***/ public String taggerInfo;
/***/ public String timeInMilliSeconds;
/***/ public String tooManyRefsGiven;
/***/ public String unknownMergeStrategy;
+ /***/ public String unmergedPaths;
/***/ public String unsupportedOperation;
+ /***/ public String untrackedFiles;
/***/ public String warningNoCommitGivenOnCommandLine;
}
--- /dev/null
+/*
+ * Copyright (C) 2011, François Rey <eclipse.org_@_francois_._rey_._name>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.pgm;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+
+@Command(usage = "usage_Status", common = true)
+class Status extends TextBuiltin {
+
+ protected final String lineFormat = CLIText.get().lineFormat;
+
+ protected final String statusFileListFormat = CLIText.get().statusFileListFormat;
+
+ protected final String statusFileListFormatWithPrefix = CLIText.get().statusFileListFormatWithPrefix;
+
+ @Override
+ protected void run() throws Exception {
+ // Print current branch name
+ final Ref head = db.getRef(Constants.HEAD);
+ boolean firstHeader = true;
+ if (head != null && head.isSymbolic()) {
+ String branch = Repository.shortenRefName(head.getLeaf().getName());
+ out.println(CLIText.formatLine(
+ MessageFormat.format(CLIText.get().onBranch, branch)));
+ } else
+ out.println(CLIText.formatLine(CLIText.get().notOnAnyBranch));
+ // List changes
+ org.eclipse.jgit.api.Status status = new Git(db).status().call();
+ Collection<String> added = status.getAdded();
+ Collection<String> changed = status.getChanged();
+ Collection<String> removed = status.getRemoved();
+ Collection<String> modified = status.getModified();
+ Collection<String> missing = status.getMissing();
+ Collection<String> untracked = status.getUntracked();
+ Collection<String> unmerged = status.getConflicting();
+ Collection<String> toBeCommitted = new ArrayList<String>(added);
+ toBeCommitted.addAll(changed);
+ toBeCommitted.addAll(removed);
+ int nbToBeCommitted = toBeCommitted.size();
+ if (nbToBeCommitted > 0) {
+ printSectionHeader(CLIText.get().changesToBeCommitted);
+ printList(CLIText.get().statusNewFile,
+ CLIText.get().statusModified, CLIText.get().statusRemoved,
+ toBeCommitted, added, changed, removed);
+ firstHeader = false;
+ }
+ Collection<String> notStagedForCommit = new ArrayList<String>(modified);
+ notStagedForCommit.addAll(missing);
+ int nbNotStagedForCommit = notStagedForCommit.size();
+ if (nbNotStagedForCommit > 0) {
+ if (!firstHeader)
+ printSectionHeader("");
+ printSectionHeader(CLIText.get().changesNotStagedForCommit);
+ printList(CLIText.get().statusModified,
+ CLIText.get().statusRemoved, null, notStagedForCommit,
+ modified, missing, null);
+ firstHeader = false;
+ }
+ int nbUnmerged = unmerged.size();
+ if (nbUnmerged > 0) {
+ if (!firstHeader)
+ printSectionHeader("");
+ printSectionHeader(CLIText.get().unmergedPaths);
+ printList(unmerged);
+ firstHeader = false;
+ }
+ int nbUntracked = untracked.size();
+ if (nbUntracked > 0) {
+ if (!firstHeader)
+ printSectionHeader("");
+ printSectionHeader(CLIText.get().untrackedFiles);
+ printList(untracked);
+ }
+ }
+
+ protected void printSectionHeader(String pattern, Object... arguments) {
+ out.println(CLIText.formatLine(MessageFormat.format(pattern, arguments)));
+ if (!pattern.equals(""))
+ out.println(CLIText.formatLine(""));
+ out.flush();
+ }
+
+ protected int printList(Collection<String> list) {
+ if (!list.isEmpty()) {
+ List<String> sortedList = new ArrayList<String>(list);
+ java.util.Collections.sort(sortedList);
+ for (String filename : sortedList) {
+ out.println(CLIText.formatLine(String.format(
+ statusFileListFormat, filename)));
+ }
+ out.flush();
+ return list.size();
+ } else
+ return 0;
+ }
+
+ protected int printList(String status1, String status2, String status3,
+ Collection<String> list, Collection<String> set1,
+ Collection<String> set2,
+ @SuppressWarnings("unused") Collection<String> set3) {
+ List<String> sortedList = new ArrayList<String>(list);
+ java.util.Collections.sort(sortedList);
+ for (String filename : sortedList) {
+ String prefix;
+ if (set1.contains(filename))
+ prefix = status1;
+ else if (set2.contains(filename))
+ prefix = status2;
+ else
+ // if (set3.contains(filename))
+ prefix = status3;
+ out.println(CLIText.formatLine(String.format(
+ statusFileListFormatWithPrefix, prefix, filename)));
+ out.flush();
+ }
+ return list.size();
+ }
+}