You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SubmoduleStatusCommand.java 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright (C) 2011, GitHub Inc. and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.api;
  11. import java.io.IOException;
  12. import java.util.ArrayList;
  13. import java.util.Collection;
  14. import java.util.HashMap;
  15. import java.util.Map;
  16. import org.eclipse.jgit.api.errors.GitAPIException;
  17. import org.eclipse.jgit.api.errors.JGitInternalException;
  18. import org.eclipse.jgit.errors.ConfigInvalidException;
  19. import org.eclipse.jgit.lib.Constants;
  20. import org.eclipse.jgit.lib.ObjectId;
  21. import org.eclipse.jgit.lib.Repository;
  22. import org.eclipse.jgit.submodule.SubmoduleStatus;
  23. import org.eclipse.jgit.submodule.SubmoduleStatusType;
  24. import org.eclipse.jgit.submodule.SubmoduleWalk;
  25. import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
  26. /**
  27. * A class used to execute a submodule status command.
  28. *
  29. * @see <a href=
  30. * "http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html"
  31. * >Git documentation about submodules</a>
  32. */
  33. public class SubmoduleStatusCommand extends
  34. GitCommand<Map<String, SubmoduleStatus>> {
  35. private final Collection<String> paths;
  36. /**
  37. * Constructor for SubmoduleStatusCommand.
  38. *
  39. * @param repo
  40. * a {@link org.eclipse.jgit.lib.Repository} object.
  41. */
  42. public SubmoduleStatusCommand(Repository repo) {
  43. super(repo);
  44. paths = new ArrayList<>();
  45. }
  46. /**
  47. * Add repository-relative submodule path to limit status reporting to
  48. *
  49. * @param path
  50. * (with <code>/</code> as separator)
  51. * @return this command
  52. */
  53. public SubmoduleStatusCommand addPath(String path) {
  54. paths.add(path);
  55. return this;
  56. }
  57. /** {@inheritDoc} */
  58. @Override
  59. public Map<String, SubmoduleStatus> call() throws GitAPIException {
  60. checkCallable();
  61. try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) {
  62. if (!paths.isEmpty())
  63. generator.setFilter(PathFilterGroup.createFromStrings(paths));
  64. Map<String, SubmoduleStatus> statuses = new HashMap<>();
  65. while (generator.next()) {
  66. SubmoduleStatus status = getStatus(generator);
  67. statuses.put(status.getPath(), status);
  68. }
  69. return statuses;
  70. } catch (IOException | ConfigInvalidException e) {
  71. throw new JGitInternalException(e.getMessage(), e);
  72. }
  73. }
  74. private SubmoduleStatus getStatus(SubmoduleWalk generator)
  75. throws IOException, ConfigInvalidException {
  76. ObjectId id = generator.getObjectId();
  77. String path = generator.getPath();
  78. // Report missing if no path in .gitmodules file
  79. if (generator.getModulesPath() == null)
  80. return new SubmoduleStatus(SubmoduleStatusType.MISSING, path, id);
  81. // Report uninitialized if no URL in config file
  82. if (generator.getConfigUrl() == null)
  83. return new SubmoduleStatus(SubmoduleStatusType.UNINITIALIZED, path,
  84. id);
  85. // Report uninitialized if no submodule repository
  86. ObjectId headId = null;
  87. try (Repository subRepo = generator.getRepository()) {
  88. if (subRepo == null) {
  89. return new SubmoduleStatus(SubmoduleStatusType.UNINITIALIZED,
  90. path, id);
  91. }
  92. headId = subRepo.resolve(Constants.HEAD);
  93. }
  94. // Report uninitialized if no HEAD commit in submodule repository
  95. if (headId == null)
  96. return new SubmoduleStatus(SubmoduleStatusType.UNINITIALIZED, path,
  97. id, headId);
  98. // Report checked out if HEAD commit is different than index commit
  99. if (!headId.equals(id))
  100. return new SubmoduleStatus(SubmoduleStatusType.REV_CHECKED_OUT,
  101. path, id, headId);
  102. // Report initialized if HEAD commit is the same as the index commit
  103. return new SubmoduleStatus(SubmoduleStatusType.INITIALIZED, path, id,
  104. headId);
  105. }
  106. }