Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

TransferConfig.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * Copyright (C) 2008-2009, Google 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.transport;
  11. import static org.eclipse.jgit.util.StringUtils.equalsIgnoreCase;
  12. import static org.eclipse.jgit.util.StringUtils.toLowerCase;
  13. import java.io.File;
  14. import java.util.EnumSet;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17. import org.eclipse.jgit.annotations.Nullable;
  18. import org.eclipse.jgit.internal.storage.file.LazyObjectIdSetFile;
  19. import org.eclipse.jgit.lib.Config;
  20. import org.eclipse.jgit.lib.ConfigConstants;
  21. import org.eclipse.jgit.lib.Config.SectionParser;
  22. import org.eclipse.jgit.lib.ObjectChecker;
  23. import org.eclipse.jgit.lib.ObjectIdSet;
  24. import org.eclipse.jgit.lib.Ref;
  25. import org.eclipse.jgit.lib.Repository;
  26. import org.eclipse.jgit.util.SystemReader;
  27. /**
  28. * The standard "transfer", "fetch", "protocol", "receive", and "uploadpack"
  29. * configuration parameters.
  30. */
  31. public class TransferConfig {
  32. private static final String FSCK = "fsck"; //$NON-NLS-1$
  33. /** Key for {@link Config#get(SectionParser)}. */
  34. public static final Config.SectionParser<TransferConfig> KEY =
  35. TransferConfig::new;
  36. /**
  37. * A git configuration value for how to handle a fsck failure of a particular kind.
  38. * Used in e.g. fsck.missingEmail.
  39. * @since 4.9
  40. */
  41. public enum FsckMode {
  42. /**
  43. * Treat it as an error (the default).
  44. */
  45. ERROR,
  46. /**
  47. * Issue a warning (in fact, jgit treats this like IGNORE, but git itself does warn).
  48. */
  49. WARN,
  50. /**
  51. * Ignore the error.
  52. */
  53. IGNORE;
  54. }
  55. /**
  56. * A git configuration variable for which versions of the Git protocol to
  57. * prefer. Used in protocol.version.
  58. *
  59. * @since 5.9
  60. */
  61. public enum ProtocolVersion {
  62. /**
  63. * Git wire protocol version 0 (the default).
  64. */
  65. V0("0"), //$NON-NLS-1$
  66. /**
  67. * Git wire protocol version 2.
  68. */
  69. V2("2"); //$NON-NLS-1$
  70. final String name;
  71. ProtocolVersion(String name) {
  72. this.name = name;
  73. }
  74. /**
  75. * Returns version number
  76. *
  77. * @return string version
  78. */
  79. public String version() {
  80. return name;
  81. }
  82. @Nullable
  83. static ProtocolVersion parse(@Nullable String name) {
  84. if (name == null) {
  85. return null;
  86. }
  87. for (ProtocolVersion v : ProtocolVersion.values()) {
  88. if (v.name.equals(name)) {
  89. return v;
  90. }
  91. }
  92. return null;
  93. }
  94. }
  95. private final boolean fetchFsck;
  96. private final boolean receiveFsck;
  97. private final String fsckSkipList;
  98. private final EnumSet<ObjectChecker.ErrorType> ignore;
  99. private final boolean allowInvalidPersonIdent;
  100. private final boolean safeForWindows;
  101. private final boolean safeForMacOS;
  102. private final boolean allowRefInWant;
  103. private final boolean allowTipSha1InWant;
  104. private final boolean allowReachableSha1InWant;
  105. private final boolean allowFilter;
  106. private final boolean allowSidebandAll;
  107. private final boolean advertiseSidebandAll;
  108. final @Nullable ProtocolVersion protocolVersion;
  109. final String[] hideRefs;
  110. /**
  111. * Create a configuration honoring the repository's settings.
  112. *
  113. * @param db
  114. * the repository to read settings from. The repository is not
  115. * retained by the new configuration, instead its settings are
  116. * copied during the constructor.
  117. * @since 5.1.4
  118. */
  119. public TransferConfig(Repository db) {
  120. this(db.getConfig());
  121. }
  122. /**
  123. * Create a configuration honoring settings in a
  124. * {@link org.eclipse.jgit.lib.Config}.
  125. *
  126. * @param rc
  127. * the source to read settings from. The source is not retained
  128. * by the new configuration, instead its settings are copied
  129. * during the constructor.
  130. * @since 5.1.4
  131. */
  132. @SuppressWarnings("nls")
  133. public TransferConfig(Config rc) {
  134. boolean fsck = rc.getBoolean("transfer", "fsckobjects", false);
  135. fetchFsck = rc.getBoolean("fetch", "fsckobjects", fsck);
  136. receiveFsck = rc.getBoolean("receive", "fsckobjects", fsck);
  137. fsckSkipList = rc.getString(FSCK, null, "skipList");
  138. allowInvalidPersonIdent = rc.getBoolean(FSCK, "allowInvalidPersonIdent",
  139. false);
  140. safeForWindows = rc.getBoolean(FSCK, "safeForWindows",
  141. SystemReader.getInstance().isWindows());
  142. safeForMacOS = rc.getBoolean(FSCK, "safeForMacOS",
  143. SystemReader.getInstance().isMacOS());
  144. ignore = EnumSet.noneOf(ObjectChecker.ErrorType.class);
  145. EnumSet<ObjectChecker.ErrorType> set = EnumSet
  146. .noneOf(ObjectChecker.ErrorType.class);
  147. for (String key : rc.getNames(FSCK)) {
  148. if (equalsIgnoreCase(key, "skipList")
  149. || equalsIgnoreCase(key, "allowLeadingZeroFileMode")
  150. || equalsIgnoreCase(key, "allowInvalidPersonIdent")
  151. || equalsIgnoreCase(key, "safeForWindows")
  152. || equalsIgnoreCase(key, "safeForMacOS")) {
  153. continue;
  154. }
  155. ObjectChecker.ErrorType id = FsckKeyNameHolder.parse(key);
  156. if (id != null) {
  157. switch (rc.getEnum(FSCK, null, key, FsckMode.ERROR)) {
  158. case ERROR:
  159. ignore.remove(id);
  160. break;
  161. case WARN:
  162. case IGNORE:
  163. ignore.add(id);
  164. break;
  165. }
  166. set.add(id);
  167. }
  168. }
  169. if (!set.contains(ObjectChecker.ErrorType.ZERO_PADDED_FILEMODE)
  170. && rc.getBoolean(FSCK, "allowLeadingZeroFileMode", false)) {
  171. ignore.add(ObjectChecker.ErrorType.ZERO_PADDED_FILEMODE);
  172. }
  173. allowRefInWant = rc.getBoolean("uploadpack", "allowrefinwant", false);
  174. allowTipSha1InWant = rc.getBoolean(
  175. "uploadpack", "allowtipsha1inwant", false);
  176. allowReachableSha1InWant = rc.getBoolean(
  177. "uploadpack", "allowreachablesha1inwant", false);
  178. allowFilter = rc.getBoolean(
  179. "uploadpack", "allowfilter", false);
  180. protocolVersion = ProtocolVersion.parse(rc
  181. .getString(ConfigConstants.CONFIG_PROTOCOL_SECTION, null,
  182. ConfigConstants.CONFIG_KEY_VERSION));
  183. hideRefs = rc.getStringList("uploadpack", null, "hiderefs");
  184. allowSidebandAll = rc.getBoolean(
  185. "uploadpack", "allowsidebandall", false);
  186. advertiseSidebandAll = rc.getBoolean("uploadpack",
  187. "advertisesidebandall", false);
  188. }
  189. /**
  190. * Create checker to verify fetched objects
  191. *
  192. * @return checker to verify fetched objects, or null if checking is not
  193. * enabled in the repository configuration.
  194. * @since 3.6
  195. */
  196. @Nullable
  197. public ObjectChecker newObjectChecker() {
  198. return newObjectChecker(fetchFsck);
  199. }
  200. /**
  201. * Create checker to verify objects pushed into this repository
  202. *
  203. * @return checker to verify objects pushed into this repository, or null if
  204. * checking is not enabled in the repository configuration.
  205. * @since 4.2
  206. */
  207. @Nullable
  208. public ObjectChecker newReceiveObjectChecker() {
  209. return newObjectChecker(receiveFsck);
  210. }
  211. private ObjectChecker newObjectChecker(boolean check) {
  212. if (!check) {
  213. return null;
  214. }
  215. return new ObjectChecker()
  216. .setIgnore(ignore)
  217. .setAllowInvalidPersonIdent(allowInvalidPersonIdent)
  218. .setSafeForWindows(safeForWindows)
  219. .setSafeForMacOS(safeForMacOS)
  220. .setSkipList(skipList());
  221. }
  222. private ObjectIdSet skipList() {
  223. if (fsckSkipList != null && !fsckSkipList.isEmpty()) {
  224. return new LazyObjectIdSetFile(new File(fsckSkipList));
  225. }
  226. return null;
  227. }
  228. /**
  229. * Whether to allow clients to request non-advertised tip SHA-1s
  230. *
  231. * @return allow clients to request non-advertised tip SHA-1s?
  232. * @since 3.1
  233. */
  234. public boolean isAllowTipSha1InWant() {
  235. return allowTipSha1InWant;
  236. }
  237. /**
  238. * Whether to allow clients to request non-tip SHA-1s
  239. *
  240. * @return allow clients to request non-tip SHA-1s?
  241. * @since 4.1
  242. */
  243. public boolean isAllowReachableSha1InWant() {
  244. return allowReachableSha1InWant;
  245. }
  246. /**
  247. * @return true if clients are allowed to specify a "filter" line
  248. * @since 5.0
  249. */
  250. public boolean isAllowFilter() {
  251. return allowFilter;
  252. }
  253. /**
  254. * @return true if clients are allowed to specify a "want-ref" line
  255. * @since 5.1
  256. */
  257. public boolean isAllowRefInWant() {
  258. return allowRefInWant;
  259. }
  260. /**
  261. * @return true if the server accepts sideband-all requests (see
  262. * {{@link #isAdvertiseSidebandAll()} for the advertisement)
  263. * @since 5.5
  264. */
  265. public boolean isAllowSidebandAll() {
  266. return allowSidebandAll;
  267. }
  268. /**
  269. * @return true to advertise sideband all to the clients
  270. * @since 5.6
  271. */
  272. public boolean isAdvertiseSidebandAll() {
  273. return advertiseSidebandAll && allowSidebandAll;
  274. }
  275. /**
  276. * Get {@link org.eclipse.jgit.transport.RefFilter} respecting configured
  277. * hidden refs.
  278. *
  279. * @return {@link org.eclipse.jgit.transport.RefFilter} respecting
  280. * configured hidden refs.
  281. * @since 3.1
  282. */
  283. public RefFilter getRefFilter() {
  284. if (hideRefs.length == 0)
  285. return RefFilter.DEFAULT;
  286. return new RefFilter() {
  287. @Override
  288. public Map<String, Ref> filter(Map<String, Ref> refs) {
  289. Map<String, Ref> result = new HashMap<>();
  290. for (Map.Entry<String, Ref> e : refs.entrySet()) {
  291. boolean add = true;
  292. for (String hide : hideRefs) {
  293. if (e.getKey().equals(hide) || prefixMatch(hide, e.getKey())) {
  294. add = false;
  295. break;
  296. }
  297. }
  298. if (add)
  299. result.put(e.getKey(), e.getValue());
  300. }
  301. return result;
  302. }
  303. private boolean prefixMatch(String p, String s) {
  304. return p.charAt(p.length() - 1) == '/' && s.startsWith(p);
  305. }
  306. };
  307. }
  308. /**
  309. * Like {@code getRefFilter() == RefFilter.DEFAULT}, but faster.
  310. *
  311. * @return {@code true} if no ref filtering is needed because there
  312. * are no configured hidden refs.
  313. */
  314. boolean hasDefaultRefFilter() {
  315. return hideRefs.length == 0;
  316. }
  317. static class FsckKeyNameHolder {
  318. private static final Map<String, ObjectChecker.ErrorType> errors;
  319. static {
  320. errors = new HashMap<>();
  321. for (ObjectChecker.ErrorType m : ObjectChecker.ErrorType.values()) {
  322. errors.put(keyNameFor(m.name()), m);
  323. }
  324. }
  325. @Nullable
  326. static ObjectChecker.ErrorType parse(String key) {
  327. return errors.get(toLowerCase(key));
  328. }
  329. private static String keyNameFor(String name) {
  330. StringBuilder r = new StringBuilder(name.length());
  331. for (int i = 0; i < name.length(); i++) {
  332. char c = name.charAt(i);
  333. if (c != '_') {
  334. r.append(c);
  335. }
  336. }
  337. return toLowerCase(r.toString());
  338. }
  339. private FsckKeyNameHolder() {
  340. }
  341. }
  342. }