Foundation Version Control for Web Developers
Foundation Version Control for Web Developers
By: Chris Kemper; Ian Oxley
Publisher: friends of ED
Pub. Date: March 21, 2012
Print ISBN-10: 1-4302-3972-7
Print ISBN-13: 978-1-4302-3972-7
Using branches as project states
Subversion for Windows 7
sudo apt-get install synaptic
You'll be prompted for your password here because of the sudo command. which is fine. Just type it in and press enter. When typing your password there won't be anything visual on the screen to indicate the typing. This is normal, so don't worry
After the installation has completed, Synaptic will live in the same place it used to, which is System
Synaptic package manager.
Using branches as project states
Although branching is great for testing out new or experimental features, it also comes in really useful for creating certain states of a project. For example, the project you are working on could have a development state and a release state, with the release state being the client-facing, stable side of the project, and the development being the improvements and bug fixes. In cases like this, it's very common for the release state of the branch to see no activity for a long time, because all development is done in the development branch to ensure the client-facing project doesn't break.
Now what if a bug is discovered in the release state? You can't merge the development branch in yet as it contains too many unfinished changes, which would cause way more problems, and you don't want to just work on the live version because that could cause other problems. In this instance, you would create a branch of the current stable version of the code, which would allow for the bug to be fixed and tested in an isolated environment without causing any other problems. You could, of course, do this on the live version of the files, but if anything is accidentally pushed, it could cause major problems. With the bug fix tested, the branch can be merged back into the release branch with the development branch remaining intact.
You can use branching easily enough for keeping a project in certain states, for developing new features or even for fixing bugs. It can also be used for creating workflows for teams, to allow for certain users to only push to certain branches, ensuring all changes are reviewed by another user before going live, and a whole lot more. If you were a project manager, you might wish to review certain code changes before they went live, which is possible using branches. You could have a development branch, as described in the previous example, but that branch would actually be a branch of the review version of the code. This means that changes from the development version could be pushed to the review version before being pushed to the live version. Although this is overly complex for the majority of users, it can be necessary for some companies to ensure all code is reviewed and handled correctly. You can see this represented in Figure 4-5, which makes it easier to digest.
Branching can be quite simple and quite complex at the same time; it all depends on how you'd like to use it. Some people couldn't live without the flexibility of branching and the ability it gives you to work on a new feature or test something new, without causing any issues to existing code. It can also be used in great depth to create complex workflows to ensure no untested code goes live or for something as simple as fixing a bug. For this exact reason, there's a full chapter dedicated to branching later on in the book. I'll go through everything you need to know about branching and really get into why it's awesome!
TortoiseSVN is the most popular windows SVN client by a long way. If you try to find a different program to use, you'll probably come across someone asking why you're not using Tortoise. Although Tortoise isn't the only option (others are available), it has a brilliant reputation. Without further ado, let's get it installed and ready to go.
To download the latest version, head over to http://tortoisesvn.net/downloads.html, where you can find the latest stable version of the program.
If you've ever had the pleasure of using TortoiseSVN on a Windows machine, then you have some familiarity with how Rabbit works; and those of you who haven't will find it a pleasure to use. Rabbit integrates straight into the Nautilus file manager, which is the default in Ubuntu and other Linux distributions using the GNOME desktop environment. I could go into more detail about it, but that's not what you're here for. If you're interested in reading more about Nautilus, you can always check out the official web site (http://live.gnome.org/Nautilus) or the Wikipedia page (http://en.wikipedia.org/wiki/Nautilus_(file_manager)) to find out anything you need to know.
Due to Ubuntu updating to Unity, installing RabbitVCS isn't as easy as is it should be; however, it can still be easily achieved. The first thing you need to do is add the Rabbit code repository into Synaptic, to make sure you always get the most up-to-date content; to do so, go to Settings
Other Software. Here are all the software sources applications that can be installed and updated from. You need to add a new one, so click the Add button, enter the following, and click “Add source”:
Now, go back into the main Synaptic window and refresh all the packages using the button at upper left. After everything has updated itself, perform a search for RabbitVCS, and you should see the six options shown in Figure 5-18.
Notepad++ has the potential to expand its use with plug-ins, although the only plug-ins available rely on the Tortoise applications you've installed, which are 32-bit and which render the plug-in useless for 64-bit users. If you are rocking a 32-bit system, the option to use this plug-in is still available to you, and it's easy enough to install and use, too. Head over to www.switchonthecode.com/tech-news/notepadplusplus-subversion-plugin to get a copy of the plug-in, and also a nice representation of how it works.
Just in case you don't fancy heading over there, I'll give you a quick look at how it actually works. To install the plug-in, download the zip file from the previously mentioned location, and copy the contained .dll file into the following location: C:\Program Files (x86)\Notepad++\plugins or (on systems earlier than Windows 7) C:\Program Files\Notepad++\plugins. With the plug-in in the correct location, restart Notepad++ if you have it open and if not, open it.
Within the plug-ins menu there will now be a new menu option called Subversion, which contains a number of options. Thanks to the plug-in, you can know Update, Revert, or Commit either the file you are working on or all the files you have open. Although it's not the most extensive of plug-ins, it still allows you to perform a limited number of actions without leaving Notepad++—if you happen to be on a 32-bit machine, that is.
Although to some people NetBeans will sound like a strange snack, to a lot of developers out there it's a great development environment and is used by a great deal of developers at different levels of skill. Oh, and did I mention that you can run it on Windows, Mac, and Linux, and because it's an open-source project, it's free to use? With open source-projects generally comes a large development community creating plug-ins and offering support, and NetBeans is no exception. You can find the various versions of NetBeans at http://netbeans.org/ where if you'd like, you can download a copy for free.
There are a few versions of NetBeans available: various Java editions, a C edition, a PHP edition, and one with everything in. The good thing is, whatever flavor of NetBeans you choose to go for, they all boast HTML5 and CSS3 support and, with a plug-in, support for SVN, Git, and Mercurial! In actual fact, support for SVN and Mercurial come out of the box for NetBeans, and a simple plug-in is required to install Git support, but I'll go through that when it comes to it. For now, though, let's have a look at how to use NetBeans to interact with our favorite version control systems, starting with SVN.
Sublime Text 2
This editor is an up and comer in the IDE world, with a lot of people seeing it as an alternative to TextMate, mainly because it actually gets updated, regularly! Sadly, unlike TextMate, it has no version control abilities built in, which results in having to play around with some packages to get the functionality you're after. If you're not using Sublime Text 2 and you fancy giving it a try, you can do so on an evaluation basis by downloading a copy to your Mac, Windows, or Linux machine from the website at www.sublimetext.com/2.
Before installing any packages, there's something else to install that makes life using Sublime Text 2 a whole lot easier: Package Control. This is a package in itself, and it makes installing new packages and a lot of other things easier. To get started, open up the console within Sublime Text by hitting Ctrl+` on Mac/Linux or Ctrl+‘ on Windows. This will open up the console at the bottom of the screen. With the screen open, type in the following code and hit return:
import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.repl ace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'
This code won't do anything until the editor is restarted, so go ahead and do that now. You may see a number of errors pop up on the screen regarding github packages not existing. If this happens, run the process again and all should be well. Just in case the code changes, or you'd rather copy and paste it, the original can be found on the website here:
Once you have the package installed, you can open up its window by hitting Ctrl+Shift+P for Windows and Linux or Cmd+Shift+P for Mac. This window exists already within Sublime Text 2; however, all of its commands are added into it. The commands we're looking for here all start with Package Control, so type that in to filter the list down a bit. There are a lot of available options where you can find out a bit more about the packages (Discover packages) or just install them, which is what you want to do. Hit enter on Package Control: Install Packages to get everything ready.
You'll notice a loading bar at the bottom of the screen while it generates the list. If you see any dialog windows coming up for unavailable packages, just ignore them. It just means that said package has moved or has been deleted. Once they're all loaded, all of the available packages will be displayed in this list; you're looking for the Git package, so find it and hit Enter to install it. You may get some of the missing repository dialog windows again at this point, but they're unrelated to the installation. You'll see a success message at the bottom of the screen when it's finished.
The first cross-platform application is Diffuse, a lovely diffing app. As it's open source, you get a lot of features, which you don't always expect with free software; so if you're having doubts, I'd put them to one side for now. Let's get straight into installing Diffuse on either Windows or Linux; these two options are the best in terms of ease of installation. If you prefer to use a Mac, you need to consider MacPorts and possibly other dependencies, which aren't particularly useful at this level. If you're using a Mac, it's best to choose one of the other options suggested; but if you're on Windows or Linux, read on!
Installing on Windows
The Windows installation is a lot simpler, mostly because the nice people at Diffuse supply an .exe file for Windows users, which cuts the pain of having to compile anything from source. To get the file, head over to http://sourcegear.com/diffmerge/downloads.php and click the Win32 link to be taken to the SourceForge page that houses the program. Once it's downloaded, run it like a normal installation process. After the install is complete, a new option is added to the Start menu, and you can launch Diffuse.
Installing on Linux
Although you need to head into Terminal to install Diffuse, it's quite painless. The installation itself is only one line of code, which is in a format similar to the commands you've used. With Terminal open, enter the following command to start the process:
sudo apt-get install diffuse
This command asks for your password, but other than that it runs quickly, so no cups of team are needed this time. Once the installation is finished, you have a fully working application, ready for use. You can run Diffuse into a stand-alone application by running diffuse in Terminal, which launches it as desired.
These guys are a dedicated VPS company, so virtual private servers are all they offer, and they do it really well. You have a few options to use when signing up, mainly having to do with the amount of RAM and traffic you'd expect to have on a monthly basis. Hosting a couple of repositories, or even a website, won't use up a huge amount of bandwidth (that is, of course, assuming you're not mega popular, and are not pushing and pulling a lot of files in and out of your repositories).
Currently Linode 512 is the smallest package offered, which gives 512MB RAM, 20GB of storage, and 200GB of data transfer for $19.95 a month. This is more than enough to work with and, in reality, if you're only using this for repositories might be overkill. But having the ability to manage the server however you like and having the option to host additional sites are great.
When you log in, your control panel gives you a number of options, including being able to restart your Linode server, clone it, back it up, or even ditch it and install a new OS instead. You also get comprehensive graphs to show data usage and so on. It's also possible to set up notifications when you're getting close to your caps so you can either calm down or get more space.
You're also under no crazy contract with Linode. You can get your money back if within seven days you decide you want out; otherwise, you just pay on a month-by-month basis, with no long-term commitment. If you're looking for a good place to start, with a server that will handle a large chunk of traffic and allow you to host pretty much anything, check out www.linode.com to see for yourself.
Although you may not know exactly who Media Temple (mt) are, you'll no doubt have seen them as sponsors of events, or you may even own one of their super-soft t-shirts. As well as being great sponsorship partners and givers of super-soft t-shirts, they also offer a wide range of top-notch web hosting products. Although we're looking at the dedicated server option, they also offer standard hosting packages, and some intense packages intended for the big dogs out there.
They have a number of Dedicated-Virtual (dv) servers available, starting with 512MB RAM, 20GB storage, and 350GB data transfer. That comes in at a price of $30 a month, and with that come the quality and high standard of hosting that Media Temple are constantly working to improve, in-depth analysis tools, a number of OS choices, and a whole lot more. They also offer a great amount of support on both their website and via Twitter. It's also possible manage your (dv) server from a handy iPhone app, which can make doing a quick restart or checking stats a breeze.
This barely scratches the service of the level of service, quality, and standards offered by Media Temple. They're always improving their products to make things more efficient, faster, and generally just better. You can see for yourself by heading over to the website at http://mediatemple.net/roadmap. While you're there, you can check out the products they have on offer and maybe even sign up for their high-quality service.
What is a branch?
In a version control system a branch is code that diverges from the main line of development. If you think of it in terms of a tree, the trunk would represent the main line of development (as it does in SVN), with the branches diverging from the trunk at various points.
I mentioned a parallel universe right at the start of this chapter; when you create a branch you can think of this as causing a split in your codebase. From that point onwards, your code can exist in two parallel futures, completely independent from one another.
When you create a branch, it inherits its history from the main line of development up until the point it was created. Going forward it has its own commit history, and almost behaves like its own repository.
In a moment I'll show you how to create a branch in SVN, Git, and Mercurial. Before I do that, let's have a quick look at two of the main uses of branches in software development.
When can I use branches?
Although you aren't restricted in any way when it comes to using branches, the two main ways they are employed are as release branches and feature branches.
Release branches are used to “freeze” the code base on a project prior to a release. When a team is working on a project, part of the team will form the release team. They'll create and work from a release branch, fixing bugs, polishing the product, and working with the testing team, to get it ready for release. Meanwhile, the rest of the team can continue working on the main line of development, perhaps with features planned for the next release.
Once released, a project's release branches will be used for ongoing maintenance against that particular release until it is no longer supported. For example, if a customer reports a problem against Version 1.0 of your product, you'd check out the release-1.0 branch, fix the problem, and commit your changes to the release-1.0 branch. At the same time, another customer could have reported a problem with Version 1.1. You could then check out the release-1.1 branch, fix the problem, and commit your changes. If it turns out that either of the bugs reported still exists in the main code base, these fixes could then be merged back into your main line of development.
Feature branches are used whenever you need to work on something that could lead to your main branch —trunk, master, or default—becoming unstable. Unlike release branches, they are only temporary and only kept for as long as it takes to implement the feature. Features might include testing out a new database abstraction library, trying out a new version of a third-party API, or rewriting a search function using a new or different algorithm. Either way, you wouldn't want your experimental code ending up in your main code base until you were sure it was stable.
Feature branches, being only temporary in nature, tend to get deleted once they have been merged back into the main code base.
Related to feature branches are topic branches. They are essentially the same as feature branches, as they are created to implement a specific feature or bug fix, and form an integral part of the workflow for developers using Git and Mercurial.
The master or default branch would represent the stable form of the code. Whenever a developer starts work on a user story, new feature, or bug fix, they'd create a topic branch named according to whatever it is they're about to work on, hack away on that branch until done, committing their work to it regularly as they go, then merge their branch back into master or default.
In older version control systems like SVN, excessive branching is not something that is encouraged, largely due to the significant cost of merging code between branches. Some would argue that excessive branching shows signs that something is wrong somewhere along the line. In Git and Mercurial, as you will see shortly, creating branches is incredibly lightweight. Switching back and forth between branches is almost instantaneous. Creating and merging branches is an integral part of the daily workflow for many developers.
How do I create a branch?
Before we go any further, let's see how to create a branch in SVN, Git, and Mercurial, and the difference between how SVN creates a branch and how Git and Mercurial do it.
Anonymous branches let you update to any revision and commit. They are the fastest way to create a branch in Mercurial, but there's no descriptive name for the branch, so you'll have to write good, meaningful commit messages if you want to remember what a branch was for at some point in the future.
Because anonymous branches have no name, you'll have to use hg update --check REV—where REV is the revision number or hash of the commit—to switch between them.
Hooks are commands, or scripts, that are triggered by events occurring in your repository. These events occur when you commit, push, and pull. Hooks have access to environment variables, can receive arguments containing revision information, and allow you to control whether a particular repository event can proceed or gets blocked. They live in, but are not checked in to, your repository, and a given event can have a hook that fires before, during, or immediately after said event—for example, pre-commit, commit, and post-commit. In this chapter, you'll have a look at what hooks are available in SVN, Git, and Mercurial, how you can enable hooks, and finally look at some examples of what you can do with hooks.
This appendix will run through some of the basic and more frequently used commands you'll be dealing with while working in the Terminal for SVN, Mercurial, and Git. If you've forgotten a command or you need to refresh yourself on things, just have a look through to find the command you need. If it's not there, use the respective help commands, which are detailed below.
There are a number of commands you'll use more often than others while going about your day-to-day version control business using SVN. These can be seen below in a quick-reference format, just in case you forget about them.
Checking out a repository
To perform a checkout of a remote repository, just use the following command:
$ svn checkout http://path-to-repository folder-name
If the folder name isn't specified in the repository, then the repository will be checked into a folder with the same name as the repository itself.
You can easily add single or multiple files using svn add, like so:
$ svn add file folder file2 file 3
You can also use a wild card for selecting multiple files with the same name or file type, such as:
$ svn add *png
When you use the svn commit command without any specific flags, it'll commit all of the changes to the repository and then launch your specified editor to add a commit message. You can, however, specify files to commit and a message in the command, like this:
$ svn commit file folder/file2 folder2 -m "Relevant commit message"
Using this command allows you to see information about previous commits either within the repository in general, or specific to a file. You can use the command on a basic level, as with the following, to show a log of all the commits in the repository.
$ svn log
You can also limit the amount of items shown by using --limit followed by the desired number, get more information by using --verbose (-v), or less information by using --quiet (-q). These can also be used in conjunction with each other and one particular file or folder, like so:
$ svn log --limit 5 -v
To update your repository with the latest changes from the server, use the following:
$ svn update
You can also update to a specific revision of a particular file by simply specifying the file after the command. You can also update a particular file to a certain revision by using the --revision (-r) flag, like so:
$ svn update -r 6 file
You can revert back to the BASE version of a file (thereby getting rid of all local changes you've made that haven't been committed) really easily by using the svn revert command. You'll need to specify a file, but it's just as easy as
$ svn revert file
You can also revert any changes within a folder, but using the --recursive (-R) flag, like so:
$ svn revert folder -R
There will be a time when you need to remove files from future revisions, which is easily achieved with the svn remove command. This will prepare the file to be deleted, but it won't actually delete it until an svn commit is done. You can delete it there and then by adding the --force flag to the command. If you have a change of heart, and would rather not delete the file and have yet to commit it, just perform an svn revert on it and it'll be restored to its original state. To perform the delete action, use this command:
$ svn remove file
Alternatives: del, remove, rm
To perform a cleanup on your local directory after a commit or update got interrupted, run svn cleanup like so:
$ svn cleanup
You can get the status of all of the files and folders within a repository by using the svn status command. You can also include remote changes and new files by adding --show-updates (-u) to the command, like so:
$ svn status -u
Alternatives: stat, st
Performing a diff
You may wish to perform a diff between two versions of a file using SVN. This is easily achieved by getting the revision numbers you'd like to compare against (potentially with svn log) and using the following:
$ svn diff -r 1:2 file
In place of revision numbers, you can also use: HEAD, BASE, COMMITTED, or PREV depending on your needs.
Creating a branch in SVN is essentially copying the current version of trunk into the branches directory with an alternative name. To perform the branch, svn copy needs to be utilized, like so:
$ svn copy -m "Creating foobar branch…" \ http://path/to/repository/trunk \ http://path/to/repository /branches/foobar
Switch to a different branch
If you're working with branches, you'll need to switch your checked out repository to the branch, so you can add changes and so on. To achieve this, the svn switch command is used in the following fashion:
$ svn switch url-to-branch
Just replace the URL for the branch to switch to it, or the URL of the trunk if you're moving back from a branch to trunk.
If you want to merge a branch back into the repository, you can do so rather easily. Before doing so, you need to find the revision where the branch was created, which can be achieved using svn log and the --stop-on-copy flag, like so:
$ svn log --stop-on-copy http://path/to/svn/repository/branches/branch
The last revision listed will be the one you need, as the merge itself will merge the changes in from the branch at the revision where it was created, right up to the most current version. This can be done by using the following, where the branch was created on revision 10:
$ svn merge -r 10:HEAD --dry-run http://path/to/svn/repository/branches/branch
You can also use the --dry-run flag on the command to test the output of the command without actually making any changes to the repository.
When you happen to come across a conflict, you have a number of options when for solving it. The first option is simply setting the file to resolved, assuming you have manually fixed the conflict, which is done like so:
$ svn resolved
The other option is to resolve the conflicted file using svn resolve and use one of the various files created by SVN when the file became conflicted to do so. The options available to you are base, working, mine-full, and theirs-full, which are used in the following way:
$ svn resolve --accept option file
Moving or renaming files
The command used either to move or rename a file in SVN is actually the same. In essence, renaming a file is simply moving it without changing the location, just the name. Below is an example of this:
$ svn move oldname.txt newname.txt
Alternatives: mv, rename, ren
If you need to get a line-by-line breakdown of a file to find out who produced each line and when, svn blame is the command you need. To use it, just use the following, and replace the file with your desired file. (You can also add --verbose (-v) to the command for extra information.)
$ svn blame file –v
If you're stuck with a command, or if you want to see all of the available commands, just use the help command in SVN, like so:
$ svn help
This will list all of the commands in SVN, but you can get more help on a specific command by using
$ svn help command
Just in case you're working away in Terminal and you happen to forget a Mercurial command, these are some of the most frequently used commands, so you can have a quick glance and get on with your Terminal awesomeness.
Creating a repository
When you need to create a repository on your local machine, just use this command:
$ hg init
This created a repository inside of the folder you're currently inside, so just create the folder outside of Terminal (or in Terminal using mkdir folder-name), cd into it and use the command. Easy.
While making changes to the files in your repository, it's always best to keep checking the status of the repository, which can be done like so:
$ hg status
When you pull in new changes from a remote source, you need to update your local version of the code with the new changes. To do this, you can simply use the following command:
$ hg update
If you need to switch branches, do so in the same way, using the above command and then the branch name, like so:
$ hg update –c branch-name
The –c in the above disregards any changes you've made locally, so be sure everything is committed before you use it.
Alternatives: up, checkout, co
If you're working with a remote repository, you'll need to push changes to it quite often. To do so, just use this command:
$ hg push
You can also specify a location manually, just in case you have a reason for doing this, by adding it on like so:
$ hg push path-to-repository
As with pushing, if you're working with a remote repository, you'll need to get the changes from it quite often, which is easily achieved by using
$ hg pull
You can also perform an update at the same time by adding the –u flag, like so:
$ hg pull –u
When you've made changes, whether by adding files or altering them, you'll need to commit those changes to the repository, which you can do really easily by using
$ hg commit
It's also possible for you to specify a commit message by adding –m to the command and adding your message in quotes, just like this:
$ hg commit –m “Useful commit message here”
When you have new files in your repository, you'll need to add them before changes you make to them will be tracked. This can be done using hg add, which when used by itself will add all untracked files to the repository. If you'd rather only add one or two files, they can be specified after the command to ensure only those files are added, like so:
$ hg add file file2 folder
There will be a time when you have to remove files that you no longer use and you'd like to stop them being tracked any further. To remove the file, just use hg remove file, which will mark that file to be deleted on the next commit. If you don't want to wait till the commit to remove the file, you can always use the --force flag to delete the file there and then.
Adding and removing
There is a command that'll allow you to save time by performing two actions in one. If you happen to have files you need to delete and ones you need to add, then hg addremove may be just what you're looking for. This command will delete any missing files and add any new ones, so if you've deleted the file in browser, this will pick it up, and mark it to be deleted.
The time will come for whatever reason when you want to examine a file line by line to see who made the changes and why they happened. This is where hg blame comes in; it'll show the author, the date the revision was created, and the revision ID. To use the command, just use hg blame file and the output will be shown in the Terminal.
After you've had a conflict, you'll need to resolve the file before it can be committed, which is why there is a command to do that. The command in question is hg resolve, which does what it says, really. Once the file is ready to be resolved, just use the command, like so:
$ hg resolve –m file
It's also possible to mark all unresolved files as resolved by removing the file reference. This isn't always adviseable, however, as you could resolve a file you aren't meant to yet.
Moving or renaming files
When renaming a file, Mercurial treats it like you're copying the file to the same location, only with a different name. The same goes for when you're changing the location of the file; Mercurial treats it like you're copying the file to its new location, then deleting the old one. Either way, the command is used like so:
$ hg rename original-file new-file-location
Alternatives: move, mv
If you've been working on a file, but then decide you'd rather go back to the version before you started making changes, then hg revert is for you. If you want to just revert the file to the last revision, then you can use the command with no arguments, like so:
$ hg revert file
It is also possible to revert back to a specific revision by adding the –r flag to the command, like this:
$ hg revert file –r 10
In this example, 10 is the specified revision. Just change that to your specified revision.
If you'd like to have a repository as a parent that you push changes to (such as a remote one), before that's possible you need to clone the original repository using this command:
$ hg clone
You can also add --noupdate, which will cause the clone to only bring the repository and not the working files, which is what you'll need if you want to clone this repository in the future.
When you're working with a remote repository, there may come a time when you cannot perform a clean update, possibly because of merge conflicts or big differences between the remote and local changes. On a basic level, you can use hg merge, which will attempt to resolve the conflict itself. If you happen to make a mistake for whatever reason, then the following update command can be used to check out a clean copy of the changes so you can try again:
$ hg update --clean .
The dot in the above needs to be included, so don't leave it out.
If you get stuck with a particular command and want a bit more information about it, that's when hg help can be really useful. Without any arguments, this command will output all of the available Mercurial commands you can use, and a brief explanation of what they do. You can, however, specify a particular command after hg help to see more detailed information about it, such as the flags and arguments it accepts, like so:
$ hg help update
In this example, I've used the update command; just replace that with your specified command and you'll have help in no time.
Creating branches is really easy. Just use hg branch branch-name and you'll be ready to go with the newly created branch. When the branch is created, you are automatically switched to it, so any commits you make now will be to the new branch. If you don't make any commits, though, and switch to another branch, it'll be removed, so bear that in mind. You can switch back to the default branch by using hg checkout default to make the switch. If you use the hg branch command without any arguments, it'll show you the current branch you're on, just in case you were unsure.
You can also see a full list of the branches you have in your repository by using hg branches –a, which will list them for you to have as a reference.
While working in Terminal from time to time you may forget a specific command or how to use one. This little guide is here to refresh your memory and give you more of those “Oh yeah!” moments while you're working.
The git add command has a few uses within Git, since it both adds untracked files and stages changed files to be committed. Without any arguments, the command won't be of any use, and you'll need to combine it with a dot to add all untracked files or to stage all changed files to be committed. You can also specify individual files by using git add file if you'd rather not add everything in one go.
Creating a repository
If you want to create a new repository, just use the git init command within the folder you would like to contain the repository and you will then be able to commit changes into it, just like that.
Cloning a repository
If you want to work from a remote location, or you're setting up a workflow of some description, you may have a parent or remote repository you'll need to clone so that in future you can push changes to it. To clone a repository, just use git clone repository-location folder-name which will clone the repository into the specified folder name. This is entirely optional, however, and if the folder name is omitted, then the folder will take the name of the repository instead. There are a lot of other things this command can do, so if you're in need of a little help, git help clone is a great resource.
Checking out branches
The git checkout command is mainly used for switching between branches, where you would use git checkout branch to switch between your branches really easily.
Creating branches in Git is really easy, since all you need to do is git branch branch-name and the branch is created. It's also possible to see a list of all the branches in your repository by using git branch –a to list all of them. This, however, doesn't switch you to the branch, but there is a version of git checkout which allows you to do this in one step, in the following form:
$ git checkout –b branch-name
This creates a new branch and switches to it in one go, which can save you some time. To delete a branch, you can also use git branch –d branch-name, which will delete it and its changes.
As with the other systems, sometimes you forget the arguments for certain commands, or even the commands themselves. You can use git help to refresh your memory, and even use git help command to get more information on a specific command.
After you've made changes to files and staged them with git add, it's time to commit them to the repository. You can either run this on a per-file basis, by using git commit file file –m "useful commit message" or all at once, by using git commit . –m "useful commit message", which will commit all staged files to the repository. If you've made a mistake and you want to unstage some changes, this can be done using git reset HEAD file which will take it back to before it was staged.
You can see the commit information for your repository using the git log command, which shows the information on your previous commits. You can also perform a log on a specific file to see all the commits containing that file with git log file, and even limit the number of results shown by using the –n flag, like so:
$ git log file –n 5
It's also possible to limit the log by author with the --author flag and a lot more, which you can see in more detail by using git help log to see all of the available options.
This command will be one of the most frequently used during your day-to-day development, as it allows you to see the current state of the files within your repository and if there is anything you need to stage, commit, or add. The command in question is git status, which will give the status of the branch you're currently in.
A time will come when you need to merge the changes from one branch into another. To do this, you need to make use of the git merge command, which can be utilized in the following way:
$ git merge branch
This will merge the specified branch into the branch you're currently inside so, before proceeding, be sure to perform a git status to find out which branch you're on, and to ensure the merge is performed how you'd like it to be.
Moving or renaming files
A time will come when you need to move a file from one destination to another or rename it, for whatever reason. Both of these tasks, as with the other systems, are performed with one command. Just use git mv source destination to perform either action, whether it's renaming a file (git mv oldname newname) or moving one (git mv file folder/file).
When working with a parent repository, you'll need to ensure your repository is up to date with the latest changes, which is achieved by using git fetch to pull from the remote repository. After git fetch has completed, you'll need to merge the changes into the repository using git merge with no arguments. These two commands can be easily shortened by using git pull instead, which performs a git fetch and git merge for you, in one command.
As with pulling, you need to ensure any changes you've been working on are pushed to the remote repository on a regular basis, which is achieved by using git push. If you've cloned from a repository to create this one, using git push with no arguments will push your changes without a problem.
When you need to remove files, doing it with Git is easy. All you need to do is use git rm file, which will instantly delete it. Once you commit it, the file will no longer be tracked and you will be unable to make any changes to it. If you've had a change of heart, using git reset HEAD file should restore the file, but if that fails using git reset --hard HEAD will reset the entire commit to the previous version, so use it with caution.
These are notes I made after reading this book. See more book notes
Just to let you know, this page was last updated Wednesday, Oct 04 23