<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Geek Gumbo &#187; Git &#8211; Version Control</title>
	<atom:link href="http://www.geekgumbo.com/category/version-control-software/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.geekgumbo.com</link>
	<description>A potpourri of Web Development, Linux, and Windows tips, tidbits, and observations</description>
	<lastBuildDate>Thu, 02 Feb 2012 20:31:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Gitolite Troubleshooting Checklist &#8211; part 4</title>
		<link>http://www.geekgumbo.com/2011/10/24/gitolite-troubleshooting-checklist-part-4/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gitolite-troubleshooting-checklist-part-4</link>
		<comments>http://www.geekgumbo.com/2011/10/24/gitolite-troubleshooting-checklist-part-4/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 00:21:32 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Gitolite]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=3756</guid>
		<description><![CDATA[With one exception every problem I've had with Gitolite has been about the ssh connection. I've thought about how to help folks who run into the ssh nightmare. Probably the best way is to show you the actual look of &#8230; <a class="more-link" href="http://www.geekgumbo.com/2011/10/24/gitolite-troubleshooting-checklist-part-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/checklist.jpeg"><img class="size-full wp-image-3791 alignleft" title="checklist" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/checklist.jpeg" alt="" width="229" height="220" /></a></p>
<p>With one exception every problem I've had with Gitolite has been about the ssh connection. I've thought about how to help folks who run into the ssh nightmare. Probably the best way is to show you the actual look of the files of a working system, no one's done this yet.  I've tried to do this through out the past three articles. If your curious what a file should look like, chances are, I've put a picture of the correct file up in one of the previous posts. With this post, I'm going to give you a check list that hopefully will uncover any problems you're having with your Gitolite install.</p>
<p>This checklist goes in the order of install. If you find your problem, you may want to re-do some of the steps further down the list to make sure everything is hooked up correctly. We'll start with, is the power plug hooked into the wall outlet...</p>
<p><span style="color: #0000ff;">Basic Components</span></p>
<ul>
<li>Have you installed Apache, Pear, and Git on the server and checked to see that they are all loaded and functional?</li>
<li>Have you installed Git on your local machine and checked to see if you can create a repository?</li>
</ul>
<p><span style="color: #0000ff;">Setting Up User Accounts on the Server</span></p>
<ul>
<li>Do you, as a regular user, have an account on the server where you want to install Gitolite?</li>
<li>Do you, also, as the Gitolite Administrator, have another account on the same server, which you'll use to install  Gitolite?</li>
</ul>
<p><span style="color: #0000ff;">SSH key-pairs on the local machine</span></p>
<ul>
<li>Have you generated two key-pairs on your local machine, one to be used for your regular user login to the Gitolite server, and one to be used with Gitolite?</li>
<li>Are both these key-pairs in the SSH2 1024bit RSA format?</li>
<li>Are both these key-pairs named differently, example id_rsa, id_rsa.pub, and id_rsa_git, id_rsa_git.pub?</li>
<li>On the key-pair you will use with Gitolite, did you not put a passphrase in the key by hitting a return when asked during the "<span style="color: #008000;">ssh-keygen -t rsa</span>"?</li>
<li>Have you opened your public key files in an editor, and trimmed the file, to make sure there are no line feeds in the public key? It should be one long line, leave the ssh-rsa.</li>
</ul>
<p><span style="color: #0000ff;">Putting SSH public keys on the server</span></p>
<ul>
<li>As the regular user, did you copy your public key, id_rsa.pub, to your $HOME/.ssh directory from your local machine?</li>
<li>After you su into the Gitolite admin account on the server, did you copy the gitolite public key, id_rsa_git.pub, to a temp directory, not to your .ssh directory?</li>
</ul>
<p><span style="color: #0000ff;">Setting up SSH on your local machine</span></p>
<ul>
<li>Have you placed the script to load the ssh-agent into your .bash_profile file? I have a picture of the script in a previous post.</li>
<li>Have you placed a line in the ssh-agent load script in your .bash_profile to do an ssh-add for the regular user's private key?</li>
<li>Have you placed another line in the ssh-agent load script in your .bash_profile to load the Gitolite administrator's private key?</li>
<li>You have two ssh-add lines in the script?...just checking</li>
<li>You've created a file named "config" in your .ssh directory?</li>
<li>You've edited the config file so the ssh-agent knows which private key to load in the ssh-agent? See an image of what the config file looks like in a previous post.</li>
</ul>
<p><span style="color: #0000ff;">Setting up Gitolite on the server in the Gitolite administrator's account</span></p>
<ul>
<li>Have you cloned the Gitolite software from GitHub?</li>
<li>Did you change directories into the Gitolite directory, and install the Gitolite software with a ./src/gl-system-install?</li>
<li>Have you checked that your env $PATH has a $HOME/bin in it by running "<span style="color: #008000;">echo $PATH</span>"? If not, have you inserted it, by assigning it in your .bash_profile or .bashrc file?</li>
<li>Now that your path is set, from ~, have you installed the gitolite-admin bare repostory on the server by running "gl-setup ~/temp/gitadmin.pub"?</li>
<li>Did you put yourself as the gitadmin in the gl-setup command by adding your gitolite administrators public key to the end of the command? Just checking again...</li>
<li>Did you go to ~/repositories, and see you now have two bare repositories: gitolite-admin.git and testing.git?</li>
</ul>
<p><span style="color: #0000ff;">Testing your SSH connection from your local machine</span></p>
<ul>
<li>Did you run "ssh gitolite-admin@gitolite_server info" and check that the output is correct? I showed the correct output in my last post.</li>
<li>If you are asked for a passphrase, when you generated the gitolite_admin key-pair, did you not include a passphrase?</li>
<li>If you are asked for a passprase, did the ssh-agent use the right key? Check your ssh-agent in .bash_profile for the ssh-adds, and the config file in /.ssh</li>
<li>If you are seeing the shell info output, you are loading the wrong key into the ssh-agent.</li>
<li>Have you checked that only one ssh-agent is running? You can kill these in windows from your task manager.</li>
<li>Have you killed the running ssh-agent and started over by reopening your shell?</li>
</ul>
<p><span style="color: #0000ff;">SSH troubleshooting on the server</span>.</p>
<p>SSH is extremely permission and ownership sensitive up and down directories on both server and local machine</p>
<ul>
<li>If you are asked for a password, did you use, and specify, the correct public key when running gl-setup? Run it again if in doubt.</li>
<li>Have you checked that the owner, both user and group, is the gitadmin user in for gitolte directories, and .ssh directories?</li>
<li>Have you checked that your file permissions are correct from root down to every file in the .ssh directory. They should be 600.</li>
<li>Have you made sure there are no line feeds in your public key?</li>
<li>Does your /.ssh/authorized_keys file have #gitolite start and #gitolite end comments?</li>
<li>Did you open your .ssh/authorized_keys file and see that you have a "command" line in your public key for every user?</li>
<li>Did you check to see that these are public keys and not private keys?</li>
<li>Did you compare the public key on the server with the public key on the local machine in your .ssh directory to see that they are the same?</li>
<li>Did you use the Gitolite public key, and not your regular user public key, in the .ssh/authorized_keys file?</li>
<li>Did you remove any other public keys in the .ssh/authorized_keys file outside of the #gitolite comment tags? If you don't, you will get the error message: "gitolite-admin does not appear to be a git repository"</li>
<li>Did you remove any keys from the .ssh/authorized_keys that do not start with a "command" line?</li>
</ul>
<p><span style="color: #0000ff;">Setting up your regular gitolite-admin repository on your local machine</span></p>
<ul>
<li>From your local home directory, did you clone the gitolite-admin repository from the server?</li>
<li>Do you now have a ~/gitolite-admin directory?</li>
<li>In the gitolite-admin directory do you have a conf and keydir directories?</li>
<li>In your keydir directory, have you copied your two public keys for your regular account and your gitolite admin account?  You should rename your regular key to something like aname.pub.</li>
<li>Does your gitolite administrator public key name on the local machine match the one you used to install gitolite-admin on the server, and the one you used with the ssh-agent?</li>
<li>If you have other users public keys to administer, have you renamed them, and placed them in the keydir directory?</li>
<li>Have you opened your gitolite-admin/conf/gitolite.conf file and configured it for your repositories and users?  I haven't covered this yet.</li>
<li>Have you done an initial commit in your gitolite-admin repository?</li>
<li>Have you checked your .git/config file for a remote URL entry?  The Gitolite admin's remote repository URL is different than in a users URL in their .git/config.</li>
<li>Have you a master branch specified in your .git/config file? I have an image of this file in my last post.</li>
<li>Have you checked that your .git/config file has a section for each branch in your repository?</li>
<li>Have you pushed your changes to the central repository?</li>
</ul>
<p><span style="color: #0000ff;">After SSH Works</span></p>
<p>One after thought that I haven't dealt with yet is the ~/gitolite-admin/conf/gitolite.conf file.  You'll need to give yourself permission to use the gitolite-admin repository, and every repository you want to administer, and put your public key in the ~/gitolite-admin/keydir directory.  Read the documentation on using gitolite, it's pretty good.</p>
<p>After you pass the ssh hurdle, you can easily check that everything is working correctly by cloning the testing repository locally, changing something locally, git pulling and pushing. In your .git/config file, you should have a remote origin which tells your git pull and push where to go. Also each branch should have a section. The command to push should be "git push origin master" after a commit.  One other gotcha, your user's remote URL in their local .git/config file will look something like this: "ncrow@gitolite_server:testing.git," while yours, as the gitolite adinistrator will look like, "gitolite_server:testing".</p>
<p>Once you get everything set up correctly, I would recommend you create a back up copy of the good key files, in case your files get hosed down the road.</p>
<p>Congratulations, that everything is running fine, or that you found your problem and corrected it.  As I here from folks, or think of other things that could go wrong, I'll add them to this list. I would like to keep this checklist up to date, as a service to all, any suggestions on things to check are appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2011/10/24/gitolite-troubleshooting-checklist-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gitolite Install &#8211; part 3</title>
		<link>http://www.geekgumbo.com/2011/10/21/gitolite-install-part-3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gitolite-install-part-3</link>
		<comments>http://www.geekgumbo.com/2011/10/21/gitolite-install-part-3/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 09:35:43 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Gitolite]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=3720</guid>
		<description><![CDATA[We've been through what Gitlolite is, and how it sets up between the server and your local client.  The second article covered what ssh is, and how Gitolite handles ssh differently, than a program like Putty.  We now have enough &#8230; <a class="more-link" href="http://www.geekgumbo.com/2011/10/21/gitolite-install-part-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/install.jpeg"><img class="alignleft size-full wp-image-3798" title="install" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/install.jpeg" alt="" width="140" height="140" /></a>We've been through what Gitlolite is, and how it sets up between the server and your local client.  The second article covered what ssh is, and how Gitolite handles ssh differently, than a program like Putty.  We now have enough background information to install Gitolite, and know what we're trying to accomplish with each step.</p>
<p style="text-align: center;"><span style="color: #0000ff;">Preliminary Set Up</span></p>
<p style="text-align: left;">I assume you have installed Apache, Perl, and Git on your server.  These all can be installed with your package manager.  Let's call the server,  "gitolite_server".  You've installed Git on your local machine.  If your running Windows on your local machine, you probably access Git in the Msysgit BASH shell.</p>
<p>On the server, in addition to your regular user name, login as root and create a "virtual" user, let's call the virtual user "gitadmin."  As the gitadmin virtual user we will install Gitolite in your virtual user home directory, which is different from your regular user "real" account home directory.</p>
<p style="text-align: center;"><span style="color: #0000ff;">Setting up the Ssh</span></p>
<p style="text-align: left;">After installing your base components, we want to set up our ssh connections. A key point to remember, ding, ding, ding.  We want to set up two ssh key-pairs on your local machine, one for you as a regular user to login to the gitolite_server together with with passphrase, login, and password.  You can use Putty for this connection if you like.  Change the name of this key-pair to something like: id_rsa_aname and id_rsa_aname.pub.  Note, this connection could be in the Putty dsa format, in which case, you would have and id_dsa and id_dsa.pub.  The second connection has to be SSH2 RSA, or you've got trouble.  I prefer to keep both keys in the RSA format.</p>
<p>The second key-pair is for the "gitadmin" virtual user.  We'll use this for the Gitolite administrator's connection to Gitolite.  Generate the gitadmin key-pair on your local machine in the Git Msysgit BASH window by typing:  "<span style="color: #008000;">ssh-keygen -t rsa</span>".  Remember, on this key-pair, we do not want a passphrase, at least for the initial install, just hit the return key twice.  Rename this key-pair to something like id_rsa_git and id_rsa_git.pub.  We end up with two key-pairs, if you don't see them look in the ~/.ssh directory on your local machine.</p>
<p>We now copy the public keys to the server, so ssh can find them, to set up your connection.  First, login to the server as the regular real user "aname".  Copy from your local machine to the server, the id_rsa_aname.pub file, and put it in "/home/aname/.ssh".   Now, "su" into the virtual gitadmin user account, and copy the id_rsa_git.pub key to a temp directory you create, something like "/home/gitadmin/temp".  Rename the pub file to something like, "gitadmin.pub".   Do not place this key in your /home/gitadmin/.ssh directory.  Gitolite will use the ~/gitadmin/.ssh directory to create its authorized_keys file from the public key you just copied.</p>
<p>Back to the local machine, the ssh-agent on your local machine loads your ssh private key file, checks for your passphrase, and then generates a signature to pass to the server.  The ssh-agent is loaded by the .bash_profile file on your local machine, when you first open the shell.  Another BIG gotcha is the ssh-agent doesn't know about any of your private keys until you tell it with an "ssh-add".  Both private keys need to be added in the .bash_profile script before everything will work.  Here's a look at my .bash_profile on my local machine.</p>
<div id="attachment_3721" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/bashprofile05.png"><img class="size-full wp-image-3721 " title="bashprofile05" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/bashprofile05.png" alt="" width="600" height="554" /></a><p class="wp-caption-text">Starting the ssh-agent in .bash_profile on your local machine</p></div>
<p style="text-align: left;">After updating your .bash_profile, close and re-open your local shell to initiate the changes.</p>
<p>We're almost there.  The last thing we need to do with ssh is to tell the ssh-agent which private file to use when opening a particular connection.  This is done in a file called "config" with no extension placed in your .ssh directory.  You'll have to create this file from scratch.  It looks something like this:</p>
<div id="attachment_3732" class="wp-caption aligncenter" style="width: 598px"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/sshconfig6.png"><img class="size-full wp-image-3732" title="sshconfig6" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/sshconfig6.png" alt="" width="588" height="306" /></a><p class="wp-caption-text">Telling the ssh-agent which key to use in ~/.ssh/config</p></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="text-align: center;"><span style="color: #0000ff;">Gitolite - Getting the Software Installed on the Server</span></p>
<p>OK, we've set up our ssh connection, let's start setting up Gitolite.  On the gitolite_server, as user "gitadmin", its time to download the Gitolite software.  This comes from GitHub, in your gitadmin home directory, type:</p>
<p><span style="color: #008000;">git clone git://github.com/sitaramc/gitolite.git</span></p>
<p>And the Gitolite software will be loaded on your server.  Isn't Git wonderful.  You'll find a Gitolite directory among other directories.</p>
<p>This is just the software, it still needs to be built, but first, as the virtual user "gitadmin" on the server, check your path environmental variable, "echo $PATH" to make sure ~/gitadmin/bin, or $HOME/bin,  is in your path.  This puts all the Gitolite scripts in your path.  If $PATH/bin is not set,  amend $PATH to add it in your .bash_profile or .bashrc file.  It should be there.</p>
<p>What we have now is a bunch of installation files; we need to install Gitolite on the server.  Let's do the build, still as user "gitadmin" on the server, type:</p>
<p><span style="color: #008000;">cd gitolite</span></p>
<p><span style="color: #008000;">./src/gl-system-install</span></p>
<p>This installs Gitolite, the program, on the gitolite_server.  Note, if you update Gitolite in the future just pull from GitHub, and run system install again, and you're all set.</p>
<p>Next, we want to create a "bare" gitolite-admin repository on the server, and designate user "gitadmin" as the Gitolite administrator by telling Gitolite to use the gitadmin public key.   Since we hooked up our path earlier, do this from the $HOME directory.  To create our gitolite-admin repository, type:</p>
<p><span style="color: #008000;">cd ~</span><br />
<span style="color: #008000;"> gl-setup ~/temp/gitadmin.pub</span></p>
<p>All Gitolite commands start with gl-  and can be found in ~/gitolite/src.   After setup, you now have in your ~/repositories directory a gitolite-admin.git bare repository, and a testing.git bare repository, you can use the testing repository to check the communication back and forth between your local machine and the server.  All repositories on the server should be bare repositories, and are default located in ~/repositories.  Repositories on the server usually have the .git extension.  You can store your central repositories anywhere on the server, but I found the default ~/repositories works fine, and I don't have to set the path to the new repository directory in my .gitolite.rc file.</p>
<p>Now, we test our connection from our local machine.  If you don't get an output like shown below, you're ssh connection is not set up correctly, and you should not  install Gitolite on your local machine until the ssh connection is correct.</p>
<p>On your local machine in the Git shell, type "<span style="color: #008000;">ssh gitadmin@gitolite_server info</span>".   Your output should look something like shown in the next image.   Some of the text in this image has been blacked out for confidentiality.</p>
<div id="attachment_3727" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitolitegoodconnect15.png"><img class="size-full wp-image-3727" title="gitolitegoodconnect15" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitolitegoodconnect15.png" alt="" width="600" height="115" /></a><p class="wp-caption-text">What a good ssh connection looks like</p></div>
<p>&nbsp;</p>
<p style="text-align: center;"><span style="color: #0000ff;">Setting up your local gitolite-admin repository</span></p>
<p>In order to talk to the bare repository on the server, we need to do "git push" and "git pull" commands from a gitolite-admin regular repository on your local machine.  Next we'll install the gitolite_admin local repository on your local machine.  Will do this with a git clone.  Back on your local machine in your home directory, type:</p>
<p><span style="color: #008000;">git clone gitadmin@gitolite_server:gitolite-admin</span></p>
<p>Congratulations.  Your done the install.  You now should have a full fledged gitolite-admin repository on your local machine at ~/gitolite-admin.</p>
<p>To change permissions on what repositories and what users can access those repositories on the gitolite_server, you make changes on your local machine in the gitolite-admin repository, commit those changes, and then "git push" them to the server.  Use the testing repository to play around, make changes and verify to yourself that everything is working properly.</p>
<p>Be aware, that you, as gitolite administrator, because you set up all your paths, urls, and keys, access repositories slightly differently than a regular user.  You use something like: gitolite_server:testing  to address a repository.  The regular users use something like dbowe@gitolite_server:testing.git.  Here's a look at the administrator's url in the .git/config file.</p>
<div id="attachment_3753" class="wp-caption aligncenter" style="width: 562px"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitconfig71.png"><img class="size-full wp-image-3753" title="gitconfig7" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitconfig71.png" alt="" width="552" height="238" /></a><p class="wp-caption-text">What the administrator&#39;s URL looks like in .git/config</p></div>
<p>&nbsp;</p>
<p>That's about it, read the documentation on how to grant authorizations.  That part of the documentation is pretty good.  Speaking of clear documentation, after I got everything installed properly, the documentation made sense, before that it was all Greek.</p>
<p>Next we'll talk about troubleshooting when something's not right.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2011/10/21/gitolite-install-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSH and the Gitolite Installation &#8211; part 2</title>
		<link>http://www.geekgumbo.com/2011/10/18/ssh-and-the-gitolite-installation-part-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssh-and-the-gitolite-installation-part-2</link>
		<comments>http://www.geekgumbo.com/2011/10/18/ssh-and-the-gitolite-installation-part-2/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 13:47:56 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Gitolite]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=3696</guid>
		<description><![CDATA[In my last post I talked about Gitolite, and how it works with Git to give you an administrative shell and master repository on a central server.  An important point was doing the install, in order, with the second step &#8230; <a class="more-link" href="http://www.geekgumbo.com/2011/10/18/ssh-and-the-gitolite-installation-part-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my last post I talked about Gitolite, and how it works with Git to give you an administrative shell and master repository on a central server.  An important point was doing the install, in order, with the second step being setting up your ssh connection.  In this post, I want to cover what is going on under the hood when using an ssh connection with Gitolite.</p>
<p><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitolite-admin251.jpg"><img class="aligncenter size-full wp-image-3689" title="gitolite-admin25" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitolite-admin251.jpg" alt="" width="600" height="447" /></a></p>
<p>If your going to create a server with a central repository, accessible over a TCP/IP connection, whether internal to the company, or to the world, you don't want to allow anyone to have access to that server, and you want your communications back and forth to be encrypted.  You want your repositories to be secure.  Setting up the encrypted communication channel between your local machine and the central server is what ssh does.</p>
<p>When installing Gitolite, we want to set up an encrypted communication channel between the Gitolite administrator's local machine, and Gitolite on the central server.  Gitolite will not work unless it's ssh connection is set up properly.</p>
<p>The gotcha on this ssh install is that this is not a normal ssh connection.  If your thinking, I'll just use Putty to establish my ssh connection to the central server from my local machine, something Putty specializes in doing, forget it.  I will tell you now, if you use Putty, you will not believe the problems you will have with the Gitolite installation.  Do not use Putty.  Forget Putty.  Let's talk ssh first, and you'll see why.</p>
<p style="text-align: center;"><span style="color: #0000ff;">SSH Basic Concepts</span></p>
<p>What most folks don't know is that sending unencrypted logins and passwords over the Internet can be detected by a software application called a sniffer.  Using a sniffer you can detect unencrypted network traffic, just like you were looking over the user's shoulder.  This is combated by encrypting the transmissions with a group of encryption programs called OpenSSH.  OpenSSH uses a public and private ssh key to ensure, you're allowed access to the server.  Once the connection is set up it encrypts all your communications to and from the server.  Git and Gitolite use OpenSSH to ensure that none of your code or data you pass to, or get from, the server can be captured by anyone else.</p>
<p>Ssh keys are generated, by you on your local machine, as a key-pair, a private and public key.  The private key you always keep on your computer, letting no one else have access to it.  It ensures you are you to the server.   The private key is usually located in a .ssh directory on your computer, and usually has the name id_rsa with no extension on the end.  The public key, which you place on the servers you would like to gain access to before attempting a connection, is initially in the same directory as the private key, and is called id_rsa.pub.  The pub for public key.</p>
<p>The normal flow, using a program like Putty, is to initiate a connection by clicking on the server you want to go to in Putty.  OpenSSH's ssh-agent loads and asks you for a passphrase (not a password).  This is usually a long sentence you put in when you generate the keys.  The passphrase is used on the local machine to verify you are the person that generated the keys on your computer, so no one else can use your keys to initiate a connection.  The ssh-agent then uses your private key to generate a signature to send to the server.  That particular signature is unique and generated only once.  The next time a signature is needed, a completely new signature is generated.</p>
<p>The OpenSSH program sends the signature generated from your private key to the server, the server's OpenSSH sshd program pulls up your public ssh key, that you previously installed on the server, checks it against the signature it just received, and if its a match, opens up an encrypted channel between your local machine and a shell on the server.  For the rest of the session, you have encrypted communications between your local machine and the server.  On the server, the public keys are normally stored in the ~/.ssh directory in a file called authorized_keys.  There could be many user's public keys in the authorized_keys file.</p>
<p>That's ssh in a very fast nutshell.  Let's talk about Putty.  There are several ssh protocols out there, SSH1, SSH2, and DSA.  Putty normally uses DSA.  Gitolite uses SSH2 RSA.  They do not match, and you won't know that's the problem when the server rejects your Gitolite connection.  It will drive you nuts.  You should not use Putty to establish a connection with Gitolite.   You can use Putty to open up a shell on the server, and knowing you need SSH2, 1024bits, RSA for Git and Gitolite, you can use a program like PuttyGenerate to export the ssh rsa keys, but it's best to generate the keys from the command line using "ssh-keygen -t rsa".</p>
<p style="text-align: center;"><span style="color: #0000ff;">Gitolite's Uniqueness</span></p>
<p>I said Gitolite's ssh set up is unique.  What you want to accomplish is to have a user not login to the server using a username and password.  And not ask for a passphrase on your local machine to log in to the server, but still have encrypted communications.  What you want is, when using Gitolite, is to just type "git pull" or "git push," and that's it.   The repository is copied to your local machine from the server, "git pull," or the repository is sent to the server, "git push," no logins and no passwords, and no shell.  Gitolite will not grant you access to a shell on the server.</p>
<p>How do we do this?  What goes on under the hood?  There's a couple of things that have to happen.  The first time you pull up the GitBASH shell on your local Window's machine, you may be asked for a passphrase for that session.  This is the local machine verifying you, and not knowing what server you may want to use.  A one time authentication, and that's it for the session.  The ssh-agent from then on should take care of all your passphrase requirements for all your logins.  This should not interfere with Gitolite's git push or git pull, but sometimes you go nuts trying to get rid of the passphrase when going to the Gitolite server.</p>
<p>Some more on the potential passphrase problem.  When you connect to Gitolite on the server, you do it from your local repository, and the way to connect is with "git pull" or "git push."  There is no way for you to gain access to a shell on the server to do something else, or something nasty, for example.   All the Gitolite installs recommend not using a passphrase when you generate your ssh keys on your local machine for the gitolite administrator.  I am in this camp.  If someone else wants to log on to my machine, or sit down quickly when I take a bathroom break, more power to them, but their not going to mess up anything on the server.  I think for the gitolite administrator's connection not to have a passphrase is acceptable.  When you generate your keys, just hit a return and don't put in a passphrase during the install.  If your system administrator, absolutely has to have a passphrase, put one in later with a -p ssh-keygen option.  I do not recommend using one on the initial set up, it's just another area that may cause you problems.</p>
<p>Git needs to know your username and the server location to comunicate with your repository, for the "git pull" and "git push" commands.  The username and repository server location are stored on your local machine in your .git/config file for each repository.  If you open and look at the .git/config file on your local machine in what ever repository you're in, you'll see a heading called [remote "origin"] with the Gitolite username, and URL to the remote server for that repository.  You also should see a heading for each branch in your repository, like [branch "master"].</p>
<div id="attachment_3747" class="wp-caption aligncenter" style="width: 562px"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitconfig7.png"><img class="size-full wp-image-3747" title="gitconfig7" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitconfig7.png" alt="" width="552" height="238" /></a><p class="wp-caption-text">.git/config should gitolite administrator&#39;s url to server</p></div>
<p>&nbsp;</p>
<p>What's left is the ssh hook up.  Since Gitolite sits on top of the master Git repositories, and you have to go through Gitolite, it handles the authentication when using Git.  The only thing being done on the server, as the Gitolite virtual user, is to run gitolite.   Gitolite sets up an authorization file in ~/gitolite/home/.ssh.  This authorization file is unique in that user's allowed to have access to the master repositories through Gitolite have their public keys in the authorized_keys file with a line appended to the beginning of the public key starting with "command."  This is called a "forced-command," because it forces you to stay in the Gitolite shell and no where else.</p>
<div id="attachment_3712" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitauth75.png"><img class="size-full wp-image-3712" title="gitauth75" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitauth75.png" alt="" width="600" height="284" /></a><p class="wp-caption-text">Part of the Gitolite authorized_keys file showing part of the command line</p></div>
<p>&nbsp;</p>
<p>When you grant access to a new user, on your local machine you put their public key, in the gitolite-admin/keydir directory after renaming it to the user's name, like aname.pub.  You then commit and push that to the server's "bare" gitolite-admin repository on the server with a "git push."</p>
<p>A successful push does two things.  First, the public key is put in the repositories ~/.gitolite/keydir directory on the server, this is used in combination with your ~/.gitolite/conf/gitolite.conf file to grant the user authorization to use various repositories.  Second, the new user's public key is added to the ~/.ssh/authorized_keys file with a special forced-command header line.  This sets up the encrypted communication channel, and the forced-command line causes any Git push or pull commands, to not use a shell, or login, and just transfer the encrypted repository.  What we want.  We're ready to do the actual Gitolite install, which I'll cover in the next article.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2011/10/18/ssh-and-the-gitolite-installation-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing Gitolite &#8211; an Overview &#8211; part 1</title>
		<link>http://www.geekgumbo.com/2011/10/14/installing-gitolite-an-overview-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installing-gitolite-an-overview-part-1</link>
		<comments>http://www.geekgumbo.com/2011/10/14/installing-gitolite-an-overview-part-1/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 13:20:09 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Gitolite]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=3688</guid>
		<description><![CDATA[I hesitate to write about Gitolite. Why?  Because I'm adding to an already voluminous amount of documentation on the subject.  What, yet another article on Gitolite.  Why so much documentation on Gitolite, because, although there are many claims in the &#8230; <a class="more-link" href="http://www.geekgumbo.com/2011/10/14/installing-gitolite-an-overview-part-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I hesitate to write about Gitolite. Why?  Because I'm adding to an already voluminous amount of documentation on the subject.  What, yet another article on Gitolite.  Why so much documentation on Gitolite, because, although there are many claims in the documentation that Gitoite is easy to install, if you start running into problems, it's not.  Anyone who has run into problems, wants to help others, and thus writes more documentation on the subject.  I had a ton of problems loading Gitolite, and I've read just about every article and series of questions and answers on Gitolite on the Internet.</p>
<p><a href="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitolite-admin251.jpg"><img class="aligncenter size-full wp-image-3689" title="gitolite-admin25" src="http://www.geekgumbo.com/wp-content/uploads/2011/10/gitolite-admin251.jpg" alt="" width="600" height="447" /></a></p>
<p>Why not just give up, if you run into problems, and use GitHub?  Because I did finally get it installed, and the effort to get it installed correctly is worth the effort.</p>
<p>What was missing from all that I read was an overview, a guideline and road map through the installation process.  This is an overview on getting Gitolite and GitWeb installed and running correctly.  The why behind all the commands you see in the documentation.</p>
<p>First, when would you want to use Gitolite, what is it?<br />
The reason to use Gitolite is, if you want to have a central master repository of your work, to which, several developers contribute.  Gitolite makes it easy to exchange work between developers.  Why not GitHub?  Well, GitHub is on the Internet, and some corporations do not want their work on the Internet.  They want it on one of their internal servers, not available to the outside world. If that's the scenario, your best choice is Gitolite.</p>
<p style="text-align: center;"><span style="color: #0000ff;">General Concepts</span></p>
<p>Git has two types of repositories, the every day repository that saves your local work on your local machine with a commit, and a "bare" repository.  A "bare" repository can only be updated with a "git push" or "git pull".  You use the bare repository on your central server as your master repository.  Git will not make commits on a bare repository, so no changes are possible directly on the server.  You have to get code from the repository with a "git pull," and make updates with a "git push" from a regular repository on your local machine.</p>
<p>A group of developers will develop code on their local machines, each using their own pet development tools, and make commits to their local repository.  When they get ready to share their code with other developers, they first pull and then push their work to the bare repository on the central server.</p>
<p>Gitolite is an administrative layer that sits on top of the bare Git repositories on the central server that gives the Gitolite administrator the ability to assign privileges and control what repositories can be updated and by who.  Only specific developers can update specific repositories.  Since it is easy to create a repositories in Git, Gitolite controls what repositories belong to which developers. Who can update what.  If a developer wants to move a copy of his repository to the master central repository, he has to go through Gitolite to get there.  Once installed the only way to a central repository is through Gitolite.</p>
<p>The way Gitolite does this is by creating a bare repository of its own on the central server to keep track of authorizations, called "gitolite-admin".  Since gitolite-admin is a bare repository, the only way to update it, and change user privileges, is by pushing changes to it from the gitolite-admin repository on the Gitolite Administrator's local machine.  Thus there needs to be a full Git gitolite-admin repository on the administrators local machine.</p>
<p style="text-align: center;"><span style="color: #0000ff;">Stages of the Gitolite Installation</span></p>
<p>Fortunately, Gitolite has distinct installation stages, with tests, to make sure each stage is installed correctly.  It's very important that you do the stages in order.  Do not jump ahead in the installation until you have completed and tested that the previous stage is working properly.</p>
<p>The stages you will follow are:</p>
<p>(1) Install the basic tools.  Install Apache, Perl, and Git on your designated central server.  Install Git on the Gitolite administrators local machine.  Test that everything is working properly.</p>
<p>(2) Install the ssh connection between the central server and the Gitolite administrators local machine.  This is the most critical step of the installation and where most of the problems happen.</p>
<p>(3) Install Gitolite on your central server.  First you install Gitolite itself, then you setup the gitolite-admin bare repository.</p>
<p>(4) Set up the local gitolite-admin repository on your local machine.</p>
<p>(5) Configure and test the Gitolite installation with test repsitories.</p>
<p>(6) Set up GitWeb.  GitWeb is a web server, like Apache, that comes with the Git install, and allows you to see the contents of your bare central repositories, on a read-only basis, in a browser window.  It will be the last thing you will install.</p>
<p>The first step is fairly simple and should be already completed, except maybe for the Git part.</p>
<p style="text-align: center;"><span style="color: #0000ff;">Step One</span></p>
<p>I am going to make a big assumption and assume you can install Apache, Perl, and Git without a problem on the central Linux server.  The install usually involves using a Linux package installer, like yum, to install Apache, Perl, and Git. You can check Apache with a basic web page, look for the Perl version, and check Git on the server by making a test repository.</p>
<p>Install Git on your local machine.  I like to install a WAMP stack on my local Windows machine using Wampserver for local development, and then install Git in a Msysgit Linux window.  If your local machine is Windows, see my article on <a title="Installing GIt on Windows" href="http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/%20">installing Git on Windows</a> to do that.  Check to see if you can create a local Git repository before continuing.</p>
<p>My next article we'll cover, the Gitolite ssh connection.  This is the most important and critical step in the installation, and the one that will cause you the most problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2011/10/14/installing-gitolite-an-overview-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git: A simple workflow, commands, and usage</title>
		<link>http://www.geekgumbo.com/2011/08/04/git-a-simple-workflow-commands-usage/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=git-a-simple-workflow-commands-usage</link>
		<comments>http://www.geekgumbo.com/2011/08/04/git-a-simple-workflow-commands-usage/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 03:48:17 +0000</pubDate>
		<dc:creator>imperialWicket</dc:creator>
				<category><![CDATA[Git - Version Control]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=3355</guid>
		<description><![CDATA[There are a lot of Git workflows, tips, usage models, tutorials, books, and other such resources out there. Nonetheless, the issue I always encounter when introducing git to new users (both new to version control and new to decentralized version &#8230; <a class="more-link" href="http://www.geekgumbo.com/2011/08/04/git-a-simple-workflow-commands-usage/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There are a lot of Git workflows, tips, usage models, tutorials, books, and other such resources out there. Nonetheless, the issue I always encounter when introducing git to new users (both new to version control and new to decentralized version control), is that it is difficult to figure out how to make git work - end to end - for a given project. </p>
<p>I want to use a very straight-forward and functional workflow, highlight a simple example of git commands that can move a user about the workflow, and detail a few scenarios that highlight how the workflow applies to projects. I will claim that the workflow is very functional for many project types, although it is not my workflow. I am not claiming that these are the best commands to fulfill the workflow, nor am I claiming that successful usage of these commands is sufficient understanding to use git. I do think that these commands are some of the simplest for navigating this workflow. I also think that having these commands available as a reference will make it easier to start using git, and to start using it in a way that has the potential to use a lot more of git's functionality.  </p>
<h3>A Successful Git Branching Model (Workflow)</h3>
<p>Vincent, over at <a href="http://nvie.com/">nvie</a>, published an excellent detail of <a href="http://nvie.com/posts/a-successful-git-branching-model/">A Successful Git Branching Model</a>. While branching model is a more appropriate descriptor, I think non-git users would fail to find this information because the concept of a branching model is generally DVCS-specific (needs source). I use this model, or a very similar sub-structure, on many of my projects, and have nothing but good things to say about it.  </p>
<p>Addressing the first two questions that generally surface about this git workflow:</p>
<ol>
<li>Yes, this workflow is appropriate even if you are a single developer or a small team.</li>
<li>No, this [seemingly] excessive branching is not a waste of time.</li>
</ol>
<p>Vincent does a great job of explaining a lot of the necessary techniques and many of the commands for keeping this branching model in order. Again, the only point I find concerning is that it generally feels like his branching model and its description target existing git users. This is fine, but I think it is a great model for git usage generally, and I also think it is straight-forward to use as a newcomer to git. In that interest, I want to spell out some functional commands to use this workflow.</p>
<h3>Git Workflow commands</h3>
<p>A few points, before I throw up an image. Any actual branch updates are abridged to one 'git add .' and 'git commit'. I do not condone this behavior for your branch modifications. You should commit often, that is why you are using version control. In my experience, about 95% of my projects have far more commits than I will ever need. But in the 5% of the cases where I actually needed to roll back or revert commits, I saved considerable time by commiting as often as I did. </p>
<p>Additionally, I have a few superfluous command techniques in place. Since I am really pushing for git newcomers to actually start (and stick to) using git, and to get others away from working in master for everything, I want to cater to those newcomers a little. In order to help them along the way, I tried to be as failsafe as possible. This is why you see things like:</p>
<pre>
git add .  # Tells git to add all files in this directory to the branch
git commit -am "commit details"
  # The -a flag tells git to add all known files before commiting.  This
  # should not be necessary if you just ran 'git add .'
</pre>
<p>This is very directly inspired by Vincent's work, although it is obviously not meant to be a one to one replica of his branch depiction.</p>
<div id="attachment_3356" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.geekgumbo.com/wp-content/uploads/2011/08/nvie-git-workflow-commands.png"><img src="http://www.geekgumbo.com/wp-content/uploads/2011/08/nvie-git-workflow-commands-300x199.png" alt="git workflow with commands" title="nvie-git-workflow-commands" width="300" height="199" class="size-medium wp-image-3356" /></a><p class="wp-caption-text">Git workflow with commands (click for full size)</p></div>
<h3>Git Workflow usage</h3>
<p>If you did not actually read through the branching model explanation and details at nvie, <a href="http://nvie.com/posts/a-successful-git-branching-model/">go back and do that</a>. Some aspects that get glossed over a bit are either just good version control habits or good git-specific habits; particularly for those of you getting started with git, I want to spell a couple of these out.</p>
<p>Branch. Adding some code? Branch. Adding resources that might break something? Branch. Changing a text string? Ok, maybe you can do that in the current branch, but you better make it a specific commit and give it an accurate message. What I mean is: branch more. Any discrete update might as well be a branch. Branching and merging between branches is simple with git, make use of it. I will highlight that Vincent makes a good point about using the no fast forward flag when merging; when you find gitk, you will be happy you started using --no-ff.</p>
<p>Use meaningful and consistent commit messages. People fight over what the consistency should be, but I am not fighting that battle here. Just be consistent. Think about things like case (initial caps?), tense (all past tense, all present, future perfect w/ negative - if you want a really interesting thought experiment when reverting), bug references (if you are using a bug tracker - you <em>are</em> using a bug tracker?), etc.</p>
<p>Some bad commit messages:</p>
<ul>
<li>fixing bugs</li>
<li>updated issues with code working</li>
<li>Replaces the images with new ones</li>
</ul>
<p>Some better commit messages:</p>
<ul>
<li>Fixes bugs in form submission mechanism.</li>
<li>Updates code formatting and corrects typographical errors in comments.</li>
<li>Replaces the images with updated versions from version 2 marketing portfolio.</li>
</ul>
<p>If you are working in a team, remember to pull often when working with develop and master (or any branches that will have multiple users). This will help avoid a whole nest of non-beginner-friendly error messages. </p>
<p>Also, don't forget this is a decentralized VCS. I only added the 'git push' commands to develop and master. It may be prudent for you to push other branches to an origin location. Origin and centralized branch techniques within teams surpasses the scope of this post, but Vincent touched on some concepts in his early discussion.</p>
<p>If you are coming from a centralized version control system, forget about 'git fetch' for now, 'git pull' probably does what you want. Get started and get comfortable with pull, and when you have time review the concepts behind pull and how fetch works. Fetch is really handy when you need it, but you can usually get by with pull.</p>
<h3>Git Workflow example scenarios</h3>
<p>I like to reserve master as a pristine representation of what went live. This represents web sites that actually spent time on the production server, libraries that are/were in use elsewhere, or applications that actually shipped. This way, if someone ever comes back and says they have a bug, you can quickly and efficiently get to the exact code that is exhibiting the issue and fix only that issue. With less complex branching models, you can get caught having to fix multiple issues, due only to the fact that you do not have a branch dedicated to your current update (I'm talking to the git users who do all their work in master...). This 'bug in a live release' example is where the master and hotfix branches shine. A word of caution - only one hotfix per hotfix branch: two hotfixes = two hotfix branches. You will thank me when you require two hotfixes and one turns out to be more problematic than you originally thought. </p>
<p>If you are working alone, and get hung up on a particular feature, sometimes it is very productive to shelf that feature and work on something else for a while. Instead of being stuck rigging up placeholders and dummy content, or commenting out work, go back to develop, and create a new feature branch. This gives you a fresh develop branch to update, without worrying about the partial functionality of the first feature. This is also an appropriate area of the branching model for priority changes. It may be the case that a larger feature has been downvoted, or is simply less important, and other features need your attention. The key is that a delay in one feature should never (of necessity) affect the schedule of another, independent feature. The develop and feature branches fullfil these usage cases. </p>
<p>The release branches are good for limiting feature creep (until you start using rebase, but that's another post). You start with what you feel to be a release candidate develop state, and then you can test against it. If there are issues, address these issues in the release branch. This provides a similar discretion to the multiple feature branches, and keeps other features from affecting your ability to address minor bugs in a release candidate. Once your release candidate is finalized, you can merge it to master, and also merge it into develop. If you are following my recommendations, at this point master gets posted, moved to production, shipped, or whatever. Be sure that if fixes were made to a release branch, those fixes are also merged back into develop. If you forget to do this your bugs will come back in the next release branch.</p>
<p>This got pretty long, if you made it this far, thanks for sticking around. I hope this helps flesh out a really great Git Workflow and opens git to a few new users who can hit the ground running.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2011/08/04/git-a-simple-workflow-commands-usage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Git Basics &#8211; How Git Saves Your Work</title>
		<link>http://www.geekgumbo.com/2011/07/19/git-basics-how-git-saves-your-work/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=git-basics-how-git-saves-your-work</link>
		<comments>http://www.geekgumbo.com/2011/07/19/git-basics-how-git-saves-your-work/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 14:22:23 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Git - Version Control]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=3299</guid>
		<description><![CDATA[When first learning Git, most folks take a cookbook approach. You "git add" and "git commit" as you move along with your project. Git is a version control system, so you assume your keeping track of changes in your project, &#8230; <a class="more-link" href="http://www.geekgumbo.com/2011/07/19/git-basics-how-git-saves-your-work/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When first learning Git, most folks take a cookbook approach.  You "git add" and "git commit" as you move along with your project.  Git is a version control system, so you assume your keeping track of changes in your project, but does Git really save the contents of your file at a particular point in time, and can you get it back? Your not completely confident.</p>
<p>I thought it would be helpful to take another look at Git's inner workings from a fresh perspective to give you a little more confidence in using Git.</p>
<p>Here goes.  Git is a system that saves the contents of the files in your project.  It can reproduce the contents of your files exactly as you originally saved them, exactly.  If you had a semicolon on line 10 of your file six versions ago, when you retrieve the file six versions back, you'll find a semicolon on line 10 in the recovered file, exactly as you saved it six versions ago. </p>
<p>How does it save the file's content exactly as you originally saved it? We can thank the National Security Agency.  They invented a two-way, unique, content encryption algorithm called "SHA-1" that turns any document's contents into a unique, 40 hex character compressed blob. </p>
<p>It's two-way, because with the SHA-1, 40 character, hex hash you can go the other way, and reproduce the contents of the file.  </p>
<p>It is unique, because if you remove that semicolon on line 10, you'll have a completely different SHA-1 value for the contents. The result is we have one hex name, that represents the entire contents of a file that is much easier to manage and track.  </p>
<p>It allows Git to quickly determine whether a file has changed by just looking at the name. It also means, since all SHA-1 is calculated the same on every computer, for every user, you can quickly and easily copy, or clone, and move an entire project to another computer, and it will be identical to the original content, exactly. </p>
<p>In Git, these hash numbers are stored in your .git/objects database that you create when you run "git init" to start your database repository.</p>
<p>Let's go over some Git terms and we'll put it all together.  </p>
<p>Your "working directory" is where you work, where you edit files, rename your files, make new directories, and develop your project as you work day by day.  If you open up a file in an editor and make a change, you've made a change to your working directory.</p>
<p>Your "index" is just one file in your .git directory. It can grow quite large depending on the number of commits.  It is a listing of each file you have committed, and the files you have staged, or are ready to commit, in your repository.  Each file takes one line in the index that contains the files SHA-1 hash, the directory path, the file name of the file, and its permissions.</p>
<p>When you do a "git add" command, git encrypts the files in your working directory that have changed contents into their new SHA-1 hash, adds the compressed SHA-1 hash to .git/objects store, and adds that file as a line in the index file ready for committing.  That file is now in the index, or staged, and ready to be committed.  You'll notice I said the files that have changed.  Git doesn't need to encrypt files that have not changed.  It already has the SHA-1 hash for them.</p>
<p>When you commit, Git really has four objects it tracks that form a hierarchy of objects: a blob, a tree, a commit, and a tag.  At the bottom is the blob that is the contents of your file as a SHA1 hash. The tag is just a way to give a particular commit a special name, and is attached to the commit object, which leaves us the tree and commit object to consider.  </p>
<p>The tree object is how Git keeps track of file names and directories.  There is a tree object for each directory.  The tree object points to the SHA-1 blobs, the files, in that directory, and other trees, sub-directories at the time of the commit.  Each tree object is encrypted into, you guessed it, a SHA-1 hash of its contents, and stored in .git/objects. The name of the trees, since they are SHA-1 hashes, allow Git to quickly see if there's been any changes to any files or directories by comparing the name to the previous name.  Pretty slick.</p>
<p>"Git commit" only works with the index, not your working directory.  One of the reasons is the SHA-1 hash of the file is created during "Git add".  During the commit, the tree objects are built up, and we end up with one name for an entire tree of blobs and trees, the top tree object, which we'll use with our commit object.</p>
<p>The commit object keeps track of the physical state of the tree at a given point in time, when you commit.  It consists of the commit name, a SHA1 hash, the previous commit name, so you can track your history of commits, the SHA-1 of current top tree with all the changes for that commit included, the original author of the initial commit, the person doing the commit, and a comment describing the commit.  Remember, there can be more than one editor of a file, other than the original author.  The commit object keeps track of both.</p>
<p>We have a hierarchy. The Git commit object points to the previous commit, and the top git tree.  The top git tree points to all the tree objects under it and all files.  The SHA-1 file names point to the contents.  We have a history.  You can easily go back and get the contents of a file if you mess up the code really bad in your working directory file by bringing back your last commit of the file, with a simple git checkout "the file", nice, and the reason to use a version control system, like Git.  </p>
<p>Committing in Git is about working with the index to make a snapshot of your project at the time of the commit.  Since the Git index has the SHA-1 of a file and its path and file name, it is used to compare the previous commit with files ready to commit, and saving anything changed along with all that was not changed by reference to the SHA-1 name. </p>
<p>That's about it for the basics.  Hopefully, this will help you have a little better understanding when you read about other Git commands, and what they do, and a little more confidence that your current file is being saved when you do a "Git commit".</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2011/07/19/git-basics-how-git-saves-your-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>You should be using a version control system</title>
		<link>http://www.geekgumbo.com/2011/06/11/you-should-be-using-a-version-control-system/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=you-should-be-using-a-version-control-system</link>
		<comments>http://www.geekgumbo.com/2011/06/11/you-should-be-using-a-version-control-system/#comments</comments>
		<pubDate>Sat, 11 Jun 2011 12:59:50 +0000</pubDate>
		<dc:creator>imperialWicket</dc:creator>
				<category><![CDATA[Git - Version Control]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=3102</guid>
		<description><![CDATA[During a relatively short-time, I've had the opportunity to work with a lot of developers on a large variety of projects. Many of these projects were centered around single developers or small teams when I came into the picture. These &#8230; <a class="more-link" href="http://www.geekgumbo.com/2011/06/11/you-should-be-using-a-version-control-system/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>During a relatively short-time, I've had the opportunity to work with a lot of developers on a large variety of projects.  Many of these projects were centered around single developers or small teams when I came into the picture.  These projects spanned a range from mobile development, to statistical analysis and modeling, to web development efforts, to complex parsing/scraping exercises.  Too many of these projects were developed independent of any formal version control system.  The primary excuses amounted to:</p>
<ol>
<li>
[<a href="http://git-scm.com/">Git</a>, <a href="http://bazaar.canonical.com/en/">Bazaar</a>, <a href="http://mercurial.selenic.com/">Mercurial/Hg</a>, <a href="http://darcs.net/">Darcs</a>, or even <a href="http://subversion.tigris.org/">Subversion/SVN</a>] is too hard and adds too much wasted time to my project efforts.
</li>
<li>
My project is small, and I am the only one working on it; so I don't need to control versioning, the latest and greatest is always on my file system.
</li>
</ol>
<p>Before I touch on those two excuses explicitly, I want to spell out some core benefits and what I consider to be the fundamental functionality of version control.  Without going into details, a few benefits of version control systems are: merging, reverting, storing snapshots, creating branches (this quickly becomes a semantic nightmare, but for anyone new to version control, branching is akin to copying the existing source so that you can work on it in a new context).  </p>
<p>In your projects, do you find yourself:</p>
<ul>
<li>
Wishing you could easily get the project back to a stable state after attempting to make updates and realizing that you made errors in your implementation technique?
</li>
<li>
Wondering which files you changed recently?
</li>
<li>
Trying to determine what change you made to accomplish a particular task, as such a change might help you in the context of your current conundrum?
</li>
<li>
Wanting to revert a set of files back to a previous revision, or to match a 'deployed' state?
</li>
<li>
Needing to isolate the differences between two versions of your project files (often on a local computer and a server, or in two different local directories)?
</li>
<li>
Wishing that multiple individuals could easily update files toward a common goal without causing each other more work in the process?
</li>
<li>
Repeatedly cycling through ctrl+Z and ctrl+shift+Z [or ctrl+Y in some programs] to undo/redo more than a single action?
</li>
</ul>
<p>If you can say, "No." to all of these, I don't believe you.  Go back through the list and think about the benefits that these options offer.  If you say, "Yes," to any of these questions, you should consider the fact that a version control system solves all of them and more.  Most modern version control systems can actually address each of the items in that list with a single command, assuming you use the version control system properly.</p>
<p>Version control generally gives you the opportunity to take controlled snapshots of your project, and then manipulate the snapshot in the context of itself, recent changes, or other snapshots.  Tasks like, "How do the current files differ from the last published version", "How do your updates compare to mine", or "I need to undo everything I did since time x or release y" are trivial.</p>
<h3>But learning a new version control system is hard...</h3>
<p>This is quite often true, but after a couple days of hard usage, you will already being seeing the benefits.  Think about how many hours you have spent unproductively checking timestamps or trying to undo massive amounts of changes.  These tasks should never be necessary!</p>
<h3>My project is small, and I am the only developer</h3>
<p>Seriously?  Did you read the list of tasks?  I can not think of a single project type that is hindered by version control.  Even if you are an impeccable developer/coder/file-updater/whatever who makes no errors and never updates existing code, version control still gives you a pristene version tracking system for historical reference.  </p>
<h3>Get started</h3>
<p>The purpose of this post is not to promote a particular version control system, but rather to highlight that version control systems are quite helpful, and they are under-used (in my experience).  If you are not using a version control system, investigate the links in the list above, and start now.  I would encourage use of a "Decentralized" implementation if you are selecting a new version control system to start, but in general, any version control system is better than no version control system.  </p>
<p>There are lots and lots of great tutorials out there for each of the systems I mentioned.  Don't let the expansive options and functionalities of any of these systems turn you away.  Pick a tool, start with the basics, and keep working at it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2011/06/11/you-should-be-using-a-version-control-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git User’s Survey 2010</title>
		<link>http://www.geekgumbo.com/2010/10/20/git-users-survey-2010/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=git-users-survey-2010</link>
		<comments>http://www.geekgumbo.com/2010/10/20/git-users-survey-2010/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 16:30:52 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Git - Version Control]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=2294</guid>
		<description><![CDATA[Git version control software is gaining in popularity. Git Users just completed the latest survey of their Git usage. The results have been published by "Planet Git," to whom we are indebted to for the results in this article. The &#8230; <a class="more-link" href="http://www.geekgumbo.com/2010/10/20/git-users-survey-2010/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Git version control software is gaining in popularity.  Git Users just completed the latest survey of their Git usage.  The results have been published by "<a href="http://planet.git-scm.com/">Planet Git</a>," to whom we are indebted to for the results in this article.  The survey was open to all users, and ran between August 31st and Oct 16th of this year.  </p>
<p><a href="http://planet.git-scm.com/ng"><img src="http://www.geekgumbo.com/wp-content/uploads/2010/10/planetgit2.png" alt="" title="planetgit2" width="585" height="171" class="aligncenter size-full wp-image-2295" /></a></p>
<p>Some 28,001 people actually opened the survey with 8,841, or 31%, taking the 35 minutes, or so, to complete the survey.  There are enough respondents to make this survey statistically relevant, and therefore, a good indicator of the collective mindset of the current Git community. These are fairly high numbers for survey completion and indicates the dedication and devotion of Git users to Git.</p>
<p>There were 28 questions, some general and others more specific.  Some of the more interesting questions were:</p>
<p><span style="color:green">Is Git easy to learn?</span><br />
Only 19% of the respondents found Git "Very Hard" or "Hard" to learn. The next choice "Reasonable Easy" came in at 53%.  "Easy" and "Very Easy" accounted for 29%. Git does take some learning, however 81% said it was easy. Speaking personally, compared to other version control applications, Git is one of the easiest to learn.</p>
<p><span style="color:green">Is Git easy to use?</span><br />
Only 1% found Git "Very Hard" to use with 8% finding it "Hard."  That's only 9% of people who tried to use Git.  The next choice, "Reasonably Easy" to use was 42% with the "Very Easy," and "Easy" category an astonishing 49%.  Git is the easiest version control software, period. </p>
<p><span style="color:green">Proficiency with Git?</span><br />
Users were asked to rate their proficiency with Git, in other words, how confident were they in their knowledge and use of Git. "Novice", and "Need advice" accounted for 23% of users. "Everyday use" was 39%. "Can offer advice" 32%, and "know it very well" at 7%, the two higher choices combined for 39%.  I suspect the "can offer advice" and "know it well" folks took the time to read about Git beyond basic usage. That number is high and says Git is indeed easy to learn.</p>
<p><span style="color:green">What Operating System do you use with Git?<br />
</span>This is another question about Git popularity. Git was originally created for the Linux environment, so you expect it to very strong with this community.  It has been ported to Mac and Windows, and to use it in these environments, a terminal window is most often used, not exactly a basic Windows users knowledge level.  Most users have more than one computer, so the results are over 100%.   Linux, as expected, pulled in 94%. 94% of Git users responding to the survey use Linux on one of their machines. I would call these folks IT knowledgeable.  Mac users accounted for a surprising 46%.  Windows came in third at 35%. Still an excellent number, that says that Git has truly arrived as a universal version control tool.</p>
<p>There has been some debate in the Windows crowd whether to use the Cygwin or MINGW version of the Unix-like environment on Windows.  In the survey, Cygwin was favored by 10%, and MINGW by 25%. On Windows, the Unix-like environment, uses the terminal window, and thus the command line to use Git.  Even though Git supplies graphical interfaces with gitk and the git gui, 95% of respondents use the command line.  It's just easier and faster to use the command line.  Maybe Microsoft had it wrong with their Windows GUI, and should have stayed with DOS and the command line...sorry, had to slip that in there.</p>
<p>Like the graphical tools, there  are a lot of extra tools and utilities you can use to make your Git life easier, surprisingly, most Git users don't use them, just the command line.  The three most popular tools are gitk, the version history viewer, at 58%; GitX, version history viewer for the Mac, at 28%; and the git gui at 25%. The next nearest tool, TortoiseGit is at 12%. Of the 25 tools surveyed, the remaining 21 tools all fell below 9% usage.</p>
<p><span style="color:green">What do you use Git for?</span><br />
This is an interesting list, and I thought the best way to present this is to just list them in order of usage. Here goes: code(programming) 91%, work projects 81%, unpaid projects 77%, private stuff(unpublished) 74%, OSS Development(public domain) 65%, web app 46%, proprietary projects 39%, managing configuration files 33%, documents(data) 30%, static website 29%, personal data 27%, front-end to another version control(git-svn) 21%, sharing data or sync 20%, backup 19%. We'll stop there. Personal data are things like writing books.  Git is being used for version control, moving code between machines, keeping track of changes in our personal data, and backing up our work. Nice.</p>
<p>For those that want to take a closer look at the survey results, they can be <a href="https://www.survs.com/results/33Q0OZZE/MV653KSPI2">found here</a>.  Again many thanks to <a href="http://planet.git-scm.com/">Planet Git</a> for the survey. </p>
<p>We have to conclude this article with the key question of the entire survey,</p>
<p>     "<span style="color:green">Overall, how happy are you with Git?</span>"<br />
What a revelation, only 5% said they were "unhappy," or "not so happy," 5%.  A resounding 54% said they were "very happy." and an astonishing 1571 users, or 19%, said they were "completely ecstatic."  That my friends, is love.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2010/10/20/git-users-survey-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git – Recover a File</title>
		<link>http://www.geekgumbo.com/2010/06/18/git-recovering-one-file/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=git-recovering-one-file</link>
		<comments>http://www.geekgumbo.com/2010/06/18/git-recovering-one-file/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 17:13:04 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Git - Version Control]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=1649</guid>
		<description><![CDATA[I was knee deep in work the other day and accidentally overwrote a file that I had spent some time working on a couple of days ago. I was not happy. However, since I commit my work often with git, &#8230; <a class="more-link" href="http://www.geekgumbo.com/2010/06/18/git-recovering-one-file/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was knee deep in work the other day and accidentally overwrote a file that I had spent some time working on a couple of days ago.</p>
<p>I was not happy.  However, since I commit my work often with git, I knew all my previous work was not lost. I just needed to recover that one file.</p>
<p>I was surprised to find that posts on recovering just a file in Git were a little harder to find on the Internet than I expected.  Everyone was very helpful when it came to resetting all your files from a previous commit, but not just one file.  And when this happens, I usually write a post about it.  We'll limit ourselves to recovering one file, and if you "grok" that, you'll know by extrapolation how to get any files you want from previous commits in Git.</p>
<p>First, if your good file, that you committed previously, is still in your index (the files in your last commit), and you haven't committed the new bad file yet, all you need to do overwrite the bad file in your working directory with the good file in your index using git checkout.  Like so:</p>
<p style="text-align: center;"><span style="color: #0000ff;">git checkout  ( path/good file name )</span></p>
<p>For example, to recover a records_db.php file in my models subdirectory, I would type:</p>
<p style="text-align: center;"><span style="color: #0000ff;">git checkout  models/records_db.php</span></p>
<p>Easy no. Your previously committed file will overwrite your bad new file in your working directory, and your all set.  Here's an example using the file test.txt.</p>
<div id="attachment_1651" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/06/gitcheckout3.png"><img class="size-full wp-image-1651" title="gitcheckout3" src="http://www.geekgumbo.com/wp-content/uploads/2010/06/gitcheckout3.png" alt="" width="550" height="555" /></a><p class="wp-caption-text">Backing up test.txt before committing the fifth revision change</p></div>
<p>Be careful, if you just do a "git checkout" without being specific about the file, you'll get all the previously committed files back, which will overwrite your current work, that you haven't committed yet, which you may not want to do.</p>
<p>Second, if you've committed the bad new file before you discovered your error, you need to tell git which committed file you want to retrieve, and its just a tad more complicated.   Git can't guess which file you want from which commit.</p>
<p>What your trying to do is bring into your current working directory, an older file.  "git checkout" alone brings your last committed file, which is, after you committed, now the bad file.</p>
<p>We need to find the good file in your commits. There's a couple of ways to do this. Let's digress a bit, and talk about how Git labels commits.  There's the absolute method, and the relative method.</p>
<p>The absolute method is the SHA1 encryption number. You can see all your commits with the absolute SHA1 number by running:</p>
<p style="text-align: center;"><span style="color: #0000ff;">git log</span></p>
<p>The number opposite the word commit is that commits absolute address.  If you get a ":" after git log runs, you can quit out of git log by typing a "q". The SHA1 numbers are long, but you only need the first three or four characters and Git will know which commit you mean.</p>
<p>Most folks, however, like to use the commit relative names. You can see the relative names by typing:</p>
<p style="text-align: center;"><span style="color: #0000ff;">git show-branch --more=10</span></p>
<p>Now that we know how to label our commits, let's get back to the subject at hand.   We need to find the good file.  By looking at the "git log" or the "git show-branch" you may not be able to determine which commit has the good file.   We may want to see the contents of the file.  For that, let's use the gitk history gui, like so:</p>
<p style="text-align: center;"><span style="color: #0000ff;">gitk --all</span></p>
<p style="text-align: left;"><span style="color: #0000ff;"><span style="color: #000000;">That's with two dashes - -, as is, the more above in the show-branch command.</span><br />
</span></p>
<p><span style="color: #0000ff;"> </span></p>
<div id="attachment_1652" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/06/gitk3.png"><img class="size-full wp-image-1652" title="gitk3" src="http://www.geekgumbo.com/wp-content/uploads/2010/06/gitk3.png" alt="" width="550" height="567" /></a><p class="wp-caption-text">Using gitk to look at file four.txt contents in the fourth commit</p></div>
<p>This is a graphical record of all your commits, and the files that were committed.  If you click on the file in the lower right window, you'll see the contents on the left.   This is the quick way to look at the file contents in each commit to find the commit you need.</p>
<p>OK, you know the commit you need.  You can double check the relative name of the commit with the "git show-branch --more=10" command and we're all set.</p>
<p>Back to what we started with "git checkout."  We will tell git to checkout the "four.txt" file from the "master~2" commit, a previous commit, like so:</p>
<p style="text-align: center;"><span style="color: #0000ff;">git checkout master~2 four.txt</span></p>
<p style="text-align: left;"><span style="color: #0000ff;"><span style="color: #000000;">Here's an actual example of the command.</span></span></p>
<p style="text-align: center;"><span style="color: #0000ff;"><span style="color: #000000;"> </span></span></p>
<div id="attachment_1653" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/06/recover3.png"><img class="size-full wp-image-1653" title="recover3" src="http://www.geekgumbo.com/wp-content/uploads/2010/06/recover3.png" alt="" width="550" height="654" /></a><p class="wp-caption-text">Recovering four.txt from the fourth commit labeled &quot;master~2&quot;</p></div>
<p>Now that wasn't bad.  You should now feel confident you can recover any file you want in Git, that is, as long as you use Git the way it was designed to be used, commit your work often, and let Git take care of all the remembering.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2010/06/18/git-recovering-one-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Removing Deleted Files from your Git Working Directory</title>
		<link>http://www.geekgumbo.com/2010/05/16/removing-deleted-files-from-your-git-working-directory/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=removing-deleted-files-from-your-git-working-directory</link>
		<comments>http://www.geekgumbo.com/2010/05/16/removing-deleted-files-from-your-git-working-directory/#comments</comments>
		<pubDate>Sun, 16 May 2010 18:44:11 +0000</pubDate>
		<dc:creator>daleV</dc:creator>
				<category><![CDATA[Git - Version Control]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://www.geekgumbo.com/?p=1458</guid>
		<description><![CDATA[You update a module that deletes a bunch of files.  An hour later, you decide to combine two files into one, and delete the other file.  At the end of the day, you decide to do a git commit. You &#8230; <a class="more-link" href="http://www.geekgumbo.com/2010/05/16/removing-deleted-files-from-your-git-working-directory/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You update a module that deletes a bunch of files.  An hour later, you decide to combine two files into one, and delete the other file.  At the end of the day, you decide to do a git commit.</p>
<p>You run git status and a bunch of deleted files show up.  Darn, well I'll do a "git add ." and try to commit.  The deleted files don't go away, and they don't stage to commit.</p>
<div id="attachment_1460" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel.png"><img class="size-full wp-image-1460 " title="gitdel" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel.png" alt="" width="550" height="467" /></a><p class="wp-caption-text">Git add . does not move the file out of the working directory</p></div>
<p>How do you get these deleted files out of your working directory, so when you run "git status," you get that blessed "nothing to commit (working directory clean)" message, we all know and love?</p>
<div id="attachment_1462" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel2.png"><img class="size-full wp-image-1462" title="gitdel2" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel2.png" alt="" width="550" height="450" /></a><p class="wp-caption-text">The same problem shown in the Git Gui</p></div>
<p>First, so we're on the same page, let's do some quick definitions.</p>
<p>The git "directory" (.git) is where git stores all the information about your project, all the history, all the commits, and all the meta information about your repository, and what files and folders are included in that repository.  There is only one ".git directory" per repository.</p>
<p>Your "working directory" is where Git keeps track of all the content changes to your files and folder as your working: all your new files, deleted files, and modified files, since your last commit.  It is created when you create a branch,  and changes as you do commits.  Each branch has its own "working directory" which can be, but doesn't have to be, different for each branch.</p>
<p>The git "index" is where you keep track of changes you want to make to your next commit.  When you do a "git add," you stage the files in your working directory to your "index" in preparation to commit.</p>
<p>If you "git add" all the file changes in your working directory to the index, the working directory is clean.  When you commit, git makes the commit match the index, and clears the index, and we get the "nothing to commit (working directory clean)" message when asking for a git status.</p>
<p>The problem with removing files or folders, as your working, is that these changes are recorded in your working directory, but a "git add ." cannot put the deleted files in the "index," because they don't exist anymore, you deleted them.  But they still show up in your working directory, when you run "git status," because they have not been cleared out of your git "working directory."  Seems like a cache 22.  You can't add them to your index to commit the deletion, and you can't get the deleted files out of your "working directory," since they are different from your last commit.  Are we doomed to have a long list of deleted files?  You know better.</p>
<p>First, let's use git add like we normally do with a switch.</p>
<p><span style="color: #0000ff;">"git add -u"    <span style="color: #000000;">This is the same as "git add --update"</span></span></p>
<div id="attachment_1465" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel3.png"><img class="size-full wp-image-1465" title="gitdel3" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel3.png" alt="" width="550" height="174" /></a><p class="wp-caption-text">Git add -u adds deleted file to the index ready for commit</p></div>
<p>The -u says look at the index, and only add files from your working directory that are in the index.  Any files with modified content in the index will be updated, and any files that have been removed in the working directory, will be put in the index for removal in the next commit.</p>
<div id="attachment_1468" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel4.png"><img class="size-full wp-image-1468" title="gitdel4" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel4.png" alt="" width="550" height="476" /></a><p class="wp-caption-text">Git add -u result shown in the Git Gui</p></div>
<div id="attachment_1471" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel5.png"><img class="size-full wp-image-1471" title="gitdel5" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel5.png" alt="" width="550" height="280" /></a><p class="wp-caption-text">Git commit removes the deleted file and we have a clean status</p></div>
<p>This is what we want, when we do a commit the deleted files go away, but  there's a catch.  The -u will work, but new files in the working  directory will not be added, since this is an update.  You still have to  run "git add ." to get the new files.  Use -u when you don't want to  commit new changes yet, but want to move deleted files to your index for  the next commit.</p>
<p>Let's simplify.  Let's use:</p>
<p><span style="color: #0000ff;">"git add -A"    <span style="color: #000000;">This is the same as using "git add --all"</span></span></p>
<p style="text-align: center;"><span style="color: #0000ff;"> </span></p>
<div id="attachment_1479" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel15.png"><img class="size-full wp-image-1479  " title="gitdel15" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel15.png" alt="" width="550" height="433" /></a><p class="wp-caption-text">Git add -A adds the deleted file and the new file to the index</p></div>
<p>This is like "git add -u," however it matches files in your working directory, and your index.  That means that it will add new files, as well as updating modified content in your index, and remove files that are no longer in the working directory.  Note, there is no "git add -a"  Linux is case sensitive, the "a" doesn't work, the "A" does.</p>
<div id="attachment_1482" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel14.png"><img class="size-full wp-image-1482 " title="gitdel14" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel14.png" alt="" width="550" height="460" /></a><p class="wp-caption-text">Git gui after a &quot;git add -A&quot;</p></div>
<p>This is the best of both worlds and the recommended way to clear those deletes from your working directory.</p>
<p>One last thought, if you use "git rm &lt;file name&gt;" when you remove a file, this removes the file from both your working directory, and updates your index, ready for commit.   <span style="color: #0000ff;"> </span></p>
<div id="attachment_1476" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel12.png"><img class="size-full wp-image-1476  " title="gitdel12" src="http://www.geekgumbo.com/wp-content/uploads/2010/05/gitdel12.png" alt="" width="550" height="472" /></a><p class="wp-caption-text">Git rm adds the deleted file directly to the index, without an add</p></div>
<p>Git rm is not always possible when your in the middle of developing, it's  just not convenient.  "<span style="color: #0000ff;">git add -A</span>" is what you want.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekgumbo.com/2010/05/16/removing-deleted-files-from-your-git-working-directory/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

