Moving to Git
Over the years I've used many Source Code Control systems and even now I still
wake up at 2AM with cold sweats thinking about them. For years we've been using
Subversion (SVN) as our SCC of choice but more and more we ran into the issues caused
by a centralised Source Code Control (SCC) system: you had to be online for a start,
and if your SCC server failed catastrophically it was a major issue. Pray your backups
worked. Further, we were terrible at forking and merging. We just didn't
bother. This meant that if you checked in code you had better be damn sure it compiled
and ran, otherwise blood would be spilled.
Git is similar to SVN with one major difference: there's no master copy of the
repository: each machine that is working on the repository has the complete repository
history, and instead of committing all changes to one central copy you can push your
changes our to different machines. When I say "complete repository history" that
actually depends on what branches each machine has, but assuming they all have a
copy of the master branch, and assuming everyone's up to date, everyone has everything,
more or less. The convention is that you choose a repository to be a central repository
(called the origin) and all updates and commits go through that repository.
However, this is just a convention and allows everyone to coordinate updates via
a central node. If that node fails then you simply pick another node and carry on.
The subtle difference here is that when you're working on code stored in Git
you will usually have a repository on your local machine. You stage your
code changes and then commit your changes to your local Git repository, and
then you push those changes to the origin repository. As an aside,
Visual Studio hides the details of staging your changes, so the experience is as if
you were committing directly with no intermediate staging. For beginners that's
usually fine but if you stick to the command line you'll have to manage staging
So you can commit (and rollback) as many changes as you want
to your local repository while you are working. You could be working offline, you
could be committing broken code, you could be forking and merging and going crazy.
Then, when it's all working properly, you merge changes from the origin, then push
your final changes in your local repository to the origin and you're done. It allows
for more regular commits without worrying about breaking someone else's work. Advanced
users would rebase their commits to get a more linear history, but that's a technique
outside of the scope of this article.
Git for CodeProject and ::Workspaces
Many years ago we added versioning to CodeProject articles but not to the downloads
associated with the articles. This was something we had been wanting to fix for
a long, long time.
We didn't want to just "fix" the problem though: we wanted to make it easier
to update and work with source code attached to articles. Git was rapidly becoming
the de facto SCC solution for software development (and in fact for document change
management in general), so we wrote ::GitMachine to serve as a backend for all code
samples that go with CodeProject articles. You'll see ::GitMachine when you click
the Browse Code link in the left hand nav bar of articles with code, and you can
use ::GitMachine separately from CodeProject articles for your own stand-alone projects
What ::GitMachine provides is the ability to connect directly to your (and others')
code samples and to update, fork (make your own copy that's connected to the original
repository), improve and share the code from within your favourite IDE. Visual Studio,
XCode, Eclipse (with EGit) and RubyMine (to name a few) all support Git. The question
for newcomers to Git is: Great, but how do I use it?
Using Git on Windows
For this article I'll focus on Windows, and more specifically I'm going to focus
on Visual Studio 2013. However, the concepts should be identical for VS 2012 and
similar in general for other Git enabled IDEs.
download Git for Windows. See Marco Bertschi's article
Working with CodeProject Workspaces::Code for a quick rundown of installing
Git on Windows.
Creating a Git repository
Second, you need a Git repository. You can either take some existing code and
upload it to a Git repository (See Marco's article "Working
with CodeProject Workspaces::Code) or you can clone an existing Git repository
to your local machine. Note that cloning is only useful if you have permission to
read and make commits to that repository, so a first step could be to fork
an existing repository in order to make a copy that you own, and then to clone it.
I've created a
project for CodeProject.com projects that might be fun for you guys to help
out with. Within that project is a
::GitMachine instance for our WYSIWYG editor. Visit that page (you'll need to
be logged on to CodeProject) and click the Fork button
Voila. You have a Git repository you can call your own. In my case I created
a fork at
Connecting to an existing remote Git repository
Fire up Visual Studio, go to View | Team Explorer and the Team Explorer window
will appear. Under "Local Git Repositories" choose Clone to clone a remote
repository onto your local machine. Remember: you work with your local repository
and then push the changes to the remote repository.
Go to the workspace you forked in the previous step and click the "Copy" icon
under "Repository URL" label in the GitMachine window.
This copies the Git repository URL to your clipboard.
In Visual Studio paste this URL into the Team Explorer "Connect" window and choose
a location on your local machine for the repository:
Hit the Clone button and the code will be copied to your local repository. Double
click on the "WYSIWYG-Editor.sln" link in the Team Explorer to fire up that solution,
then switch to the Solution Explorer to view the code.
Editing then Committing your changes
After making changes you will want to commit them to either your local repository
(Commit) or your local repo and the remote repository (Commit and Push).
In the Solution Explorer right click the solution and choose Commit
This will take you to the Team Explorer. Enter in a commit message (eg "Fixed
a typo") and choose the Commit action you want. In this case I'll choose Commit
The changes will be committed to your local repository and then pushed to the
remote repository. The Commit window now presents options to sync your code with
the remote repository or issue a Fetch (grab changes from the remote repository
and store them in a local branch so you can review and merge later) or Pull
command (grab changes from the remote repository and merge them into your working
branch in one operation). In this instance there are no changes so we're done!
You've forked a repository, cloned it to your local machine, made changes and
pushed those changes back to your fork of the original repository. The final step
is to have your changes merged with the original repository.
To issue a Pull Request I simply go back to my
Workspace, go to the GitMachine instance and click the Pull Requests button.
Clicking that takes you to the Pull Request page where you would then select
"New Pull Request".
Hit "Send Pull Request" and the request will appear on the workspace of the original
Clicking the Pull Requests button takes you to a page that allows you to manage
your Pull Requests as well as providing instructions on what to actually do with
it. In this case:
Step 1: Check out a new branch - run this from your project directory
git checkout -b codeproject-master master
Step 2: Bring in chris-maunder's changes and test
git pull https:
Step 3: Merge the changes and update the server
git checkout master
git merge --no-ff codeproject-master
git push origin master
Put on your coat and hat - we're heading outside
At this point I prefer to make use of the command line. The following can be
done using Visual Studio but it just feels cleaner and faster (to me) to simply
pop open a Command Prompt and cut and paste the commands:
In this situation I had pending commits that caused the merge to abort. No problem:
Using Team Explorer I select my master branch then Commit and Push my local changes
to the remote repository. I then switch back to the
branch created in Step 1 above.
The merge was done successfully and in Visual Studio I can see the changes. I
test, confirm it's all good and the finish handling the pull request.
Note that in the final step I had to provide my CodeProject username and password
(Git can be configured to cache credentials if you don't wish be asked each time).
Now when I go back to the original repository (the one we forked) I see in the
Commits window an entry for the "Merge Branch" that we did, plus the Push that I
had to do because I had outstanding changes, and we also see the "Fixed a Typo"
commit that we did in the fork. The changes are all now back in the original repository
for everyone to access the next time they Pull or Fetch.
Well done - you've forked, Clones, Pushed, issued a Pull Request, Merged, Committed
and Pushed the changes back to the original repository for others to access. Code
Collaboration is a beautiful thing.