@Test public void testAbbreviateOnEmptyRepository() throws IOException { ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba"); assertEquals(id.abbreviate(2), reader.abbreviate(id, 2)); assertEquals(id.abbreviate(7), reader.abbreviate(id, 7)); assertEquals(id.abbreviate(8), reader.abbreviate(id, 8)); assertEquals(id.abbreviate(10), reader.abbreviate(id, 10)); assertEquals(id.abbreviate(16), reader.abbreviate(id, 16)); assertEquals( AbbreviatedObjectId.fromObjectId(id), // reader.abbreviate(id, OBJECT_ID_STRING_LENGTH)); Collection<ObjectId> matches; matches = reader.resolve(reader.abbreviate(id, 8)); assertNotNull(matches); assertEquals(0, matches.size()); matches = reader.resolve(AbbreviatedObjectId.fromObjectId(id)); assertNotNull(matches); assertEquals(1, matches.size()); assertEquals(id, matches.iterator().next()); }
@Test public void testAbbreviateIsActuallyUnique() throws Exception { // This test is far more difficult. We have to manually craft // an input that contains collisions at a particular prefix, // but this is computationally difficult. Instead we force an // index file to have what we want. // ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba"); byte[] idBuf = toByteArray(id); List<PackedObjectInfo> objects = new ArrayList<PackedObjectInfo>(); for (int i = 0; i < 256; i++) { idBuf[9] = (byte) i; objects.add(new PackedObjectInfo(ObjectId.fromRaw(idBuf))); } String packName = "pack-" + id.name(); File packDir = new File(db.getObjectDatabase().getDirectory(), "pack"); File idxFile = new File(packDir, packName + ".idx"); File packFile = new File(packDir, packName + ".pack"); FileUtils.mkdir(packDir, true); OutputStream dst = new SafeBufferedOutputStream(new FileOutputStream(idxFile)); try { PackIndexWriter writer = new PackIndexWriterV2(dst); writer.write(objects, new byte[OBJECT_ID_LENGTH]); } finally { dst.close(); } new FileOutputStream(packFile).close(); assertEquals(id.abbreviate(20), reader.abbreviate(id, 2)); AbbreviatedObjectId abbrev8 = id.abbreviate(8); Collection<ObjectId> matches = reader.resolve(abbrev8); assertNotNull(matches); assertEquals(objects.size(), matches.size()); for (PackedObjectInfo info : objects) assertTrue("contains " + info.name(), matches.contains(info)); try { db.resolve(abbrev8.name()); fail("did not throw AmbiguousObjectException"); } catch (AmbiguousObjectException err) { assertEquals(abbrev8, err.getAbbreviatedObjectId()); matches = err.getCandidates(); assertNotNull(matches); assertEquals(objects.size(), matches.size()); for (PackedObjectInfo info : objects) assertTrue("contains " + info.name(), matches.contains(info)); } assertEquals(id, db.resolve(id.abbreviate(20).name())); }
@Test public void testAbbreviateLooseBlob() throws Exception { ObjectId id = test.blob("test"); assertEquals(id.abbreviate(2), reader.abbreviate(id, 2)); assertEquals(id.abbreviate(7), reader.abbreviate(id, 7)); assertEquals(id.abbreviate(8), reader.abbreviate(id, 8)); assertEquals(id.abbreviate(10), reader.abbreviate(id, 10)); assertEquals(id.abbreviate(16), reader.abbreviate(id, 16)); Collection<ObjectId> matches = reader.resolve(reader.abbreviate(id, 8)); assertNotNull(matches); assertEquals(1, matches.size()); assertEquals(id, matches.iterator().next()); assertEquals(id, db.resolve(reader.abbreviate(id, 8).name())); }
/** * Adds properties to the specified {@code transformer} for the current Git commit hash. The * following properties are added to {@code transformer}: * * <ul> * <li>{@code repository.commit}: The full commit hash, in lowercase hexadecimal form. * <li>{@code repository.commit.short}: The abbreviated commit hash, which is the first {@code * abbrevLen} hexadecimal characters of the full commit hash. * </ul> * * <p>If {@code baseDir} is not currently stored in a Git repository, or if the current Git commit * hash could not be determined, this method logs a warning and returns {@code false}. * * @param transformer The transformer. * @param baseDir The base directory where versioned files are contained. * @param abbrevLen The length of the abbreviated commit hash to create, in number of hexadecimal * characters. * @param log The Maven log instance. * @return {@code true} if the commit hash was identified and the properties added to the {@code * transformer}; otherwise, {@code false}. */ public static boolean addCommitProperties( Transformer transformer, File baseDir, int abbrevLen, Log log) { try { RepositoryBuilder builder = new RepositoryBuilder(); Repository repository = builder.findGitDir(baseDir).readEnvironment().build(); ObjectId objectId = repository.resolve(Constants.HEAD); if (objectId != null) { transformer.setParameter("repository.commit", objectId.getName()); transformer.setParameter("repository.commit.short", objectId.abbreviate(abbrevLen).name()); return true; } else { log.warn("Could not determine current repository commit hash."); return false; } } catch (IOException ex) { log.warn("Could not determine current repository commit hash.", ex); return false; } }
@Override protected void run() throws Exception { if (squash && ff == FastForwardMode.NO_FF) throw die(CLIText.get().cannotCombineSquashWithNoff); // determine the merge strategy if (strategyName != null) { mergeStrategy = MergeStrategy.get(strategyName); if (mergeStrategy == null) throw die(MessageFormat.format(CLIText.get().unknownMergeStrategy, strategyName)); } // determine the other revision we want to merge with HEAD final Ref srcRef = db.getRef(ref); final ObjectId src = db.resolve(ref + "^{commit}"); // $NON-NLS-1$ if (src == null) throw die(MessageFormat.format(CLIText.get().refDoesNotExistOrNoCommit, ref)); Ref oldHead = db.getRef(Constants.HEAD); Git git = new Git(db); MergeCommand mergeCmd = git.merge() .setStrategy(mergeStrategy) .setSquash(squash) .setFastForward(ff) .setCommit(!noCommit); if (srcRef != null) mergeCmd.include(srcRef); else mergeCmd.include(src); MergeResult result; try { result = mergeCmd.call(); } catch (CheckoutConflictException e) { result = new MergeResult(e.getConflictingPaths()); // CHECKOUT_CONFLICT } switch (result.getMergeStatus()) { case ALREADY_UP_TO_DATE: if (squash) outw.print(CLIText.get().nothingToSquash); outw.println(CLIText.get().alreadyUpToDate); break; case FAST_FORWARD: ObjectId oldHeadId = oldHead.getObjectId(); outw.println( MessageFormat.format( CLIText.get().updating, oldHeadId.abbreviate(7).name(), result.getNewHead().abbreviate(7).name())); outw.println(result.getMergeStatus().toString()); break; case CHECKOUT_CONFLICT: outw.println(CLIText.get().mergeCheckoutConflict); for (String collidingPath : result.getCheckoutConflicts()) outw.println("\t" + collidingPath); // $NON-NLS-1$ outw.println(CLIText.get().mergeCheckoutFailed); break; case CONFLICTING: for (String collidingPath : result.getConflicts().keySet()) outw.println(MessageFormat.format(CLIText.get().mergeConflict, collidingPath)); outw.println(CLIText.get().mergeFailed); break; case FAILED: for (Map.Entry<String, MergeFailureReason> entry : result.getFailingPaths().entrySet()) switch (entry.getValue()) { case DIRTY_WORKTREE: case DIRTY_INDEX: outw.println(CLIText.get().dontOverwriteLocalChanges); outw.println(" " + entry.getKey()); // $NON-NLS-1$ break; case COULD_NOT_DELETE: outw.println(CLIText.get().cannotDeleteFile); outw.println(" " + entry.getKey()); // $NON-NLS-1$ break; } break; case MERGED: String name; if (!isMergedInto(oldHead, src)) name = mergeStrategy.getName(); else name = "recursive"; // $NON-NLS-1$ outw.println(MessageFormat.format(CLIText.get().mergeMadeBy, name)); break; case MERGED_NOT_COMMITTED: outw.println(CLIText.get().mergeWentWellStoppedBeforeCommitting); break; case MERGED_SQUASHED: case FAST_FORWARD_SQUASHED: case MERGED_SQUASHED_NOT_COMMITTED: outw.println(CLIText.get().mergedSquashed); outw.println(CLIText.get().mergeWentWellStoppedBeforeCommitting); break; case ABORTED: throw die(CLIText.get().ffNotPossibleAborting); case NOT_SUPPORTED: outw.println(MessageFormat.format(CLIText.get().unsupportedOperation, result.toString())); } }