Mercurial > hg4j
annotate src/org/tmatesoft/hg/internal/WorkingDirFileWriter.java @ 713:661e77dc88ba tip
Mac support: respect Mac alternatives of command-line arguments for common unix tools
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Sun, 03 Aug 2014 18:09:00 +0200 | 
| parents | 42b88709e41d | 
| children | 
| rev | line source | 
|---|---|
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 1 /* | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 2 * Copyright (c) 2012-2013 TMate Software Ltd | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 3 * | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 4 * This program is free software; you can redistribute it and/or modify | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 5 * it under the terms of the GNU General Public License as published by | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 6 * the Free Software Foundation; version 2 of the License. | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 7 * | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 8 * This program is distributed in the hope that it will be useful, | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 11 * GNU General Public License for more details. | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 12 * | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 13 * For information on how to redistribute this software under | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 14 * the terms of a license other than GNU General Public License | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 15 * contact TMate Software at support@hg4j.com | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 16 */ | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 17 package org.tmatesoft.hg.internal; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 18 | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 19 import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 20 | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 21 import java.io.File; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 22 import java.io.FileOutputStream; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 23 import java.io.IOException; | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 24 import java.io.InputStream; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 25 import java.nio.ByteBuffer; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 26 import java.nio.channels.FileChannel; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 27 | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 28 import org.tmatesoft.hg.core.HgFileRevision; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 29 import org.tmatesoft.hg.core.HgIOException; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 30 import org.tmatesoft.hg.repo.HgDataFile; | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 31 import org.tmatesoft.hg.repo.HgManifest; | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 32 import org.tmatesoft.hg.repo.HgRuntimeException; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 33 import org.tmatesoft.hg.util.ByteChannel; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 34 import org.tmatesoft.hg.util.CancelledException; | 
| 526 
2f9ed6bcefa2
Initial support for Revert command with accompanying minor refactoring
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
525diff
changeset | 35 import org.tmatesoft.hg.util.LogFacility.Severity; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 36 import org.tmatesoft.hg.util.Path; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 37 | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 38 /** | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 39 * | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 40 * @author Artem Tikhomirov | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 41 * @author TMate Software Ltd. | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 42 */ | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 43 public class WorkingDirFileWriter implements ByteChannel { | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 44 | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 45 | 
| 526 
2f9ed6bcefa2
Initial support for Revert command with accompanying minor refactoring
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
525diff
changeset | 46 private final Internals hgRepo; | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 47 private final boolean execCap, symlinkCap; | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 48 private final FileSystemHelper fileFlagsHelper; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 49 private File dest; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 50 private FileChannel destChannel; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 51 private int totalBytesWritten; | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 52 private ByteArrayChannel linkChannel; | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 53 private int fmode; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 54 | 
| 526 
2f9ed6bcefa2
Initial support for Revert command with accompanying minor refactoring
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
525diff
changeset | 55 public WorkingDirFileWriter(Internals internalRepo) { | 
| 
2f9ed6bcefa2
Initial support for Revert command with accompanying minor refactoring
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
525diff
changeset | 56 hgRepo = internalRepo; | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 57 execCap = Internals.checkSupportsExecutables(internalRepo.getRepo().getWorkingDir()); | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 58 symlinkCap = Internals.checkSupportsSymlinks(internalRepo.getRepo().getWorkingDir()); | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 59 if (symlinkCap || execCap) { | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 60 fileFlagsHelper = new FileSystemHelper(internalRepo.getSessionContext()); | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 61 } else { | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 62 fileFlagsHelper = null; | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 63 } | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 64 } | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 65 | 
| 572 
becd2a1310a2
Report file object in case of error to be helpful as much as possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
526diff
changeset | 66 /** | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 67 * Writes content of specified file revision into local filesystem, or create a symlink according to flags. | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 68 * Executable bit is set if specified and filesystem supports it. | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 69 * @throws HgRuntimeException | 
| 572 
becd2a1310a2
Report file object in case of error to be helpful as much as possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
526diff
changeset | 70 */ | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 71 public void processFile(final HgDataFile df, final int fileRevIndex, HgManifest.Flags flags) throws HgIOException, HgRuntimeException { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 72 processFile(df.getPath(), new Fetch() { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 73 public void readInto(ByteChannel ch) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 74 try { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 75 df.contentWithFilters(fileRevIndex, ch); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 76 } catch (CancelledException ex) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 77 handleUnexpectedCancel(ex); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 78 } | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 79 } | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 80 }, flags); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 81 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 82 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 83 public void processFile(final HgFileRevision fr) throws HgIOException, HgRuntimeException { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 84 processFile(fr.getPath(), new Fetch() { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 85 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 86 public void readInto(ByteChannel ch) throws IOException, HgRuntimeException { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 87 try { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 88 fr.putContentTo(ch); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 89 } catch (CancelledException ex) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 90 handleUnexpectedCancel(ex); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 91 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 92 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 93 }, fr.getFileFlags()); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 94 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 95 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 96 /** | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 97 * Closes supplied content stream | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 98 */ | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 99 public void processFile(Path fname, final InputStream content, HgManifest.Flags flags) throws HgIOException, HgRuntimeException { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 100 processFile(fname, new Fetch() { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 101 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 102 public void readInto(ByteChannel ch) throws IOException, HgRuntimeException { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 103 try { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 104 ByteBuffer bb = ByteBuffer.wrap(new byte[8*1024]); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 105 int r; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 106 while ((r = content.read(bb.array())) != -1) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 107 bb.position(0).limit(r); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 108 for (int wrote = 0; wrote < r; ) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 109 r -= wrote; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 110 wrote = ch.write(bb); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 111 assert bb.remaining() == r - wrote; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 112 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 113 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 114 } catch (CancelledException ex) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 115 handleUnexpectedCancel(ex); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 116 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 117 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 118 }, flags); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 119 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 120 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 121 private interface Fetch { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 122 void readInto(ByteChannel ch) throws IOException, HgRuntimeException; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 123 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 124 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 125 private void processFile(Path fname, Fetch fetch, HgManifest.Flags flags) throws HgIOException, HgRuntimeException { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 126 try { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 127 byte[] symlinkContent = null; | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 128 try { | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 129 prepare(fname, flags); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 130 fetch.readInto(this); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 131 } finally { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 132 symlinkContent = close(fname, flags); | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 133 } | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 134 if (flags == HgManifest.Flags.Link && symlinkCap) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 135 assert symlinkContent != null; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 136 fileFlagsHelper.createSymlink(dest.getParentFile(), dest.getName(), symlinkContent); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 137 } else if (flags == HgManifest.Flags.Exec && execCap) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 138 fileFlagsHelper.setExecutableBit(dest.getParentFile(), dest.getName()); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 139 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 140 // Although HgWCStatusCollector treats 644 (`hg manifest -v`) and 664 (my fs) the same, it's better | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 141 // to detect actual flags here | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 142 fmode = flags.fsMode(); // default to one from manifest | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 143 if (fileFlagsHelper != null) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 144 // if neither execBit nor link is supported by fs, it's unlikely file mode is supported, too. | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 145 try { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 146 fmode = fileFlagsHelper.getFileMode(dest, fmode); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 147 } catch (IOException ex) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 148 // Warn, we've got default value and can live with it | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 149 hgRepo.getSessionContext().getLog().dump(getClass(), Warn, ex, "Failed get file access rights"); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 150 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 151 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 152 } catch (IOException ex) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 153 String msg = String.format("Failed to write file %s to the working directory", fname); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 154 throw new HgIOException(msg, ex, dest); | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 155 } | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 156 } | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 157 | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 158 private void prepare(Path fname, HgManifest.Flags flags) throws IOException { | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 159 String fpath = fname.toString(); | 
| 526 
2f9ed6bcefa2
Initial support for Revert command with accompanying minor refactoring
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
525diff
changeset | 160 dest = new File(hgRepo.getRepo().getWorkingDir(), fpath); | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 161 if (fpath.indexOf('/') != -1) { | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 162 dest.getParentFile().mkdirs(); | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 163 } | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 164 destChannel = null; | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 165 linkChannel = null; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 166 totalBytesWritten = 0; | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 167 fmode = 0; | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 168 if (flags != HgManifest.Flags.Link) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 169 destChannel = new FileOutputStream(dest).getChannel(); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 170 } else { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 171 linkChannel = new ByteArrayChannel(); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 172 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 173 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 174 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 175 private byte[] close(Path fname, HgManifest.Flags flags) throws IOException { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 176 if (flags != HgManifest.Flags.Link) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 177 destChannel.close(); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 178 destChannel = null; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 179 // leave dest in case anyone enquires with #getDestinationFile | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 180 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 181 if (linkChannel != null) { | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 182 final byte[] rv = linkChannel.toArray(); | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 183 linkChannel = null; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 184 return rv; | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 185 } | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 186 return null; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 187 } | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 188 | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 189 public int write(ByteBuffer buffer) throws IOException, CancelledException { | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 190 final int written; | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 191 if (linkChannel != null) { | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 192 written = linkChannel.write(buffer); | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 193 } else { | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 194 written = destChannel.write(buffer); | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 195 } | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 196 totalBytesWritten += written; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 197 return written; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 198 } | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 199 | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 200 /** | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 201 * Information purposes only, to find out trouble location if {@link #processFile(HgDataFile, int)} fails | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 202 */ | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 203 public File getDestinationFile() { | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 204 return dest; | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 205 } | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 206 | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 207 public int bytesWritten() { | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 208 return totalBytesWritten; | 
| 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 209 } | 
| 580 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 210 | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 211 public int fmode() { | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 212 return fmode; | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 213 } | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 214 | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 215 public int mtime() { | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 216 return (int) (dest.lastModified() / 1000); | 
| 
bd5926e24aa3
Respect unix flags for checkout/revert
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
572diff
changeset | 217 } | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 218 | 
| 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 219 private void handleUnexpectedCancel(CancelledException ex) { | 
| 707 
42b88709e41d
Merge: support 'unresolved' resolution with MergeStateBuilder
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
705diff
changeset | 220 hgRepo.getLog().dump(WorkingDirFileWriter.class, Severity.Error, ex, "Our impl doesn't throw cancellation"); | 
| 705 
b4242b7e7dfe
Merge command: implement conflict resolution alternatives
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 221 } | 
| 525 
0be5be8d57e9
Repository checkout support, first iteration
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 222 } | 
