How to actually use a source control system? - version-control

So I get that most of you are frowning at me for not currently using any source control. I want to, I really do, now that I've spent some time reading the questions / answers here. I am a hobby programmer and really don't do much more than tinker, but I've been bitten a couple of times now not having the 'time machine' handy...
I still have to decide which product I'll go with, but that's not relevant to this question.
I'm really struggling with the flow of files under source control, so much so I'm not even sure how to pose the question sensibly.
Currently I have a directory hierarchy where all my PHP files live in a Linux Environment. I edit them there and can hit refresh on my browser to see what happens.
As I understand it, my files now live in a different place. When I want to edit, I check it out and edit away. But what is my substitute for F5? How do I test it? Do I have to check it back in, then hit F5? I admit to a good bit of trial and error in my work. I suspect I'm going to get tired of checking in and out real quick for the frequent small changes I tend to make. I have to be missing something, right?
Can anyone step me through where everything lives and how I test along the way, while keeping true to the goal of having a 'time machine' handy?

Eric Sink has a great series of posts on source control basics. His company (Sourcegear) makes a source control tool called Vault, but the how-to is generally pretty system agnostic.

Don't edit your code on production.
Create a development environment, with the appropriate services (apache w/mod_php).
The application directory within your dev environment is where you do your work.
Put your current production app in there.
Commit this directory to the source control tool. (now you have populated source control with your application)
Make changes in your new development environment, hitting F5 when you want to see/test what you've changed.
Merge/Commit your changes to source control.

Actually, your files, while stored in a source repository (big word for another place on your hard drive, or a hard drive somewhere else), can also exist on your local machine, too, just where they exist now.
So, all files that aren't checked out would be marked as "read only", if you are using VSS (not sure about SVN, CVS, etc). So, you could still run your website by hitting "F5" and it will reload the files where they currently are. If you check one out and are editing it, it becomes NOT read only, and you can change it.
Regardless, the web server that you are running will load readonly/writable files with the same effect.

You still have all the files on your hard drive, ready for F5!
The difference is that you can "checkpoint" your files into the repository. Your daily life doesn't have to change at all.

You can do a "checkout" to the same directory where you currently work so that doesn't have to change. Basically your working directory doesn't need to change.

This is a wildly open ended question because how you use a SCM depends heavily on which SCM you choose. A distributed SCM like git works very differently from a centralized one like Subversion.
svn is way easier to digest for the "new user", but git can be a little more powerful and improve your workflow. Subversion also has really great docs and tool support (like trac), and an online book that you should read:
http://svnbook.red-bean.com/
It will cover the basics of source control management which will help you in some way no matter which SCM you ultimately choose, so I recommend skimming the first few chapters.
edit: Let me point out why people are frowning on you, by the way: SCM is more than simply a "backup of your code". Having "timemachine" is nothing like an SCM. With an SCM you can go back in your change history and see what you actually changed and when which is something you'll never get with blobs of code. I'm sure you've asked yourself on more than one occasion: "how did this code get here?" or "I thought I fixed that bug"-- if you did, thats why you need SCM.

You don't "have" to change your workflow in a drastic way. You could, and in some cases you should, but that's not something version control dictates.
You just use the files as you would normally. Only under version control, once you reach a certain state of "finished" or at least "working" (solved an issue in your issue tracker, finished a certain method, tweaked something, etc), you check it in.
If you have more than one developer working on your codebase, be sure to update regularly, so you're always working against a recent (merged) version of the code.

Here is the general workflow that you'd use with a non-centralized source control system like CVS or Subversion: At first you import your current project into the so-called repository, a versioned storage of all your files. Take care only to import hand-generated files (source, data files, makefiles, project files). Generated files (object files, executables, generated documentation) should not be put into the repository.
Then you have to check out your working copy. As the name implies, this is where you will do all your local edits, where you will compile and where you will point your test server at. It's basically the replacement to where you worked at before. You only need to do these steps once per project (although you could check out multiple working copies, of course.)
This is the basic work cycle: At first you check out all changes made in the repository into your local working copy. When working in a team, this would bring in any changes other team members made since your last check out. Then you do your work. When you've finished with a set of work, you should check out the current version again and resolve possible conflicts due to changes by other team members. (In a disciplined team, this is usually not a problem.) Test, and when everything works as expected you commit (check in) your changes. Then you can continue working, and once you've finished again, check out, resolve conflicts, and check in again. Please note that you should only commit changes that were tested and work. How often you check in is a matter of taste, but a general rule says that you should commit your changes at least once at the end of your day. Personally, I commit my changes much more often than that, basically whenever I made a set of related changes that pass all tests.

