Practical SVN for PHP Developers

Embed Size (px)

Citation preview

  • 1. Practical SVNfor PHP Developers Matthew Weier O'Phinney Project Lead Zend Framework Lorna Jane Mitchell Software Engineer Ibuildings

2. What is Version Control? 3.

  • What didyouchange from the previous revision?
  • What changes haveothersrecorded since your last local update?

Change Management 4. Types ofVersion Control 5.

  • Each checkout is a fully functional repository
  • Anybody may accept patches from anyone else
  • Anybody may send patches to anyone else
  • Ideal for projects with parallel feature developement

Distributed 6.

  • One canonical repository
  • All changes are submitted to the repository
  • All changes are retrieved from the repository
  • Ideal when:
    • a canonical version is required,
    • access to the repository should be controlled

Non-Distributed 7. What is Subversion? 8.

  • Non-Distributed Version Control System
  • Successor to CVS
  • Stores and versions:
    • source code
    • documentation
    • anything, really

Subversion is... 9. Installing Subversion 10. Choose a Protocol 11.

  • give repo access to local users
  • give users and/or groups read/write on the repo to grant access
  • file:///home/lorna/svn-repos/main/trunk/

Local filesystem 12.

  • give repo access to users with ssh credentials
  • give users and/or groups read/write on the repo to grant access
  • svn+ssh svn://rivendell/home/lorna/svn-repos/main/trunk

svn+ssh 13.

  • make repo web-browseable and have apache handle credentials
  • basic or digest HTTP authentication (e.g., .htpasswd)
  • mod_authz_svn - an Apache module to give finer access control
  • http://svn.example.com/main/trunk

WebDAV via HTTP/S 14. Installing on Linux 15.

  • Debian/Ubuntu:aptitude install subversion
  • Fedora/RedHat:yum install subversion

Distribution packages 16.

  • download from http://subversion.tigris.org
  • check dependencies (install apache, mod_dav, etc., first)
  • compile

From source 17. Setting up a repository 18. Whatisa repository ? 19.

  • The place all changesets are stored
  • A black box; you may only interact with it using svn tools

A repository is... 20. Creating the repository 21. Use svnadmin create 22. Create initial content 23. Commit initial structure 24. Alternate way: import into the repo 25. About repository structure 26.

  • Trunk the main code version
  • Branches copies of code which can be modified
  • Tags copies of code which are never changed
  • All are cheap copies

Repository Structure 27. Using Subversion 28. Checkout: svn checkout (co) 29. .svn directory 30. Status: svn status (st) 31.

  • ' ' no modifications
  • 'A' Added
  • 'C' Conflicted
  • 'D' Deleted
  • 'M' Modified
  • '?' item is not under version control
  • '!' item is missing (removed by non-svn command) or incomplete
  • 'X' external resource managed by svn (svn:externals)

Common status codes 32. Add to repo: svn add 33. Commit to repo: svn commit (ci) 34. Changelog: svn log 35. Dealing with missing files 36.

  • ! in the status listing
  • Usually because something was moved or deletedwithout using the svn tools
  • Alwaysuse svn rm and svn mv
  • To fix: update (svn up) and try again

Missing files - ! in the status 37. What and When to commit 38.

  • hourly, semi-daily, daily checkins
  • code only, tests only, docs only

Badpractices 39. Each commit should include all code, tests, and docs related to a discrete behavior or set of functionality. TheBest Practice: 40.

  • Easy to cherry-pick changesets between branches
  • Trivial to identify changesets to rollback

Why? 41. Examples 42. Examples 43.

  • PLAN your project; break it into distinct units of functionality
  • Use an issue tracker; issues should include expectations, actual results, and reproduce code (these become your tests!)
  • No unit of functionality should take more than 3-4 hours to implement; longer, and it likely should be broken into sub-tasks.

How? 44. Conflicts 45.

  • svnblame / annotate / praise
  • shows who last edited which line

svn blame 46. Example 47.

  • Two people change same line of same file
  • svn will ask user to choose

Conflicts 48.

  • index.php.r4version from before either your changes or the commit that has conflicted
  • index.php.r6current repo version
  • index.php.mineworking copy before server showed conflict
  • index.phpwhole file with some markup to show just the conflict(s) in place

Example: conflict adds files 49.

  • edit index.php until correct
  • may copy one of the "extra" files into place of this one
  • let SVN know you're all sorted

svn resolved 50.

  • Good team communication
  • Update often
  • Commit first!

