background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount
Eric.London's picture

There is nothing more frustrating than not having permissions set correctly on a server. I recently tried to commit a bunch of files to subversion and received the following error:

svn: Can't create directory 'sites/default/files/some/path/.svn': Permission denied

This usually indicates your user does not have permission to alter the .svn folders to execute the subversion commit command. The failed command will leave your subversion status with a tilde (~):

$ svn stat
~      sites/default/files/some/path
~      sites/default/files/some/other/path

You'll first need to reset permissions and ownership:

# change directories, you don't want to reset every file permission
$ cd sites/default/files

# use a find command and "-exec" switch to reset ownership and permissions
# NOTE: the group, owner, and permissions will vary on every server configuration
$ find . -exec chown Eric.apache {} \; -exec chmod -R ug+rw {} \;

Now, you can revert the files to remove the tilde (~) status:

$ svn stat
~      sites/default/files/some/path
~      sites/default/files/some/other/path
$ svn revert "sites/default/files/some/path"
$ svn revert "sites/default/files/some/other/path"
$ svn stat
?      sites/default/files/some/path
?      sites/default/files/some/other/path

At this point, you should be able to re-add the files to subversion and commit.

Eric.London's picture

If you've ever gotten the following error, you might need to reset the file permissions and ownership on all of your project files, including the hidden subversion files (located in the .svn folders). This can occur if you've ever executed a subversion command as root, which I try to avoid doing.

svn: Can't open file 'PATH/TO/YOUR/FILES/.svn/lock': Permission denied

The following commands can be used to reset the permissions and ownership for all the files in your directory. NOTE: only execute these commands if you feel comfortable with the shell and know what the file permissions should be set to for your files.

# go to the path of your project
cd /PATH/TO/MY/PROJECT

# reset ownership
# NOTE: replace apache.staff with your user and group
sudo find . -exec chown apache.staff {} \;

# reset permissions
# NOTE: replace 2770 with your file permissions
sudo find . -exec chmod 2770 {} \;

# Now you can run the cleanup command to repair your .svn folders
svn cleanup

Eric.London's picture

I recently had to deploy some new code to an old production environment. Like a good doobie, I made all my changes in a local checked out copy of the subversion file system. I did not want to break the production environment, so I copied the entire vhost into my home directory on the server. I tried to execute an svn update command, but it terminated with the message: object of the same name already exists. This means that a file was creating in my development environment (later revision) that was also created in the production environment. When I ran a svn stat command, there were too many additions, deletions, and modifications, so I decided to write a PHP script to compare the directory structure and files of the 2 environments. I used this script to analyze the file system and create a deployment plan...

<?php
// define where all my files are
$path_httpdocs = '/my/first/path/httpdocs';
$path_httpdocs_new = '/my/second/path/httpdocs';

// get a list of files from the 1st location, ignoring subversion folders
chdir($path_httpdocs);
$files_httpdocs = `find . | grep -v \.svn | sort`;
$files_httpdocs = explode("\n", $files_httpdocs);

// get a list of files from the 2nd location, ignoring subversion folders
chdir($path_httpdocs_new);
$files_httpdocs_new = `find . | grep -v \.svn | sort`;
$files_httpdocs_new = explode("\n", $files_httpdocs_new);

// check for file list diffs
$diffs = array_diff($files_httpdocs, $files_httpdocs_new);
sort($diffs);
echo
"### Additions to httpdocs:\n";
print_r($diffs);

// loop through files and check if they are additions
foreach ($diffs as $f) {
  if (
file_exists($path_httpdocs . '/' . $f) && !file_exists($path_httpdocs_new . '/' . $f)) {
   
// copy new addition to new folder
   
copy($path_httpdocs . '/' . $f, $path_httpdocs_new .'/' . $f);
  }
}

// check for file list diffs
$diffs = array_diff($files_httpdocs_new, $files_httpdocs);
sort($diffs);
echo
"### Additions to httpdocs_new:\n";
print_r($diffs);

// do not continue if there are file differences in the 2 directories
if (count(array_diff($files_httpdocs, $files_httpdocs_new)) || count(array_diff($files_httpdocs_new, $files_httpdocs))) {
  echo
"### Clean up file differences before continuing...\n";
  die;
}

// loop through files and check file properties
$diffs = array();
foreach (
$files_httpdocs as $f) {
  if (!
is_file($path_httpdocs . '/' . $f)) continue;

 
// do a diff on the files 
 
$command = "diff \"$path_httpdocs/$f\" \"$path_httpdocs_new/$f\"";
 
$t = `$command`;

 
// if the diff command generated output, store it
 
if (strlen($t)) {
   
$diffs[$f] = $t;
  }

}

// print all the file diffs
print_r($diffs);
?>

Eric.London's picture

You may have a lot of Drupal sites installed on the same server. Instead of creating a cron job for each individual site, you could write a script like this to loop through your sites and execute each cron job automatically. Here's the script I created using PHP, lynx, and find:

#!/usr/bin/php

<?php

// define where vhosts exist
$sitesDir = '/var/www/vhosts';

// change dir
chdir($sitesDir);

// get a list of directories
// Pipe 1: get all directories
// Pipe 2: remove "./" from beginning of each line
// Pipe 3: remove "."
$command = "find . -maxdepth 1 -type d | sed 's/^\.\///' | sed 's/^\.$//'";

// execute command
$dirs = `$command`;

// convert string into array
$dirs = explode("\n", trim($dirs));

// loop through directories
foreach ($dirs as $d) {
 
// ensure cron.php exists
 
if (file_exists($sitesDir . '/' . $d . '/httpdocs/cron.php')) {
   
$command = "/usr/bin/lynx -source http://$d/cron.php > /dev/null 2>&1";
   
$output = `$command`;
  }
}

?>

I then added the following cron job to root:

#min    hour    dMonth  month   dWeek   command
*/5     *       *       *       *       ~/scripts/drupal-crons.php

Eric.London's picture

Here's a quick shell command that will recursively remove the ".svn" folders in your current path. This can be useful if you want to convert a checked out subversion repository into a normal file system. Just be careful, there is no going back!

find . -type d -name "\.svn" -exec rm -rf {} \;

Syndicate content