Great question. With source control you can still do your "F5" refresh process. But after each edit (or a few minor edits) you want to check your code in so you have a copy backed up.
Depending on the source control system, you don't have to explicitly check out the file each time. Just editing the file will check it out. I've written a visual guide to source control that many people have found useful when grokking the basics.

I would recommend a distributed version control system (mercurial, git, bazaar, darcs) rather than a centralized version control system (cvs, svn). They're much easier to setup and work with.
Try mercurial (which is the VCS that I used to understand how version control works) and then if you like you can even move to git.
There's a really nice introductory tutorial on Mercurial's homepage: Understanding Mercurial. That will introduce you to the basic concepts on VCS and how things work. It's really great. After that I suggest you move on to the Mercurial tutorials: Mercurial tutorial page, which will teach you how to actually use Mercurial. Finally, you have a free ebook that is a really great reference on how to use Mercurial: Distributed Revision Control with Mercurial
If you're feeling more adventurous and want to start off with Git straight away, then this free ebook is a great place to start: Git Magic (Very easy read)
In the end, no matter what VCS tool you choose, what you'll end up doing is the following:
Have a repository that you don't manually edit, it only for the VCS
Have a working directory, where you make your changes as usual.
Change what you like, press F5 as many times as you wish. When you like what you've done and think you would like to save the project the way it is at that very moment (much like you would do when you're, for example, writing something in Word) you can then commit your changes to the repository.
If you ever need to go back to a certain state in your project you now have the power to do so.
And that's pretty much it.

If you are using Subversion, you check out your files once . Then, whenever you have made big changes (or are going to lunch or whatever), you commit them to the server. That way you can keep your old work flow by pressing F5, but every time you commit you save a copy of all the files in their current state in your SVN-repository.

Depends on the source control system you use. For example, for subversion and cvs your files can reside in a remote location, but you always check out your own copy of them locally. This local copy (often referred to as the working copy) are just regular files on the filesystem with some meta-data to let you upload your changes back to the server.
If you are using Subversion here's a good tutorial.

Depending on the source control system, 'checkout' may mean different things. In the SVN world, it just means retrieving (could be an update, could be a new file) the latest copy from the repository. In the source-safe world, that generally means updating the existing file and locking it. The text below uses the SVN meaning:
Using PHP, what you want to do is checkout your entire project/site to a working folder on a test apache site. You should have the repository set up so this can happen with a single checkout, including any necessary sub folders. You checkout your project to set this up one time.
Now you can make your changes and hit F5 to refresh as normal. When you're happy with a set of changes to support a particular fix or feature, you can commit in as a unit (with appropriate comments, of course). This puts the latest version in the repository.
Checking out/committing one file at a time would be a hassle.

A source control system is generally a storage place for your files and their history and usually separate from the files you're currently working on. It depends a bit on the type of version control system but suppose you're using something CVS-like (like subversion), then all your files will live in two (or more) places. You have the files in your local directory, the so called "working copy" and one in the repository, which can be located in another local folder, or on another machine, usually accessed over the network. Usually, after the first import of your files into the repository you check them out under a working folder where you continue working on them. I assume that would be the folder where your PHP files now live.
Now what happens when you've checked out a copy and you made some non-trivial changes that you want to "save"? You simply commit those changes in your working copy to the version control system. Now you have a history of your changes. Should you at any point wish to go back to the version at which you committed those changes, then you can simply revert your working copy to an older revision (the name given to the set of changes that you commit at once).
Note that this is all very CVS/SVN-specific, as GIT would work slightly different. I'd recommend starting with subversion and reading the first few chapters of the very excellent SVN Book to get you started.

