From b071721ad3fcd76216e1ca8ae11a9ebdbfd7410c Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Thu, 5 Jul 2018 11:33:07 +0300 Subject: [PATCH] CHE-9418: Fix Git status message if the repository is checkouted to tag or commit. (#10172) Fix Git status message if the repository is checkouted to tag or commit. Changed getCurrentBranch method in the Git API to getCurrentReference that returns Reference object that contains reference and type (branch, tag or commit). --- .../project/ProjectExplorerViewImpl.java | 1 + .../pullrequest/client/vcs/GitVcsService.java | 2 +- .../selenium/pageobject/ProjectExplorer.java | 15 +++++ .../selenium/git/CheckoutReferenceTest.java | 28 ++++++--- .../eclipse/che/api/git/shared/Status.java | 7 +++ .../eclipse/che/api/git/GitConnection.java | 11 +++- .../che/api/git/GitValueProviderFactory.java | 11 +--- .../org/eclipse/che/api/git/Reference.java | 57 ++++++++++++++++++ .../eclipse/che/api/git/ReferenceType.java | 17 ++++++ .../org/eclipse/che/git/impl/StatusTest.java | 58 +++++++++++++++++- .../che/git/impl/jgit/JGitConnection.java | 60 ++++++++++++++----- .../che/git/impl/jgit/JGitStatusImpl.java | 32 ++++++++-- .../che/git/impl/jgit/JGitConnectionTest.java | 2 +- 13 files changed, 261 insertions(+), 40 deletions(-) create mode 100644 wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/Reference.java create mode 100644 wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/ReferenceType.java diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java index eb234ecb28..32fbd10c92 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java @@ -263,6 +263,7 @@ public class ProjectExplorerViewImpl extends BaseView getBranchName(ProjectConfig project) { return service .getStatus(Path.valueOf(project.getPath()), emptyList()) - .then((Function) status -> status.getBranchName()); + .then((Function) status -> status.getRefName()); } @Override diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java index 0a96883795..17d94f7be4 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java @@ -69,6 +69,7 @@ import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -89,6 +90,9 @@ public class ProjectExplorer { private final NotificationsPopupPanel notificationsPopupPanel; private final int DEFAULT_TIMEOUT; + @FindBy(id = "git.reference.name") + WebElement projectReference; + @Inject public ProjectExplorer( SeleniumWebDriver seleniumWebDriver, @@ -291,6 +295,17 @@ public class ProjectExplorer { By.xpath(format(PROJECT_EXPLORER_ITEM_TEMPLATE, path)), timeout); } + /** + * Wait the specified reference to be present near the project name in the project explorer. + * + * @param reference git reference e.g. branch, tag or commit + */ + public void waitReferenceName(String reference) { + loader.waitOnClosed(); + + seleniumWebDriverHelper.waitTextEqualsTo(projectReference, "(" + reference + ")"); + } + /** * Waits until library will be present in External Libraries folder * diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/git/CheckoutReferenceTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/git/CheckoutReferenceTest.java index f89af5d4c0..19b58035fe 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/git/CheckoutReferenceTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/git/CheckoutReferenceTest.java @@ -10,10 +10,7 @@ */ package org.eclipse.che.selenium.git; -import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Git.BRANCHES; -import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Git.CHECKOUT_REFERENCE; -import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Git.GIT; -import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Git.SHOW_HISTORY; +import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Git.*; import static org.eclipse.che.selenium.pageobject.Wizard.TypeProject.BLANK; import static org.testng.Assert.assertTrue; @@ -26,10 +23,7 @@ import org.eclipse.che.selenium.core.client.TestGitHubRepository; import org.eclipse.che.selenium.core.client.TestUserPreferencesServiceClient; import org.eclipse.che.selenium.core.user.DefaultTestUser; import org.eclipse.che.selenium.core.workspace.TestWorkspace; -import org.eclipse.che.selenium.pageobject.CodenvyEditor; -import org.eclipse.che.selenium.pageobject.Ide; -import org.eclipse.che.selenium.pageobject.Menu; -import org.eclipse.che.selenium.pageobject.ProjectExplorer; +import org.eclipse.che.selenium.pageobject.*; import org.eclipse.che.selenium.pageobject.git.Git; import org.eclipse.che.selenium.pageobject.git.GitHistory; import org.testng.annotations.BeforeClass; @@ -114,6 +108,12 @@ public class CheckoutReferenceTest { editor.waitActive(); editor.waitTextIntoEditor(UPDATE_FILE); + // check current reference + menu.runCommand(GIT, STATUS); + git.waitGitStatusBarWithMess("On branch " + DEFAULT_BRANCH); + + projectExplorer.waitReferenceName(DEFAULT_BRANCH); + // check the name of the default branch openBranchPanelAndWaitRefHeadName(DEFAULT_BRANCH); @@ -134,6 +134,12 @@ public class CheckoutReferenceTest { editor.waitTextIntoEditor(CHANGE_FILE); editor.waitTextNotPresentIntoEditor(UPDATE_FILE); + // check current reference + menu.runCommand(GIT, STATUS); + git.waitGitStatusBarWithMess("HEAD detached at " + hashCommit); + + projectExplorer.waitReferenceName(sha1); + // switch to default branch projectExplorer.waitAndSelectItem(PROJECT_NAME); menu.runCommand(GIT, BRANCHES); @@ -175,6 +181,12 @@ public class CheckoutReferenceTest { editor.selectTabByName(JS_FILE); editor.waitTextIntoEditor(CHANGE_FILE_1); + // check current reference + menu.runCommand(GIT, STATUS); + git.waitGitStatusBarWithMess("HEAD detached at " + TAG_NAME_1); + + projectExplorer.waitReferenceName(TAG_NAME_1); + // check the git history openGitHistoryForm(); diff --git a/wsagent/che-core-api-git-shared/src/main/java/org/eclipse/che/api/git/shared/Status.java b/wsagent/che-core-api-git-shared/src/main/java/org/eclipse/che/api/git/shared/Status.java index 9ead29e467..c1b0483e29 100644 --- a/wsagent/che-core-api-git-shared/src/main/java/org/eclipse/che/api/git/shared/Status.java +++ b/wsagent/che-core-api-git-shared/src/main/java/org/eclipse/che/api/git/shared/Status.java @@ -20,10 +20,17 @@ public interface Status { void setClean(boolean isClean); + /** @deprecated Use {@link #getRefName()} instead. */ String getBranchName(); + /** @deprecated Use #setRefName(String) instead. */ void setBranchName(String branchName); + /** Returns reference name e.g. branch, tag or commit id */ + String getRefName(); + + void setRefName(String refName); + /** New files that are staged in index. */ List getAdded(); diff --git a/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitConnection.java b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitConnection.java index 791531f2a5..7f95853990 100644 --- a/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitConnection.java +++ b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitConnection.java @@ -396,11 +396,20 @@ public interface GitConnection extends Closeable { /** * Get the current branch on the current directory * - * @return the name of the branch + * @deprecated Use {@link #getCurrentReference()} instead. + * @return the name of the branch or HEAD if the repo points to tag or commit * @throws GitException if any exception occurs */ String getCurrentBranch() throws GitException; + /** + * Get the current reference on the current directory + * + * @return reference object with branch, tag or commit id + * @throws GitException if any exception occurs + */ + Reference getCurrentReference() throws GitException; + /** * Revert the specified commit * diff --git a/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitValueProviderFactory.java b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitValueProviderFactory.java index 4a964a35e7..f912e4553e 100644 --- a/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitValueProviderFactory.java +++ b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitValueProviderFactory.java @@ -23,7 +23,6 @@ import java.util.stream.Collectors; import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.fs.server.PathTransformer; -import org.eclipse.che.api.git.params.LogParams; import org.eclipse.che.api.git.shared.Remote; import org.eclipse.che.api.project.server.type.ReadonlyValueProvider; import org.eclipse.che.api.project.server.type.ValueProvider; @@ -59,15 +58,7 @@ public class GitValueProviderFactory implements ValueProviderFactory { case VCS_PROVIDER_NAME: return singletonList("git"); case GIT_CURRENT_HEAD_NAME: - String currentBranch = gitConnection.getCurrentBranch(); - return singletonList( - "HEAD".equals(currentBranch) - ? gitConnection - .log(LogParams.create().withMaxCount(1)) - .getCommits() - .get(0) - .getId() - : currentBranch); + return singletonList(gitConnection.getCurrentReference().getName()); case GIT_REPOSITORY_REMOTES: return gitConnection .remoteList(null, false) diff --git a/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/Reference.java b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/Reference.java new file mode 100644 index 0000000000..a5dcaa4c91 --- /dev/null +++ b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/Reference.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.api.git; + +/** @author Igor Vinokur */ +public class Reference { + private final String refName; + private final ReferenceType type; + + /** + * Represents Git reference e.g. branch, tag or commit id. + * + * @param refName reference name + * @param type reference type + */ + protected Reference(String refName, ReferenceType type) { + this.refName = refName; + this.type = type; + } + + /** Returns reference name. */ + public String getName() { + return refName; + } + + /** Returns reference type */ + public ReferenceType getType() { + return type; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Reference)) return false; + + Reference reference = (Reference) o; + + if (refName != null ? !refName.equals(reference.refName) : reference.refName != null) + return false; + return getType() == reference.getType(); + } + + @Override + public int hashCode() { + int result = refName != null ? refName.hashCode() : 0; + result = 31 * result + (getType() != null ? getType().hashCode() : 0); + return result; + } +} diff --git a/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/ReferenceType.java b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/ReferenceType.java new file mode 100644 index 0000000000..c85fc2c25d --- /dev/null +++ b/wsagent/che-core-api-git/src/main/java/org/eclipse/che/api/git/ReferenceType.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.api.git; + +public enum ReferenceType { + BRANCH, + TAG, + COMMIT +} diff --git a/wsagent/che-core-api-git/src/test/java/org/eclipse/che/git/impl/StatusTest.java b/wsagent/che-core-api-git/src/test/java/org/eclipse/che/git/impl/StatusTest.java index aa77ecb646..01b33935af 100644 --- a/wsagent/che-core-api-git/src/test/java/org/eclipse/che/git/impl/StatusTest.java +++ b/wsagent/che-core-api-git/src/test/java/org/eclipse/che/git/impl/StatusTest.java @@ -14,6 +14,7 @@ import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.eclipse.che.git.impl.GitTestUtil.addFile; import static org.eclipse.che.git.impl.GitTestUtil.cleanupTestRepo; +import static org.eclipse.che.git.impl.GitTestUtil.connectToGitRepositoryWithContent; import static org.eclipse.che.git.impl.GitTestUtil.connectToInitializedGitRepository; import static org.eclipse.che.git.impl.GitTestUtil.deleteFile; import static org.testng.Assert.assertEquals; @@ -27,8 +28,10 @@ import org.eclipse.che.api.git.GitConnectionFactory; import org.eclipse.che.api.git.params.AddParams; import org.eclipse.che.api.git.params.CheckoutParams; import org.eclipse.che.api.git.params.CommitParams; +import org.eclipse.che.api.git.params.LogParams; import org.eclipse.che.api.git.params.RmParams; -import org.eclipse.che.api.git.shared.*; +import org.eclipse.che.api.git.params.TagCreateParams; +import org.eclipse.che.api.git.shared.Status; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -325,4 +328,57 @@ public class StatusTest { assertTrue(status.getUntracked().isEmpty()); assertTrue(status.getUntrackedFolders().isEmpty()); } + + @Test( + dataProvider = "GitConnectionFactory", + dataProviderClass = org.eclipse.che.git.impl.GitConnectionFactoryProvider.class + ) + public void shouldReturnCurrentBranch(GitConnectionFactory connectionFactory) throws Exception { + // given + GitConnection connection = connectToGitRepositoryWithContent(connectionFactory, repository); + final String branchName = "newBranch"; + connection.branchCreate(branchName, null); + connection.checkout(CheckoutParams.create(branchName)); + + // when + final Status status = connection.status(emptyList()); + + // then + assertEquals(status.getRefName(), branchName); + } + + @Test( + dataProvider = "GitConnectionFactory", + dataProviderClass = org.eclipse.che.git.impl.GitConnectionFactoryProvider.class + ) + public void shouldReturnTagName(GitConnectionFactory connectionFactory) throws Exception { + // given + GitConnection connection = connectToGitRepositoryWithContent(connectionFactory, repository); + final String tagName = "newTag"; + connection.tagCreate(TagCreateParams.create(tagName)); + connection.checkout(CheckoutParams.create(tagName)); + + // when + final Status status = connection.status(emptyList()); + + // then + assertEquals(status.getRefName(), tagName); + } + + @Test( + dataProvider = "GitConnectionFactory", + dataProviderClass = org.eclipse.che.git.impl.GitConnectionFactoryProvider.class + ) + public void shouldReturnCommitId(GitConnectionFactory connectionFactory) throws Exception { + // given + GitConnection connection = connectToGitRepositoryWithContent(connectionFactory, repository); + final String commitId = connection.log(LogParams.create()).getCommits().get(0).getId(); + connection.checkout(CheckoutParams.create(commitId)); + + // when + final Status status = connection.status(emptyList()); + + // then + assertEquals(status.getRefName(), commitId); + } } diff --git a/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitConnection.java b/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitConnection.java index 7e7598d7c0..85eb32c313 100644 --- a/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitConnection.java +++ b/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitConnection.java @@ -21,6 +21,9 @@ import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.stream.Collectors.toList; +import static org.eclipse.che.api.git.ReferenceType.BRANCH; +import static org.eclipse.che.api.git.ReferenceType.COMMIT; +import static org.eclipse.che.api.git.ReferenceType.TAG; import static org.eclipse.che.api.git.params.CommitParams.create; import static org.eclipse.che.api.git.shared.BranchListMode.LIST_ALL; import static org.eclipse.che.api.git.shared.BranchListMode.LIST_LOCAL; @@ -92,8 +95,16 @@ import org.eclipse.che.api.git.GitConnection; import org.eclipse.che.api.git.GitUrlUtils; import org.eclipse.che.api.git.GitUserResolver; import org.eclipse.che.api.git.LogPage; +import org.eclipse.che.api.git.Reference; import org.eclipse.che.api.git.UserCredential; -import org.eclipse.che.api.git.exception.*; +import org.eclipse.che.api.git.exception.GitCheckoutInProgressException; +import org.eclipse.che.api.git.exception.GitCommitInProgressException; +import org.eclipse.che.api.git.exception.GitConflictException; +import org.eclipse.che.api.git.exception.GitException; +import org.eclipse.che.api.git.exception.GitInvalidRefNameException; +import org.eclipse.che.api.git.exception.GitInvalidRepositoryException; +import org.eclipse.che.api.git.exception.GitRefAlreadyExistsException; +import org.eclipse.che.api.git.exception.GitRefNotFoundException; import org.eclipse.che.api.git.params.AddParams; import org.eclipse.che.api.git.params.CheckoutParams; import org.eclipse.che.api.git.params.CloneParams; @@ -783,7 +794,7 @@ class JGitConnection implements GitConnection { GitUser gitUser = newDto(GitUser.class).withName(committerName).withEmail(committerEmail); return newDto(Revision.class) - .withBranch(getCurrentBranch()) + .withBranch(getCurrentReference().getName()) .withId(result.getId().getName()) .withMessage(result.getFullMessage()) .withCommitTime(MILLISECONDS.convert(result.getCommitTime(), SECONDS)) @@ -1453,7 +1464,7 @@ class JGitConnection implements GitConnection { @Override public PushResponse push(PushParams params) throws GitException, UnauthorizedException { List> updates = new ArrayList<>(); - String currentBranch = getCurrentBranch(); + String currentRefName = getCurrentReference().getName(); String remoteName = params.getRemote(); String remoteUri = getRepository() @@ -1493,8 +1504,8 @@ class JGitConnection implements GitConnection { remoteRefName.startsWith("refs/for/") ? remoteRefName.substring("refs/for/".length()) : remoteRefName; - if (!currentBranch.equals(Repository.shortenRefName(remoteRefName)) - && !currentBranch.equals(shortenRefFor) + if (!currentRefName.equals(Repository.shortenRefName(remoteRefName)) + && !currentRefName.equals(shortenRefFor) && !remoteRefName.startsWith(R_TAGS)) { continue; } @@ -1510,7 +1521,7 @@ class JGitConnection implements GitConnection { String errorMessage = format( ERROR_PUSH_CONFLICTS_PRESENT, - currentBranch + BRANCH_REFSPEC_SEPERATOR + remoteBranch, + currentRefName + BRANCH_REFSPEC_SEPERATOR + remoteBranch, remoteUri); if (remoteRefUpdate.getMessage() != null) { errorMessage += "\nError errorMessage: " + remoteRefUpdate.getMessage() + "."; @@ -1878,12 +1889,11 @@ class JGitConnection implements GitConnection { if (CHECKOUT_REPOSITORIES.contains(repositoryPath)) { throw new GitCheckoutInProgressException(CHECKOUT_IN_PROGRESS_ERROR); } - String branchName = getCurrentBranch(); StatusCommand statusCommand = getGit().status(); if (filter != null) { filter.forEach(statusCommand::addPath); } - return new JGitStatusImpl(branchName, statusCommand); + return new JGitStatusImpl(getCurrentReference(), statusCommand); } @Override @@ -2241,12 +2251,7 @@ class JGitConnection implements GitConnection { return getRepository().getDirectory().getPath(); } - /** - * Get the current branch on the current directory - * - * @return the name of the branch - * @throws GitException if any exception occurs - */ + @Override public String getCurrentBranch() throws GitException { try { return Repository.shortenRefName(repository.exactRef(HEAD).getLeaf().getName()); @@ -2255,6 +2260,33 @@ class JGitConnection implements GitConnection { } } + /** + * Get the current reference on the current directory + * + * @return reference object with branch, tag or commit id + * @throws GitException if any exception occurs + */ + public Reference getCurrentReference() throws GitException { + try { + String reference = Repository.shortenRefName(repository.exactRef(HEAD).getLeaf().getName()); + if (HEAD.equals(reference)) { + reference = repository.resolve(HEAD).getName(); + try (RevWalk revWalk = new RevWalk(repository)) { + for (Tag tag : tagList(null)) { + String tagName = tag.getName(); + if (revWalk.parseCommit(repository.resolve(tagName)).getName().equals(reference)) { + return new Reference(tagName, TAG) {}; + } + } + } + return new Reference(reference, COMMIT) {}; + } + return new Reference(reference, BRANCH) {}; + } catch (IOException exception) { + throw new GitException(exception.getMessage(), exception); + } + } + /** * Method for cleaning name of remote branch to be checked out. I.e. it takes something like * "origin/testBranch" and returns "testBranch". This is needed for view-compatibility with diff --git a/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitStatusImpl.java b/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitStatusImpl.java index 367a99890d..f78b3bf9a4 100644 --- a/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitStatusImpl.java +++ b/wsagent/che-core-git-impl-jgit/src/main/java/org/eclipse/che/git/impl/jgit/JGitStatusImpl.java @@ -12,12 +12,16 @@ package org.eclipse.che.git.impl.jgit; import static java.lang.System.lineSeparator; +import static org.eclipse.che.api.git.ReferenceType.BRANCH; +import static org.eclipse.che.api.git.ReferenceType.COMMIT; +import static org.eclipse.jgit.lib.Constants.HEAD; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import org.eclipse.che.api.git.InfoPage; +import org.eclipse.che.api.git.Reference; import org.eclipse.che.api.git.exception.GitException; import org.eclipse.che.api.git.shared.Status; import org.eclipse.jgit.api.StatusCommand; @@ -30,7 +34,9 @@ import org.eclipse.jgit.api.errors.GitAPIException; */ public class JGitStatusImpl implements Status, InfoPage { + private final Reference reference; private String branchName; + private String refName; private boolean clean; private List added; private List changed; @@ -43,12 +49,14 @@ public class JGitStatusImpl implements Status, InfoPage { private String repositoryState; /** - * @param branchName current repository branch name + * @param reference current reference * @param statusCommand Jgit status command * @throws GitException when any error occurs */ - public JGitStatusImpl(String branchName, StatusCommand statusCommand) throws GitException { - this.branchName = branchName; + JGitStatusImpl(Reference reference, StatusCommand statusCommand) throws GitException { + this.reference = reference; + this.refName = reference.getName(); + this.branchName = reference.getType() == BRANCH ? refName : HEAD; org.eclipse.jgit.api.Status gitStatus; try { @@ -72,7 +80,13 @@ public class JGitStatusImpl implements Status, InfoPage { public void writeTo(OutputStream out) throws IOException { StringBuilder status = new StringBuilder(); - status.append("On branch ").append(branchName).append(lineSeparator()); + status + .append(reference.getType() == BRANCH ? "On branch " : "HEAD detached at ") + .append( + reference.getType() == COMMIT + ? reference.getName().substring(0, 8) + : reference.getName()) + .append(lineSeparator()); if (isClean()) { status.append(lineSeparator()).append("nothing to commit, working directory clean"); } else { @@ -118,6 +132,16 @@ public class JGitStatusImpl implements Status, InfoPage { this.clean = clean; } + @Override + public String getRefName() { + return refName; + } + + @Override + public void setRefName(String refName) { + this.refName = refName; + } + @Override public String getBranchName() { return branchName; diff --git a/wsagent/che-core-git-impl-jgit/src/test/java/org/eclipse/che/git/impl/jgit/JGitConnectionTest.java b/wsagent/che-core-git-impl-jgit/src/test/java/org/eclipse/che/git/impl/jgit/JGitConnectionTest.java index 6327c197d6..6cf107a2f8 100644 --- a/wsagent/che-core-git-impl-jgit/src/test/java/org/eclipse/che/git/impl/jgit/JGitConnectionTest.java +++ b/wsagent/che-core-git-impl-jgit/src/test/java/org/eclipse/che/git/impl/jgit/JGitConnectionTest.java @@ -223,7 +223,7 @@ public class JGitConnectionTest { when(repository.exactRef(Constants.HEAD)).thenReturn(ref); when(ref.getLeaf()).thenReturn(ref); when(ref.getName()).thenReturn(branchTest); - String branchName = jGitConnection.getCurrentBranch(); + String branchName = jGitConnection.getCurrentReference().getName(); assertEquals(branchName, branchTest); }