Mercurial > jhg
comparison src/org/tmatesoft/hg/core/HgRevertCommand.java @ 526:2f9ed6bcefa2
Initial support for Revert command with accompanying minor refactoring
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Tue, 15 Jan 2013 17:07:19 +0100 |
| parents | |
| children | 78a9e26e670d |
comparison
equal
deleted
inserted
replaced
| 525:0be5be8d57e9 | 526:2f9ed6bcefa2 |
|---|---|
| 1 /* | |
| 2 * Copyright (c) 2013 TMate Software Ltd | |
| 3 * | |
| 4 * This program is free software; you can redistribute it and/or modify | |
| 5 * it under the terms of the GNU General Public License as published by | |
| 6 * the Free Software Foundation; version 2 of the License. | |
| 7 * | |
| 8 * This program is distributed in the hope that it will be useful, | |
| 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 11 * GNU General Public License for more details. | |
| 12 * | |
| 13 * For information on how to redistribute this software under | |
| 14 * the terms of a license other than GNU General Public License | |
| 15 * contact TMate Software at support@hg4j.com | |
| 16 */ | |
| 17 package org.tmatesoft.hg.core; | |
| 18 | |
| 19 import java.io.File; | |
| 20 import java.util.Arrays; | |
| 21 import java.util.LinkedHashSet; | |
| 22 import java.util.Set; | |
| 23 | |
| 24 import org.tmatesoft.hg.internal.DirstateBuilder; | |
| 25 import org.tmatesoft.hg.internal.DirstateReader; | |
| 26 import org.tmatesoft.hg.internal.Experimental; | |
| 27 import org.tmatesoft.hg.internal.Internals; | |
| 28 import org.tmatesoft.hg.repo.HgInvalidRevisionException; | |
| 29 import org.tmatesoft.hg.repo.HgManifest; | |
| 30 import org.tmatesoft.hg.repo.HgRepository; | |
| 31 import org.tmatesoft.hg.repo.HgRuntimeException; | |
| 32 import org.tmatesoft.hg.repo.HgManifest.Flags; | |
| 33 import org.tmatesoft.hg.util.CancelledException; | |
| 34 import org.tmatesoft.hg.util.Path; | |
| 35 | |
| 36 /** | |
| 37 * WORK IN PROGRESS. | |
| 38 * | |
| 39 * Restore files to their checkout state, 'hg revert' counterpart. | |
| 40 * | |
| 41 * @author Artem Tikhomirov | |
| 42 * @author TMate Software Ltd. | |
| 43 */ | |
| 44 @Experimental(reason="Work in progress") | |
| 45 public class HgRevertCommand extends HgAbstractCommand<HgRevertCommand> { | |
| 46 | |
| 47 private final HgRepository repo; | |
| 48 private final Set<Path> files = new LinkedHashSet<Path>(); | |
| 49 private int changesetToCheckout = HgRepository.WORKING_COPY; // XXX WORKING_COPY_PARENT, in fact | |
| 50 private boolean keepOriginal = true; | |
| 51 | |
| 52 public HgRevertCommand(HgRepository hgRepo) { | |
| 53 repo = hgRepo; | |
| 54 } | |
| 55 | |
| 56 /** | |
| 57 * Additive | |
| 58 * | |
| 59 * @param paths files to revert | |
| 60 * @return <code>this</code> for convenience | |
| 61 */ | |
| 62 public HgRevertCommand file(Path... paths) { | |
| 63 files.addAll(Arrays.asList(paths)); | |
| 64 return this; | |
| 65 } | |
| 66 | |
| 67 /** | |
| 68 * Revert the given files to their states as of a specific revision | |
| 69 * | |
| 70 * @param changesetRevIndex | |
| 71 * @return <code>this</code> for convenience | |
| 72 * @throws HgBadArgumentException | |
| 73 */ | |
| 74 public HgRevertCommand changeset(int changesetRevIndex) throws HgBadArgumentException { | |
| 75 int lastCsetIndex = repo.getChangelog().getLastRevision(); | |
| 76 if (changesetRevIndex < 0 || changesetRevIndex > lastCsetIndex) { | |
| 77 throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changesetRevIndex, lastCsetIndex), null).setRevisionIndex(changesetRevIndex); | |
| 78 } | |
| 79 changesetToCheckout = changesetRevIndex; | |
| 80 return this; | |
| 81 } | |
| 82 | |
| 83 /** | |
| 84 * Handy supplement to {@link #changeset(int)} | |
| 85 * | |
| 86 * @param revision | |
| 87 * @return <code>this</code> for convenience | |
| 88 * @throws HgBadArgumentException | |
| 89 */ | |
| 90 public HgRevertCommand changeset(Nodeid revision) throws HgBadArgumentException { | |
| 91 try { | |
| 92 return changeset(repo.getChangelog().getRevisionIndex(revision)); | |
| 93 } catch (HgInvalidRevisionException ex) { | |
| 94 throw new HgBadArgumentException("Can't find revision", ex).setRevision(revision); | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 // TODO keepOriginal() to save .orig | |
| 99 | |
| 100 /** | |
| 101 * Perform the back out for the given files | |
| 102 * | |
| 103 * @throws HgIOException | |
| 104 * @throws HgException | |
| 105 * @throws CancelledException | |
| 106 */ | |
| 107 public void execute() throws HgException, CancelledException { | |
| 108 try { | |
| 109 final int csetRevision; | |
| 110 if (changesetToCheckout == HgRepository.WORKING_COPY) { | |
| 111 csetRevision = repo.getChangelog().getRevisionIndex(repo.getWorkingCopyParents().first()); | |
| 112 } else { | |
| 113 csetRevision = changesetToCheckout; | |
| 114 } | |
| 115 Internals implRepo = Internals.getInstance(repo); | |
| 116 final DirstateBuilder dirstateBuilder = new DirstateBuilder(implRepo); | |
| 117 dirstateBuilder.fillFrom(new DirstateReader(implRepo, new Path.SimpleSource())); | |
| 118 final HgCheckoutCommand.CheckoutWorker worker = new HgCheckoutCommand.CheckoutWorker(implRepo); | |
| 119 | |
| 120 HgManifest.Inspector insp = new HgManifest.Inspector() { | |
| 121 | |
| 122 public boolean next(Nodeid nid, Path fname, Flags flags) { | |
| 123 if (worker.next(nid, fname, flags)) { | |
| 124 dirstateBuilder.recordUncertain(fname); | |
| 125 return true; | |
| 126 } | |
| 127 return false; | |
| 128 } | |
| 129 | |
| 130 public boolean end(int manifestRevision) { | |
| 131 return false; | |
| 132 } | |
| 133 | |
| 134 public boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision) { | |
| 135 return true; | |
| 136 } | |
| 137 }; | |
| 138 | |
| 139 for (Path file : files) { | |
| 140 File f = new File(repo.getWorkingDir(), file.toString()); | |
| 141 if (f.isFile()) { | |
| 142 if (keepOriginal) { | |
| 143 File copy = new File(f.getParentFile(), f.getName() + ".orig"); | |
| 144 if (copy.exists()) { | |
| 145 copy.delete(); | |
| 146 } | |
| 147 f.renameTo(copy); | |
| 148 } else { | |
| 149 f.delete(); | |
| 150 } | |
| 151 } | |
| 152 repo.getManifest().walkFileRevisions(file, insp, csetRevision); | |
| 153 worker.checkFailed(); | |
| 154 } | |
| 155 dirstateBuilder.serialize(); | |
| 156 } catch (HgRuntimeException ex) { | |
| 157 throw new HgLibraryFailureException(ex); | |
| 158 } | |
| 159 } | |
| 160 } |
