gitrepository.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 475 行
JAVA
475 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.git;import com.caucho.util.*;import com.caucho.vfs.*;import java.io.*;import java.security.*;import java.util.*;import java.util.logging.*;import java.util.zip.*;/** * Top-level class for a repository */public class GitRepository { private static final L10N L = new L10N(GitRepository.class); private static final Logger log = Logger.getLogger(GitRepository.class.getName()); private static final int OBJ_NONE = 0; private static final int OBJ_COMMIT = 1; private static final int OBJ_TREE = 2; private static final int OBJ_BLOB = 3; private static final int OBJ_TAG = 4; private Path _root; public GitRepository(Path root) { _root = root; } public void initDb() throws IOException { if (_root.lookup("HEAD").canRead()) return; _root.mkdirs(); _root.lookup("refs").mkdir(); _root.lookup("refs/heads").mkdir(); _root.lookup("objects").mkdir(); _root.lookup("objects/info").mkdir(); _root.lookup("objects/pack").mkdir(); _root.lookup("branches").mkdir(); _root.lookup("tmp").mkdir(); WriteStream out = _root.lookup("HEAD").openWrite(); try { out.println("ref: refs/heads/master"); } finally { out.close(); } } public String getMaster() { try { Path path = _root.lookup("refs/heads/master"); ReadStream is = path.openRead(); try { return is.readLine(); } finally { is.close(); } } catch (IOException e) { throw new RuntimeException(e); } } public Object objectType(String sha1) throws IOException { GitObjectStream is = open(sha1); try { return is.getType(); } finally { is.close(); } } public String getTag(String tag) { Path path = _root.lookup("refs").lookup(tag); if (! path.canRead()) return null; ReadStream is = null; try { is = path.openRead(); String hex = is.readLine(); return hex.trim(); } catch (IOException e) { log.log(Level.FINE, e.toString(), e); return null; } finally { if (is != null) is.close(); } } public String []listRefs(String dir) { try { Path path = _root.lookup("refs").lookup(dir); if (path.isDirectory()) return path.list(); else return new String[0]; } catch (IOException e) { log.log(Level.FINE, e.toString(), e); return new String[0]; } } public Path getRefPath(String path) { return _root.lookup("refs").lookup(path); } public void writeTag(String tag, String hex) { Path path = _root.lookup("refs").lookup(tag); try { path.getParent().mkdirs(); } catch (IOException e) { log.log(Level.FINEST, e.toString(), e); } WriteStream out = null; try { out = path.openWrite(); out.println(hex); } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } finally { try { if (out != null) out.close(); } catch (Exception e) { log.log(Level.FINEST, e.toString(), e); } } } public GitCommit parseCommit(String sha1) throws IOException { GitObjectStream is = open(sha1); try { if (! "commit".equals(is.getType())) throw new IOException(L.l("'{0}' is an unexpected type, expected 'commit'", is.getType())); return is.parseCommit(); } finally { is.close(); } } public GitTree parseTree(String sha1) throws IOException { GitObjectStream is = open(sha1); try { if (! "tree".equals(is.getType())) throw new IOException(L.l("'{0}' is an unexpected type, expected 'commit'", is.getType())); return is.parseTree(); } finally { is.close(); } } public void copyToFile(Path path, String sha1) throws IOException { GitObjectStream is = open(sha1); try { if (! "blob".equals(is.getType())) throw new IOException(L.l("'{0}' is an unexpected type, expected 'blot'", is.getType())); WriteStream os = path.openWrite(); try { os.writeStream(is.getInputStream()); } finally { os.close(); } } finally { is.close(); } } public boolean contains(String sha1) { String prefix = sha1.substring(0, 2); String suffix = sha1.substring(2); Path path = _root.lookup("objects").lookup(prefix).lookup(suffix); return path.exists(); } private GitObjectStream open(String sha1) throws IOException { String prefix = sha1.substring(0, 2); String suffix = sha1.substring(2); Path path = _root.lookup("objects").lookup(prefix).lookup(suffix); return new GitObjectStream(path); } /** * Writes a file to the repository */ public String writeFile(Path path) throws IOException { InputStream is = path.openRead(); try { TempOutputStream os = new TempOutputStream(); String type = "blob"; String hex = writeData(os, type, is, path.getLength()); return writeFile(os, hex); } finally { is.close(); } } /** * Writes a file to the repository */ public String writeTree(GitTree tree) throws IOException { TempOutputStream treeOut = new TempOutputStream(); tree.toData(treeOut); int treeLength = treeOut.getLength(); InputStream is = treeOut.openRead(); try { TempOutputStream os = new TempOutputStream(); String type = "tree"; String hex = writeData(os, type, is, treeLength); return writeFile(os, hex); } finally { is.close(); } } /** * Writes a file to the repository */ public String writeCommit(GitCommit commit) throws IOException { TempStream commitOut = new TempStream(); WriteStream out = new WriteStream(commitOut); out.print("tree "); out.println(commit.getTree()); /* if (user != null) { out.print("author "); out.print(user); out.print(" "); out.print(timestamp / 1000); out.println(" +0000"); out.print("committer "); out.print(user); out.print(" "); out.print(timestamp / 1000); out.println(" +0000"); } */ String parent = commit.getParent(); if (parent != null) { out.print("parent "); out.println(parent); } HashMap<String,String> attr = commit.getAttributeMap(); if (attr != null) { ArrayList<String> keys = new ArrayList<String>(attr.keySet()); Collections.sort(keys); for (String key : keys) { out.print(key); out.print(' '); out.print(attr.get(key)); out.println(); } } out.println(); if (commit.getMessage() != null) out.println(commit.getMessage()); out.close(); int commitLength = commitOut.getLength(); InputStream is = commitOut.openRead(); try { TempOutputStream os = new TempOutputStream(); String type = "commit"; String hex = writeData(os, type, is, commitLength); return writeFile(os, hex); } finally { is.close(); } } public String writeFile(TempOutputStream os, String hex) throws IOException { Path objectPath = lookupPath(hex); if (objectPath.exists()) return hex; objectPath.getParent().mkdirs(); Path tmpDir = _root.lookup("tmp"); tmpDir.mkdirs(); Path tmp = _root.lookup("tmp").lookup("tmp." + hex); WriteStream tmpOs = tmp.openWrite(); try { tmpOs.writeStream(os.openRead()); } finally { tmpOs.close(); } tmp.renameTo(objectPath); return hex; } private Path lookupPath(String sha1) { String prefix = sha1.substring(0, 2); String suffix = sha1.substring(2); return _root.lookup("objects").lookup(prefix).lookup(suffix); } private String writeData(OutputStream os, String type, InputStream is, long length) throws IOException { TempBuffer buf = TempBuffer.allocate(); try { DeflaterOutputStream out = new DeflaterOutputStream(os); MessageDigest md = MessageDigest.getInstance("SHA-1"); for (int i = 0; i < type.length(); i++) { int ch = type.charAt(i); out.write(ch); md.update((byte) ch); } out.write(' '); md.update((byte) ' '); String lengthString = String.valueOf(length); for (int i = 0; i < lengthString.length(); i++) { int ch = lengthString.charAt(i); out.write(ch); md.update((byte) ch); } out.write(0); md.update((byte) 0); long readLength = 0; int len; byte []buffer = buf.getBuffer(); while ((len = is.read(buffer, 0, buffer.length)) > 0) { out.write(buffer, 0, len); md.update(buffer, 0, len); readLength += len; } out.close(); if (readLength != length) throw new IOException(L.l("written length does not match data")); return Hex.toHex(md.digest()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } finally { TempBuffer.free(buf); } } @Override public String toString() { return getClass().getSimpleName() + "[" + _root + "]"; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?