Mercurial > hg4j
annotate src/org/tmatesoft/hg/internal/COWTransaction.java @ 709:497e697636fc
Report merged lines as changed block if possible, not as a sequence of added/deleted blocks. To facilitate access to merge parent lines AddBlock got mergeLineAt() method that reports index of the line in the second parent (if any), while insertedAt() has been changed to report index in the first parent always
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 21 Aug 2013 16:23:27 +0200 |
parents | dde18bc7053b |
children |
rev | line source |
---|---|
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
1 /* |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
2 * Copyright (c) 2013 TMate Software Ltd |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
3 * |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
4 * This program is free software; you can redistribute it and/or modify |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
6 * the Free Software Foundation; version 2 of the License. |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
7 * |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
8 * This program is distributed in the hope that it will be useful, |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
11 * GNU General Public License for more details. |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
12 * |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
13 * For information on how to redistribute this software under |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
14 * the terms of a license other than GNU General Public License |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
15 * contact TMate Software at support@hg4j.com |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
16 */ |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
17 package org.tmatesoft.hg.internal; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
18 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
19 import java.io.File; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
20 import java.io.IOException; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
21 import java.util.Iterator; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
22 import java.util.LinkedList; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
23 import java.util.List; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
24 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
25 import org.tmatesoft.hg.core.HgIOException; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
26 import org.tmatesoft.hg.core.SessionContext; |
665
dde18bc7053b
Test Copy-on-Write transactions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
654
diff
changeset
|
27 import org.tmatesoft.hg.repo.HgInvalidStateException; |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
28 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
29 /** |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
30 * This transaction strategy makes a copy of original file and breaks origin hard links, if any. |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
31 * Changes are directed to actual repository files. |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
32 * |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
33 * On commit, remove all backup copies |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
34 * On rollback, move all backup files in place of original |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
35 * |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
36 * @author Artem Tikhomirov |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
37 * @author TMate Software Ltd. |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
38 */ |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
39 public final class COWTransaction extends Transaction { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
40 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
41 private final FileUtils fileHelper; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
42 private final List<RollbackEntry> entries = new LinkedList<RollbackEntry>(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
43 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
44 public COWTransaction(SessionContext.Source ctxSource) { |
654
12a4f60ea972
1) Console push tool. 2) Pass class to blame into FileUtils
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
635
diff
changeset
|
45 fileHelper = new FileUtils(ctxSource.getSessionContext().getLog(), this); |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
46 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
47 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
48 @Override |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
49 public File prepare(File f) throws HgIOException { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
50 if (known(f)) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
51 return f; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
52 } |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
53 if (!f.exists()) { |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
54 return recordNonExistent(f); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
55 } |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
56 final File parentDir = f.getParentFile(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
57 assert parentDir.canWrite(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
58 File copy = new File(parentDir, f.getName() + ".hg4j.copy"); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
59 fileHelper.copy(f, copy); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
60 final long lm = f.lastModified(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
61 copy.setLastModified(lm); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
62 File backup = new File(parentDir, f.getName() + ".hg4j.orig"); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
63 if (backup.exists()) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
64 backup.delete(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
65 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
66 if (!f.renameTo(backup)) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
67 throw new HgIOException(String.format("Failed to backup %s to %s", f.getName(), backup.getName()), backup); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
68 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
69 if (!copy.renameTo(f)) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
70 throw new HgIOException(String.format("Failed to bring on-write copy in place (%s to %s)", copy.getName(), f.getName()), copy); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
71 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
72 f.setLastModified(lm); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
73 record(f, backup); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
74 return f; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
75 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
76 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
77 @Override |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
78 public File prepare(File origin, File backup) throws HgIOException { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
79 if (known(origin)) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
80 return origin; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
81 } |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
82 if (!origin.exists()) { |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
83 return recordNonExistent(origin); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
84 } |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
85 fileHelper.copy(origin, backup); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
86 final RollbackEntry e = record(origin, backup); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
87 e.keepBackup = true; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
88 return origin; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
89 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
90 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
91 @Override |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
92 public void done(File f) throws HgIOException { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
93 find(f).success = true; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
94 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
95 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
96 @Override |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
97 public void failure(File f, IOException ex) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
98 find(f).failure = ex; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
99 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
100 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
101 // XXX custom exception for commit and rollback to hold information about files rolled back |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
102 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
103 @Override |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
104 public void commit() throws HgIOException { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
105 for (Iterator<RollbackEntry> it = entries.iterator(); it.hasNext();) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
106 RollbackEntry e = it.next(); |
665
dde18bc7053b
Test Copy-on-Write transactions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
654
diff
changeset
|
107 if (!e.success) { |
dde18bc7053b
Test Copy-on-Write transactions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
654
diff
changeset
|
108 throw new HgInvalidStateException(String.format("Attempt to commit transaction without successful clearance of file %s", e.origin)); |
dde18bc7053b
Test Copy-on-Write transactions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
654
diff
changeset
|
109 } |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
110 if (e.failure != null) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
111 throw new HgIOException("Can't close transaction with a failure.", e.failure, e.origin); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
112 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
113 if (!e.keepBackup && e.backup != null) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
114 e.backup.delete(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
115 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
116 it.remove(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
117 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
118 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
119 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
120 @Override |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
121 public void rollback() throws HgIOException { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
122 LinkedList<RollbackEntry> success = new LinkedList<RollbackEntry>(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
123 for (Iterator<RollbackEntry> it = entries.iterator(); it.hasNext();) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
124 RollbackEntry e = it.next(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
125 e.origin.delete(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
126 if (e.backup != null) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
127 if (!e.backup.renameTo(e.origin)) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
128 String msg = String.format("Transaction rollback failed, could not rename backup %s back to %s", e.backup.getName(), e.origin.getName()); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
129 throw new HgIOException(msg, e.origin); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
130 } |
621
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
617
diff
changeset
|
131 // renameTo() doesn't update timestamp, while the rest of the code relies |
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
617
diff
changeset
|
132 // on file timestamp to detect revlog changes. Rollback *is* a change, |
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
617
diff
changeset
|
133 // even if it brings the old state. |
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
617
diff
changeset
|
134 e.origin.setLastModified(System.currentTimeMillis()); |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
135 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
136 success.add(e); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
137 it.remove(); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
138 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
139 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
140 |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
141 private File recordNonExistent(File f) throws HgIOException { |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
142 record(f, null); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
143 try { |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
144 f.getParentFile().mkdirs(); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
145 f.createNewFile(); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
146 return f; |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
147 } catch (IOException ex) { |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
148 throw new HgIOException("Failed to create new file", ex, f); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
149 } |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
150 } |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
151 |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
152 private RollbackEntry record(File origin, File backup) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
153 final RollbackEntry e = new RollbackEntry(origin, backup); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
154 entries.add(e); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
155 return e; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
156 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
157 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
158 private boolean known(File f) { |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
159 RollbackEntry e = lookup(f); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
160 return e != null; |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
161 } |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
162 |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
163 private RollbackEntry find(File f) { |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
164 RollbackEntry e = lookup(f); |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
165 if (e != null) { |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
166 return e; |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
167 } |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
168 assert false; |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
169 return new RollbackEntry(f,f); |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
170 } |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
171 |
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
172 private RollbackEntry lookup(File f) { |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
173 for (RollbackEntry e : entries) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
174 if (e.origin.equals(f)) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
175 return e; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
176 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
177 } |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
178 return null; |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
179 } |
635
4ec2d44e2bf3
Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
621
diff
changeset
|
180 |
617
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
181 private static class RollbackEntry { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
182 public final File origin; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
183 public final File backup; // may be null to indicate file didn't exist |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
184 public boolean success = false; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
185 public IOException failure = null; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
186 public boolean keepBackup = false; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
187 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
188 public RollbackEntry(File o, File b) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
189 origin = o; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
190 backup = b; |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
191 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
192 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
193 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
194 public static class Factory implements Transaction.Factory { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
195 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
196 public Transaction create(SessionContext.Source ctxSource) { |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
197 return new COWTransaction(ctxSource); |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
198 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
199 |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
200 } |
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
201 } |