I set up my git repository with the usual:
# Create directory mkdir projectname # Change to it cd projectname # Initialize the repsitory git init
Then I add a
.gitignore file with the specifics for this project.
# Local .gitignore dist pkg
And then I add the file to project and commit it.
# Add the .gitignore file git add .gitignore # Commit the changes git commit -m 'initial'
My global ignore file
$HOME/.gitignore contains everything that I have common for all projects.
# Global $HOME/.gitignore *~ .DS_Store tags *.gz
Git works with changes, this is important, so you are not actually adding a file to the repository, you are adding the changes. This means that you will have to add files every time you have made a change to them. I like this since it gives me an extra level of control, but if you don’t, you can always use the
-a option when you commit and it will include the changes to files that have been added to the repository at least once.
# Add and commit the changes git commit -a -m 'changes to all added files'
After setting up the initial repository and adding the
.gitignore file, I am set to go. I usually start with creating a new branch for development.
# Create the branch but don't switch to it. git branch dev # Or, create the branch and switch to it. git co -b dev # The co above is an alias for checkout, it was created like this git config --global alias.co "checkout"
After creating, and moving to, this branch I create another branch for the task that I am going to work on. For example
# Create a new branch, setup_tests git co -b setup_tests
I do what I have to do to get the task done and then I switch to the
dev branch and merge the changes in.
# Switch branch to dev git co dev # Merge in the changes from setup_tests git merge setup_tests
If at any point I feel like I need to do something that doesn’t have to do with this task, such as add some utility functions, I just commit the current branch and start a new one from where I am. This gives me very fine-grained control over the source code and it lets me throw away changes that goes bad without parsing and removing the bad changes manually.
If I forget to do my fine-grained branching, Git allows me to just add some of the changes from a file. The simplest way to do this is via the interactive add command.
# Enter git interactive add git add -i
Another command I find myself using more and more is
stash. If the change that I need to do is totally unrelated to what I am doing now and I just need to fix it, I
stash my current branch on the stash-stack and move to the branch where I need the change.
# Saves the changes on the stash stack git stash # Switch branch, change, and commit git co development git commit -a -m 'urgent change' #Switch back, and apply the stash. git co setup_tests git stash apply
Like I said, the stash is a stack and the command
git stash apply applies the top of the stack. If you have the need to apply a stash that is not on top, this is also possible. See the help,
git help stash, for information on this.
When I need to test my changes on Windows, especially on the awful IE6, I switch to this virtual machine and then I clone the repository.
# Clone the repository git clone path_to_my_local_mac_directory
Now, I have a perfect copy of my repository and I can test and make the needed changes at will. After this I just push the changes back to the Mac again and pull them back to windows from now on.
# Pushes the current branch git push # Pull the changes back git pull
I usually find doing this in the development branch the best way to go and then I reserve the merging into the master branch to the repository that I have designated as main, the one on the Mac.
At the moment I am developing on my main repository and there is one caveat with this. If you push changes into this repository the working directory will not be updated. Thus, if you have local changes in your working directory and just commit them without checking the status. You will revert the changes that have been made on the remote repository. This is by no means a fatal problem since you can just revert your changes and move on, but it is still annoying. The lesson to learn is to always use
git status before you commit.
# Shows the status of the repository git status
When developing this course I have the usual issues with keeping questions in sync with the answers. Git solves this without any problems at all. All I do is to keep to branches of the tree, master, and solution. I do all the course development in the solution-branch and then I just merge it into the master branch where I remove all the correct answers. After that I move back to developing in the solution-branch.
If you want to get started with Git I can highly recommend the series of screencasts at “Gitcasts”: Start with the RailsConf Git Talk, it gives a good overview. If you’re on Windows and like GUI tools move on with the Git on Windows Talk. I use the Cygwin version for my windows version of Git since I have these tools installed anyway.