Tool to manage using git as a deployment management tool
Switch branches/tags
Nothing to show
Clone or download
Pull request Compare This branch is 206 commits behind git-deploy:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


    git-deploy - automate the git steps required for a deploying code from a
    git repository

        git deploy [deploy-options] [action [prefix]] [action-options]
        git deploy --man

            start|sync|finish|abort  # normal manual rollout sequence (finish is automatic if sync succeeds)
            start|release|abort      # normal git-production env sequence
            hotfix                   # Roll out the site with a hotfix
            revert                   # revert site to previous rollout (interactive select)
            show                     # show list of tags
            show-tag                 # show the current tag (if it exists)
            tag                      # create a tag for this commit (restricted to certain environments)
            log                      # during a rollout show log of changes since the last rollout
            diff                     # during a rollout show differences between previous rollout
            status                   # show rollout status of current repository

    Use git-deploy --man to see complete set of options and details of use.

    --force Force the action, and bypass most sanity checks. Do not use
            unless you know what you are doing.

            Emits progress information to STDERR during processing.

    --help  Print a brief help message and exits. (You are probably reading
            what this outputs right now.)

    --man   Uses perldoc/man to output far far more than you ever realized
            there was to know about using this tool.

            Print out the step log if one exists. If nothing is printed out
            then there is no rollout underway.

            Perl strfime() format to use in datestamped tags. Defaults to
            '%Y%m%d-%H%M'. Please do not change this wantonly. Various
            features of the deploy process expect to be able to parse the
            date stamp and require it to be in more or less this format.

            Message to use when creating a tag. Required when creating a new
            tag. Since you cant know the name of the newly created tag when
            writing the message you can use the special sequence %TAG as a

            Print to STDOUT whatever prefix would be used given the current
            arguments and then exit. Throw an error if there would be no

            Address to use to send announcement mails to. Defaults to

            Prints to STDOUT the current deploy file if and only if the
            commit it contains corresponds to HEAD. Otherwise prints
            nothing. Exits immeditately afterward.

            Set the deploy file name. If this option is not provided the
            deploy file defaults to "./lib/.deploy" if a directory named
            "./lib" exists, and otherwise to "./.deploy"

            Instead of printing out a single tagname for the current commits
            tag print out a verbose list of tags, sorted by the date that
            they contain in order of most recent to oldest. The output will
            be structured like this:

                7e25a770901c.. *tag: sheep-20080827-1419
                2806eb24c3c2..  tag: cows-20080827-1240
                d6af6e1ad6f1..  tag: goats_20080826-1458
                889f65216880..  tag: goats_20080826-1034
                90318602f8d2..  tag: cows_20080826-1005
                6bd340c67bdb..  tag: sheep-20080825-2245
                19587c195a8b..  tag: sheep-20080825-2116 -> sheep-20080825-2105
                19587c195a8b..  tag: sheep-20080825-2105

            The first column is the abbreviated commit SHA1 (abbreviation
            can be disabled with the "--long-digest" option), Followed by
            either "<space><space>" or by "<space><star>". The starred items
            correspond to HEAD. The arrow indicates that there are two
            different tags to the same commit, and points to the oldest
            equivalent tag. This is then followed by either 'tag:' or
            'branch:' (depending on whether "--include-branches" is invoked)
            and then the item name. This may then be followed by space and
            then an arrow and then a second name, which indicates that the
            item is a duplicate and shows the oldest displayed item (undated
            items like branches go last in an alphabetic order with some
            special exceptions for trunk or master).

            When used with just "--list" mode, only starred items
            corresponding to HEAD are displayed, --list-all shows unstarred
            items that do not correspond to HEAD as well.

            Show information about branches as well when in "--list" mode

            Show full SHA1's when in "--list" mode.

            Totally ignore tags which are from before this date. Defaults to

            Checking *every* tag to see if it corresponds to HEAD can be
            expensive. This options makes it possible to filter old tags by
            date to avoid checking them when you know they wont match.

            Make a tag. This is the same as the "tag" action except the tag
            will not be automatically pushed.

            Note: that you cannot use this function in/for all environments.

            If you think your environment should be allowed contact the

            Do not check that the working directory is clean before doing

            Skip any actions that involve talking to a remote repository.

            Name of remote site to access when pushing, pulling or fetching.
            Defaults to 'origin'.

            Using an remote site name of 'none' is the same as using

            Name of remote branch to access when pushing, pulling or
            fetching. Defaults to the current branch just like git pull or
            git push would.

        Used to start a multi step rollout procedure. Remembers (and if
        necessary tags) start position as well as create locks to prevent
        two people from doing a procedure at the same time. See "hotfix"
        below for rollout out a hotfix on top of a previous rollout tag.

        Used to declare that the current commit is ready for sync. At some
        point in the future this will automatically call the appropriate
        sync command, however currently the sync is done manually as a
        separate step.

        A command which can be used any time prior to the manual
        syncronization step which will automatically rollback the current
        state to the start position. Note this is NOT the way to "rollback a
        rollout", it is the way to abort a rollout prior to its completion.

        I.e. if someone else has started a rollout and gone away you can do:

            git-deploy --force abort

        And the state of the rollout machine will be reset back to what it
        was before they ran "git-deploy start".

        Note that the "abort" command used to be called "rollback" but that
        term lead to a lot of confusion and we are trying to avoid it going

        Used to declare that the rollout session is finished, push any new
        commits or tags, create the final emails of what changed and related

        Used in the "two step" rollout process for boxes where there is no
        manual syncronization step.

    tag Used in the "one step" rollout process to tag a commit and push it
        to the remote.

        This is used to do an interactive "revert" of the site to a previous
        rollout. It combines the steps "start/git reset .../sync/finish"
        into one process, with interactive selection of the commit to revert
        to. If sync hooks and deploy hooks are provided then they will be
        automatically run as normal. If they arent a manual sync/finish is

        Show the tag for the current commit if there is one.

        Show the status of the deploy procedure. Can be used to check what
        step you are on.

        Here's how you can do a hotfix rollout. I.e. when you have an
        existing rollout tag that you want to apply a hotfix on.

        First, instead of "git-deploy start" do:

            git-deploy hotfix

        That'll start "git-deploy" without doing the normal "git pull"
        operation. Then you cherry-pick your hotfix:

            git cherry-pick SHA1_OF_HOTFIX

        Then note the sha1 of your cherry-picked commit. This is your

            git --no-pager log -1 --pretty=%H

        Then do a:

            git pull

        Followed by:

            git push

        To push your hotfix to the Git server. But now you're not at what
        you want to roll out, so do:

            git reset --hard NEW_SHA1
            git checkout -f

        This will ensure that you are on your hotfix commit, and that any
        git hooks are executed. You should then TEST the code. On a
        webserver this normally involves

            prodctl restart

        and then some manual testing of the relevant web site.

        When you are satisfied that things are ok you can do execute the

            git-deploy sync

        TODO: The last 3 pull/push/reset steps are busywork that should be
        merged into "git-deploy sync".

    git deploy provides tools for managing a git based roll out process.

    The basic idea is that the process is divided into basically three
    stages, each one starting with the execution of this tool.

    The steps are as follows:

        $ git deploy start
          # perfom tests
        $ git deploy sync
          # perfom syncronization
        $ git deploy finish

    If there is a problem in general the tool will detect it, and advise you
    of what it is and how to deal with it.

    This will ensure that tags are created which you can roll back to, and
    ensure that they are pushed afterwards, amongst various other things.

    git deploy will fetch all tags from the remote repository configured in
    the current repository before processing. You can disable this behaviour
    by using --no-remote which overrides all remote actions.

    In the case of an unclean working directory an error message will be
    produced and a git status will be output. Note: This includes untracked
    files, which must be either deleted or added to the repositories
    .gitignore (which itself must then be committed) before you can proceed
    with using git deploy. You can disable this with --no-check.

    Additionally git deploy contains a number of utilities for reviewing the
    state of the repository from the point of view of the tags it contains.
    Specifically "--list" and "--list-all" are good ways of viewing the
    rollout history and checking what commit you are on. See the
    documentation for these options for details

  Git Production Environments
    Some environment use a git checkout as their working directory. In this
    case the three step rollout is overkill. As a replacement there is a
    simpler two step process:

        git-deploy start
        git-deploy release

    If you want to abort you can say:

        git-deploy abort

    instead. To use this option you need to configure the repository by

       git config deploy.can_make_tags true

  Deploy Files
    A deploy file consists of a set of keys and values followed by a newline
    followed by the deployment message use to create the deployment tag. For

        commit: 7e25a770901c9b1eb75ad1511580a98acff4ad60
        tag: sheep-20080827-1419
        deploy-date: 2008-08-27 14:19:58
        deployed-by: rafael

        rollout of sheep


    If new key/values are added they will always be added before the blank

  Deploy Hooks
    At various points in the deployment process git-deploy will execute
    user-supplied deployment hooks.

    The idea of this is to provide a mechanism by which actions and tests
    will be automatically executed, and if necessary can prevent the
    syncronization from occuring.

    Deploy hooks can be specific at the generic level, that is for all
    applications, and on an application specific basis.

   Structure of the deploy hooks
    The pre-deploy framework is expected to reside in the
    $GIT_WORK_DIR/deploy directory (i.e. the deploy directory of the
    repository that's being rolled out). This directory has the following

        $GIT_WORK_DIR/deploy/                   # deploy directory
                            /apps/              # Directory per application + 'common'
                                 /common/       # deploy scripts that apply to all apps
                                 /$app/         # deploy scripts for a specific $app
                            /sync/              # sync

    The $app in deploy/{apps,sync}/$app is the server prefix that you'd see
    in the rollout tag. E.g. A company might have multiple environments
    which they roll out, for instance "sheep", "cows" and "goats". Here is a
    practical example of the deployment hooks that might be used in the
    "sheep" environment:

        $ tree deploy/apps/{sheep,common}/ deploy/sync/
        `-- ->
        |-- sheep.sync

    All the hooks in deploy/apps are prefixed by a "phase" in which
    "git-deploy" will execute them (e.g. "pre-pull" just before a pull).

    During these phases "git-deploy" will "glob" in all the
    deploy/apps/{common,$app}/$phase.* hooks and execute them in "sort"
    order, first the "common" hooks and then the $app specific hooks. Note
    that the hooks MUST have their executable bit set.

   Available phase hooks
    Currently, these are the hooks that will be executed. These all
    correspond to specific git-deploy actions:

    *   pre-start

        The first hook to be executed. Will be run before the deployment tag
        is created (but obviously, after we do "git fetch").

    *   pre-pull

        Executed before we update the working tree with "git pull". This is
        where hooks that e.g. take the deployment machine out of the load
        balancer should be executed.

    *   post-pull

        Just after the pull in the "start" phase.

    *   pre-sync

        Just before we create the tag we're about to sync out and execute
        the deploy/sync/$app.sync hook.

    *   post-sync

        After we've synced. Here you could e.g. send custom E-Mails
        indicating that the deployment was a success.

    *   post-rollback

        Hooks executed after a rollback, either via "rollback" or "revert".
        Most of the time you want to use "post-tree-update" hooks instead,
        but this is useful e.g. for putting a staging server back into a
        load balancer.

    These hooks will be executed in one or more action, depending on some
    general condition:

    *   post-tree-update

        Executed after we update the working tree to a new revisions,
        whether that's after the "pull" in the "start" phase, after "git
        reset --hard" in the "rollback" phase, or after a "revert".

        Here's where hooks that e.g. restart the webserver and run any
        critical tests (e.g. config tests) should be run.

        The exit code from these hooks is ignored in actions like "rollback"
        and "revert". We don't want the abort or revert to fail just because
        some webserver didn't restart.

   Return values
    Each script is expected to return a nonzero exit code on failure, and a
    zero exit code on success (in other words standard unix shell return
    semantics). Any script that "fails" will cause "git-deploy" to abort at
    that point.

    More granular failure codes are planned in the future. E.g. "failed but
    should try again", "failed but should ask the user if trying again" etc.
    But this hasn't yet been implemented.

  Sync Hooks
    A special case for a hook that really should be just a regular phase
    hook. But isn't yet because it would have required more major surgery on
    "git-deploy" at the time phase hooks were written, as well as access by
    the author to all deployment environments (which wasn't the case).

    The only notable difference is that there is only one phase hook for
    each $app, and it's located in deploy/sync/$app.sync.

  Testing code on a single server
    For debugging purposes, it can be necessary to have a branch running on
    a single server in production. Here's a sequence that can allow you to
    do that:

        cd /usr/local/git_tree/main
        git-deploy hotfix
        lb <single host> rollout
        git checkout <your branch>
        deployme --hosts=<single host> --no-activate --tag=debugging-<date+time>
        lb <single host> ok

    Check everything works ok on that host, usually logging in through ssh,
    then restore it to its former state lb <single host> rollout

        git checkout trunk
        deployme --no-sync --host=<single host>
        lb <single host> ok
        git-deploy rollback

  config options
        deploy.mail_tool            ( "/usr/sbin/sendmail -f" )
        deploy.tag_prefix                   (Mandatory)                  (Mandatory)

    Future thoughts: use gitconfig to replace most of the other config or
    environment vars.