The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

App::Gitc::Util - The workhorse of gitc

VERSION

version 0.60

Exported Subroutines

confirm($message)

Displays $message and waits for the user to press 'y' or 'n'. If he enters 'y', a true value is returned. If he enters 'n', a false value is returned.

current_branch

Returns the name of the branch that's currently checked out in Git.

its_config

Returns the config specific to this project's ITS.

eventum_statuses

Returns the from and to state based on a command provided to GITC.

its

Returns an ITS pseudo-object

Some day it would be nice to add 'new' to these and return a real instantiated object... but this fits the bill.

its_for_changeset

Guesses which ITS object we need based on the changeset name, returns the object if it supports it, or just the class name.

git

A wrapper for executing git commands and handling errors. In void context, the command is executed using system. In scalar context, the command's output is captured, chomped and returned. In list context, a list of chomped lines is returned.

git_config

Returns a nested hash data structure representing Git's configuration.

guarantee_a_clean_working_directory

Make sure that all tracked files match the index and match the commit object. If the working directory is not clean, ask the user whether to proceed. If he wants to proceed, this sub stashes the current changes and returns the stash's commit ID. In this case, it's the caller's responsibility to invoke "git stash apply" with this ID to restore the changes, when appropriate.

If the user does not want to proceed, an exception is thrown. In most cases, this will accomplish what the user desired by halting the program.

If the directory is clean, a false value is returned which indicates that nothing was stashed while guaranteeing cleanliness.

let_user_edit($filename)

Open's the user's preferred editor so that he can interactively edit $filename.

meta_data_add($data)

Appends the contents of the hashref $data to the changeset meta data. Returns a unique identifier which can be used by "meta_data_rm".

meta_data_rm({id => $id, changeset => $changeset})

Deletes the meta data entry with ID $id in changeset $changeset.

meta_data_rm_all($changeset)

Deletes all changeset meta data for the changeset named $changeset. The project is determined by the current working directory. Returns the number of meta data entries that were deleted.

meta_data_rm_project($project)

Deletes all changeset meta data for the project named $project. Returns the number of meta data entries that were deleted.

new_branch_version($branch, $new_major_version)

Increments and returns the most recent version tagged for the given $branch. This only applies to projects that have the 'use_version_tags' config set to true. If $new_major_version is truthy, increment the major version # and make minor 0

new_version_tag($branch)

Returns a tag name for an updated version of the given $branch. This only applies to projects that have the 'use_version_tags' config set to true.

project_config

Returns a hashref with configuration details about this project.

Configuration is loaded from the following sources: * /etc/gitc/gitc.config * $PROJECT_ROOT/gitc.config * $HOME/.gitc/gitc.config

It will then parse all the paths in the GITC_CONFIG environment variable (separated by :).

These configuration files are all merged together with the later files overriding the earlier.

Finally we merge the default config with the per-project configuration we found to generate a final fully baked configuration for the project.

Optionally Exported Subroutines

The following subroutines are only exported when they're asked for.

archived_tags

Returns an arrayref of arrayrefs representing all tags that have been archived for the current project. The internal arrayrefs hold the tag's SHA1 and ref name, in that order. The tags are returned in sorted order increasing by ref name (the same order as .git/packed-refs).

branch_basis($commit_id)

Determines the base branch for the given $commit_id. The base branch is the most specific branch on which this commit lies. It's typically used for converting an earlier commit on a branch (such as tag "test/2009-12-29T12_13_14") into the name of the branch (such as "test"). If we can't determine the branch name, returns 'unknown'.

branch_point($ref)

Returns a commit ID indicating the commit on which the branch at $ref is based. For example, if we have a topology like this

              o-----A
             /
    o---o---X---o---M

where A is the head of a branch and M is the head of master. The branch point of A is commit X. If A is later merged into M, the branch point remains the same.

See "full_changeset_name" for a way to convert a changeset name into a value suitable for $ref.

changeset_group($changeset)

Given a $changeset name, returns an arrayref of the changeset names (for existing changesets) in this same changeset group. A changeset group is defined as any changesets that share the same Eventum number or prefix (if the group is not associated with an Eventum issue). The resulting list of changesets is sorted in the traditional order. See "sort_changesets_by_name".

TODO: This code should be reworked to use logic for each its

changeset_merged_to($changeset)

Returns a list (or string, depending on context) of environments to which this changeset has been merged. If it's not been merged yet, the list is empty (of course).

changesets_promoted_between

Given a hashref of named arguments, returns a list of changeset names indicating which changesets were promoted to $target for $project between the times $start and $end. The times should be in the format 'yyyy-mm-ddTHH:MM:SS'

commit_decorations($commit)

Returns a list (or arrayref, depending on context) of decorations associated with $commit (a commit ID). In cases where many Git processes are forked to obtain decoration info, this function can be substantially faster.

current_branch_version($branch)

Determines the most recent version tagged for the given $branch. This only applies to projects that have the 'use_version_tags' config set to true.

environment_preceding($environment)

Given an $environment name, returns the name of the environment that precedes that one in promotion order. For instance environment_preceding('stage') produces 'test'.

If there is no such $environment, an exception is thrown. If no environment precedes the one given, returns undef.

full_changeset_name($name)

Given the $name of a changeset, returns a Git ref which correctly addresses that changeset's head. It doesn't matter if the changeset is newly opened, pending review or merged. The resulting ref points at the head of that changeset.

See also short_ref_name.

git_dir

Returns the absolute path of the current .git directory. Bare repositories and normal repositories are both handled correctly.

git_fetch_and_clean_up

Fetches the remote repository and does a little routine maintenance to make sure that the repository performs optimally. This is called from commands which are consistently, but infrequently, run by developers. It helps to hide some of the repository maintenace that Git requires.

