SVN to Git migration

SVN to Git

SVN was a good enough version control system (VCS) and sometimes even a synonym for VCS in everyday talks. However, technologies change and the way of developing computer software as well, in my opinion, SVN became some kind of “disturbing” or “breaking” thing in development process. It’s slow, centralized and linear. I mean it’s really slow. And when Git was introduced, usually nobody realized how it’s different to SVN and why we need it. Today it’s de-facto standard for VCS. It has a bit different logic, but you can get used to it relatively quickly without any problems.

But back to the topic. So you want to get rid of SVN repository and start using Git without loosing your commits history and other stuff. Actually save all data and work with Git instead of SVN? There’s already enough articles on the internet about that, even in the official book. But I will describe how I did it myself with some additional commands. Everything is done with the help of built in Git commands.

  1. So first, you’ll need an SVN repo to convert. Define a repo path. It may look like this svn://example.com/svn/repo_example/
  2. In case repository requires authorization for accessing it, prepare name and password of SVN user
  3. You will probably want to map SVN usernames to Git users, you can do that by creating a special text file in format: svn_username = Name Surname . Each user on the new line.

    This command will help you to to find all users that were commiting to SVN repo and create authors file:

    svn log --xml | grep -P "^<author" | sort -u | \
          perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt
    

    All you have to do is open it and add appropriate Git usernames on the right hand side.

Ok. Now you’re ready to start the process. Import of SVN repo to the Git is done by git svn clone command. This will init Git repo and import SVN data (you can do that by using separate git commands).

git svn clone --username=SVN_USERNAME --authors-file=/path/to/authors.txt -s --no-metadata svn://example.com/svn/repo_example/

This will create a git repo with the same name in the current folder. It may take a while to complete, especially on bigger repositories.

Once it finished, you’ll have a ready Git repo with your data. But you’re not done yet.

Git doesn’t track empty directories, so you’ll need to fix that. Run:

find . -type d -empty -exec touch {}/.gitignore \;

This will make it track even those empty dirs by creating special empty file .gitignore in them.

Commit changes.

Now, your SVN tags are remote branches in your newly created Git repo. Fix that by running:

git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done

It will convert them to real Git tags.

SVN branches are remote branches as well, fix that too:

git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done

Now they’re normal branches.

You may want to fix some branches names, for example trunk to develop, do that using git command:

git branch -m old_branch_name new_branch_name

Now you can cleanup some SVN stuff in your Git repository you no longer need:

git branch -rd git-svn
git config --remove-section svn-remote.svn
git config --remove-section svn
rm -rf .git/svn

Now you’re all set. If you want to push it to some remote repo, do that by adding an origin and push all data:

git remote add origin [email protected]:repo_name.git
git push origin --all
git push origin --tags

Now you can come back to work using Git repository.

Delete test orders from Magento 1.5.x/1.4.x

So you have a Magento project, created a new theme, added products and categories, and made a few orders for testing of delivery and payment. You made sure that everything works fine and the client is ready to launch your site developed. But you still see weird orders in admin panel. Client says they must be removed and they can’t do that in admin panel. But how? You can only cancel that orders, but they will remain there with status “Cancelled”. Unfortunately, Magento doesn’t to remove them through admin panel, so you will not find any button “Delete Order”. This may frustrate you as a developer and your client. The fact that the ordering data is stored in different database tables (sales, warehouse, etc..)

So you should clean up those manually by running these lines of SQL code:

For Magento 1.5.x:

SET FOREIGN_KEY_CHECKS=0;

TRUNCATE `sales_flat_order`;
TRUNCATE `sales_flat_order_address`;
TRUNCATE `sales_flat_order_grid`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sales_flat_order_status_history`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_order_payment`;
TRUNCATE `sales_flat_quote_payment`;
TRUNCATE `sales_flat_shipment`;
TRUNCATE `sales_flat_shipment_item`;
TRUNCATE `sales_flat_shipment_grid`;
TRUNCATE `sales_flat_invoice`;
TRUNCATE `sales_flat_invoice_grid`;
TRUNCATE `sales_flat_invoice_item`;
TRUNCATE `sendfriend_log`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `wishlist`;
TRUNCATE `log_quote`;
TRUNCATE `report_event`;

