Changes between Version 14 and Version 15 of faq/gitification


Ignore:
Timestamp:
May 27, 2012, 8:55:41 PM (7 years ago)
Author:
Bart
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • faq/gitification

    v14 v15  
     1[[PageOutline]]
     2
    13= Gitification of Indymedia linksunten =
    24
     
    79Since a Drupal website is not a monolithic bloc and nearly each module is maintained by different developers we needed to find a way to update the core and each module separately from one another. The traditional way git offers for this is a concept called [http://git-scm.com/book/en/Git-Tools-Submodules git-submodule]. It is complicated, unintuitive and detested by many for good reasons. But as git follows the [http://docstore.mik.ua/orelly/weblinux2/modperl/ch13_01.htm TMTOWTDI] paradigm we could avoid using git-submodule and settled for [https://github.com/apenwarr/git-subtree git-subtree] instead which has recently been [https://github.com/apenwarr/git-subtree/commit/8cd698957f57f62ec3d313403bebced2fdf751e5 merged] into git core. Besides the possibility to update the core and each module separately and replaying our patches to the updated version automatically, we want the linksunten code to be one git repository which simply "works" after cloning it. After our move to git we will use the [http://drupal.org/project/features features] and [http://drupal.org/project/ctools ctools] modules to version control as much of our configuration data as possible.
    810
    9 == Drupal core ==
     11== Installation ==
     12
     13=== Drupal core ===
    1014
    1115We create a new directory, initialise git, tell git which name and email to use, create a temporary file which we commit, delete and commit again to create a master branch:
     
    5458There are some more modifications to do but they are really linksunten specific (like applying the two core patches via {{{git am}}} which have been created via {{{git format-patch}}} before) so we leave them out.
    5559
    56 == Drupal modules ==
     60=== Drupal modules ===
    5761
    5862Normally, Drupal modules are installed under sites/default/modules. This would be fine with our approach but it would create unnecessary huge merges when updating the core and it keeping all parts separately accessible from the root directory of our installation is much clearer arranged. So we create a modules (and perhaps also a files, libraries and themes) directory, a symbolic link to it and add commit the link:
     
    8690}}}
    8791
    88 == Update a patched module ==
    89 
    90 First, we create a new [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging branch] containing the version of our module we want to update to. As we have already added i18n as a remote we can checkout the desired version in a separate branch using the corresponding [http://git-scm.com/book/en/Git-Basics-Tagging tag]. As long as there are no [http://git.661346.n2.nabble.com/1-8-0-Remote-tag-namespace-td5980437.html separate namespaces for remote tags] in git we definitely want to start with a git fetch to be sure to refer to tag of the right module:
     92== Update ==
     93
     94We are going to update a patched Drupal module using git-subtree and git-rebase. We create a new [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging branch] containing the version of our module we want to update to. As we have already added i18n as a remote we can checkout the desired version in a separate branch using the corresponding [http://git-scm.com/book/en/Git-Basics-Tagging tag]. As long as there are no [http://git.661346.n2.nabble.com/1-8-0-Remote-tag-namespace-td5980437.html separate namespaces for remote tags] in git we definitely want to start with a git fetch to be sure to refer to tag of the right module:
    9195{{{
    9296git fetch i18n-6.x-1.x
     
    115119}}}
    116120
    117 == Migrating the modules ==
    118 
    119 In the past, drupal.org used [http://www.nongnu.org/cvs/ CVS] as version control system and switched to git quite recently. Unfortunately, not all module maintainers have adapted their code base to the new revision control system manually. Instead, the Drupal team migrated lots of projects automatically so at least at the moment you'll often find no tags and generally bad git documentation on drupal.org.
     121The same process can be applied to update the core. Hopefully, you did not need to patch the core (as we did) so a {{{git fetch}}} will reside in [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging fast-forward merges]
     122
     123== Literally controlling versions with git_deply ==
     124
     125In the past, drupal.org used [http://www.nongnu.org/cvs/ CVS] as version control system and switched to git quite recently. Unfortunately, not all module maintainers have adapted their code base to the new revision control system manually. Instead, the Drupal team migrated lots of projects automatically. So at least at the moment, you'll discover that the module releases are not tagged ad all.
     126
     127Another problem is the available updates page at ''/admin/reports/updates''. When checking out a module via git there are no version information added by the drupal.org package manager. Enter [http://drupal.org/project/git_deploy git_deploy]. More precisely, commit 68bd1a8219cbe59e7fbe56b317a600321116ddfa from Thu Apr 26 10:15:16 2012 -0700.
     128
     129=== git_deploy 6.x-2.x ===
     130
     131{{{
     132<?php
     133
     134/**
     135 * @file
     136 *
     137 * This module add versioning information to projects checked out of git.
     138 */
     139
     140/**
     141 * Implement hook_system_info_alter() to provide metadata to drupal from git.
     142 *
     143 * We support populating $info['version'] and $info['project'].
     144 *
     145 * @param $info
     146 *   The module/theme info array we're altering.
     147 * @param $file
     148 *   An object describing the filesystem location of the module/theme.
     149 */
     150function git_deploy_system_info_alter(&$info, $file) {
     151  $type = isset($info['engine']) ? 'theme' : 'module';
     152  if (empty($info['version'])) {
     153    $directory = dirname($file->filename);
     154    // Check whether this belongs to core. Speed optimization.
     155    if (substr($directory, 0, strlen($type)) != $type) {
     156      while ($directory && !is_dir("$directory/.git")) {
     157        $directory = substr($directory, 0,  strrpos($directory, '/'));
     158      }
     159      $git_dir = "$directory/.git";
     160      // Theoretically /.git could exist.
     161      if ($directory && is_dir($git_dir)) {
     162        $git = "git --git-dir $git_dir";
     163        // Find first the project name based on fetch URL.
     164        // Eat error messages. >& is valid on Windows, too. Also, $output does
     165        // not need initialization because it's taken by reference.
     166        exec("$git remote show -n origin 2>&1", $output);
     167        if ($fetch_url = preg_grep('/^\s*Fetch URL:/', $output)) {
     168          $fetch_url = current($fetch_url);
     169          $project_name = substr($fetch_url, strrpos($fetch_url, '/') + 1);
     170          if (substr($project_name, -4) == '.git') {
     171            $project_name = substr($project_name, 0, -4);
     172          }
     173          $info['project'] = $project_name;
     174        }
     175        // Try to fill in branch and tag.
     176        exec("$git rev-parse --abbrev-ref HEAD 2>&1", $branch);
     177        $tag_found = FALSE;
     178        if ($branch) {
     179          $branch = $branch[0];
     180          // Any Drupal-formatted branch.
     181          $branch_preg =  '\d+\.x-\d+\.';
     182          if (preg_match('/^' . $branch_preg . 'x$/', $branch)) {
     183            $info['version'] = $branch . '-dev';
     184            // Nail down the core and the major version now that we know
     185            // what they are.
     186            $branch_preg = preg_quote(substr($branch, 0, -1));
     187          }
     188          // Now try to find a tag.
     189          exec("$git rev-list --topo-order --max-count=1 HEAD 2>&1", $last_tag_hash);
     190          if ($last_tag_hash) {
     191            exec("$git describe  --tags $last_tag_hash[0] 2>&1", $last_tag);
     192            if ($last_tag) {
     193              $last_tag = $last_tag[0];
     194              // Make sure the tag starts as Drupal formatted (for eg.
     195              // 7.x-1.0-alpha1) and if we are on a proper branch (ie. not
     196              // master) then it's on that branch.
     197              if (preg_match('/^(' . $branch_preg . '\d+(?:-[^-]+)?)(-(\d+-)g[0-9a-f]{7})?$/', $last_tag, $matches)) {
     198                $tag_found = TRUE;
     199                $info['version'] = isset($matches[2]) ? $matches[1] . '.' . $matches[3] . 'dev' : $last_tag;
     200              }
     201            }
     202          }
     203        }
     204        if (!$tag_found) {
     205          $last_tag = '';
     206        }
     207        // The git log -1 command always succeeds and if we are not on a
     208        // tag this will happen to return the time of the last commit which
     209        // is exactly what we wanted.
     210        exec("$git log -1 --pretty=format:%at $last_tag 2>&1", $datestamp);
     211        if ($datestamp && is_numeric($datestamp[0])) {
     212          $info['datestamp'] = $datestamp[0];
     213        }
     214
     215        // However, the '_info_file_ctime' should always get the latest value.
     216        if (empty($info['_info_file_ctime'])) {
     217          $info['_info_file_ctime'] = $datestamp[0];
     218        }
     219        else {
     220          $info['_info_file_ctime'] = max($info['_info_file_ctime'], $datestamp[0]);
     221        }
     222      }
     223    }
     224  }
     225}
     226}}}