Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Git version control engine #1261

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions commands/pm/download.pm.inc
Expand Up @@ -212,6 +212,16 @@ function drush_pm_download() {
$skip_list = array('.', '..');
$skip_list = array_merge($skip_list, drush_version_control_reserved_files());
drush_scan_directory($request['project_install_location'], '/.*/', $skip_list, 'unlink', TRUE, 'filename', 0, TRUE);

// If the version control engine is a proper vcs we also need to remove
// orphan directories.
if ($version_control->engine != 'backup') {
$empty_dirs = drush_find_empty_directories($request['full_project_path'], $version_control->reserved_files());
foreach ($empty_dirs as $empty_dir) {
// Some VCS files are read-only on Windows (e.g., .svn/entries).
drush_delete_dir($empty_dir, TRUE);
}
}
}

// Copy the project to the install location.
Expand Down
21 changes: 21 additions & 0 deletions commands/pm/pm.drush.inc
Expand Up @@ -1802,6 +1802,27 @@ function pm_drush_engine_version_control() {
'drush [command] cck --svncommitparams=\"--username joe\"' => 'Commit changes as the user \'joe\' (Quotes are required).'
),
),
'git' => array(
'signature' => 'git status %s',
'description' => 'Quickly add/remove/commit your project changes to Git.',
'options' => array(
'gitsync' => 'Automatically add new files to the Git repository and remove deleted files. Caution.',
'gitcommit' => 'Automatically commit changes to Git repository. Implies the --gitsync option.',
),
'sub-options' => array(
'gitcommit' => array(
'gitmessage' => 'Override default commit message which is: Drush automatic commit: <the drush command line used>',
'gitcommitparams' => 'Add options to the `git commit` command',
),
'gitsync' => array(
'gitaddparams' => 'Add options to the `git add` command',
),
),
'examples' => array(
'drush dl --gitcommit ctools' => 'Download the ctools module and commit the changes.',
'drush [command] ctools --gitcommit --gitcommitparams=\"--author joe\"' => 'Commit changes as the user \'joe\' (Quotes are required).'
),
),
);
}

Expand Down
7 changes: 7 additions & 0 deletions commands/pm/updatecode.pm.inc
Expand Up @@ -346,6 +346,13 @@ function pm_update_project($project, $version_control) {
$skip_list = array('.', '..');
$skip_list = array_merge($skip_list, drush_version_control_reserved_files());
drush_scan_directory($project['full_project_path'], '/.*/', $skip_list, 'unlink', TRUE, 'filename', 0, TRUE);

// If the version control engine is a proper vcs we also need to remove
// orphan directories.
if (($version_control->engine != 'backup') && (drush_get_option('package-handler', 'wget') == 'wget')) {
$files = drush_find_empty_directories($project['full_project_path'], $version_control->reserved_files());
array_map('drush_delete_dir', $files);
}
}

// Add the project to a context so we can roll back if needed.
Expand Down
94 changes: 94 additions & 0 deletions commands/pm/version_control/git.inc
@@ -0,0 +1,94 @@
<?php

/**
* @file
* Drush pm GIT extension
*/

class drush_version_control_git implements drush_version_control {

/**
* Implementation of pre_update().
*/
public function pre_update(&$project, $items_to_test = array()) {

// No-op. Nothing to do here.
return TRUE;
}

/**
* Implementation of rollback().
*/
public function rollback($project) {
// TODO, do we need this at all?
// Other VCS implementations do a revert ... but can we trust that a commit was made?
}

/**
* Implementation of post_update().
*/
public function post_update($project) {
if ($this->sync($project)) {
// Only attempt commit on a sucessful sync
$this->commit($project);
}
}

/**
* Implementation of post_download().
*/
public function post_download($project) {
if ($this->sync($project)) {
// Only attempt commit on a sucessful sync
$this->commit($project);
}
}

/**
* Automatically add any unversioned files to Git and remove any files
* that have been deleted on the file system in the full_project_path.
*/
private function sync($project) {
if (drush_get_option('gitsync') || drush_get_option('gitcommit')) {
$errors = '';
if (!drush_shell_exec('git add --all '. drush_get_option('gitaddparams') .' '. $project['full_project_path'])) {
$errors .= implode("\n", drush_shell_exec_output());
}
if (!empty($errors)) {
return drush_set_error('DRUSH_PM_GIT_SYNC_PROBLEMS', dt("Problems were encountered adding or removing files to/from this GIT working copy.\nThe specific errors are below:\n!errors", array('!errors' => $errors)));
}
return TRUE;
}
}

/**
* Automatically commit changes to the repository
*/
private function commit($project) {
if (drush_get_option('gitcommit')) {
$message = drush_get_option('gitmessage');
if (empty($message)) {
$from = '';
if (!empty($project['existing_version'])) {
$from = "from $project[existing_version] ";
}
$version = !empty($project['version']) ? $project['version'] : $project['recommended'];
$message = dt("Update $project[name] ${from}to $version");
}
if (drush_shell_exec('git commit '. drush_get_option('gitcommitparams') .' -m '. escapeshellarg($message))) {
drush_log(dt('Project !name committed to Git successfully', array('!name' => $project['name'])), 'ok');
}
else {
drush_set_error('DRUSH_PM_GIT_COMMIT_PROBLEMS', dt("Problems were encountered committing your changes to Git.\nThe specific errors are below:\n!errors", array('!errors' => implode("\n", drush_shell_exec_output()))));
}
}
else {
drush_print(dt("You should consider committing the new code to your Git repository.\nIf this version becomes undesireable, use Git to roll back."));
}
}

public static function reserved_files() {
// .gitignore is not in this list as it can be safely committed to a project.
return array('.git');
}
}
2 changes: 1 addition & 1 deletion includes/drush.inc
Expand Up @@ -1705,7 +1705,7 @@ function drush_version_control_reserved_files() {

if (!$files) {
// Also support VCSs that are not drush vc engines.
$files = array('.git', '.gitignore', '.hg', '.hgignore', '.hgrags');
$files = array('.hg', '.hgignore', '.hgrags');
$engine_info = drush_get_engines('version_control');
$vcs = array_keys($engine_info['engines']);
foreach ($vcs as $name) {
Expand Down