ALTER TABLE `sales_flat_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_status_history` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_grid` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;

-- let's reset customers
TRUNCATE `customer_address_entity`;
TRUNCATE `customer_address_entity_datetime`;
TRUNCATE `customer_address_entity_decimal`;
TRUNCATE `customer_address_entity_int`;
TRUNCATE `customer_address_entity_text`;
TRUNCATE `customer_address_entity_varchar`;
TRUNCATE `customer_entity`;
TRUNCATE `customer_entity_datetime`;
TRUNCATE `customer_entity_decimal`;
TRUNCATE `customer_entity_int`;
TRUNCATE `customer_entity_text`;
TRUNCATE `customer_entity_varchar`;
TRUNCATE `log_customer`;
TRUNCATE `log_visitor`;
TRUNCATE `log_visitor_info`;

ALTER TABLE `customer_address_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `log_customer` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor_info` AUTO_INCREMENT=1;

-- Now, let's Reset all ID counters
TRUNCATE `eav_entity_store`;
ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1;

SET FOREIGN_KEY_CHECKS=1;

For Magento 1.4.x:

SET FOREIGN_KEY_CHECKS=0;
TRUNCATE `sales_order`;
TRUNCATE `sales_order_datetime`;
TRUNCATE `sales_order_decimal`;
TRUNCATE `sales_order_entity`;
TRUNCATE `sales_order_entity_datetime`;
TRUNCATE `sales_order_entity_decimal`;
TRUNCATE `sales_order_entity_int`;
TRUNCATE `sales_order_entity_text`;
TRUNCATE `sales_order_entity_varchar`;
TRUNCATE `sales_order_int`;
TRUNCATE `sales_order_text`;
TRUNCATE `sales_order_varchar`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sendfriend_log`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `wishlist`;
TRUNCATE `log_quote`;
TRUNCATE `report_event`;
ALTER TABLE `sales_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;

TRUNCATE `customer_address_entity`;
TRUNCATE `customer_address_entity_datetime`;
TRUNCATE `customer_address_entity_decimal`;
TRUNCATE `customer_address_entity_int`;
TRUNCATE `customer_address_entity_text`;
TRUNCATE `customer_address_entity_varchar`;
TRUNCATE `customer_entity`;
TRUNCATE `customer_entity_datetime`;
TRUNCATE `customer_entity_decimal`;
TRUNCATE `customer_entity_int`;
TRUNCATE `customer_entity_text`;
TRUNCATE `customer_entity_varchar`;
TRUNCATE `log_customer`;
TRUNCATE `log_visitor`;
TRUNCATE `log_visitor_info`;
ALTER TABLE `customer_address_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `log_customer` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor_info` AUTO_INCREMENT=1;
TRUNCATE `eav_entity_store`;
ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1;
SET FOREIGN_KEY_CHECKS=1;

After you have done it, all test orders will be removed from the database. So, you should execute this queries immediately after launch.

Which CMS to choose, WordPress, Drupal or Joomla? [INFOGRAPHICS]

Wich open source backend platform will suit your needs?

With a wealth of open-source CMS platforms available, it’s imperative to do your homework before you select one to use on your site. We have decided to take a microscope to three of the web’s most popular open-source platforms – and there is a good reason for their success. But even if none of these three platforms will perfectly suit your needs, use the questions we have asked to research some other platforms on the market that may be better-tailored to help your site succeed.

Continue reading “Which CMS to choose, WordPress, Drupal or Joomla? [INFOGRAPHICS]”

Can’t find and install Skype (or another app) in Android Market?

I came across this issue few months ago when I bought an Android phone (HTC Wildfire) and of course I needed Skype to be there as I’m using it at work. I was aware that Skype team already released an updated Skype for Android app that supports low-resolution displays (320×240 in this case) and my device was listed on official websites as supported one. But guess what? I even couldn’t find Skype app in Market on my phone, only some chinese apps and searching it by process name returned me 404.

Then I tried to use desktop web version of Android Market to install it in some tricky way (I never “rooted” my phone, in fact I don’t like it (and actually don’t need it)), but that was also unfortunate experience, but at least I’ve got some message like this:

Wow, at least it explains the part of the problem. However I was able to install Skype on another Samsung Android phone with the same carrier and country. And after a minute I realized I have foreign Vodafone card from my last trip. And indeed, with this SIM I easily found Skype app and downloaded/installed it on Wi-Fi. And it even found updates for some Android core apps like Youtube and Google Maps!

So we can conclude that Google is limiting user experience depending on country and carrier, which is bad trend as for the user, taking into consideration internet as a global network, this limit is very confusing, especially for free apps. So if you have another SIM card, try to insert it and search for your app again.

Switch to self-hosted private git easily

Don’t like plans on github or had enough with downtimes on services like that, it’s not enough space provided by git hosting service? No problem! Switch to self-hosted git then, it’s quick and easy, you will still be able to track changes etc in console or via GUI of your git client, or you can even setup gitweb/instaweb to have web-interface. Personally, I don’t like any git hosting service because they’re not reliable and don’t provide enough space and private repos.

So what you need is gitolite – easy to use, well-documented git server managing system via git itself. You can read installation instructions and installation transcript first or just start from below if you feel you’re lucky.

If you’re setting up git on your server obviously you have root access (i will list instructions on this way only, you can find other types of installations.

Copy ~/.ssh/id_rsa.pub from your workstation (or create new one), copy your file to the server. Put it in /tmp/Your_Name.pub.

cd ~
git clone git://github.com/sitaramc/gitolite gitolite-source
cd gitolite-source

Now checkout whatever branch you want, by default it should checkout “pu” branch, or do “git checkout -t origin/pu” if you have another one.

mkdir -p /usr/local/share/gitolite/conf /usr/local/share/gitolite/hooks
src/gl-system-install /usr/local/bin /usr/local/share/gitolite/conf /usr/local/share/gitolite/hooks

Switch to git user:

su - git

if you have su: user git does not exist, you need to add git user to the system then run the command above again:

useradd git
passwd git

Now run:

which gl-setup

This should respond with /usr/local/bin/gl-setup. If this is not what you get, you have some $PATH issues. Make sure /usr/local/bin is in the $PATH for the git user, and that no prior components of the path contain another copy of gl-setup. You must run the one in the directory that is the first argument of gl-system-install above.

Now run setup script and pass it your key:

gl-setup /tmp/YourName.pub

Set up process finishes here. Now clone gitonlite settings repo on your client:

cd
git clone git@server:gitolite-admin

You can find repos setting file in /conf/gitonline.conf:

repo    gitolite-admin
        RW+     =   YourName

repo    testing
        RW+     =   @all

To add new repo, simply add this lines to that file and commit/push on this repo (you will see server response about initializing new repo:

repo    newrepo
        RW+     =   YourName

If you want to add more users, you need to paste key file to /keydir/ with the same username (/keydir/AnotherUser.pub) as you’re adding to repo (AnotherUser for example):

repo    newrepo
        RW+     =   YourName
        RW+     =   AnotherUser

If you want to migrate yout github repos to gitonline, heres a script that helps to do it:

#!/bin/bash

githubuser=your_github_username
gitonlinehost=your_gitonlite_server_hostname
repos=( repo1 repo2 repo3 )

for repo in ${repos[@]}
do
echo $repo
git clone --bare [email protected]:$githubuser/$repo
cd $repo.git
git push --mirror git@gitonlinehost:$repo.git
cd ..
rm -fr $repo.git
done

‘repos’ contain the names of the repos to be migrated. Note that collaborators, comments and anything outside of git itself will not be migrated!

Xerox Phaser 3117 drivers for Mac OS X

If you have a nice GDI printer Xerox Phaser 3117, you will wonder there’s no driver for Mac OS X and Xerox website says this printer is not supported in Mac OS X 10.6.

As you know Mac OS X uses Apple’s developed CUPS (Common UNIX Printing System), so I’ve been used this printer on FreeBSD with Samsung GDI driver, but that wasn’t working via Mac’s interface. Even though there’s a special drivers build for this printer Splix, that was not working properly.

So you need to install 3 packages and select installed driver for your GDI printer:

  1. Samsung GDI (180 KB)

    The samsung-gdi package includes PPDs for 26 Samsung-GDI printers.
    The samsung-gdi package includes PPDs for 26 Samsung-GDI printers.
  2. Foomatic-RIP (640 KB)

    The Foomatic-RIP package installs the necessary core runtime components to enable printing with Foomatic machinery in Mac OS X. This package is generally not useful without Ghostscript and at least one foomatic PPD.
  3. Ghostscript (33 MB)

    GPL Ghostscript is an open-source PostScript interpreter that includes integrated support for the CUPS printing system in Mac OS X. It is the replacement for ESP Ghostscript.

Packages sources are listed here.

And then select the installed driver for your printer:

You’re done!

Remove unused shortcodes from post content


If you have installed some plugin that adds shortcodes like [shortcode id=1] (for example [nggallery id=4], [tweeetmeme id=4 section=Name] etc), one you remove that, this pieces of text will appear in your post content unprocessed (just appear like they are in backend). WordPress has it’s own Shortcode API, so managing them is very easy. So if you don’t plan to use it or just temporary disable, you can use a pretty simple function that you can add to any plugin or theme’s functions.php that removes any shortcode you want from post output:

add_shortcode('shorcodename', 'my_remove_shortcode');
function my_remove_shortcode(){
	return '';
}

Here shortcodename is any shortcode name you want to remove, for example for Next Gen Gallery is nggallery (example shortcode [nggallery id=1])

If you need to remove more shortcodes, just add more add_shortcode lines with your shortcode like this:

add_shortcode('shorcodename', 'my_remove_shortcode');
add_shortcode('nggallery', 'my_remove_shortcode');
function my_remove_shortcode(){
	return '';
}

Changing post count on home page in WordPress template


Some professional WordPress websites usually have custom post roll layout and different post count on homepage. So this means when you go to second page of post roll you should’t see repeating items as a consequence of another post count than set in ‘Blog pages show at most’ setting in Reading section of Settings in WP-admin. Continue reading “Changing post count on home page in WordPress template”