<commit_before>
module GitCma
  # Public: A versioned document storage with publishing pipeline support. Documents are internally
  # stored as a single file in a separate git repository for each document. Each state in the publishing
  # process is a separate branch.
  #
  # Every save to a document goes in as a commit to a master branch representing a draft stage. The
  # master branch is never reset, all changes only go forward.
  #
  # A promotion to a following state is recorded as a merge commit from the original state baranch to
  # a new state branch. New state revision is therefore not the same revision as the original revision.
  # Documents in all states except `master` can be rolled back to their previous revision (git reset), and
  # a revision history is available for each state separately.
  class Document
    attr_reader :name, :revision
    attr_accessor :content

    # Public: create a new document
    #
    # name    - the name of the document, must be a valid filename. Will be generated randomly if not provided
    # options - an options Hash with extra attributes
    #           :content - the new document's content (optional)
    #           :repo    - rugged repository object when loading an existing document. (optional).
    #                      Not meant to be used directly
    def initialize(name = nil, opts = {})
      @name = name || SecureRandom.hex(16) # FIXME check that the content id isn't already used
      @repo = opts[:repo]
      @content = opts[:content]
    end

    # Storage

    # Public: save the document as a new revision. Commits the content to the top of `master`, updates `master`
    # and updates the Document's revision to the newly created commit.
    #
    # timestamp - the time of the save
    #
    # Returns the sha of the created revision
    def save!(timestamp)
      parents = (repository.empty? ? [] : [repository.head.target].compact)
      @revision = commit!(@content, parents, 'refs/heads/master', 'save from git CMA', timestamp)
    end

    # Public: loads the revision specified by `rev`. Updates content and revision of the Document
    #
    # rev - the revision to load. Can be a sha or a state name (e.g. `published`).
    #        Defaults to `master` (optional)
    #
    # Returns the sha of the loaded revision.
    def load!(rev = nil)
      rev ||= repository.head.target

      begin
        rev_obj = repository.lookup(rev)
      rescue Rugged::InvalidError
        rev = Rugged::Reference.lookup(repository, "refs/heads/#{rev}").target
        rev_obj = repository.lookup(rev)
      end

      tree = rev_obj.tree
      file = repository.lookup(tree.first[:oid]).read_raw

      @content = file.data
      @revision = rev
    end

    # Public: List all the revisions.
    #
    # state   - list history of a given state, e.g. `published`. (optional)
    # block   - yield each revision to the block as it's traversed. Useful for early termination
    #
    # Returns an array of revision hashes if no block was given, otherwise yields every revision
    # to the block and returns nothing.
    def history(state = nil, &block)
      rev = revision

      if state
        ref = Rugged::Reference.lookup(repository, "refs/heads/#{state}")
        rev = ref.target if ref
      end

      results = []
      return results unless rev<commit_msg>Reverting a bad refactoring<commit_after>
module GitCma
  # Public: A versioned document storage with publishing pipeline support. Documents are internally
  # stored as a single file in a separate git repository for each document. Each state in the publishing
  # process is a separate branch.
  #
  # Every save to a document goes in as a commit to a master branch representing a draft stage. The
  # master branch is never reset, all changes only go forward.
  #
  # A promotion to a following state is recorded as a merge commit from the original state baranch to
  # a new state branch. New state revision is therefore not the same revision as the original revision.
  # Documents in all states except `master` can be rolled back to their previous revision (git reset), and
  # a revision history is available for each state separately.
  class Document
    attr_reader :name, :revision
    attr_accessor :content

    # Public: create a new document
    #
    # name    - the name of the document, must be a valid filename. Will be generated randomly if not provided
    # options - an options Hash with extra attributes
    #           :content - the new document's content (optional)
    #           :repo    - rugged repository object when loading an existing document. (optional).
    #                      Not meant to be used directly
    def initialize(name = nil, opts = {})
      @name = name || SecureRandom.hex(16) # FIXME check that the content id isn't already used
      @repo = opts[:repo]
      @content = opts[:content]
    end

    # Storage

    # Public: save the document as a new revision. Commits the content to the top of `master`, updates `master`
    # and updates the Document's revision to the newly created commit.
    #
    # timestamp - the time of the save
    #
    # Returns the sha of the created revision
    def save!(timestamp)
      parents = (repository.empty? ? [] : [repository.head.target].compact)
      @revision = commit!(@content, parents, 'refs/heads/master', 'save from git CMA', timestamp)
    end

    # Public: loads the revision specified by `rev`. Updates content and revision of the Document
    #
    # rev - the revision to load. Can be a sha or a state name (e.g. `published`).
    #        Defaults to `master` (optional)
    #
    # Returns the sha of the loaded revision.
    def load!(rev = nil)
      rev ||= repository.head.target

      begin
        rev_obj = repository.lookup(rev)
      rescue Rugged::InvalidError
        rev = Rugged::Reference.lookup(repository, "refs/heads/#{rev}").target
        rev_obj = repository.lookup(rev)
      end

      tree = rev_obj.tree
      file = repository.lookup(tree.first[:oid]).read_raw

      @content = file.data
      @revision = rev
    end

    # Public: List all the revisions.
    #
    # state   - list history of a given state, e.g. `published`. (optional)
    # block   - yield each revision to the block as it's traversed. Useful for early termination
    #
    # Returns an array of revision hashes if no block was given, otherwise yields every revision
    # to the block and returns nothing.
    def history(state = nil, &block)
      rev = if state
        ref = Rugged::Reference.lookup(repository, "refs/heads/#{state}")
        rev = ref.target if ref
      else
        revision
      end

      results = []
      return results unless rev
{'fraction_non_alphanumeric': 0.07550535077288942, 'fraction_numerical': 0.0005945303210463733, 'mean_word_length': 2.6530944625407167, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2937049', 'n_tokens_mistral': 1772, 'n_tokens_neox': 1723, 'n_words': 805}