Avoiding Conflicts 51. Branching and Tagging 52. Patterns 53. Feature Branches Graph by Eli White 54.

  • Pros:
    • Features may be developed in isolation
    • Trunk always contains finished features
  • Cons:
    • Features may be developed in isolation
    • Hard to cleanly merge at times if multiple features touch the same areas of code
    • Harder to rollback (trunk doesn't always have discrete featuresets)

Feature Branches 55. Long-lived Branches Graph by Eli White 56.

  • Pros:
    • Production is always stable
    • Rollback by pointing to production tags
  • Cons:
    • Long-lived feature development often lags trunk features
      • Difficult to determine what to merge
    • Difficult to do parallel feature development
    • More difficult to rollback specific features

Long-lived Branches 57. Release Branches Graph by Eli White 58.

  • Pros:
    • Easy to isolate features by version (parallel development)
    • Possibility of keeping multiple active versions of a project
  • Cons:
    • Harder to merge patches between branches (files may differ widely)

Release Branches 59. Merging 60.

  • Moving changes between branches (including trunk)
  • Merge single changes
  • Merging as part of a branch lifecycle

Merging 61.

  • Check out the target branch
  • From the target directory, run svn diff until the output illustrates the operation you wanted
  • Replace "diff" with "merge"
  • Review changes to working copy and/or test

How to merge 62.

  • Use svn log to identify discrete changesets you want to merge.
  • Use the cherry-pick flag of svn merge (-c) to merge that single changeset.
  • Works well if you're following the best practices outlined earlier!

How to merge: the easy way 63. Administering Repositories 64. Backing up your Repository 65.

  • Copying files directly can lead to corruption in the copy
  • Use svnadmin hotcopy orsvnadmin dump

svnadmin hotcopy 66. Authentication 67.

  • Dependent on how the OS does authentication:
    • Local accounts
    • Virtual accounts
    • etc.
  • SSH public keys are a common solution

svnserve or svn+ssh 68.

  • Typically HTTP basic or digest authentication
    • Use htpasswd to generate user/pass pairs
    • Can still allow anonymous access
    • Configure your server to require it

WebDAV (http/https) 69. Example HTTP Auth configuration 70. Authorization 71.

  • Typically conf/authz in your repo, or access.conf accessible to web server
  • INI-style file with [sections]
    • [groups]section to define users and groups
    • [/path]specifies path on repo
    • [repo:/path]specifies path on specific repo (if more than one repo defined)

ACL File 72.

  • ACLs:
    • [user|group] = [r|rw]
    • * as group/user means any user
    • Groups are prefixed with @

ACL File 73. ACL File: example 74.

  • Svnserve, file access, or svn+ssh: conf/authz in your repository
  • WebDAV: anywhere.
    • Tell your vhost where to find it
    • Must setup authorization prior to authentication

ACL File: placement 75. ACL File in WebDAV: vhost setup 76. Hooks 77.

  • Allow extending SVN's capabilities via userland scripts
  • Hook into specific processes:
    • pre/post-commit, start-commit
    • pre/post-revprop-change
    • pre/post-lock
    • pre/post-unlock

What are hooks? 78. Running a linter REPOS = "$1" TXN = "$2" PHP = "/path/to/php" SVNLOOK = "/path/to/svnlook" AWK = "/path/to/awk" GREP = "/path/to/egrep" SED = "/path/to/sed" CHANGED = `$SVNLOOK changed -t "$TXN" "$REPOS" |$AWK '{print $2}' |$GREP php$` for FILE in $CHANGED do MESSAGE = `$SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | $PHP -l` if [ $? - ne 0 ] then echo 1 >& 2 echo "***********************************" 1 >& 2 echo "PHP error in: $FILE:" 1 >& 2 echo `echo "$MESSAGE" | $SED "s| -| $FILE|g"` 1 >& 2 echo "***********************************" 1 >& 2 exit 1 fi done 79. *********************************** PHP error in: test.php echo $foobar *********************************** Sample linter output 80.

  • Run post-commit prevents blocking issues
  • Send email notification when tests fail
  • Two approaches:
    • Run entire suite
    • Grep committed files for classes, and test just those classes
  • Typically best to do this from a Continuous Integration server, and not via subversion hooks

Running unit tests 81.

  • Email, Nabaztag, TwitterSVN
  • Email notifications post-commit
  • SVN::Notify:
    • http://search.cpan.org/~dwheeler/SVN-Notify-2.79/lib/SVN/Notify.pm
    • Can selectively determine which people/lists get notifications based on commit path
    • Plain text and/or HTML emails

Sending notifications 82. Example notification: 83.

  • svn2feed.py: http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/svn2feed.py
  • Add svn2feed.py to your hooks/ directory

Publishing RSS Feeds 84. Adding svn2feed.py to yourpost-commit hook: path / to / python path / to / hooks / svn2feed.py-- svn - path / usr / bin /-- max - items = 100-- format = atom-- revision "$REV" item - url"http://localhost/svn/" -- feed - url = "http://localhost/rss/svn.rss" -- feed - file "path/to/rss/svn.rss" "$REPOS" & 85.

  • Trigger docbook build process, or PhpDocumentor
  • Run post-commit, so as not to block
  • Typically best done from a CI server, and not subversion hooks

Generating documentation 86.

  • PHP_CodeSniffer includes a script, bin/scripts/phpcs-svn-pre-commit
    • Edit the script to provide the path to svnlook:
    • define('PHP_CODESNIFFER_SVNLOOK','/usr/bin/svnlook');
  • Edit the pre-commit hook script to invoke the script:
    • /path/to/bin/scripts/phpcs-svn-pre-commit "$REPOS" -t "$TXN" >&2 || exit 1

Running PHP_CodeSniffer 87.

      • Transmitting file data .svn: Commit failed (details follow):
      • svn: 'pre-commit' hook failed with error output:
      • FILE: temp.php
      • ---------------------------------------------------------------
      • FOUND 1 ERROR(S) AND 0 WARNING(S) AFFECTING 1 LINE(S)
      • ---------------------------------------------------------------
      • 2 | ERROR | Missing file doc comment
      • --------------------------------------------------------------

PHP_CodeSniffer hook output 88.

      • http://pear.php.net/manual/en/package.php.php-codesniffer.svn-pre-commit.php

For more info on PHP_CodeSniffer: 89. Deploying from SVN 90.

  • What else needs to happen at deploy time?
  • Preserve uploads
  • Set permissions
  • Database patches

Deployment Considerations 91.

  • Checkout retains link to repo
  • Meta data present on server
  • Inconsistent state during update
  • Export is clean copy, no dependencies
  • Other ways to keep track of version

Checkout or Export 92.

  • Tag and export from svn include some tag info
  • Use symlinks to enable seamless switching
  • Wrap in a script
  • Have a rollback plan/script
  • Consider database strategies

Best Practices 93. Thank you.