A place to discuss Development techniques, .NET, XNA, NHibernate or anything else that tickles your fancy

Thursday, June 17, 2010

Git for the Lazy

Posting this here for anyone interested. Great, quick, easy Git setup and getting started guide.

Sunday, June 6, 2010

Git Day to Day usage

Part 2 of the Git Guides I wrote up for my XNA team:

Let's discuss how to use Git once you've got your personal repository cloned. First you're going to want to open up Git Bash to follow along. You can use Tortoise and Git Gui to do these processes as well, but the command line has everything I need to be able to walk you through this. So right click on the repo folder (the folder you cloned to) and choose "Open Git Bash Here".


When you clone your repo from your personal repo, Git automatically adds your remote repository as your "origin" repo. You can type in "git remote" and see it listed under "origin". This is your working repository, and what you've got write access to. First things first, you need to add your "upstream" repo. This is typically a read only repository and it's where everyone pulls their changes from. In this case, it's:
Code:
ssh://git@projects.domain.com/projectMain.git


Type in:
Code:
git remote add upstream ssh://git@projects.domain.com/projectMain.git


Now when you type in "git remote" you'll have two listings: origin and upstream.

Origin: Your personal repo that you have write access to
Upstream: The main repo that you only have read access to which you fetch changes from

So lets say you've settled in for an evening of coding, here's the typical way you'd begin your night:
Code:
git fetch upstream
git rebase upstream/master
git branch SomeNewBranchName
git checkout SomeNewBranchName


This 1.) Gets changes from upstream 2.) Rebases your master branch, updating it with the changes from upstream 3.) branches master to a new branch for you to make some changes (favor branching over working on the master branch directly) 4.) switches your current branch to the new branch which changes all the files on your HD so you can start working on your new branch immediately

Say you make a few changes, and now you're ready to commit for the first time. You can run a "git status" to see the files that you've got that have changed. Or you can open up the Git Gui and it'll show you your pending changes. In general, we want to add all the changed files to the repo, like so:
Code:
git add *


Now your changes are staged you can perform a local commit:
Code:
git commit -m "Made some changes and these are my checkin notes"


You can continue working on that branch and staging/making local commits with additional notes. That's part of the beauty of a distributed repository source control system, you are your own source control offline. So when you're finally done and you'd like to put what you've got online you can use:
Code:
git push origin SomeNewBranchName


This will send your local checkin history to the repo you have specified as "origin" (which is the place you cloned from, your writable repo). Now, if that feature is ready to be pulled in to the trunk of our project, you can issue a pull request to the maintainer. Once they receive the request, They'll go in and pull the changes you just pushed to your repo, and then merge them in to the main projects master branch for everyone to see the next time they do a "git fetch upstream".

Now you can run your fetch/rebase process again, and your master branch will be updated with the changes that was pulled in to the trunk.

So, to recap:
1.) Add the main repo as upstream
2.) fetch/rebase to update your local repo
3.) create a new branch whenever you start in on a new feature/change
4.) do lots of small local checkins at logical points as you work on a feature/change so it's easier to roll back to
5.) push to your origin when complete or when you want someone else to check out something you're working on or you want to make sure what you've got gets backed up

Tips:
- Favor branching first over working on master
- Add everyone elses repos to your git config list so you can check out everyone's changes if the need arises. But make sure that you've got your personal repo, and the main upstream repo specified as you'll use those two exclusively during your day to day process

Git Getting started Guide

Wrote a getting started guide for a group of XNA artists/coders that I was on the team of a while back, and got a few requests to turn it into a blog post. This is what I give to people who are new to Git and want to get set up. Next, I'll post a daily usage guide.

So outside of GitHub, you handle multiple repositories by actually creating multiple repositories for a project. I like to start by creating a Project.Main and then a Project.UserA, Project.UserB, Project.Me. Everyone has Read/write access to their own repository, and read access to all of the others. I create a repository for myself, as I'm no exception. I don't want to be working directly on the main repo, that should be used for fetches only, and the occasional pushes from me whenever there's something to commit for everyone.

