annotate src/org/tmatesoft/hg/internal/WorkingDirFileWriter.java @ 705:b4242b7e7dfe

Merge command: implement conflict resolution alternatives
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 15 Aug 2013 18:43:50 +0200
parents 6526d8adbc0f
children 42b88709e41d
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: 572
diff 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: 572
diff 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: 628
diff 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: 628
diff changeset
28 import org.tmatesoft.hg.core.HgFileRevision;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 572
diff 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: 580
diff 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: 525
diff 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: 525
diff changeset
46 private final Internals hgRepo;
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
47 private final boolean execCap, symlinkCap;
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 572
diff changeset
52 private ByteArrayChannel linkChannel;
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 525
diff changeset
55 public WorkingDirFileWriter(Internals internalRepo) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
56 hgRepo = internalRepo;
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
57 execCap = Internals.checkSupportsExecutables(internalRepo.getRepo().getWorkingDir());
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
58 symlinkCap = Internals.checkSupportsSymlinks(internalRepo.getRepo().getWorkingDir());
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
59 if (symlinkCap || execCap) {
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
60 fileFlagsHelper = new FileSystemHelper(internalRepo.getSessionContext());
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
61 } else {
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
62 fileFlagsHelper = null;
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 526
diff changeset
66 /**
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 572
diff 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: 580
diff 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: 526
diff changeset
70 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
72 processFile(df.getPath(), new Fetch() {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
73 public void readInto(ByteChannel ch) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
74 try {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
75 df.contentWithFilters(fileRevIndex, ch);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
76 } catch (CancelledException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
77 handleUnexpectedCancel(ex);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
78 }
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
79 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
80 }, flags);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
81 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
82
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
84 processFile(fr.getPath(), new Fetch() {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
85
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
86 public void readInto(ByteChannel ch) throws IOException, HgRuntimeException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
87 try {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
88 fr.putContentTo(ch);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
89 } catch (CancelledException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
90 handleUnexpectedCancel(ex);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
91 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
92 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
93 }, fr.getFileFlags());
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
94 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
95
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
96 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
97 * Closes supplied content stream
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
98 */
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
100 processFile(fname, new Fetch() {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
101
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
102 public void readInto(ByteChannel ch) throws IOException, HgRuntimeException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
103 try {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
104 ByteBuffer bb = ByteBuffer.wrap(new byte[8*1024]);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
105 int r;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
106 while ((r = content.read(bb.array())) != -1) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
107 bb.position(0).limit(r);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
108 for (int wrote = 0; wrote < r; ) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
109 r -= wrote;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
110 wrote = ch.write(bb);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
111 assert bb.remaining() == r - wrote;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
112 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
113 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
114 } catch (CancelledException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
115 handleUnexpectedCancel(ex);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
116 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
117 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
118 }, flags);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
119 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
120
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
121 private interface Fetch {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
122 void readInto(ByteChannel ch) throws IOException, HgRuntimeException;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
123 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
124
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
126 try {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
127 byte[] symlinkContent = null;
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
128 try {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
129 prepare(fname, flags);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
130 fetch.readInto(this);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
131 } finally {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
132 symlinkContent = close(fname, flags);
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
133 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
134 if (flags == HgManifest.Flags.Link && symlinkCap) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
135 assert symlinkContent != null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
136 fileFlagsHelper.createSymlink(dest.getParentFile(), dest.getName(), symlinkContent);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
137 } else if (flags == HgManifest.Flags.Exec && execCap) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
138 fileFlagsHelper.setExecutableBit(dest.getParentFile(), dest.getName());
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
139 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
141 // to detect actual flags here
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
142 fmode = flags.fsMode(); // default to one from manifest
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
143 if (fileFlagsHelper != null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
145 try {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
146 fmode = fileFlagsHelper.getFileMode(dest, fmode);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
147 } catch (IOException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff 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: 628
diff changeset
150 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
151 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
152 } catch (IOException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
154 throw new HgIOException(msg, ex, dest);
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 628
diff 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: 525
diff 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: 572
diff changeset
164 destChannel = null;
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 572
diff changeset
167 fmode = 0;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
168 if (flags != HgManifest.Flags.Link) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
169 destChannel = new FileOutputStream(dest).getChannel();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
170 } else {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
171 linkChannel = new ByteArrayChannel();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
172 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
173 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
174
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 628
diff changeset
176 if (flags != HgManifest.Flags.Link) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
177 destChannel.close();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
178 destChannel = null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
179 // leave dest in case anyone enquires with #getDestinationFile
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
180 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
181 if (linkChannel != null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
182 final byte[] rv = linkChannel.toArray();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
183 linkChannel = null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
184 return rv;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
185 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff 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: 572
diff changeset
190 final int written;
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
191 if (linkChannel != null) {
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
192 written = linkChannel.write(buffer);
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
193 } else {
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
194 written = destChannel.write(buffer);
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 572
diff changeset
200 /**
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 572
diff changeset
202 */
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
203 public File getDestinationFile() {
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff 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: 572
diff changeset
210
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
211 public int fmode() {
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
212 return fmode;
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
213 }
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
214
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
215 public int mtime() {
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
216 return (int) (dest.lastModified() / 1000);
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 572
diff changeset
217 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
218
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
219 private void handleUnexpectedCancel(CancelledException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
220 hgRepo.getSessionContext().getLog().dump(WorkingDirFileWriter.class, Severity.Error, ex, "Our impl doesn't throw cancellation");
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
221 }
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
222 }