annotate src/org/tmatesoft/hg/core/HgMergeCommand.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 4ffc17c0b534
children
rev   line source
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2013 TMate Software Ltd
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.core;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
19 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
20
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
21 import java.io.File;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
22 import java.io.FileInputStream;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
23 import java.io.IOException;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
24 import java.io.InputStream;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
25
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
26 import org.tmatesoft.hg.internal.Callback;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
27 import org.tmatesoft.hg.internal.CsetParamKeeper;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
28 import org.tmatesoft.hg.internal.DirstateBuilder;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
29 import org.tmatesoft.hg.internal.DirstateReader;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
30 import org.tmatesoft.hg.internal.Experimental;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
31 import org.tmatesoft.hg.internal.FileUtils;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
32 import org.tmatesoft.hg.internal.Internals;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
33 import org.tmatesoft.hg.internal.ManifestRevision;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
34 import org.tmatesoft.hg.internal.MergeStateBuilder;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
35 import org.tmatesoft.hg.internal.Pool;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
36 import org.tmatesoft.hg.internal.Transaction;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
37 import org.tmatesoft.hg.internal.WorkingDirFileWriter;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38 import org.tmatesoft.hg.repo.HgChangelog;
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
39 import org.tmatesoft.hg.repo.HgManifest;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40 import org.tmatesoft.hg.repo.HgParentChildMap;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41 import org.tmatesoft.hg.repo.HgRepository;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 import org.tmatesoft.hg.repo.HgRepositoryLock;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 import org.tmatesoft.hg.repo.HgRevisionMap;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
44 import org.tmatesoft.hg.repo.HgRuntimeException;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
45 import org.tmatesoft.hg.util.CancelledException;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46 import org.tmatesoft.hg.util.Path;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
47
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48 /**
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
49 * Merge two revisions, 'hg merge REV' counterpart
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
50 *
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
51 * @author Artem Tikhomirov
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
52 * @author TMate Software Ltd.
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
53 * @since 1.2
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
54 */
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
55 @Experimental(reason="Provisional API. Work in progress")
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 public class HgMergeCommand extends HgAbstractCommand<HgMergeCommand> {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
58 private final HgRepository repo;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
59 private int firstCset, secondCset, ancestorCset;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
60
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 public HgMergeCommand(HgRepository hgRepo) {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62 repo = hgRepo;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
63 firstCset = secondCset = ancestorCset = BAD_REVISION;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
64 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
65
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
66 public HgMergeCommand changeset(Nodeid changeset) throws HgBadArgumentException {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
67 initHeadsAndAncestor(new CsetParamKeeper(repo).set(changeset).get());
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
68 return this;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
69 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
70
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
71 public HgMergeCommand changeset(int revisionIndex) throws HgBadArgumentException {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
72 initHeadsAndAncestor(new CsetParamKeeper(repo).set(revisionIndex).get());
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
73 return this;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
74 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
75
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
76 public void execute(Mediator mediator) throws HgCallbackTargetException, HgRepositoryLockException, HgIOException, HgLibraryFailureException, CancelledException {
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
77 if (firstCset == BAD_REVISION || secondCset == BAD_REVISION || ancestorCset == BAD_REVISION) {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
78 throw new IllegalArgumentException("Merge heads and their ancestors are not initialized");
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
79 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
80 final HgRepositoryLock wdLock = repo.getWorkingDirLock();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
81 wdLock.acquire();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
82 try {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
83 Pool<Nodeid> cacheRevs = new Pool<Nodeid>();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84 Pool<Path> cacheFiles = new Pool<Path>();
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
85
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
86 Internals implRepo = Internals.getInstance(repo);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
87 final DirstateBuilder dirstateBuilder = new DirstateBuilder(implRepo);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
88 dirstateBuilder.fillFrom(new DirstateReader(implRepo, new Path.SimpleSource(repo.getSessionContext().getPathFactory(), cacheFiles)));
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
89 final HgChangelog clog = repo.getChangelog();
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
90 final Nodeid headCset1 = clog.getRevision(firstCset);
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
91 dirstateBuilder.parents(headCset1, clog.getRevision(secondCset));
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
92 //
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
93 MergeStateBuilder mergeStateBuilder = new MergeStateBuilder(implRepo);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
94 mergeStateBuilder.prepare(headCset1);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
95
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
96 ManifestRevision m1, m2, ma;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
97 m1 = new ManifestRevision(cacheRevs, cacheFiles).init(repo, firstCset);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
98 m2 = new ManifestRevision(cacheRevs, cacheFiles).init(repo, secondCset);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
99 ma = new ManifestRevision(cacheRevs, cacheFiles).init(repo, ancestorCset);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
100 Transaction transaction = implRepo.getTransactionFactory().create(repo);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
101 ResolverImpl resolver = new ResolverImpl(implRepo, dirstateBuilder, mergeStateBuilder);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
102 try {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
103 for (Path f : m1.files()) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
104 Nodeid fileRevBase, fileRevA, fileRevB;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
105 if (m2.contains(f)) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
106 fileRevA = m1.nodeid(f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
107 fileRevB = m2.nodeid(f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
108 fileRevBase = ma.contains(f) ? ma.nodeid(f) : null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
109 if (fileRevA.equals(fileRevB)) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
110 HgFileRevision fr = new HgFileRevision(repo, fileRevA, m1.flags(f), f);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
111 resolver.presentState(f, fr, fr, null);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
112 mediator.same(fr, resolver);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
113 } else if (fileRevBase == fileRevA) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
114 assert fileRevBase != null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
115 HgFileRevision frBase = new HgFileRevision(repo, fileRevBase, ma.flags(f), f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
116 HgFileRevision frSecond= new HgFileRevision(repo, fileRevB, m2.flags(f), f);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
117 resolver.presentState(f, frBase, frSecond, frBase);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
118 mediator.fastForwardB(frBase, frSecond, resolver);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
119 } else if (fileRevBase == fileRevB) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
120 assert fileRevBase != null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
121 HgFileRevision frBase = new HgFileRevision(repo, fileRevBase, ma.flags(f), f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
122 HgFileRevision frFirst = new HgFileRevision(repo, fileRevA, m1.flags(f), f);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
123 resolver.presentState(f, frFirst, frBase, frBase);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
124 mediator.fastForwardA(frBase, frFirst, resolver);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
125 } else {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
126 HgFileRevision frBase = fileRevBase == null ? null : new HgFileRevision(repo, fileRevBase, ma.flags(f), f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
127 HgFileRevision frFirst = new HgFileRevision(repo, fileRevA, m1.flags(f), f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
128 HgFileRevision frSecond= new HgFileRevision(repo, fileRevB, m2.flags(f), f);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
129 resolver.presentState(f, frFirst, frSecond, frBase);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
130 mediator.resolve(frBase, frFirst, frSecond, resolver);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
131 }
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
132 } else {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
133 // m2 doesn't contain the file, either new in m1, or deleted in m2
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
134 HgFileRevision frFirst = new HgFileRevision(repo, m1.nodeid(f), m1.flags(f), f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
135 if (ma.contains(f)) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
136 // deleted in m2
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
137 HgFileRevision frBase = new HgFileRevision(repo, ma.nodeid(f), ma.flags(f), f);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
138 resolver.presentState(f, frFirst, null, frBase);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
139 mediator.onlyA(frBase, frFirst, resolver);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
140 } else {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
141 // new in m1
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
142 resolver.presentState(f, frFirst, null, null);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
143 mediator.newInA(frFirst, resolver);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
144 }
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
145 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
146 resolver.apply();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
147 } // for m1 files
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
148 for (Path f : m2.files()) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
149 if (m1.contains(f)) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
150 continue;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
151 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
152 HgFileRevision frSecond= new HgFileRevision(repo, m2.nodeid(f), m2.flags(f), f);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
153 // file in m2 is either new or deleted in m1
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
154 if (ma.contains(f)) {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
155 // deleted in m1
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
156 HgFileRevision frBase = new HgFileRevision(repo, ma.nodeid(f), ma.flags(f), f);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
157 resolver.presentState(f, null, frSecond, frBase);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
158 mediator.onlyB(frBase, frSecond, resolver);
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
159 } else {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
160 // new in m2
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
161 resolver.presentState(f, null, frSecond, null);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
162 mediator.newInB(frSecond, resolver);
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
163 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
164 resolver.apply();
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
165 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
166 resolver.serializeChanged(transaction);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
167 transaction.commit();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
168 } catch (HgRuntimeException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
169 transaction.rollback();
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
170 mergeStateBuilder.abandon();
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
171 throw ex;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
172 } catch (HgIOException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
173 transaction.rollback();
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
174 mergeStateBuilder.abandon();
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
175 throw ex;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
176 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
177 } catch (HgRuntimeException ex) {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
178 throw new HgLibraryFailureException(ex);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
179 } finally {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
180 wdLock.release();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
181 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
182 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
183
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
184 private void initHeadsAndAncestor(int csetIndexB) throws HgBadArgumentException {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
185 firstCset = secondCset = ancestorCset = BAD_REVISION;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
186 if (csetIndexB == HgRepository.BAD_REVISION) {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
187 throw new HgBadArgumentException("Need valid second head for merge", null);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
188 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
189 // TODO cache/share parent-child map, e.g. right in HgChangelog?! #getOrCreate
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
190 HgParentChildMap<HgChangelog> pmap = new HgParentChildMap<HgChangelog>(repo.getChangelog());
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
191 pmap.init();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
192 final HgRevisionMap<HgChangelog> rmap = pmap.getRevisionMap();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
193 final Nodeid csetA = repo.getWorkingCopyParents().first();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
194 final Nodeid csetB = rmap.revision(csetIndexB);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
195 final Nodeid ancestor = pmap.ancestor(csetA, csetB);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
196 assert !ancestor.isNull();
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
197 if (ancestor.equals(csetA) || ancestor.equals(csetB)) {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
198 throw new HgBadArgumentException(String.format("Revisions %s and %s are on the same line of descent, use update instead of merge", csetA.shortNotation(), csetB.shortNotation()), null);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
199 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
200 firstCset = rmap.revisionIndex(csetA);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
201 secondCset = csetIndexB;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
202 ancestorCset = rmap.revisionIndex(ancestor);
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
203 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
204
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
205 /**
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
206 * This is the way client code takes part in the merge process.
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
207 * It's advised to subclass {@link MediatorBase} unless special treatment for regular cases is desired
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
208 */
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
209 @Experimental(reason="Provisional API. Work in progress")
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
210 @Callback
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
211 public interface Mediator {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
212 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
213 * file revisions are identical in both heads
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
214 */
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
215 public void same(HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
216 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
217 * file left in first/left/A trunk only, deleted in second/right/B trunk
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
218 */
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
219 public void onlyA(HgFileRevision base, HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
220 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
221 * file left in second/right/B trunk only, deleted in first/left/A trunk
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
222 */
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
223 public void onlyB(HgFileRevision base, HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
224 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
225 * file is missing in ancestor revision and second/right/B trunk, introduced in first/left/A trunk
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
226 */
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
227 public void newInA(HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
228 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
229 * file is missing in ancestor revision and first/left/A trunk, introduced in second/right/B trunk
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
230 */
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
231 public void newInB(HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
232 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
233 * file was changed in first/left/A trunk, unchanged in second/right/B trunk
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
234 */
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
235 public void fastForwardA(HgFileRevision base, HgFileRevision first, Resolver resolver) throws HgCallbackTargetException;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
236 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
237 * file was changed in second/right/B trunk, unchanged in first/left/A trunk
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
238 */
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
239 public void fastForwardB(HgFileRevision base, HgFileRevision second, Resolver resolver) throws HgCallbackTargetException;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
240 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
241 * File changed (or added, if base is <code>null</code>) in both trunks
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
242 */
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
243 public void resolve(HgFileRevision base, HgFileRevision first, HgFileRevision second, Resolver resolver) throws HgCallbackTargetException;
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
244 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
245
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
246 /**
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
247 * Clients shall not implement this interface.
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
248 * They use this API from inside {@link Mediator#resolve(HgFileRevision, HgFileRevision, HgFileRevision, Resolver)}
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
249 */
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
250 @Experimental(reason="Provisional API. Work in progress")
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
251 public interface Resolver {
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
252 public void use(HgFileRevision rev);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
253 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
254 * Replace current revision with stream content.
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
255 * Note, callers are not expected to {@link InputStream#close()} this stream.
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
256 * It will be {@link InputStream#close() closed} at <b>Hg4J</b>'s discretion
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
257 * not necessarily during invocation of this method. IOW, the library may decide to
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
258 * use this stream not right away, at some point of time later, and streams supplied
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
259 * shall respect this.
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
260 *
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
261 * @param content New content to replace current revision, shall not be <code>null</code>
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
262 * @throws IOException propagated exceptions from content
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
263 */
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
264 public void use(InputStream content) throws IOException;
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
265 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
266 * Do not use this file for resolution. Marks the file for deletion, if appropriate.
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
267 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
268 public void forget(HgFileRevision rev);
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
269 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
270 * Record the file for later processing by 'hg resolve'. It's required
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
271 * that processed file present in both trunks. We need two file revisions
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
272 * to put an entry into merge/state file.
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
273 *
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
274 * XXX Perhaps, shall take two HgFileRevision arguments to facilitate
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
275 * extra control over what goes into merge/state and to ensure this method
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
276 * is not invoked when there are no conflicting revisions.
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
277 */
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
278 public void unresolved();
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
279 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
280
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
281 /**
708
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
282 * Base mediator implementation, with regular resolution (and "don't delete anything" approach in mind).
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
283 * Subclasses shall override methods to provide alternative implementation or to add extra logic (e.g. ask user).
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
284 */
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
285 @Experimental(reason="Provisional API. Work in progress")
708
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
286 public static class MediatorBase implements Mediator {
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
287 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
288 * Implementation keeps this revision
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
289 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
290 public void same(HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
291 resolver.use(rev);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
292 }
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
293 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
294 * Implementation keeps file revision from first/left/A trunk.
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
295 * Subclasses may opt to {@link Resolver#forget(HgFileRevision) delete} it as it's done in second/right/B trunk.
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
296 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
297 public void onlyA(HgFileRevision base, HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
298 resolver.use(rev);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
299 }
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
300 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
301 * Implementation restores file from second/right/B trunk.
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
302 * Subclasses may ask user to decide if it's necessary to do that
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
303 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
304 public void onlyB(HgFileRevision base, HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
305 resolver.use(rev);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
306 }
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
307 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
308 * Implementation keeps this revision
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
309 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
310 public void newInA(HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
311 resolver.use(rev);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
312 }
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
313 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
314 * Implementation adds this revision. Subclasses my let user decide if it's necessary to add the file
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
315 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
316 public void newInB(HgFileRevision rev, Resolver resolver) throws HgCallbackTargetException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
317 resolver.use(rev);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
318 }
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
319 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
320 * Implementation keeps latest revision
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
321 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
322 public void fastForwardA(HgFileRevision base, HgFileRevision first, Resolver resolver) throws HgCallbackTargetException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
323 resolver.use(first);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
324 }
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
325 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
326 * Implementation keeps latest revision
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
327 */
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
328 public void fastForwardB(HgFileRevision base, HgFileRevision second, Resolver resolver) throws HgCallbackTargetException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
329 resolver.use(second);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
330 }
708
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
331
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
332 /**
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
333 * Implementation marks file as unresolved
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
334 */
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
335 public void resolve(HgFileRevision base, HgFileRevision first, HgFileRevision second, Resolver resolver) throws HgCallbackTargetException {
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
336 resolver.unresolved();
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 707
diff changeset
337 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
338 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
339
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
340 private static class ResolverImpl implements Resolver {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
341
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
342 private final Internals repo;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
343 private final DirstateBuilder dirstateBuilder;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
344 private final MergeStateBuilder mergeStateBuilder;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
345 private boolean changedDirstate;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
346 private HgFileRevision revA;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
347 private HgFileRevision revB;
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
348 private HgFileRevision revBase;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
349 private Path file;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
350 // resolutions:
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
351 private HgFileRevision resolveUse, resolveForget;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
352 private File resolveContent;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
353 private boolean resolveMarkUnresolved;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
354
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
355 public ResolverImpl(Internals implRepo, DirstateBuilder dirstateBuilder, MergeStateBuilder mergeStateBuilder) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
356 repo = implRepo;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
357 this.dirstateBuilder = dirstateBuilder;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
358 this.mergeStateBuilder = mergeStateBuilder;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
359 changedDirstate = false;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
360 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
361
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
362 void serializeChanged(Transaction tr) throws HgIOException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
363 if (changedDirstate) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
364 dirstateBuilder.serialize(tr);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
365 }
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
366 mergeStateBuilder.serialize();
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
367 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
368
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
369 void presentState(Path p, HgFileRevision revA, HgFileRevision revB, HgFileRevision base) {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
370 assert revA != null || revB != null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
371 file = p;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
372 this.revA = revA;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
373 this.revB = revB;
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
374 revBase = base;
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
375 resolveUse = resolveForget = null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
376 resolveContent = null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
377 resolveMarkUnresolved = false;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
378 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
379
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
380 void apply() throws HgIOException, HgRuntimeException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
381 if (resolveMarkUnresolved) {
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
382 HgFileRevision c = revBase;
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
383 if (revBase == null) {
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
384 // fake revision, null parent
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
385 c = new HgFileRevision(repo.getRepo(), Nodeid.NULL, HgManifest.Flags.RegularFile, file);
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
386 }
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
387 mergeStateBuilder.unresolved(file, revA, revB, c, revA.getFileFlags());
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
388 changedDirstate = true;
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
389 dirstateBuilder.recordMergedExisting(file, revA.getPath());
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
390 } else if (resolveForget != null) {
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
391 // it revision to forget comes from second/B trunk, shall record it as removed
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
392 // only when corresponding file in first/A trunk is missing (merge:_forgetremoved())
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
393 if (resolveForget == revA || (resolveForget == revB && revA == null)) {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
394 changedDirstate = true;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
395 dirstateBuilder.recordRemoved(file);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
396 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
397 } else if (resolveUse != null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
398 if (resolveUse != revA) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
399 changedDirstate = true;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
400 final WorkingDirFileWriter fw = new WorkingDirFileWriter(repo);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
401 fw.processFile(resolveUse);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
402 if (resolveUse == revB) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
403 dirstateBuilder.recordMergedFromP2(file);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
404 } else {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
405 dirstateBuilder.recordMerged(file, fw.fmode(), fw.mtime(), fw.bytesWritten());
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
406 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
407 } // if resolution is to use revA, nothing to do
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
408 } else if (resolveContent != null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
409 changedDirstate = true;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
410 // FIXME write content to file using transaction?
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
411 InputStream is;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
412 try {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
413 is = new FileInputStream(resolveContent);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
414 } catch (IOException ex) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
415 throw new HgIOException("Failed to read temporary content", ex, resolveContent);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
416 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
417 final WorkingDirFileWriter fw = new WorkingDirFileWriter(repo);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
418 fw.processFile(file, is, revA == null ? revB.getFileFlags() : revA.getFileFlags());
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
419 // XXX if presentState(null, fileOnlyInB), and use(InputStream) - i.e.
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
420 // resolution is to add file with supplied content - shall I put 'Merged', MergedFromP2 or 'Added' into dirstate?
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
421 if (revA == null && revB != null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
422 dirstateBuilder.recordMergedFromP2(file);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
423 } else {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
424 dirstateBuilder.recordMerged(file, fw.fmode(), fw.mtime(), fw.bytesWritten());
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
425 }
706
cd5c87d96315 Merge: tests for mediator notifications
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
426 } // else no resolution was chosen, fine with that
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
427 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
428
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
429 public void use(HgFileRevision rev) {
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
430 if (rev == null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
431 throw new IllegalArgumentException();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
432 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
433 assert resolveContent == null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
434 assert resolveForget == null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
435 resolveUse = rev;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
436 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
437
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
438 public void use(InputStream content) throws IOException {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
439 if (content == null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
440 throw new IllegalArgumentException();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
441 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
442 assert resolveUse == null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
443 assert resolveForget == null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
444 try {
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
445 resolveContent = FileUtils.createTempFile();
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
446 new FileUtils(repo.getLog(), this).write(content, resolveContent);
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
447 } finally {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
448 content.close();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
449 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
450 // do not care deleting file in case of failure to allow analyze of the issue
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
451 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
452
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
453 public void forget(HgFileRevision rev) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
454 if (rev == null) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
455 throw new IllegalArgumentException();
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
456 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
457 if (rev != revA || rev != revB) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
458 throw new IllegalArgumentException("Can't forget revision which doesn't represent actual state in either merged trunk");
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
459 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
460 assert resolveUse == null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
461 assert resolveContent == null;
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
462 resolveForget = rev;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
463 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
464
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
465 public void unresolved() {
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
466 if (revA == null || revB == null) {
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
467 throw new UnsupportedOperationException("To mark conflict as unresolved need two revisions");
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 706
diff changeset
468 }
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 704
diff changeset
469 resolveMarkUnresolved = true;
704
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
470 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
471 }
7743a9c10bfa Merge command introduced
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
472 }