This is all very subjective depending on the the source control solution that you decide to use. One that you will definitely want to look into is Subversion.
You mentioned that you're doing PHP, but are you doing it in a Linux environment or Windows? It's not really important, but what I typically did when I worked in a PHP environment was to have a production branch and a development branch. This allowed me to configure a cron job (a scheduled task in Windows) for automatically pulling from the production-ready branch for the production server, while pulling from the development branch for my dev server.
Once you decide on a tool, you should really spend some time learning how it works. The concepts of checking in and checking out don't apply to all source control solutions, for example. Either way, I'd highly recommend that you pick one that permits branching. This article goes over a great (in my opinion) source control model to follow in a production environment.
Of course, I state all this having not "tinkered" in years. I've been doing professional development for some time and my techniques might be overkill for somebody in your position. Not to say that there's anything wrong with that, however.

I just want to add that the system that I think was easiest to set up and work with was Mercurial. If you work alone and not in a team you just initialize it in your normal work folder and then go on from there. The normal flow is to edit any file using your favourite editor and then to a checkin (commit).
I havn't tried GIT but I assume it is very similar. Monotone was a little bit harder to get started with. These are all distributed source control systems.

It sounds like you're asking about how to use source control to manage releases.
Here's some general guidance that's not specific to websites:
Use a local copy for developing changes
Compile (if applicable) and test your changes before checking in
Run automated builds and tests as often as possible (at least daily)
Version your daily builds (have some way of specifying the exact bits of code corresponding to a particular build and test run)
If possible, use separate branches for major releases (or have a development and a release branch)
When necessary, stabilize your code base (define a set of tests such that passing all of those tests means you are confident enough in the quality of your product to release it, then drive toward 0 test failures, i.e. ban any checkins to the release branch other than fixes for the outstanding issues)
When you have a build which has the features you want and has passed all of the necessary tests, deploy it.
If you have a small team, a stable product, a fast build, and efficient, high-quality tests then this entire process might be 100% automated and could take place in minutes.

