Matthias Sohn
12 years ago
committed by
Gerrit Code Review @ Eclipse.org
7 changed files with 448 additions and 2 deletions
@ -0,0 +1,230 @@ |
|||||||
|
/* |
||||||
|
* 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(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,167 @@ |
|||||||
|
/* |
||||||
|
* 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(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue