12

I've got a Git repository in which all my code is in the master branch, and I was previously just ignoring all the Drupal files, so that I kept a strict separation between code that I wrote (or modified or might modify) and code that could be generated with Drush or whatever.

This seemed like a good strategy until I had to upgrade Drupal. I realized I want to be able to roll back if things went poorly, and what better tool to use than Git to do that. I thought to myself this would be the perfect situation for a feature branch, so I made a drupal-7.14 branch, gave it its own .gitignore to ignore all my code and settings files and pay attention to only files that are part of the Drupal install which I wouldn't be touching. I did an upgrade by hand (download, unzip, untar, copy), sorting through borderline cases like robots.txt and .htaccess, and overwriting Drupal's .gitignore with my own. I fixed some settings that worked with 7.14 but not with 7.15, to recover from a 500 error, and then everything seemed perfect. I renamed the branch to drupal-7.15 and was about to go happily on my way.

Until I realized what I had inadvertently done: files that were previously untracked by my master branch but left in the working directory were now removed from the working directory when I checked out master, since they were no longer untracked files! D'oh!

If I merge the drupal-7.15 branch with master I'll lose the separation of code.

There's probably some way to convert a branch to a submodule. Assuming that's possible, that might be the best strategy. I knew before I did this that submodules were the "right" solution, but since I didn't realize the side effect of using branches for previously untracked files, I decided to cut corners and go that route. (Also, all the approaches I've seen to using submodules with Drupal assume that you're starting a new project and Drupal will be the master branch. It is undesirable to me to make someone else's code the master branch, and I already had a repo with a master branch. This looked like it would be unnecessarily complicated just to do an upgrade.)

There may be some other solution that I haven't thought of.

How can I best recover from this with the fewest possible downsides?

UPDATE: This is in development (in a Linux VM on my laptop), and has not gone to production yet. By the time we go to production I plan to have everything wrapped up in feature modules, but that's not in place yet.

UPDATE 2: Submodules may not work. According to Pro Git, "Submodules allow you to keep a Git repository as a subdirectory of another Git repository". Drupal doesn't provide any such a nice separation. Instead of all Drupal code being in a subdirectory, the relationship is more or less inverted, but there's still no clean separation, since you may be editing your .htaccess and robots.txt, so your code and the Drupal repo are mixed together. I'm looking for a workaround to this problem.

9
  • 1
    Your question is really about git. I think you will get better answers by having this migrated to a site that isn't Drupal specific. About upgrades: I always do upgrades by building the make file in a new directory and then update the symlink from old to new public directory, that makes code-rollbacks trivial.
    – Letharion
    Commented Sep 4, 2012 at 14:32
  • 2
    @Letharion I disagree. Everyone will go through this process of upgrading their site from their current version to a new one. Using git to upgrade core is fairly common, as this is a widely used method to upgrade modules. A lot of people will struggle with this problem as, I have had before. There is currently no good documentation on the web that addresses this issue and I believe this is a good place for it.
    – iStryker
    Commented Sep 4, 2012 at 14:41
  • Just to clarify, I think a question about "Best pratice for upgrading Drupal" would then be more suitable, as this question is really "How do I repair a git mistake", which I don't think belong here. Don't have any strong feelings on the topic though, so I'll leave it at that. :)
    – Letharion
    Commented Sep 4, 2012 at 14:46
  • Ok fair enough. The problem Brandon has is fairly common. Maybe I should create a new question or rewrite this one (and move the rest to another question). The first 2-3 paragraph are common. You create a git repo of 7.x-1.0 and you want to upgrade to 7.x-1.1. The problem files are .gitignore, .htaccess and robot.txt. Sometimes you want them track because they are modded, sometime you don't want them tracked because because they are modded. When upgrading the repo do you create a new branch the merge or just update master. @Letharion Suggestion?
    – iStryker
    Commented Sep 4, 2012 at 15:10
  • @Letharion: I thought about whether to put this on StackOverflow as a Git question or here as a Drupal question. If I put it there everyone would complain and say this is really about Drupal, and I think they'd really be right. Even though Git may be the tool used to repair the situation, the direction taken depends on a knowledge of Drupal. Every Drupal user uses Git (or they should if they don't), but only a tiny fraction of Git users use Drupal. People who respond to question about Git aren't going to understand the Drupal background.
    – iconoclast
    Commented Sep 4, 2012 at 15:22