git_tag

A wrapper around "git tag" which updates the commit decoration hash (See "commit_decorations". This should always be used instead of calling "git tag" directly.

Returns nothing useful.

highest_quickfix_number($project_name)

Returns the highest number used for any quickfix changeset in $project_name. If there have been no quickfix changesets, returns 0.

history($project_name, $changeset)

Returns a list (or arrayref, depending on context) of hashes. Each hash represents the details about a particular event related to the changeset named $changeset within the project named $project_name. The events are returned in chronological order.

If $project_name is omitted, the name of the project in the current working directory is used instead.

history_owner($history)

Returns the name of the owner of a changeset based on a changeset's $history.

history_reviewer

Returns the name of the most recent reviewer of this changeset. If this changeset has never been submitted for review, returns undef.

history_status

Returns the current status of a changeset based on a changeset's $history.

history_submitter

Returns the user ID of the most recent submitter. If there is no submitter in the history, returns undef.

is_auto_fetch

Returns a true value if this user wants to automatically fetch from the origin.

is_merge_commit($ref)

Returns true if the commit pointed at by $ref is a merge commit. Otherwise, it returns false.

is_suspendable

Marks the currently running gitc command as suspendable. If a command which is marked as suspendable is currently suspended, calling this function throws an exception.

Any command which suspends itself should call this function. It helps avoid user error when the user tries to run the same command again instead of resuming the suspended command.

is_valid_ref($name)

Returns a commit ID if $name is a valid Git "ref". Otherwise, it returns false.

open_packed_refs($prefix)

Opens the current repository's packed refs and returns:

    * a file handle to the opened packed refs
    * a file handle to a temporary file
    * the name of the temporary file

The first line read from the first filehandle is the first packed ref in the file. Any header lines are stripped and automatically copied to the new temporary file.

The mandatory $prefix argument specifies a prefix for the temporary file. This should usually be the name of the gitc command calling "open_packed_refs".

The temporary file does not automatically delete itself. The caller is responsible for that.

parse_changeset_spec($spec)

$spec is a single command line argument which is supposed to uniquely identify a changeset and its associated project. undef means "infer everything from the repository I'm in". project#changeset means to use the specified project and changeset. changeset means to use the given changeset within the current directory's project.

Returns a list containing the project name and the changeset name. If there's any trouble obtaining those two, an exception is thrown.

project_name

Returns the name of the project in the current working directory.

project_root

Returns an absolute path to the current repository's project root. If called from a bare repository, it throws an exception.

remote_branch_exists($branch_name)

Returns true if origin has a branch named $branch_name. Otherwise, it returns false.

sendmail($args)

Sends an email with a standard format, allowing the user to edit the template. $args is a single hashref of named arguments. The argument to specifies the username of the recipient. subject provides the email subject. changeset is the name of the changeset associated with this email.

The following optional arguments are also accepted. project is the name of the project related to this changeset email. If it's omitted, the project in the current working directory is used instead. content specifies the main body of the email. If omitted, an empty body template is used. link provides a URL which is included at the top of the email.

If the lazy argument is true, the email message is built but not sent. Instead, "sendmail" returns a code reference. When that code reference is called, the email is sent. This is particularly useful when you want a user to compose an email in one context (so he can cancel an operation early, for example) but delay sending the email until you're certain it should go out.

find_sendmail()

Returns the full path to the sendmail binary.

short_ref_name($ref)

Given a Git $ref, returns a shorter name for it. This is typically the name of the changeset to which $ref refers. This function is the inverse of "full_changeset_name".

sort_changesets_by_name

Sorts a list of changeset names into a sensible order. Typical usage is:

    sort_changesets_by_name( \@list_of_changesets );
    # @list_of_changesets is now sorted

split_decorations($decorations)

Converts a string of $decorations as produced by git log --decorate or git log --pretty=format:%d into a list of full ref names.

toplevel

Returns the top-level directory for the current branch.

traverse_commits( $log_string, $callback )

Invokes git log $log_string and calls the code reference $callback for each commit encountered. $callback is invoked with the following arguments in a hashref:

    commit  - this commit's ID
    parents - an arrayref of the commit's parent commit IDs
    message - an arrayref of the commit's message lines

unmerged_changesets($project_name)

Returns a hashref whose keys are the names of unmerged changesets and whose values are the respective changeset histories (see "history").

unpromoted($from, $to)

Returns a list of the changesets which are included in $from but not yet part of $to. For example, unpromoted('origin/master', 'origin/test'), returns the changesets that are in master but not in test.

One way to think about it is that if you promoted $from into $to, what other things would be promoted to $to as a result. This is the way that gitc-unpromoted is implemented. This subroutine implements a more general idea of "not included in" than that command makes available.

$from can also be an arrayref of branches. In this case it means, "If I were to promote everything listed in @$from, what all would be promoted.

The order of the returned changesets is significant. Changesets always appear in the list before their dependencies. In Git terms, "child commits are given before their parents." Since demotions are not accomodated by Git's data model, they are placed at the end of the list of unpromoted changesets.

Private Subroutines

command_name

Returns the name of the gitc command that started this whole mess. This is mostly a helper subroutine for eventum_transition_status. If the command name can't be determined, an exception is thrown.

_states

Used internally to calculate target for state change.

state_blocked

Given a command and a specified state this checks the block list in the project configuration and returns true if the state should block the command from proceeding.

NOTE: Block list must be an arraref in the project configuration

AUTHOR

Grant Street Group <developers@grantstreet.com>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2013 by Grant Street Group.

This is free software, licensed under:

  The GNU Affero General Public License, Version 3, November 2007