syntax = "proto3";

package gitaly;

option go_package = "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb";

// LogEntry is a single entry in a partition's write-ahead log.
//
// Schema for :
// - `partition/<partition_id>/log/entry/<log_index>`.
message LogEntry {
  // ReferenceTransaction models a single reference transaction.
  message ReferenceTransaction {
    // Change models a single reference change.
    message Change {
      // reference_name is the fully qualified name of the reference
      // to update.
      bytes reference_name = 1;
      // new_oid is the new oid to point the reference to. Deletions
      // are denoted as the SHA1 or SHA256 zero OID depending on the
      // hash type used in the repository.
      bytes new_oid = 2;
    }

    // changes are the reference changes performed in this reference transaction.
    repeated Change changes = 1;
  }

  // RepositoryDeletion models a repository deletion.
  message RepositoryDeletion {
  }

  // Housekeeping models a housekeeping run. It is supposed to handle housekeeping tasks for repositories such as the
  // cleanup of unneeded files and optimizations for the repository's data structures. It is a collection of smaller
  // tasks.
  message Housekeeping {
    // PackRefs models a pack-refs housekeeping task. This task is to pack loose references into a singular packed-refs
    // file to optimize ref accessing time. In other words, it's a wrapper for git-pack-refs command.
    message PackRefs {
      // pruned_refs is the list of fully qualified references to be pruned. Gitaly removes the loose reference files on
      // the disk. They still stay intact in the packed-refs.
      repeated bytes pruned_refs = 1;
    }

    // Repack models a repacking housekeeping task. The task re-organizes the packfiles for faster access and prune
    // unreachable objects if any.
    message Repack {
      // new_files are the new packfiles that will be added to the repository. They are the result of `git-repack(1)`
      // command.
      repeated string new_files = 1;
      // deleted_files are the redundant packfiles which are already packed into the new packfiles above. We keep that
      // list to prevent deleting new packfiles introduced by other concurrent updates.
      repeated string deleted_files = 2;
      // is_full_repack tells if the repacking task is a full repack or not.
      bool is_full_repack = 3;
    }

    // WriteCommitGraphs models commit-graphs updates. An up-to-date
    // commit-graphs structure accelerates commit graph walks.
    message WriteCommitGraphs {
    }

    // pack_refs signifies if the housekeeping run includes a pack-refs task.
    PackRefs pack_refs = 1;

    // repack signifies if the housekeeping run includes a repacking task.
    Repack repack = 2;

    // write_commit_graphs signififies if the housekeeping run includes commit-graphs updates.
    WriteCommitGraphs write_commit_graphs = 3;
  }

  // relative_path is the relative path of the repository the changes in the
  // log entry are targeting.
  string relative_path = 1;
  // reference_transactions contains the reference transactions this
  // entry records. The logged reference updates have already passed
  // through verification and are applied without any further checks.
  // The reference transactions are applied in order.
  repeated ReferenceTransaction reference_transactions = 2;
  // repository_deletion, when set, indicates this log entry deletes the repository.
  RepositoryDeletion repository_deletion = 6;
  // housekeeping, when set, indicates this log entry contains a housekeeping task.
  Housekeeping housekeeping = 9;

  // Operation models a single operation to be performed.
  message Operation {
    // CreateHardLink creates a hard link. The existing inode metadata, including
    // permissions, will be shared with all of the hard links to the same file.
    message CreateHardLink {
      // source_path is the relative path of the file the hard link should point to.
      string source_path = 1;
      // source_in_storage is set when the source path is relative to the storage
      // root instead of the log entry.
      bool source_in_storage = 2;
      // destination_path is a relative path from the storage root to where the hard
      // link should be created at.
      string destination_path = 3;
    }

    // RemoveDirectoryEntry removes a directory or a file
    // from the parent directory. When removing a directory,
    // it must be empty.
    message RemoveDirectoryEntry {
      // path is the relative path of the directory entry to remove in the storage.
      string path = 1;
    }

    // CreateDirectory creates a directory at a relative path.
    message CreateDirectory {
      // path is a relative path where to create the directory.
      string path = 1;
      // permissions are the Unix permision bits to set on the created directory.
      uint32 permissions = 2;
    }

    oneof operation {
      // create_hard_link creates a hard link in the storage.
      CreateHardLink       create_hard_link       = 1;
      // remove_directory_entry removes a directory entry from the storage.
      RemoveDirectoryEntry remove_directory_entry = 2;
      // create_directory creates a directory in the storage.
      CreateDirectory      create_directory       = 3;
    };
  }

  // operations is an ordered list of operations to run in order to apply
  // this log entry.
  repeated Operation operations = 10;
}

// LSN serializes a log sequence number. It's used for storing a partition's
// applied LSN in the database.
//
// Schema for:
// - `partition/<partition_id>/applied_lsn`
message LSN {
  // value is an LSN pointing to a position in the log.
  uint64 value = 1;
}
