// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.acceptance.server.change;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.pushHead;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestSession;
import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.change.GetRelated.ChangeAndCommit;
import com.google.gerrit.server.change.GetRelated.RelatedInfo;
import com.google.gerrit.server.edit.ChangeEditModifier;
import com.google.gerrit.server.edit.ChangeEditUtil;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class GetRelatedIT extends AbstractDaemonTest {
  @Inject
  private ChangeEditUtil editUtil;

  @Inject
  private ChangeEditModifier editModifier;

  @Inject
  private ChangeData.Factory changeDataFactory;

  @Test
  public void getRelatedNoResult() throws Exception {
    PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo);
    assertRelated(push.to("refs/for/master").getPatchSetId());
  }

  @Test
  public void getRelatedLinear() throws Exception {
    // 1,1---2,1
    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);

    for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
      assertRelated(ps,
          changeAndCommit(ps2_1, c2_1, 1),
          changeAndCommit(ps1_1, c1_1, 1));
    }
  }

  @Test
  public void getRelatedReorder() throws Exception {
    // 1,1---2,1
    //
    // 2,2---1,2

    // Create two commits and push.
    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);

    // Swap the order of commits and push again.
    testRepo.reset("HEAD~2");
    RevCommit c2_2 = testRepo.cherryPick(c2_1);
    RevCommit c1_2 = testRepo.cherryPick(c1_1);
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_2 = getPatchSetId(c1_1);
    PatchSet.Id ps2_2 = getPatchSetId(c2_1);

    for (PatchSet.Id ps : ImmutableList.of(ps2_2, ps1_2)) {
      assertRelated(ps,
          changeAndCommit(ps1_2, c1_2, 2),
          changeAndCommit(ps2_2, c2_2, 2));
    }

    for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
      assertRelated(ps,
          changeAndCommit(ps2_1, c2_1, 2),
          changeAndCommit(ps1_1, c1_1, 2));
    }
  }

  @Test
  public void getRelatedAmendParentChange() throws Exception {
    // 1,1---2,1
    //
    // 1,2

    // Create two commits and push.
    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);

    // Amend parent change and push.
    testRepo.reset("HEAD~1");
    RevCommit c1_2 = amendBuilder()
        .add("c.txt", "2")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_2 = getPatchSetId(c1_2);

    for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
      assertRelated(ps,
          changeAndCommit(ps2_1, c2_1, 1),
          changeAndCommit(ps1_1, c1_1, 2));
    }

    assertRelated(ps1_2,
        changeAndCommit(ps2_1, c2_1, 1),
        changeAndCommit(ps1_2, c1_2, 2));
  }

  @Test
  public void getRelatedReorderAndExtend() throws Exception {
    // 1,1---2,1
    //
    // 2,2---1,2---3,1

    // Create two commits and push.
    ObjectId initial = repo().exactRef("HEAD").getObjectId();
    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);

    // Swap the order of commits, create a new commit on top, and push again.
    testRepo.reset(initial);
    RevCommit c2_2 = testRepo.cherryPick(c2_1);
    RevCommit c1_2 = testRepo.cherryPick(c1_1);
    RevCommit c3_1 = commitBuilder()
        .add("c.txt", "3")
        .message("subject: 3")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_2 = getPatchSetId(c1_1);
    PatchSet.Id ps2_2 = getPatchSetId(c2_1);
    PatchSet.Id ps3_1 = getPatchSetId(c3_1);

    for (PatchSet.Id ps : ImmutableList.of(ps3_1, ps2_2, ps1_2)) {
      assertRelated(ps,
          changeAndCommit(ps3_1, c3_1, 1),
          changeAndCommit(ps1_2, c1_2, 2),
          changeAndCommit(ps2_2, c2_2, 2));
    }

    for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
      assertRelated(ps,
          changeAndCommit(ps3_1, c3_1, 1),
          changeAndCommit(ps2_1, c2_1, 2),
          changeAndCommit(ps1_1, c1_1, 2));
    }
  }

  @Test
  public void getRelatedReworkSeries() throws Exception {
    // 1,1---2,1---3,1
    //
    // 1,2---2,2---3,2

    // Create three commits and push.
    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "1")
        .message("subject: 2")
        .create();
    RevCommit c3_1 = commitBuilder()
        .add("b.txt", "1")
        .message("subject: 3")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);
    PatchSet.Id ps3_1 = getPatchSetId(c3_1);

    // Amend all changes change and push.
    testRepo.reset(c1_1);
    RevCommit c1_2 = amendBuilder()
        .add("a.txt", "2")
        .create();
    RevCommit c2_2 = commitBuilder()
        .add("b.txt", "2")
        .message(parseBody(c2_1).getFullMessage())
        .create();
    RevCommit c3_2 = commitBuilder()
        .add("b.txt", "3")
        .message(parseBody(c3_1).getFullMessage())
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_2 = getPatchSetId(c1_2);
    PatchSet.Id ps2_2 = getPatchSetId(c2_2);
    PatchSet.Id ps3_2 = getPatchSetId(c3_2);

    for (PatchSet.Id ps : ImmutableList.of(ps1_1, ps2_1, ps3_1)) {
      assertRelated(ps,
          changeAndCommit(ps3_1, c3_1, 2),
          changeAndCommit(ps2_1, c2_1, 2),
          changeAndCommit(ps1_1, c1_1, 2));
    }

    for (PatchSet.Id ps : ImmutableList.of(ps1_2, ps2_2, ps3_2)) {
      assertRelated(ps,
          changeAndCommit(ps3_2, c3_2, 2),
          changeAndCommit(ps2_2, c2_2, 2),
          changeAndCommit(ps1_2, c1_2, 2));
    }
  }

  @Test
  public void getRelatedReworkThenExtendInTheMiddleOfSeries() throws Exception {
    // 1,1---2,1---3,1
    //
    // 1,2---2,2---3,2
    //   \---4,1

    // Create three commits and push.
    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "1")
        .message("subject: 2")
        .create();
    RevCommit c3_1 = commitBuilder()
        .add("b.txt", "1")
        .message("subject: 3")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);
    PatchSet.Id ps3_1 = getPatchSetId(c3_1);

    // Amend all changes change and push.
    testRepo.reset(c1_1);
    RevCommit c1_2 = amendBuilder()
        .add("a.txt", "2")
        .create();
    RevCommit c2_2 = commitBuilder()
        .add("b.txt", "2")
        .message(parseBody(c2_1).getFullMessage())
        .create();
    RevCommit c3_2 = commitBuilder()
        .add("b.txt", "3")
        .message(parseBody(c3_1).getFullMessage())
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_2 = getPatchSetId(c1_2);
    PatchSet.Id ps2_2 = getPatchSetId(c2_2);
    PatchSet.Id ps3_2 = getPatchSetId(c3_2);

    // Add one more commit 4,1 based on 1,2.
    testRepo.reset(c1_2);
    RevCommit c4_1 = commitBuilder()
        .add("d.txt", "4")
        .message("subject: 4")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps4_1 = getPatchSetId(c4_1);

    // 1,1 is related indirectly to 4,1.
    assertRelated(ps1_1,
        changeAndCommit(ps4_1, c4_1, 1),
        changeAndCommit(ps3_1, c3_1, 2),
        changeAndCommit(ps2_1, c2_1, 2),
        changeAndCommit(ps1_1, c1_1, 2));

    // 2,1 and 3,1 don't include 4,1 since we don't walk forward after walking
    // backward.
    for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps3_1)) {
      assertRelated(ps,
          changeAndCommit(ps3_1, c3_1, 2),
          changeAndCommit(ps2_1, c2_1, 2),
          changeAndCommit(ps1_1, c1_1, 2));
    }

    // 1,2 is related directly to 4,1, and the 2-3 parallel branch stays intact.
    assertRelated(ps1_2,
        changeAndCommit(ps4_1, c4_1, 1),
        changeAndCommit(ps3_2, c3_2, 2),
        changeAndCommit(ps2_2, c2_2, 2),
        changeAndCommit(ps1_2, c1_2, 2));

    // 4,1 is only related to 1,2, since we don't walk forward after walking
    // backward.
    assertRelated(ps4_1,
        changeAndCommit(ps4_1, c4_1, 1),
        changeAndCommit(ps1_2, c1_2, 2));

    // 2,2 and 3,2 don't include 4,1 since we don't walk forward after walking
    // backward.
    for (PatchSet.Id ps : ImmutableList.of(ps2_2, ps3_2)) {
      assertRelated(ps,
          changeAndCommit(ps3_2, c3_2, 2),
          changeAndCommit(ps2_2, c2_2, 2),
          changeAndCommit(ps1_2, c1_2, 2));
    }
  }

  @Test
  public void getRelatedCrissCrossDependency() throws Exception {
    // 1,1---2,1---3,2
    //
    // 1,2---2,2---3,1

    // Create two commits and push.
    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);

    // Amend both changes change and push.
    testRepo.reset(c1_1);
    RevCommit c1_2 = amendBuilder()
        .add("a.txt", "2")
        .create();
    RevCommit c2_2 = commitBuilder()
        .add("b.txt", "2")
        .message(parseBody(c2_1).getFullMessage())
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_2 = getPatchSetId(c1_2);
    PatchSet.Id ps2_2 = getPatchSetId(c2_2);

    // PS 3,1 depends on 2,2.
    RevCommit c3_1 = commitBuilder()
        .add("c.txt", "1")
        .message("subject: 3")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps3_1 = getPatchSetId(c3_1);

    // PS 3,2 depends on 2,1.
    testRepo.reset(c2_1);
    RevCommit c3_2 = commitBuilder()
        .add("c.txt", "2")
        .message(parseBody(c3_1).getFullMessage())
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps3_2 = getPatchSetId(c3_2);

    for (PatchSet.Id ps : ImmutableList.of(ps1_1, ps2_1, ps3_2)) {
      assertRelated(ps,
          changeAndCommit(ps3_2, c3_2, 2),
          changeAndCommit(ps2_1, c2_1, 2),
          changeAndCommit(ps1_1, c1_1, 2));
    }

    for (PatchSet.Id ps : ImmutableList.of(ps1_2, ps2_2, ps3_1)) {
      assertRelated(ps,
          changeAndCommit(ps3_1, c3_1, 2),
          changeAndCommit(ps2_2, c2_2, 2),
          changeAndCommit(ps1_2, c1_2, 2));
    }
  }

  @Test
  public void getRelatedParallelDescendentBranches() throws Exception {
    // 1,1---2,1---3,1
    //   \---4,1---5,1
    //    \--6,1---7,1

    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    RevCommit c3_1 = commitBuilder()
        .add("c.txt", "3")
        .message("subject: 3")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);
    PatchSet.Id ps3_1 = getPatchSetId(c3_1);

    testRepo.reset(c1_1);
    RevCommit c4_1 = commitBuilder()
        .add("d.txt", "4")
        .message("subject: 4")
        .create();
    RevCommit c5_1 = commitBuilder()
        .add("e.txt", "5")
        .message("subject: 5")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps4_1 = getPatchSetId(c4_1);
    PatchSet.Id ps5_1 = getPatchSetId(c5_1);

    testRepo.reset(c1_1);
    RevCommit c6_1 = commitBuilder()
        .add("f.txt", "6")
        .message("subject: 6")
        .create();
    RevCommit c7_1 = commitBuilder()
        .add("g.txt", "7")
        .message("subject: 7")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id ps6_1 = getPatchSetId(c6_1);
    PatchSet.Id ps7_1 = getPatchSetId(c7_1);

    // All changes are related to 1,1, keeping each of the parallel branches
    // intact.
    assertRelated(ps1_1,
        changeAndCommit(ps7_1, c7_1, 1),
        changeAndCommit(ps6_1, c6_1, 1),
        changeAndCommit(ps5_1, c5_1, 1),
        changeAndCommit(ps4_1, c4_1, 1),
        changeAndCommit(ps3_1, c3_1, 1),
        changeAndCommit(ps2_1, c2_1, 1),
        changeAndCommit(ps1_1, c1_1, 1));

    // The 2-3 branch is only related back to 1, not the other branches.
    for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps3_1)) {
      assertRelated(ps,
          changeAndCommit(ps3_1, c3_1, 1),
          changeAndCommit(ps2_1, c2_1, 1),
          changeAndCommit(ps1_1, c1_1, 1));
    }

    // The 4-5 branch is only related back to 1, not the other branches.
    for (PatchSet.Id ps : ImmutableList.of(ps4_1, ps5_1)) {
      assertRelated(ps,
          changeAndCommit(ps5_1, c5_1, 1),
          changeAndCommit(ps4_1, c4_1, 1),
          changeAndCommit(ps1_1, c1_1, 1));
    }

    // The 6-7 branch is only related back to 1, not the other branches.
    for (PatchSet.Id ps : ImmutableList.of(ps6_1, ps7_1)) {
      assertRelated(ps,
          changeAndCommit(ps7_1, c7_1, 1),
          changeAndCommit(ps6_1, c6_1, 1),
          changeAndCommit(ps1_1, c1_1, 1));
    }
  }

  @Test
  public void getRelatedEdit() throws Exception {
    // 1,1---2,1---3,1
    //   \---2,E---/

    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    RevCommit c3_1 = commitBuilder()
        .add("c.txt", "3")
        .message("subject: 3")
        .create();
    pushHead(testRepo, "refs/for/master", false);

    Change ch2 = getChange(c2_1).change();
    editModifier.createEdit(ch2, getPatchSet(ch2));
    editModifier.modifyFile(editUtil.byChange(ch2).get(), "a.txt",
        RestSession.newRawInput(new byte[] {'a'}));
    ObjectId editRev =
        ObjectId.fromString(editUtil.byChange(ch2).get().getRevision().get());

    PatchSet.Id ps1_1 = getPatchSetId(c1_1);
    PatchSet.Id ps2_1 = getPatchSetId(c2_1);
    PatchSet.Id ps2_edit = new PatchSet.Id(ch2.getId(), 0);
    PatchSet.Id ps3_1 = getPatchSetId(c3_1);

    for (PatchSet.Id ps : ImmutableList.of(ps1_1, ps2_1, ps3_1)) {
      assertRelated(ps,
          changeAndCommit(ps3_1, c3_1, 1),
          changeAndCommit(ps2_1, c2_1, 1),
          changeAndCommit(ps1_1, c1_1, 1));
    }

    assertRelated(ps2_edit,
        changeAndCommit(ps3_1, c3_1, 1),
        changeAndCommit(new PatchSet.Id(ch2.getId(), 0), editRev, 1),
        changeAndCommit(ps1_1, c1_1, 1));
  }

  @Test
  public void pushNewPatchSetWhenParentHasNullGroup() throws Exception {
    // 1,1---2,1
    //   \---2,2

    RevCommit c1_1 = commitBuilder()
        .add("a.txt", "1")
        .message("subject: 1")
        .create();
    RevCommit c2_1 = commitBuilder()
        .add("b.txt", "2")
        .message("subject: 2")
        .create();
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id psId1_1 = getPatchSetId(c1_1);
    PatchSet.Id psId2_1 = getPatchSetId(c2_1);

    for (PatchSet.Id psId : ImmutableList.of(psId1_1, psId2_1)) {
      assertRelated(psId,
          changeAndCommit(psId2_1, c2_1, 1),
          changeAndCommit(psId1_1, c1_1, 1));
    }

    // Pretend PS1,1 was pushed before the groups field was added.
    PatchSet ps1_1 = db.patchSets().get(psId1_1);
    ps1_1.setGroups(null);
    db.patchSets().update(ImmutableList.of(ps1_1));
    indexer.index(changeDataFactory.create(db, psId1_1.getParentKey()));

    if (!cfg.getBoolean("change", null, "getRelatedByAncestors", false)) {
      // PS1,1 has no groups, so disappeared from related changes.
      assertRelated(psId2_1);
    }

    RevCommit c2_2 = testRepo.amend(c2_1)
        .add("c.txt", "2")
        .create();
    testRepo.reset(c2_2);
    pushHead(testRepo, "refs/for/master", false);
    PatchSet.Id psId2_2 = getPatchSetId(c2_2);

    // Push updated the group for PS1,1, so it shows up in related changes even
    // though a new patch set was not pushed.
    assertRelated(psId2_2,
        changeAndCommit(psId2_2, c2_2, 2),
        changeAndCommit(psId1_1, c1_1, 1));
  }

  private List<ChangeAndCommit> getRelated(PatchSet.Id ps) throws IOException {
    return getRelated(ps.getParentKey(), ps.get());
  }

  private List<ChangeAndCommit> getRelated(Change.Id changeId, int ps)
      throws IOException {
    String url = String.format("/changes/%d/revisions/%d/related",
        changeId.get(), ps);
    return newGson().fromJson(adminSession.get(url).getReader(),
        RelatedInfo.class).changes;
  }

  private RevCommit parseBody(RevCommit c) throws IOException {
    testRepo.getRevWalk().parseBody(c);
    return c;
  }

  private PatchSet.Id getPatchSetId(ObjectId c) throws OrmException {
    return getChange(c).change().currentPatchSetId();
  }

  private PatchSet getPatchSet(Change c) throws OrmException {
    return db.patchSets().get(c.currentPatchSetId());
  }

  private ChangeData getChange(ObjectId c) throws OrmException {
    return Iterables.getOnlyElement(queryProvider.get().byCommit(c));
  }

  private static ChangeAndCommit changeAndCommit(
      PatchSet.Id psId, ObjectId commitId, int currentRevisionNum) {
    ChangeAndCommit result = new ChangeAndCommit();
    result._changeNumber = psId.getParentKey().get();
    result.commit = new CommitInfo();
    result.commit.commit = commitId.name();
    result._revisionNumber = psId.get();
    result._currentRevisionNumber = currentRevisionNum;
    result.status = "NEW";
    return result;
  }

  private void assertRelated(PatchSet.Id psId, ChangeAndCommit... expected)
      throws Exception {
    List<ChangeAndCommit> actual = getRelated(psId);
    assertThat(actual).named("related to " + psId).hasSize(expected.length);
    for (int i = 0; i < actual.size(); i++) {
      String name = "index " + i + " related to " + psId;
      ChangeAndCommit a = actual.get(i);
      ChangeAndCommit e = expected[i];
      assertThat(a._changeNumber).named("change ID of " + name)
          .isEqualTo(e._changeNumber);
      // Don't bother checking changeId; assume _changeNumber is sufficient.
      assertThat(a._revisionNumber).named("revision of " + name)
          .isEqualTo(e._revisionNumber);
      assertThat(a.commit.commit).named("commit of " + name)
          .isEqualTo(e.commit.commit);
      assertThat(a._currentRevisionNumber).named("current revision of " + name)
          .isEqualTo(e._currentRevisionNumber);
    }
  }
}
