A rough dissection of a recent sync between live and stage

A wanted our staging version of our internal site to get synced with production. Technically, we all did, but it was A's request that really kicked off the process. In the past, doing this meant that someone had to manually copy all of the files from the production side to the development side, after first making a copy so that developers could find and reapply their pending changes. With svn, things were a little more straightforward, but still required a certain amount of work.

B and I went into the production side and ran

$ svn diff

This spit out screens full of changes, and then errored. Someone had deleted a directory without telling svn. The solution was pretty easy

$ cd dir
$ svn revert missing_dir
$ svn rm missing_dir
$ svn commit missing_dir

Appropriate check in comments were left, and away we went to the next missing directory. Finally, svn diff ran all the way through, but it was a huge number of files to commit all at once -- and surely they didn't all relate to the same individual changes, right?

An easy way to see the list of changed files is

$ svn status

You can pipe that through grep to see *only* the modified files:

$ svn status | egrep '^M'

You can replace the M with other statuses. I'll leave that as an exercise for the reader. In any case, ideally, we would have taken a list of modified files and figured out which ones belonged to which sets of changes, but some bulk checkins were done under a blanket "getting up to date" style checkin. This isn't optimum, but works.

$ svn commit

Pow! Now the subversion repository has copies of everything that was in the production side.

$ cd ../stage

Let's pretend that that command put us in the correct directory.

Now, what kind of status is stage in? If only there were a way to tell what had changed. Oh!

$ svn diff

Pages and pages later, we realize that a lot has been changed. We want to update, but we don't want to lose our changes.

If we didn't care, we would just do:

$ svn revert

and subversion would do its best to overwrite all of our changes with up to date copies of what was in its repository. Since we just checked in the production side, that would be a good way to make stage match it fairly exactly (minus generated files). But, we don't want to lose our changes, so instead we just do:

$ svn update

Assuming that nothing tragic happens and there are no other problems like filesystem permissions or lock contention, subversion should go through every file and directory and apply changes to bring the stage side up to date without overwriting anything that had already changed on stage. The merging of changes happens not on a file-by-file basis, but on a line-by-line basis.

Let's explain that again, because it's important. I will use a completely fictional example. A and B are both checked out of the repository at the same time. This is not exactly how our production and stage servers were put into svn, but the operation is very similar, so bear with me.

$ svn co path_to_svn/some_project A
$ svn co path_to_svn/some_project B
$ cat A/monkey.txt
foo
bar
baz
$ emacs A/monkey.txt
$ cat A/monkey.txt
foo
monkey
baz
$ echo pirate >>B/monkey.txt
$ cat B/monkey.txt
foo
bar
baz
pirate
$ svn commit A/monkey.txt
(svn messages omitted)
$ svn update B/monkey.txt
(svn messages omitted)
$ cat B/monkey.txt
foo
monkey
baz
pirate

So, you can see that after the various svn magicks, B/monkey.txt has the changes from A and B.

Let's do one more thing, just for show:

$ svn revert B/monkey.txt
(svn messages omitted)
$ cat B/monkey.txt
foo
monkey
baz

This is important, because sometimes you want to throw away changes that you have made. With our stage site, it was assumed that we started with all files up to date with the live side, but it is possible that some things were *older* than on production, rather than *newer*. As such, those files might have to be reverted to be overwritten with the right stuff.

But let's get back from the theoretical to the reality.

$ svn update
(svn messages omitted)

Now, some of those omitted messages involved conflicts. There *were* conflicts. Ain't no thing: we can fix them! But how do we find them?

$ svn status | egrep '^C'
C some_dir/some_conflicting_file.php

I went through and fixed a bunch of conflicts one at a time. I find it useful to search files for <<<<, since that will get to the start of a conflict block. Conflicts also show up when you do an

$ svn diff

so, you can look for them that way, too. I used my best judgment to get files up to date, but there are many files that differ from the live site.

What is the final product?

Stage now has all the changes made to the production side since I first checked everything in. In most places, stage matches production exactly, but there are many unaccounted-for changes to stage that need to be audited and either checked in or thrown away. Do an

$ svn diff

today! The web sites will thank you for it!

0 Responses to A rough dissection of a recent sync between live and stage

  1. There are currently no comments.

Leave a Reply

About You