Project.Main repository everyone has read access from (so you can set as your upstream to fetch changes from)
Project.: Each persons individual project/repository where you have read/write/commit access to. Everyone has read access to everyone else's repo, except the repo owner and myself (as admin has it by default).

Be sure to have each user clone FROM their specific REPOSITORY, and not from the main project repo.

Getting started with Git
1.) READ THIS FIRST. This is a great guide to get you started using Git. It's not just an informational read, you need to follow along with the guide if you haven't set it up before.

2.) After using msysgit, you might be a bit more familiar with something like: TortoiseGit, which is a pretty slick UI integration for Git. 99% of what you are going to do with Git can be done through Tortoise or GitGUI, so you can avoid the cmd prompt if you'd like (that seems to scare a lot of people away, myself originally as well). NOTE: During the Tortoise config, choose to use OpenSSH instead of PuTTY (which is a pita to configure).

3.) Take your SSH Key in the .pub file in your .ssh folder in your user dir, and go to "preferences" in the upper right corner of RepositoryHost (you need to log in first of course). Go to the "Public Keys" tab on the right, and "Add Key". Copy/Paste your .pub ssh key (the whole block of text including your email address you used when you registered the SSH key originally) , and hit "add Key", you can give the key name anything. Like "Home PC" or "Laptop" or anything like that.

4.) Clone the repository. Use either GitBash:
Code:
git clone ssh://git@projects.domain.com/projectname.git
or Tortoise and pass it: ssh://git@projects.domain.com/projectname.git. If your ssh was set up and registered correctly, you'll be gtg here. When you clone, it clones the full git repo to the folder you chose, just like SVN does on an initial "Create repository here" run.

5.) Open up your GitBash prompt to your repo directory and type in:
Code:
git config core.autocrlf false
. That will ensure git doesn't attempt to modify every file in the list due to discrepancies in line ends on windows.

6.) In GitBash, or using gitGui or Tortoise, add the following remote as "upstream": ssh://git@projects.domain/projectMain.git . In GitBash the command would look like:
Code:
git remote add upstream ssh://git@projects.domain.com/projectMain.git


7.) Congrats, Git's all set up. Now all you do is follow the standard Git workflow. Here's a good article on how to do that(ignore the github specific stuff). Basically it's going to involve you fetching from upstream (The main project: proj.main), Rebasing (updating your local copy to the upstream's new header version, so you don't work on old code), Branch to do some work, commit to your local repo, pushing that to origin, then submitting me a pull request (via PM, Email, etc.). Rinse. Repeat. Check out the official git homepage for more info.

So what does Git give you? If you just went through all that, and you're new to it, you might be asking yourself, wtf, why should I care about this stupid SCM.

I'm glad you asked. SCM (Source Control Management) is very important for projects like these, as it allows us to push up changes that are versioned, just like wikipedia, so if something gets screwed up, or we ever need to go back to a previous implementation/version, we can. SCM allows you to track exactly what changed and why (with ticket linking) so when something breaks, you've got a clear indication of why, and what the intent was behind the change.

Git is a fairly new SCM, and it's a huge buzz, primarily because it's a Distributed Source control. What does that mean? Well, in an SVN model (Subversion) you check in to one centralized server, and when you branch, or push up, it's all managed remotely. If you want to get a previous version, you have to ask the server to get it for you. If you want to work locally on a project an do some branching/investigate versions but you don't have a connection to the server, you're out of luck, because that's where all the info is at.

Git changes that model. Each and every person has their own full image of the Repository on disk. So you can work in an offline model, and more importantly, nearly everything in Git is a branch. Everything you do should be branching for changes, and then pulling those branch changes into your primary branch and merging with master (the trunk). It's also very, very fast, compared to other SCMs, and it has a high degree of flexibility (also it's downside with the learning curve).

There you go, ask away if there's questions or anyone has issues with cloning their repo or getting onto our SCM site.