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.

LfsBlobFilter.java 2.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (C) 2017, 2021 Markus Duft <markus.duft@ssi-schaefer.com> 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.lfs;
  11. import java.io.IOException;
  12. import java.io.InputStream;
  13. import java.nio.file.Files;
  14. import java.nio.file.Path;
  15. import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
  16. import org.eclipse.jgit.lib.ObjectLoader;
  17. import org.eclipse.jgit.lib.Repository;
  18. import org.eclipse.jgit.util.TemporaryBuffer;
  19. import org.eclipse.jgit.util.TemporaryBuffer.LocalFile;
  20. /**
  21. * Provides transparently either a stream to the blob or a LFS media file if
  22. * managed by LFS.
  23. *
  24. * @since 4.11
  25. */
  26. public class LfsBlobFilter {
  27. /**
  28. * In case the given {@link ObjectLoader} points to a LFS pointer file
  29. * replace the loader with one pointing to the LFS media file contents.
  30. * Missing LFS files are downloaded on the fly - same logic as the smudge
  31. * filter.
  32. *
  33. * @param db
  34. * the repo
  35. * @param loader
  36. * the loader for the blob
  37. * @return either the original loader, or a loader for the LFS media file if
  38. * managed by LFS. Files are downloaded on demand if required.
  39. * @throws IOException
  40. * in case of an error
  41. */
  42. public static ObjectLoader smudgeLfsBlob(Repository db, ObjectLoader loader)
  43. throws IOException {
  44. if (loader.getSize() > LfsPointer.FULL_SIZE_THRESHOLD) {
  45. return loader;
  46. }
  47. try (InputStream is = loader.openStream()) {
  48. LfsPointer ptr = LfsPointer.parseLfsPointer(is);
  49. if (ptr != null) {
  50. Lfs lfs = new Lfs(db);
  51. AnyLongObjectId oid = ptr.getOid();
  52. Path mediaFile = lfs.getMediaFile(oid);
  53. if (!Files.exists(mediaFile)) {
  54. SmudgeFilter.downloadLfsResource(lfs, db, ptr);
  55. }
  56. return new LfsBlobLoader(mediaFile);
  57. }
  58. }
  59. return loader;
  60. }
  61. /**
  62. * Run the LFS clean filter on the given stream and return a stream to the
  63. * LFS pointer file buffer. Used when inserting objects.
  64. *
  65. * @param db
  66. * the {@link Repository}
  67. * @param originalContent
  68. * the {@link InputStream} to the original content
  69. * @return a {@link TemporaryBuffer} representing the LFS pointer. The
  70. * caller is responsible to destroy the buffer.
  71. * @throws IOException
  72. * in case of any error.
  73. */
  74. public static TemporaryBuffer cleanLfsBlob(Repository db,
  75. InputStream originalContent) throws IOException {
  76. LocalFile buffer = new TemporaryBuffer.LocalFile(null);
  77. CleanFilter f = new CleanFilter(db, originalContent, buffer);
  78. try {
  79. while (f.run() != -1) {
  80. // loop as long as f.run() tells there is work to do
  81. }
  82. } catch (IOException e) {
  83. buffer.destroy();
  84. throw e;
  85. }
  86. return buffer;
  87. }
  88. }