annotate src/org/tmatesoft/hg/core/HgMergeCommand.java @ 708:4ffc17c0b534

Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 20 Aug 2013 18:41:34 +0200
parents 42b88709e41d
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 }