The Perl Advent Calendar needs more articles for 2022. Submit your idea today!


VCI::Abstract::Commit - Represents a single atomic commit to the repository.


Usually, when you modify a repository in version control, you modify many files simultaneously in a single "commit" (also called a "checkin").

This object represents one of those commits in the history of a project.

Some version-control systems don't actually understand the idea of an "atomic commit" (meaning they don't understand that certain changes were all committed simultaneously), but VCI does its best to figure out what files were committed together and represent them all as one object.

A VCI::Abstract::Commit implements VCI::Abstract::FileContainer, so all of FileContainer's methods are also available here.

Note: Depending on how this object was constructed, it may or may not actually contain information on all of the files that were committed in this change. For example, when you use "history" in VCI::Abstract::File, Commit objects might only contain information about that single file. This is due to the limits of various version-control systems.



These are all read-only.


A datetime representing the date and time of this commit.

On VCSes that don't understand atomic commits, this will be the time of the earliest commited file in this set.


A string identifying who committed this revision. That is, the username of the committer, or their real name and email address (or something similar). The format of this string is not guaranteed.


Some VCSes differentiate between the person who wrote a patch, and the person who committed it. For VCSes that understand this difference, this is a string identifying who wrote the patch, in a simialr format to "committer".

For VCSes that don't understand the concept of "author" (or for commits where the "author" field isn't set), this is identical to "committer".


All of the items added, removed, or modified in this commit, as an arrayref of VCI::Abstract::Committable objects.


Just the items that were added in this commit, as an arrayref of VCI::Abstract::Committable objects.


Just the items that were deleted in this commit, as an arrayref of VCI::Abstract::Committable objects.


The items that were modified (not added or removed, just changed) in this commit, as an arrayref of VCI::Abstract::Committable objects.

Any files that were "moved" will have their new names, not their old names.


Some version-control systems understand the idea that a file can be renamed or moved, not just removed and then added.

If a file was moved or renamed, it will show up in this accessor, which is a hashref where the keys are the new path and the value is a VCI::Abstract::Committable representing the old path. (That might seem backwards until you realize that the new name is what shows up in "modified", so having keys on the new name is much more useful.)

Each file will also show up in "modified" if it also had modifications during this commit. (However, if there were no changes to the file other than that it was moved, it won't show up in "modified".)


A hashref of objects that were copied from another file/directory, preserving their history. The place we were copied from could have been in some other Project (and in rare cases, a completely different Repository, though VCI might not track that it was copied in that case).

The keys are the name of the file as it is now, and the value is a VCI::Abstract::Committable that represents the path it was copied from.

Any item in copied will also show up in modified if it was changed during this commit, and added otherwise.


A string representing the unique identifier of this commit, according to the version-control system.

For version-controls systems that don't understand atomic commits, this will be some unique identifier generated by VCI. This identifier is guaranteed to be stable--that is, you can use it to retrieve this commit object from "get_commit" in VCI::Abstract::Project.

Individual VCI::VCS implementations will specify the format of their revision IDs, if they are a VCS that doesn't have unique identifiers for commits, or if there is any ambiguity about what exactly "revision id" means for that VCS.


In many VCSes, there is a difference between the "unique revision identifier" (which is a long and complex string uniquely identifying a particular revision) and the actual simple "revision number" displayed. revno represents the revision number (as opposed to "revision", which represents the unique identifier).

Often this is a simple integer, but in some VCSes this could also be a string like "".

In some VCSes, revno and "revision" are identical. In other VCSes, revno is just a shorter version of "revision".


A universally-unique identifier for this Commit. This is a unique string that identifies this exact commit across all possible Repositories and Projects in the world. If any Commit from any Repository or Project has this uuid, it is this Commit.

Note that it's possible that two Commits with differing uuids could be the same Commit, because for VCSes where "revisions_are_universal" in VCI isn't true, the uuid is generated based on the name of the Repository (and possibly Project) this Commit is in, and if you call the same Repository or Project by two different names, you may get two different UUIDs for the Commit objects in that Repository/Project.

Note: Currently, there is a chance that the way this is generated will change between versions of VCI. If it does, it will be noted in the Changes file that comes along with the VCI package.


The message that was entered by the committer, describing this commit.


Returns a representation of the changes made to files in this commit, as a VCI::Abstract::Diff object.

If the VCS provides a diff format that tracks renames and copies, the diff will be in that format. In other words, it will represent the changes in the same way the Commit represents them. For example, if a file has been moved and then modified, in a normal diff you'd see one entire file removed and then another added. In this diff you will only see that a file was modified, and that file will have the new name.



Usually you won't construct an instance of this class directly, but instead, use various methods of VCI::Abstract::Project to get Commits out of the Project's History.


Takes all "Accessors" as named parameters. The following fields are required: "time", "revision", and project.

If "committer" and "message" aren't specified, they default to an empty string.