I recommend Subversion. Setting up a repository and using it is actually fairly trivial, even from the command line. Here's how it would go:
if you haven't setup your repo (repository)
1) Make sure you've got Subversion installed on your server
$ which svn
/usr/bin/svn
which is a tool that tells you the path to another tool. if it returns nothing that tool is not installed on your system
1b) If not, get it
$ apt-get install subversion
apt-get is a tool that installs other tools onto your system
If that's not the right name for subversion in apt, try this
$ apt-cache search subversion
or this
$ apt-cache search svn
Find the right package name and install it using apt-get install packagename
2) Create a new repository on your server
$ cd /path/to/directory/of/repositories
$ svnadmin create my_repository
svnadmin create reponame creates a new repository in the present working directory (pwd) with the name reponame
You are officially done creating your repository
if you have an existing repo, or have finished setting it up
1) Make sure you've got Subversion installed on your local machine per the instructions above
2) Check out the repository to your local machine
$ cd /repos/on/your/local/machine
$ svn co svn+ssh://www.myserver.com/path/to/directory/of/repositories/my_repository
svn co is the command you use to check out a repository
3) Create your initial directory structure (optional)
$ cd /repos/on/your/local/machine
$ cd my_repository
$ svn mkdir branches
$ svn mkdir tags
$ svn mkdir trunk
$ svn commit -m "Initial structure"
svn mkdir runs a regular mkdir and creates a directory in the present working directory with the name you supply after typing svn mkdir and then adds it to the repository.
svn commit -m "" sends your changes to the repository and updates it. Whatever you place in the quotes after -m is the comment for this commit (make it count!).
The "working copy" of your code would go in the trunk directory. branches is used for working on individual projects outside of trunk; each directory in branches is a copy of trunk for a different sub project. tags is used more releases. I suggest just focusing on trunk for a while and getting used to Subversion.
working with your repo
1) Add code to your repository
$ cd /repos/on/your/local/machine
$ svn add my_new_file.ext
$ svn add some/new/directory
$ svn add some/directory/*
$ svn add some/directory/*.ext
The second to last line adds every file in that directory. The last line adds every file with the extension .ext.
2) Check the status of your repository
$ cd /repos/on/your/local/machine
$ svn status
That will tell you if there are any new files, and updated files, and files with conflicts (differences between your local version and the version on the server), etc.
3) Update your local copy of your repository
$ cd /repos/on/your/local/machine
$ svn up
Updating pulls any new changes from the server you don't already have
svn up does care what directory you're in. If you want to update your entire repository, makre sure you're in the root directory of the repository (above trunk)
That's all you really need to know to get started. For more information I recommend you check out the Subversion Book.

Related

Eclipse: How to export local history to a real SCM system like Git or SVN

I have an Eclipse project which started out as a smallish, quick'n'dirty, private hack. I did not bother to use a real SCM (source code management) system like Git or SVN, not even locally. What I have instead is a few days' worth of Local History, an out-of-the-box Eclipse feature. As so often, the project grew and I want to share it including history, because the history shows a lot of refactoring steps which come in handy as a showcase in order to teach someone else about refactoring, clean code etc.
I already know that I can manually retrieve old versions file by file and manually migrate them to e.g. a Git repository, committing changes one by one and file by file. But what I am really interested in is:
Can I reset the whole project (not just a single file) to a certain date using Local History?
Is there a way to export certain (or all) snapshots of the local project history, so I can commit them to Git snapshot by snapshot?
Is there even an option (or an external tool, script etc.) by means of which I can automatically migrate a project's local history to a real SCM system like Git (preferred) or SVN? It would also be okay if the tool just created lots of full project snapshots in subfolders named by timestamps.
Disclaimer: Yes, I do know that I should have used Git right from the start. It would have cost me just three minutes to set up a local repository etc. But... BUT. You know. ;-)
I don't think there is, but keep in mind that the task shouldn't be too tedious.
Make a copy of your project before starting, just for safety's sake and then:
git init
(revert to snapshot 1)
git add .
git commit -m "First snapshot commit"
(revert to snapshot 2)
git add .
git commit -m "Second snapshot commit"
Wash, rinse, repeat.
If you've only got a few dozen snapshots, it shouldn't take more than an hour or so to do, which is probably a lot less than it would take to figure out a programmatic solution.
Unfortunately, the answer is "no" to all of your questions. At least, using standard built-in Eclipse functionality; there's always a chance that someone has written a plugin that meets your needs, but in this case I'd be surprised. Check the Eclipse Marketplace (found under the Help menu).

Which version control system should I use for my small personal code files?

I have some general scripts that I use and they keep getting modified over time. Right now, I do not use any version control software for them so basically the old files are lost unless I explicitly save them.
I need a good minimal version control system that I can use on a single machine. Which one do you use for such projects?
Git or mercurial both work great. No server required.
I've used subversion for this in the past. Mostly this is because I'm in windows, and TortoiseSVN is a dead simple UI for my repo.
For a scenario like yours, which is relatively simple, I'd recommend using either what you're familiar with, or what is easy to use on your platform.
Git is actually really easy to use in such a setting, and it scales just as well to really small repositories with a few commits a month as it does to huge ones with a hundred a day. Here's how you would set up such a repository:
$ cd ~/your-scripts
$ git init
$ git add .
$ git commit -m 'Start script repository'
Ta-da!
As a hosting solution we make use of http://codesion.com/free_cvs_svn, you will note they also support Git hosting. They also host a bunch of other services that go hand in-in-hand with versioning.
Check out some of the personal version control systems. Hers is a short list:
FileHamster
History Explorer
FolderTrack
Oops! Backup
They are super easy to use and "automatically checkin" when ever you modify your files.
Note: I am the author of FolderTrack and recomend it for software because it can treat a bunch of files as 1 big project. Therefore if you need to revert your project to where it was yesterday, it will revert the 8, 10, or how ever many other files you modified since that time.
Free code: BOS

Managing web project over multiple hosts with revision control

Greetings! :-)
I would like to describe a workflow strategy with some gaps in it, and I would be glad if you could fill in the gaps and otherwise give comments. If admins think that this does not validate as a question, then please delete away.
I am working on a webproject having files with PHP, Javascript (jQuery), HTML, CSS and postgresql code for in-database functions, table creation and configuration. All files are changed frequently. I use Apache.
This is what I want:
Introduce revision control.
Use build files for managing compilation and revision control.
Start using a proper IDE.
Be able to hack on my stationary and laptop with little time wasted on keeping code and IDE project configurations synchronized.
Have a setup for the project so some friends (approx 4-5) may join the project in the future.
This is what I am planning to start to use:
Bazaar for revision control and "project distribution".
Ant for build files.
Eclipse setup with proper plugins for managing Bazaar and Ant.
With Bazaar I intend to put code files, build files and even Eclipse project configuration files (configuration files of the project that I create in Eclipse to work with the webproject) under revision control. That way I can pull all that stuff from my stationary to my laptop via Bazaar.
Since I also put Eclipse's project conf files under revision control, I expect that I can without hazzle immediately open the Eclipse project directly on my laptop. So even if I make modifications to the project settings in Eclipse this should also be synchronized over laptop and host.
But I do have a few questions. Do you know how I should use bazaar so that I am notified or stopped when I try to modify the code on my stationary but have forgotten to push/check-in modifications from my laptop?
Also how should I setup Bazaar so that others can easily join the project in the future? I dont like using a service like launchpad, and would like my stationary to be the server. Is it not a bit risky to do it through ssh because I would have to create a new user account on my stationary each time a new user wants to join in?
Thoughts? Comments? It would be appreciated.
On the first question, you should consider using "checkouts", also called bound branches. That makes bzr behave more like svn in that every commit automatically goes to the "server" and you can't forget to push. Of course, bzr can't really detect if you forget to commit something.
On the second question, you can set up a bzr server that runs over HTTP/DAV and uses the web server's authentication methods. However, if you don't really like other people using your machine as a server, you might want to consider using a totally distributed approach, where your codevelopers publish their own branches and you pull in the things you want.
The Bazaar documentation is quite good and has the details on these topics.

When it comes to developing for the IPhone, should I use Git or Subversion?

It sounds to me like subversion's centralized model works better for web application development where you have a team of engineers working currently on the same code base and releasing constantly.
On the other hand Git's distributed model is appealing for an IPhone app because 1) I dont' need a connection to browse the repository 2) it's a lot faster 3) development will be shared but not as often.
Sorry if I answered my own question and I don't mean stir a debate, feel free to give single line answers.
Definitely git. I've learnt two new things this year: iPhone programming and git.
Whilst iPhone programming has made me hate my life, git has improved the way
I develop software. The painless branching has meant that I can
make a branch for everything, without telling the rest of the world, and when
I'm completely satisfied with it I can merge it back into our wonderfully stable
master/trunk.
It's great, there's no pressure to release anything that isn't ready and seeing
as you can check in locally, it's easier to sculpt small, useful commits.
I'm still undecided on the iPhone thing.
I'd vote for whichever one you had configured in your shop.
One thing you should realize about distributed vs. centralized VCS is that a distributed one can do everything a centralized one can. With git, you can have a single public repository, the authoritative version of the code, managed in any number of ways - for example, if all of the developers can push to it, it gains everything you want about a centralized VCS, except with all the added benefits of git and none of the inadequacies of CVS/SVN.
While Xcode has SVN integration, I find it to be an extremely poor implementation. You can check out (sorry for the pun) the excellent Versions if you'd like an alternative.
Having said that, I'm basically a one-man shop (although I use two machines) and I find git to be much nicer to use.
I am a one man shop when it comes to iPhone development, and I use Mercurial (which is very, very similar to git). My deciding factor was simply that I wanted to learn to use a distributed source management system.
The primary difference if you are a one man shop is that code branching and merging is much easier in git/Mercurial. A minor difference is that svn repositories take up much more disk space (but on an iPhone project, this is not terribly likely to be a major issue). Other than that, you are not likely to notice that much of a difference.
Here's my general advice on source control. Subversion is by far my favorite tool, and the one I have the most experience with. That said, the first thing I do on any workstation is download and install SVK, which gives you disconnected access to subversion repositories (since I predominately work from a laptop, sometimes in a park or my backyard with no wifi access).
Subversion+SVK gives you most of the benefits of git or mercurial or bazaar (though I am evaluating those as well). I think future development of Subversion is going to add SVK/git/Hg capabilities to support the DVCS use case.
So I would advise NOT deploying git if you're already using subversion, and instead grab SVK and get going with that (plus it's pretty mature, it's been around for a few years now). Downside is it can be slow at times (written in perl).
Download SVK
Svn support is built into Xcode. You can install a newer client manually.
If there's no one forcing you to use svn, then you should probably use git, since git can interoperate with svn (which means, technically, you could use git while the people you are working with use svn; that's probably too much trouble though).
As for XCode integration, git has none but it is not too hard to get git working using some keystrokes in XCode. I wrote some scripts that will do it for the most frequently used git commands and placed them in user scripts. Here are two examples:
git initialize
#!/bin/sh
#
# This script initializes a git repository and adds all the elements
# of the project directory to the repository
# Set the basic variables of the script.
project_directory=`osascript << APPLESCRIPT
tell application "Xcode"
set mypath to the project directory of project 1
set mypath to the POSIX path of mypath as string
end tell
APPLESCRIPT`
cd $project_directory
# create the git project configuration files
cat << EOF > .gitignore
.gitignore
.DS_Store
.gitattributes
build/*
EOF
cat << EOF > .gitattributes
*.pbxproj -crlf -diff -merge
EOF
/usr/local/bin/git init
/usr/local/bin/git add *
git add
#!/bin/sh
#
# This script does a git adds a file of the user's choosing
# to the git repository.
# Set the basic variables of the script.
project_directory=`osascript << APPLESCRIPT
tell application "Xcode"
set mypath to the project directory of project 1
set mypath to the POSIX path of mypath as string
end tell
APPLESCRIPT`
files_to_add=`%%%{PBXUtilityScriptsPath}%%%/AskUserForExistingFileDialog "Add files"`
cd $project_directory
/usr/local/bin/git add $files_to_add
You can see a pattern here that will allow you to quickly write up the others. Inside the "user scripts" dialogue, you can assign key sequences to the commands. I find that in everyday use I rarely need to go to the command line to use git.
I can't really give you a clear answer because I've not used CVS or Subversion for some time - but I have used Git projects with other iPhone developers and it works quite well.
The only potential peril is that sometimes you have to resolve merge conflicts in the XCode project if more than one person is adding new files - but I would think SVN would have similar issues.
If you do use git, github.com works very well as a repository - and they have a great set of documentation for working with Git on the Mac (you could just visit that part of the site to get set up).
How do you upgrade the svn client in XCode? I've done this in the past to go from 1.4 to 1.5 but it was tedious, difficult, not documented, and glitchy. I've since tried to back out my hack (which broke my Apache server) and now I can't use it at all. This is after upgrading to the latest XCode which is supposed to support 1.5 natively.

Different Distributed Version Control Systems working together

My office has a central Source Safe 2005 install that we use for source control. I can't change what the office uses on the server.
I develop on a laptop and would like to have a different local source control repository that can sync with the central server (when available) regardless of the what that central provider is. The reason for the request is so I can maintain a local stable branch/build for client presentations while continuing to develop without having to jump through flaming hoops. Also, as a consultant, my clients may request that I use their source control provider and flexibility here would make life easier.
Can any of the existing distributed source control clients handle that?
Well... KernelTrap has something on this. Looks like you can use vss2svn to pipe the Source Safe repo into a Subversion repository, then use the very nice git-svn to pull into a local git repo.
I would assume the commits back to VSS would not be a smooth, automatic process using this method.
You should be able to check out the current version of the code and then create a git repository around it. Updating that and committing it to your local git repository should be painless. As should cloning it.
The only catch is that you need to have them both ignore each other (I've done something similar with SVN) by messing with the appropriate ignore files. I'm presuming SourceSafe let's you ignore things. And you'll need to do certain operations twice (like telling both that you are deleting a file).
This episode of HanselMinutes covers exactly what I was hoping to hear. Apparently Git can be used locally then attached to external subversion/vss repositories as need. They talk about it 14 ~ 15 minutes in.
some day I work in a company that use VSS (and in other companies that use other less unknow SCM) but i prefer use SVN (someday I'll try GIT) for active development, for me and my group.
First of all, this situation it's only good idea, if commit to VSS are few over month, because working with other SCM (than VSS) give you more flexibility, but commint to VSS from SVN is expensive in time.
My solution was:
VSS -> SVN: I have linux script (or ant script, or XXX script) that copy from currrent update directory work of VSS to current SVN, then refresh SVN client and update/merge/commit to SVN. With this, you are update from changes of the rest of company that use VSS.
SVN -> VSS: In this way, you need a checkout of all your modify files to VSS, then you can simply use the reverse script to copy from current update SVN directory (ignore .svn directories) and copy to current update VSS directory, update and commit.
But remember, in a few case does worth your time to do this.