annotate src/org/tmatesoft/hg/internal/COWTransaction.java @ 664:ae2d439fbed3

Utilize transaction when writing fncache. Better HgIOException
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 10 Jul 2013 19:33:51 +0200
parents 12a4f60ea972
children dde18bc7053b
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;
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
27
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 * 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
30 * 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
31 *
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 * 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
33 * 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
34 *
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 * @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
36 * @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
37 */
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 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
39
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 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
41 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
42
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 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
44 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
45 }
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 @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
48 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
49 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
50 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
51 }
635
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
52 if (!f.exists()) {
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
53 return recordNonExistent(f);
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
54 }
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
55 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
56 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
57 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
58 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
59 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
60 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
61 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
62 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
63 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
64 }
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 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
66 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
67 }
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 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
69 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
70 }
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 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
72 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
73 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
74 }
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 @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
77 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
78 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
79 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
80 }
635
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
81 if (!origin.exists()) {
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
82 return recordNonExistent(origin);
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
83 }
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
84 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
85 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
86 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
87 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
88 }
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 @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
91 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
92 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
93 }
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 @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
96 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
97 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
98 }
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 // 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
101
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 @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
103 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
104 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
105 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
106 assert e.success;
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
107 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
108 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
109 }
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.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
111 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
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 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
114 }
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
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 @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
118 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
119 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
120 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
121 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
122 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
123 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
124 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
125 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
126 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
127 }
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
128 // 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
129 // 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
130 // 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
131 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
132 }
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
133 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
134 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
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 }
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
635
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
138 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
139 record(f, null);
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
140 try {
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
141 f.getParentFile().mkdirs();
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
142 f.createNewFile();
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
143 return f;
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
144 } catch (IOException ex) {
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
145 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
146 }
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
147 }
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
148
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
149 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
150 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
151 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
152 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
153 }
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
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 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
156 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
157 return e != null;
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
158 }
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
159
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
160 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
161 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
162 if (e != null) {
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
163 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
164 }
635
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
165 assert false;
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
166 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
167 }
635
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
168
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
169 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
170 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
171 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
172 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
173 }
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 }
635
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
175 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
176 }
635
4ec2d44e2bf3 Compound test scenario for checkout, add, remove, revert and commit
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 621
diff changeset
177
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
178 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
179 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
180 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
181 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
182 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
183 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
184
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 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
186 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
187 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
188 }
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 }
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
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 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
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 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
194 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
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
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 }
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 }