3 Answers 3

10

It seems from discussion above that your question isn't about fixing your git repo, but about maintaining a Drupal site in git, and how that works with core updates.

I think that standard practice is in fact keeping all files in your repository, including Drupal core. The separation of Drupal code from custom code seems like a nice idea, but I don't think it's necessary, and I don't see what advantages it gives you. It also seems to assume that you will never want to patch core (or have to do it as a part of your deploy), which, while it isn't best practice, is definitely something you want to be able to do if something breaks in production. Keeping your commits nice and focused also helps to get this kind of separation.

The solution I've used is to keep all code in the same repository, put as much as possible in Features or other kinds of exports/code/configuration, and maintain a list of patches that need to be applied to out-of-the-box core and contrib.

When you update core, start in your dev environment:

  • Make sure working directory is clean
  • Dump latest database (drush sql-dump). Either make a commit with the dump or save it somewhere safe.
  • Update core (drush up drupal)
  • Commit all changes.
  • Check patches file. If any patches need to be applied, apply them, and make another commit
  • Run update.php if necessary (already done if you used drush for the update)
  • Test your dev site. If everything is fine, push code to production. Run drush updb on production.
  • If there's a problem and you need to revert, either revert or reset your repo (git reset --hard HEAD~2 should do it), or revert the two commits if you want to keep the history. Replace your database with the dump.

The database dump is necessary because you otherwise can't undo changes made to the database by updates. You can also do the updating in a branch, in which case reverting just means checking out master. It's slightly inadvisable if you're working on one dev site because you can't really switch back to master and keep working there in parallel because of the database.

Using this more simple git-side workflow will allow you to use git's full power when you need it without the complication of submodules, etc. If this doesn't seem adequate, could you explain why you need further separation of code?

0

From my comments above, this question you have is about maintaining a Drupal site files with git, and how that works with core updates. You didn't mention anything about backing up and upgrading the database. I will try not to copy anything from goron answer.

I have created a blog post about this issue Upgrading Drupal core on your website with Git

Alternative Methods

  1. Run Drush command drush up drupal
  2. Apply a patch of the differences between the versions. See http://drupal.org/node/359234 & http://fuerstnet.de/en/drupal-upgrade-easier

You didn't state this, but if you are interested in tracking the changes between Drupal versions, I would do this by using tags instead of branches. Once you are done with your upgrade commit to master, tag your code as 7.x.

6
  • If I understand correctly, you're also suggesting that I keep all of Drupal core code in the same repository. This seems to be the consensus. I'm reluctant, but I may have to give in and do it that way.
    – iconoclast
    Commented Sep 4, 2012 at 20:05
  • Yes all in one repository. I have modules, profiles and themes inside the core/main repository that are their own git repos. I don't know if the best way, but its the best way that I know of.
    – iStryker
    Commented Sep 5, 2012 at 12:56
  • this solution provides no way of going back. my reason for vote down. Commented Feb 7, 2013 at 0:07
  • @Serpiente: I don't see why lack of a way to go back should be a reason for a downvote. If it's the best approach, that's enough. If you don't think it's the best approach, please state why not.
    – iconoclast
    Commented May 7, 2014 at 22:33
  • @iconoclast what is the matter of a revision system if you cant go back in your timeline? e.g. think about a failed update - what would be the way to recover here? A shipped version of "whatever" software should have clear dependencies, these include especially the framework core. Otherwise you can simple drop your git and start doing FTP rollouts again. just my 2 cents. Commented May 7, 2014 at 23:17
0

I'm running the setup with two branches just like the OP: one branch with my custom code only, and one branch that has both my custom and core files. I ran into the same situation: the ignored core files are removed when switching between branches.

I ended up having two identical git directories: - one for working on my custom code, with the core files present but ignored, and I would never switch to the "full" branch in this directory - one for performing merges, so that I would perform the branch switching and merging inside this directory only.

The reason that I choose this two-branches setup is because I want to easily track all local commits to core files, it's easier to examine and re-apply core mods when upgrading core files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.