|
|
|
|
|
|
|
|
import java.io.FileInputStream; |
|
|
import java.io.FileInputStream; |
|
|
import java.io.FileNotFoundException; |
|
|
import java.io.FileNotFoundException; |
|
|
import java.io.IOException; |
|
|
import java.io.IOException; |
|
|
import java.nio.file.AtomicMoveNotSupportedException; |
|
|
|
|
|
import java.nio.file.Files; |
|
|
import java.nio.file.Files; |
|
|
import java.nio.file.NoSuchFileException; |
|
|
import java.nio.file.NoSuchFileException; |
|
|
import java.nio.file.StandardCopyOption; |
|
|
import java.nio.file.StandardCopyOption; |
|
|
|
|
|
|
|
|
FileUtils.delete(tmp, FileUtils.RETRY); |
|
|
FileUtils.delete(tmp, FileUtils.RETRY); |
|
|
return InsertLooseObjectResult.EXISTS_LOOSE; |
|
|
return InsertLooseObjectResult.EXISTS_LOOSE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
Files.move(FileUtils.toPath(tmp), FileUtils.toPath(dst), |
|
|
|
|
|
StandardCopyOption.ATOMIC_MOVE); |
|
|
|
|
|
dst.setReadOnly(); |
|
|
|
|
|
unpackedObjectCache.add(id); |
|
|
|
|
|
return InsertLooseObjectResult.INSERTED; |
|
|
|
|
|
} catch (AtomicMoveNotSupportedException e) { |
|
|
|
|
|
LOG.error(e.getMessage(), e); |
|
|
|
|
|
FileUtils.delete(tmp, FileUtils.RETRY); |
|
|
|
|
|
return InsertLooseObjectResult.FAILURE; |
|
|
|
|
|
|
|
|
return tryMove(tmp, dst, id); |
|
|
} catch (NoSuchFileException e) { |
|
|
} catch (NoSuchFileException e) { |
|
|
// It's possible the directory doesn't exist yet as the object |
|
|
// It's possible the directory doesn't exist yet as the object |
|
|
// directories are always lazily created. Note that we try the |
|
|
// directories are always lazily created. Note that we try the |
|
|
// rename/move first as the directory likely does exist. |
|
|
// rename/move first as the directory likely does exist. |
|
|
|
|
|
|
|
|
// Create the directory |
|
|
|
|
|
|
|
|
// |
|
|
|
|
|
// Create the directory. |
|
|
|
|
|
// |
|
|
FileUtils.mkdir(dst.getParentFile(), true); |
|
|
FileUtils.mkdir(dst.getParentFile(), true); |
|
|
} catch (IOException e) { |
|
|
} catch (IOException e) { |
|
|
|
|
|
// Any other IO error is considered a failure. |
|
|
|
|
|
// |
|
|
LOG.error(e.getMessage(), e); |
|
|
LOG.error(e.getMessage(), e); |
|
|
FileUtils.delete(tmp, FileUtils.RETRY); |
|
|
FileUtils.delete(tmp, FileUtils.RETRY); |
|
|
return InsertLooseObjectResult.FAILURE; |
|
|
return InsertLooseObjectResult.FAILURE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
Files.move(FileUtils.toPath(tmp), FileUtils.toPath(dst), |
|
|
|
|
|
StandardCopyOption.ATOMIC_MOVE); |
|
|
|
|
|
dst.setReadOnly(); |
|
|
|
|
|
unpackedObjectCache.add(id); |
|
|
|
|
|
return InsertLooseObjectResult.INSERTED; |
|
|
|
|
|
|
|
|
return tryMove(tmp, dst, id); |
|
|
} catch (IOException e) { |
|
|
} catch (IOException e) { |
|
|
|
|
|
// The object failed to be renamed into its proper location and |
|
|
|
|
|
// it doesn't exist in the repository either. We really don't |
|
|
|
|
|
// know what went wrong, so fail. |
|
|
|
|
|
// |
|
|
LOG.error(e.getMessage(), e); |
|
|
LOG.error(e.getMessage(), e); |
|
|
FileUtils.delete(tmp, FileUtils.RETRY); |
|
|
FileUtils.delete(tmp, FileUtils.RETRY); |
|
|
return InsertLooseObjectResult.FAILURE; |
|
|
return InsertLooseObjectResult.FAILURE; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private InsertLooseObjectResult tryMove(File tmp, File dst, |
|
|
|
|
|
ObjectId id) |
|
|
|
|
|
throws IOException { |
|
|
|
|
|
Files.move(FileUtils.toPath(tmp), FileUtils.toPath(dst), |
|
|
|
|
|
StandardCopyOption.ATOMIC_MOVE); |
|
|
|
|
|
dst.setReadOnly(); |
|
|
|
|
|
unpackedObjectCache.add(id); |
|
|
|
|
|
return InsertLooseObjectResult.INSERTED; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
boolean searchPacksAgain(PackList old) { |
|
|
boolean searchPacksAgain(PackList old) { |
|
|
// Whether to trust the pack folder's modification time. If set |
|
|
// Whether to trust the pack folder's modification time. If set |
|
|
// to false we will always scan the .git/objects/pack folder to |
|
|
// to false we will always scan the .git/objects/pack folder to |