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.

RefWriter.java 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright (C) 2008, Charles O'Farrell <charleso@charleso.org>
  3. * Copyright (C) 2009-2010, Google Inc.
  4. * Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com>
  5. * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
  6. *
  7. * This program and the accompanying materials are made available under the
  8. * terms of the Eclipse Distribution License v. 1.0 which is available at
  9. * https://www.eclipse.org/org/documents/edl-v10.php.
  10. *
  11. * SPDX-License-Identifier: BSD-3-Clause
  12. */
  13. package org.eclipse.jgit.lib;
  14. import java.io.IOException;
  15. import java.io.StringWriter;
  16. import java.util.Collection;
  17. import java.util.Map;
  18. import org.eclipse.jgit.internal.storage.file.RefDirectory;
  19. import org.eclipse.jgit.util.RefList;
  20. import org.eclipse.jgit.util.RefMap;
  21. /**
  22. * Writes out refs to the {@link org.eclipse.jgit.lib.Constants#INFO_REFS} and
  23. * {@link org.eclipse.jgit.lib.Constants#PACKED_REFS} files.
  24. *
  25. * This class is abstract as the writing of the files must be handled by the
  26. * caller. This is because it is used by transport classes as well.
  27. */
  28. public abstract class RefWriter {
  29. private final Collection<Ref> refs;
  30. /**
  31. * <p>Constructor for RefWriter.</p>
  32. *
  33. * @param refs
  34. * the complete set of references. This should have been computed
  35. * by applying updates to the advertised refs already discovered.
  36. */
  37. public RefWriter(Collection<Ref> refs) {
  38. this.refs = RefComparator.sort(refs);
  39. }
  40. /**
  41. * <p>Constructor for RefWriter.</p>
  42. *
  43. * @param refs
  44. * the complete set of references. This should have been computed
  45. * by applying updates to the advertised refs already discovered.
  46. */
  47. public RefWriter(Map<String, Ref> refs) {
  48. if (refs instanceof RefMap)
  49. this.refs = refs.values();
  50. else
  51. this.refs = RefComparator.sort(refs.values());
  52. }
  53. /**
  54. * <p>Constructor for RefWriter.</p>
  55. *
  56. * @param refs
  57. * the complete set of references. This should have been computed
  58. * by applying updates to the advertised refs already discovered.
  59. */
  60. public RefWriter(RefList<Ref> refs) {
  61. this.refs = refs.asList();
  62. }
  63. /**
  64. * Rebuild the {@link org.eclipse.jgit.lib.Constants#INFO_REFS}.
  65. * <p>
  66. * This method rebuilds the contents of the
  67. * {@link org.eclipse.jgit.lib.Constants#INFO_REFS} file to match the passed
  68. * list of references.
  69. *
  70. * @throws java.io.IOException
  71. * writing is not supported, or attempting to write the file
  72. * failed, possibly due to permissions or remote disk full, etc.
  73. */
  74. public void writeInfoRefs() throws IOException {
  75. final StringWriter w = new StringWriter();
  76. final char[] tmp = new char[Constants.OBJECT_ID_STRING_LENGTH];
  77. for (Ref r : refs) {
  78. if (Constants.HEAD.equals(r.getName())) {
  79. // Historically HEAD has never been published through
  80. // the INFO_REFS file. This is a mistake, but its the
  81. // way things are.
  82. //
  83. continue;
  84. }
  85. ObjectId objectId = r.getObjectId();
  86. if (objectId == null) {
  87. // Symrefs to unborn branches aren't advertised in the info/refs
  88. // file.
  89. continue;
  90. }
  91. objectId.copyTo(tmp, w);
  92. w.write('\t');
  93. w.write(r.getName());
  94. w.write('\n');
  95. ObjectId peeledObjectId = r.getPeeledObjectId();
  96. if (peeledObjectId != null) {
  97. peeledObjectId.copyTo(tmp, w);
  98. w.write('\t');
  99. w.write(r.getName());
  100. w.write("^{}\n"); //$NON-NLS-1$
  101. }
  102. }
  103. writeFile(Constants.INFO_REFS, Constants.encode(w.toString()));
  104. }
  105. /**
  106. * Rebuild the {@link org.eclipse.jgit.lib.Constants#PACKED_REFS} file.
  107. * <p>
  108. * This method rebuilds the contents of the
  109. * {@link org.eclipse.jgit.lib.Constants#PACKED_REFS} file to match the
  110. * passed list of references, including only those refs that have a storage
  111. * type of {@link org.eclipse.jgit.lib.Ref.Storage#PACKED}.
  112. *
  113. * @throws java.io.IOException
  114. * writing is not supported, or attempting to write the file
  115. * failed, possibly due to permissions or remote disk full, etc.
  116. */
  117. public void writePackedRefs() throws IOException {
  118. boolean peeled = false;
  119. for (Ref r : refs) {
  120. if (r.getStorage().isPacked() && r.isPeeled()) {
  121. peeled = true;
  122. break;
  123. }
  124. }
  125. final StringWriter w = new StringWriter();
  126. if (peeled) {
  127. w.write(RefDirectory.PACKED_REFS_HEADER);
  128. if (peeled)
  129. w.write(RefDirectory.PACKED_REFS_PEELED);
  130. w.write('\n');
  131. }
  132. final char[] tmp = new char[Constants.OBJECT_ID_STRING_LENGTH];
  133. for (Ref r : refs) {
  134. if (r.getStorage() != Ref.Storage.PACKED)
  135. continue;
  136. ObjectId objectId = r.getObjectId();
  137. if (objectId == null) {
  138. // A packed ref cannot be a symref, let alone a symref
  139. // to an unborn branch.
  140. throw new NullPointerException();
  141. }
  142. objectId.copyTo(tmp, w);
  143. w.write(' ');
  144. w.write(r.getName());
  145. w.write('\n');
  146. ObjectId peeledObjectId = r.getPeeledObjectId();
  147. if (peeledObjectId != null) {
  148. w.write('^');
  149. peeledObjectId.copyTo(tmp, w);
  150. w.write('\n');
  151. }
  152. }
  153. writeFile(Constants.PACKED_REFS, Constants.encode(w.toString()));
  154. }
  155. /**
  156. * Handles actual writing of ref files to the git repository, which may
  157. * differ slightly depending on the destination and transport.
  158. *
  159. * @param file
  160. * path to ref file.
  161. * @param content
  162. * byte content of file to be written.
  163. * @throws java.io.IOException
  164. */
  165. protected abstract void writeFile(String file, byte[] content)
  166. throws IOException;
  167. }