<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Hack ↺ Repeat</title>
 <link href="http://feeds.feedburner.com/hack-repeat" rel="self"/>
 <link href="http://www.hack-repeat.com"/>
 <updated>2012-05-05T13:11:27+02:00</updated>
 <id>http://www.hack-repeat.com</id>
 <author>
   <name>Matteo Scotuzzi</name>
   <email>matteo.scotuzzi@gmail.com</email>
 </author>

 
 <entry>
   <title>From zero to git, episode 2: Branching, merging and tagging</title>
   <link href="http://www.hack-repeat.com/from-zero-to-git-2-branching-merging-and-tagging/"/>
   <updated>2011-10-07T00:00:00+02:00</updated>
   <id>http://www.hack-repeat.com/from-zero-to-git-2-branching-merging-and-tagging</id>
   <content type="html">&lt;p&gt;In this post I&amp;#8217;ll further expand the basic git usage with branches and tags (previous: &amp;#8221;&lt;a href='http://www.hack-repeat.com/from-zero-to-git-1-daily-disconnected-git-commands/'&gt;git daily disconnected commands&lt;/a&gt;&amp;#8221;).&lt;/p&gt;

&lt;h2 id='good_habits_local_branching'&gt;Good habits: local branching&lt;/h2&gt;

&lt;p&gt;Do you remember the practical advice about when to commit from the previous article? Sometimes just committing is not enough, for example &amp;#8220;when you are about to start something you feel like you may regret&amp;#8221; because in case you actually regret your actions, you have to dig with &lt;code&gt;git log&lt;/code&gt; to find the id of the precise commit you want to go back to (remember that &lt;code&gt;7c628c78707a76b11a70716ad082da621047afe2&lt;/code&gt;?). It&amp;#8217;s not difficult, but we can do better with branches.&lt;/p&gt;

&lt;h3 id='show_me_the_branches'&gt;Show me the branches&lt;/h3&gt;

&lt;p&gt;A branch is just a label that automatically follows your commits: you already have one that is following you, but you don&amp;#8217;t know: it is called &lt;em&gt;master&lt;/em&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git branch
&lt;span class='go'&gt;* master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;branch&lt;/code&gt; command shows your local branches. The current active branch (the one that is checked-out and you see as your working directory) is displayed with an &lt;code&gt;*&lt;/code&gt; ahead of it. As I said there&amp;#8217;s already one and since you have it checked-out, every time you commit, &lt;code&gt;master&lt;/code&gt; moves to point to that last commit.&lt;/p&gt;

&lt;h3 id='branch_it'&gt;Branch it&lt;/h3&gt;

&lt;p&gt;Now I want to put some changes in my project. Maybe it&amp;#8217;s something experimental, and I want to have a safe fallback to the current revision, waiting for me under a named label.&lt;/p&gt;

&lt;p&gt;From the current branch (in this case &lt;code&gt;master&lt;/code&gt;), we &lt;code&gt;checkout&lt;/code&gt; an exact copy under another label so that the current label stays on the last commit it was attached to (in this case this will be our safe fallback).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git checkout -b something-I-will-regret
&lt;span class='go'&gt;Switched to a new branch &amp;#39;something-I-will-regret&amp;#39;&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git branch
&lt;span class='go'&gt;  master&lt;/span&gt;
&lt;span class='go'&gt;* something-I-will-regret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://www.hack-repeat.com/media/images/blog/branching-1.png'&gt;&lt;img alt='Branching 1' src='http://www.hack-repeat.com/media/images/blog/branching-1.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;checkout&lt;/code&gt; command is used to pick something in the git history and put it in the working copy. The &lt;code&gt;-b&lt;/code&gt; option is used to create a new branch (based on the contents of the current one) under the branch name specified after &lt;code&gt;-b&lt;/code&gt; (something-I-will-regret, in this case) and, after that, putting that branch in the working copy (or more intuitively, &lt;em&gt;switching you to&lt;/em&gt; the newly created branch).&lt;/p&gt;

&lt;p&gt;Now at each commit, the checked-out branch (you can&amp;#8217;t check out more than one at a time) will follow us, while any other non checked-out branch will stay still, pointing the commits they were on the last time they moved.&lt;/p&gt;

&lt;p&gt;Remembering what we learned in the previous article, we can work on the something that we will regret. For this example, modify something, add it to the index and commit it.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; &lt;span class='c'&gt;# file modified&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git status 
&lt;span class='gp'&gt;#&lt;/span&gt; On branch something-I-will-regret
&lt;span class='gp'&gt;#&lt;/span&gt; Changes not staged &lt;span class='k'&gt;for &lt;/span&gt;commit:
&lt;span class='gp'&gt;#&lt;/span&gt;   &lt;span class='o'&gt;(&lt;/span&gt;use &lt;span class='s2'&gt;&amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot;&lt;/span&gt; to update what will be committed&lt;span class='o'&gt;)&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt;   &lt;span class='o'&gt;(&lt;/span&gt;use &lt;span class='s2'&gt;&amp;quot;git checkout -- &amp;lt;file&amp;gt;...&amp;quot;&lt;/span&gt; to discard changes in working directory&lt;span class='o'&gt;)&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt;	modified:   due.txt
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git commit -m&lt;span class='s2'&gt;&amp;quot;Fixed a bad mistake&amp;quot;&lt;/span&gt;
&lt;span class='go'&gt;[something-I-will-regret 05da584] Fixed a bad mistake&lt;/span&gt;
&lt;span class='go'&gt; 1 files changed, 1 insertions(+), 1 deletions(-)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://www.hack-repeat.com/media/images/blog/branching-2.png'&gt;&lt;img alt='Branching 2' src='http://www.hack-repeat.com/media/images/blog/branching-2.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change, add and commit any time you want, then we will move back.&lt;/p&gt;

&lt;h3 id='moving_between_branches'&gt;Moving between branches&lt;/h3&gt;

&lt;p&gt;Now is the time we regret the correction, so we want to go back: we already know the command that we need: &lt;code&gt;checkout&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git checkout master 
&lt;span class='go'&gt;Switched to branch &amp;#39;master&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://www.hack-repeat.com/media/images/blog/branching-3.png'&gt;&lt;img alt='Branching 3' src='http://www.hack-repeat.com/media/images/blog/branching-3.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same command we used before to &amp;#8220;switch&amp;#8221; to the something-I-will-regret branch, but this time we didn&amp;#8217;t need the &lt;code&gt;-b&lt;/code&gt; because we wanted to get to an &lt;em&gt;existing&lt;/em&gt; branch.&lt;/p&gt;

&lt;p&gt;If you watch your files you&amp;#8217;ll notice that they are back to the state they were on the last commit we did on master branch. Finally we know that git didn&amp;#8217;t lie to us :D.&lt;/p&gt;

&lt;p&gt;Notice that the branch named something-I-will-regret is still there, and all the commits you did under that name are there, too.&lt;/p&gt;

&lt;p&gt;You know what? I changed my mind again. The something-I-will-regret branch was not that bad. Let&amp;#8217;s merge it back into master branch.&lt;/p&gt;

&lt;h3 id='fastforward_merge'&gt;Fast-forward merge&lt;/h3&gt;

&lt;p&gt;What we are going to do now is a very special case of merging. This will happen just because after branching (&lt;code&gt;git checkout -b something-I-will-regret&lt;/code&gt;) we haven&amp;#8217;t changed anything in the master branch. The effect is that master was just behind something-I-will-regret, but the two never really diverged.&lt;/p&gt;

&lt;p&gt;We are going to lose the previous position of our master, making it point to the same commit that something-I-will-regret is pointing to (hence fast-forward).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git merge something-I-will-regret 
&lt;span class='go'&gt;Updating 879611a..05da584&lt;/span&gt;
&lt;span class='go'&gt;Fast-forward&lt;/span&gt;
&lt;span class='go'&gt; due.txt |    2 +-&lt;/span&gt;
&lt;span class='go'&gt; 1 files changed, 1 insertions(+), 1 deletions(-)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://www.hack-repeat.com/media/images/blog/branching-4.png'&gt;&lt;img alt='Branching 4' src='http://www.hack-repeat.com/media/images/blog/branching-4.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;merge&lt;/code&gt; command in this case you are merging the state of the branch specified in the command (something-I-will-regret) into the current branch (master).&lt;/p&gt;

&lt;p&gt;Now that we are sure that all went well, we don&amp;#8217;t need the something-I-will-regret anymore, so we delete it: if you are on something-I-will-regret, checkout another branch (e.g. master).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git branch
&lt;span class='go'&gt;* master&lt;/span&gt;
&lt;span class='go'&gt;  something-I-will-regret&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git branch -d something-I-will-regret
&lt;span class='go'&gt;Deleted branch something-I-will-regret (was 05da584).&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git branch
&lt;span class='go'&gt;* master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://www.hack-repeat.com/media/images/blog/branching-5.png'&gt;&lt;img alt='Branching 5' src='http://www.hack-repeat.com/media/images/blog/branching-5.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-d&lt;/code&gt; means delete obviously. If we didn&amp;#8217;t merge and simply wanted to discard the changes made in something-I-will-regret restarting to work on what we had in master, from the master branch, this is the command: &lt;code&gt;git branch -D something-I-will-regret&lt;/code&gt;. It&amp;#8217;s very similar to the previous one, but &lt;code&gt;-D&lt;/code&gt; uses a capital &amp;#8220;d&amp;#8221;. This difference avoid that you delete branches that are &amp;#8220;not fully merged&amp;#8221;, use carefully.&lt;/p&gt;

&lt;p&gt;Now you can create new branches, work on them, discard changes by moving back, accept changes by fast forwarding. Cool.&lt;/p&gt;

&lt;h2 id='tags'&gt;Tags&lt;/h2&gt;

&lt;p&gt;This is a simple one.&lt;/p&gt;

&lt;p&gt;Tags, like branches, are labels pointing to commits, but unlike branches they don&amp;#8217;t move. You need to create them explicitly when you need them.&lt;/p&gt;

&lt;p&gt;A typical use case is to mark points in the repository history corresponding to a release version.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git tag v0.1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://www.hack-repeat.com/media/images/blog/tagging-1.png'&gt;&lt;img alt='Tagging 1' src='http://www.hack-repeat.com/media/images/blog/tagging-1.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that&amp;#8217;s it, we have saved a commit with the tag &lt;code&gt;v0.1&lt;/code&gt; (it can be any string, I just took my way of defining version numbers) that will be there just in case you ever need to get back to some old version/releases of your project. You can checkout a tag by name just like you do with a branch name, just remember it is not a branch, so you should &lt;strong&gt;not&lt;/strong&gt; commit while in there unless you know what would happen.&lt;/p&gt;

&lt;p&gt;Actually this is a &amp;#8220;lightweight&amp;#8221; tag, but for the purpose of this article this will be enough.&lt;/p&gt;

&lt;h2 id='appendix_something_about_objects'&gt;Appendix: Something about objects&lt;/h2&gt;

&lt;p&gt;We talked a lot about commit. Git records commits as &lt;em&gt;commit objects&lt;/em&gt;. This object stores informations like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the date&lt;/li&gt;

&lt;li&gt;a reference to an object representing the state of the files&lt;/li&gt;

&lt;li&gt;references to other commits objects, the parents of the current commit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think it&amp;#8217;s useful to stress something about the last point, in particular if this is your first time using a revision control system: since the commits specify moments in history, we also need to put them together in a coherent flow. That commit references point to the parents of this commit (usually it&amp;#8217;s just one parent, though).&lt;/p&gt;

&lt;p&gt;This references creates a graph that represents the history of the repository. In the examples we&amp;#8217;ve seen so far it&amp;#8217;s more like a sequence (this should be clear looking at the little graph images in this post).&lt;/p&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Here is a recap on the commands we saw in this article:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git branch &lt;span class='c'&gt;# shows local branch situation&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git checkout -b branch-name &lt;span class='c'&gt;# creates a branch based on the contents of the current checked out state and switches to it&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git checkout branch-name &lt;span class='c'&gt;# switches to the named branch. The current status should be clean to do this&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git merge branch-name &lt;span class='c'&gt;# merges changes committed in the named branch into the current checked out branch&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git branch -d branch-name &lt;span class='c'&gt;# delete a branch (i.e. the label) safely&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git branch -D branch-name &lt;span class='c'&gt;# delete a branch (i.e. the label) unsafely (unmerged changes will be discarded)&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git tag tag-name &lt;span class='c'&gt;# create a lightweight tag&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You are now able to work with git trying new things without leaving your files in a bad state (with tags and branching). In the next episode we will see some situations where merging is not automatic , something that happens more frequently when multiple people work on a project but that can prove useful even when working alone. Now that you are a git user you can&amp;#8217;t miss it :D.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>From zero to git, episode 1: Daily disconnected git commands</title>
   <link href="http://www.hack-repeat.com/from-zero-to-git-1-daily-disconnected-git-commands/"/>
   <updated>2011-10-06T00:00:00+02:00</updated>
   <id>http://www.hack-repeat.com/from-zero-to-git-1-daily-disconnected-git-commands</id>
   <content type="html">&lt;p&gt;This article is part of a very practical experimental series that aims to teach git to novices, without forcing git theory right away.&lt;/p&gt;

&lt;p&gt;In this article I&amp;#8217;ll try to show you the bare minimum commands (four commands in this article) needed to start using git assuming that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;you have lots of copies of your projects directories named like this: &lt;em&gt;project_old&lt;/em&gt; and &lt;em&gt;project_new_feature&lt;/em&gt; and &lt;em&gt;project_20110611&lt;/em&gt; and you hate them&lt;/li&gt;

&lt;li&gt;you just want to start to track your file changes&lt;/li&gt;

&lt;li&gt;you don&amp;#8217;t need to use a remote server to backup or share your local repository (you are working alone on your project)&lt;/li&gt;

&lt;li&gt;you don&amp;#8217;t use a GUI, just the command line&lt;/li&gt;

&lt;li&gt;you &lt;a href='http://www.hack-repeat.com/from-zero-to-git-0-first-things-first/'&gt;have created a local empty repository&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I suggest that you follow the little example I will show you, &lt;strong&gt;typing all the commands yourself&lt;/strong&gt;. This will make it easier to learn the basics that are contained in this article. Once you get to the end, you&amp;#8217;ll find a little recap on the commands you used, in case you want to review them when starting to work on your own project.&lt;/p&gt;

&lt;h2 id='the_status'&gt;The status&lt;/h2&gt;

&lt;p&gt;Now that &lt;a href='http://www.hack-repeat.com/from-zero-to-git-0-first-things-first/'&gt;we have a local repository&lt;/a&gt; we will start with the daily operations: we will start &amp;#8220;inspecting&amp;#8221; its current status with the &lt;code&gt;status&lt;/code&gt; command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git status
&lt;span class='gp'&gt;#&lt;/span&gt; On branch master
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt; Initial commit
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='go'&gt;nothing to commit (create/copy files and use &amp;quot;git add&amp;quot; to track)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is probably the most used git command, we will see various kinds of output from this command.&lt;/p&gt;

&lt;h2 id='tracking_files'&gt;Tracking files&lt;/h2&gt;

&lt;p&gt;Now, we can put some file in it. At this point, if you have an existing project you can put your project files in the repo&amp;#8217;s directory, but for the sake of this tutorial we will create something form scratch.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s create a file and re-run the status command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; &lt;span class='nb'&gt;echo &lt;/span&gt;bazbar &amp;gt; uno.txt
&lt;span class='gp'&gt;$&lt;/span&gt; git status
&lt;span class='gp'&gt;#&lt;/span&gt; On branch master
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt; Initial commit
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt; Untracked files:
&lt;span class='gp'&gt;#&lt;/span&gt;   &lt;span class='o'&gt;(&lt;/span&gt;use &lt;span class='s2'&gt;&amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot;&lt;/span&gt; to include in what will be committed&lt;span class='o'&gt;)&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt;	uno.txt
&lt;span class='go'&gt;nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Contrary to other systems, Git doesn&amp;#8217;t track blindly anything you change in the working directory, so we have to introduce the concept of &lt;em&gt;index&lt;/em&gt;, that is just a list of the things you want to put in the repository&amp;#8217;s history next.&lt;/p&gt;

&lt;p&gt;I created a file named &lt;code&gt;uno.txt&lt;/code&gt;: the &lt;code&gt;status&lt;/code&gt; command now shows that we have &amp;#8220;untracked files&amp;#8221;. What we want to do is to add the files we want to be tracked to our repository&amp;#8217;s index. As suggested by the previous output itself, we will use the &lt;code&gt;add&lt;/code&gt; command to put the file in the index, ready to be tracked:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git add uno.txt
&lt;span class='gp'&gt;$&lt;/span&gt; git status 
&lt;span class='gp'&gt;#&lt;/span&gt; On branch master
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt; Initial commit
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt; Changes to be committed:
&lt;span class='gp'&gt;#&lt;/span&gt;   &lt;span class='o'&gt;(&lt;/span&gt;use &lt;span class='s2'&gt;&amp;quot;git rm --cached &amp;lt;file&amp;gt;...&amp;quot;&lt;/span&gt; to unstage&lt;span class='o'&gt;)&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;span class='gp'&gt;#&lt;/span&gt;	new file:   uno.txt
&lt;span class='gp'&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;With the &lt;code&gt;add&lt;/code&gt; command we can add single files (as we did with &lt;code&gt;uno.txt&lt;/code&gt;), multiple files (as we will see in a following paragraph) or entire directories.&lt;/p&gt;

&lt;p&gt;Now we have a file staged in the git index that means that it is selected to be tracked by git: next we have to record this very state of the index as a commit.&lt;/p&gt;

&lt;h2 id='what_not_to_add'&gt;What not to add&lt;/h2&gt;

&lt;p&gt;Not every file has to be included in your repository. Files containing passwords and other sensible data, most generated files (e.g. binary executables) should not be included in a repository. To exclude them automatically &lt;strong&gt;before&lt;/strong&gt; ever adding them you can create a .gitignore file at the root of your repository.&lt;/p&gt;

&lt;p&gt;See &amp;#8221;&lt;a href='http://book.git-scm.com/4_ignoring_files.html'&gt;Ignoring files&lt;/a&gt;&amp;#8221; from the git-book to learn how to use a .gitignore file. See &lt;a href='https://github.com/github/gitignore'&gt;gitignore project&lt;/a&gt; on github as a starting point for many programming-related gitignore templates.&lt;/p&gt;

&lt;h2 id='freezing_a_moment_in_history_the_commit'&gt;Freezing a moment in history: the commit&lt;/h2&gt;

&lt;p&gt;Now that we decided what we want to be recorded (that is what we decided to &lt;code&gt;add&lt;/code&gt; to the index), we need to use the &lt;code&gt;commit&lt;/code&gt; command to create a snapshot of the current state of our files.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git commit -m&lt;span class='s2'&gt;&amp;quot;Added bazbar to fix the lack of it&amp;quot;&lt;/span&gt;
&lt;span class='go'&gt;[master (root-commit) 7c628c7] Added bazbar to fix the lack of it&lt;/span&gt;
&lt;span class='go'&gt; 1 files changed, 1 insertions(+), 0 deletions(-)&lt;/span&gt;
&lt;span class='go'&gt; create mode 100644 uno.txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(You can put a space between the -m and the &amp;#8220;Message&amp;#8221; if you prefer).&lt;/p&gt;

&lt;p&gt;The command I used has a -m option attached to it: m stands for &amp;#8220;commit &lt;strong&gt;m&lt;/strong&gt;essage&amp;#8221;, that is a non optional part of the commit object itself: a commit object is one of the object types stored in your .git directory (the actual repository) that is used to keep track of the pieces of information about a &lt;strong&gt;revision&lt;/strong&gt;. If you don&amp;#8217;t add the message in the commit command, git will launch your text editor for you to type the message: saving and closing will finalize the commit.&lt;/p&gt;

&lt;h2 id='practicaladvice_moment_when_to_commit'&gt;Practical-advice moment: when to commit?&lt;/h2&gt;

&lt;p&gt;Quite often, if you ask me. Actually it&amp;#8217;s something you have to work out yourself but the general advice is valid since git tends to maintain your repo compact in size: it&amp;#8217;s not like having a copy of your contents for every change, it&amp;#8217;s far far less.&lt;/p&gt;

&lt;p&gt;So when you are about to start something you feel like you may regret, think about committing (and, when you will know git better, branching); when you accomplished something you can describe compactly in a commit message, think about committing.&lt;/p&gt;

&lt;p&gt;The idea is that you should avoid a big fat commit at the end of the day, even if you just worked all day on a single aspect of your project: much better having at least two-three commits, the more the better, just don&amp;#8217;t fall to the other side (90 commits a day may be simply too much of them :D).&lt;/p&gt;

&lt;h2 id='captains_log_stardate_7c628c7'&gt;Captain&amp;#8217;s log, stardate 7c628c7&lt;/h2&gt;

&lt;p&gt;Now we will make another commit: open uno.txt, change something (add a line, change something that is already there, &amp;#8230;), save uno.txt and create a file named due.txt with something in it.&lt;/p&gt;

&lt;p&gt;The result of &lt;code&gt;git status&lt;/code&gt; shows due.txt as an untracked file, and uno.txt in modified state.&lt;/p&gt;

&lt;p&gt;Now it&amp;#8217;s just identical to what we&amp;#8217;ve done previously starting with the &amp;#8221;&lt;a href='http://www.hack-repeat.com/from-zero-to-git-1-daily-disconnected-git-commands/#tracking_files'&gt;Tracking files&lt;/a&gt;&amp;#8221; paragraph, so add (to the index) anything you want to be in your next commit, for example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git add uno.txt due.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;to add both files (this is the way to add multiple files at once, space separated; alternatively you can run several subsequent git add commands and get the same result).&lt;/p&gt;

&lt;p&gt;After that, commit with a message.&lt;/p&gt;

&lt;p&gt;Now that we have a proper history of commits, let&amp;#8217;s visualize it (note that this command works also with just one commit): meet the &lt;code&gt;log&lt;/code&gt; command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git log
&lt;span class='go'&gt;commit 879611a6e5b9b8f20aed15c62c82c432fdf188a0&lt;/span&gt;
&lt;span class='go'&gt;Author: Matteo Scotuzzi &amp;lt;matteo.scotuzzi@...&amp;gt;&lt;/span&gt;
&lt;span class='go'&gt;Date:   Thu Oct 6 14:59:48 2011 +0200&lt;/span&gt;

&lt;span class='go'&gt;    Committing changes and a new file at once&lt;/span&gt;

&lt;span class='go'&gt;commit 7c628c78707a76b11a70716ad082da621047afe2&lt;/span&gt;
&lt;span class='go'&gt;Author: Matteo Scotuzzi &amp;lt;matteo.scotuzzi@...&amp;gt;&lt;/span&gt;
&lt;span class='go'&gt;Date:   Sun Oct 2 15:16:47 2011 +0200&lt;/span&gt;

&lt;span class='go'&gt;    Added bazbar to fix the lack of it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note: if the list of commit is longer than the terminal&amp;#8217;s height you can navigate up/down with keyboard keys (internally uses &lt;code&gt;less&lt;/code&gt; command to display). To go back to your terminal, press &lt;code&gt;q&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What&amp;#8217;s that? It&amp;#8217;s your git captain&amp;#8217;s log! It displays the commits in reverse chronological order (like in blog posts, the last is at the top of the list).&lt;/p&gt;

&lt;p&gt;This log will be valuable to remember the last step of your project (assuming you wrote good commit messages) and is necessary to get the id of the commits in case you need it: each commit has a SHA-1 hash string like 7c628c78707a76b11a70716ad082da621047afe2 that identifies uniquely the (contents of the) commit itself. We will see in a future article how this information can come in handy.&lt;/p&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Here is a recap on the commands we saw in this article:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; &lt;span class='c'&gt;# in the working directory of an existing repository&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git status
&lt;span class='gp'&gt;$&lt;/span&gt; &lt;span class='c'&gt;# work work work&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git status
&lt;span class='gp'&gt;$&lt;/span&gt; git add your-work
&lt;span class='gp'&gt;$&lt;/span&gt; git commit -m&lt;span class='s2'&gt;&amp;quot;Some cool work&amp;quot;&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; &lt;span class='c'&gt;# more work&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git add more-work
&lt;span class='gp'&gt;$&lt;/span&gt; git commit -m&lt;span class='s2'&gt;&amp;quot;more work&amp;quot;&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git log
&lt;span class='gp'&gt;$&lt;/span&gt; &lt;span class='c'&gt;# admire your work&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;At this point you can continue to work re-starting with &amp;#8221;&lt;a href='http://www.hack-repeat.com/from-zero-to-git-1-daily-disconnected-git-commands/#the_status'&gt;The status&lt;/a&gt;&amp;#8221; paragraph. You are now recording steps in your work and that&amp;#8217;s a good accomplishment! But what if you screw up? You need to go back, but you&amp;#8217;ll notice that you don&amp;#8217;t know how to do so! The next post, &lt;a href='http://www.hack-repeat.com/from-zero-to-git-2-branching-merging-and-tagging/'&gt;branching, merging and tagging&lt;/a&gt; is what you need.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>From zero to git, episode 0: first things first</title>
   <link href="http://www.hack-repeat.com/from-zero-to-git-0-first-things-first/"/>
   <updated>2011-10-06T00:00:00+02:00</updated>
   <id>http://www.hack-repeat.com/from-zero-to-git-0-first-things-first</id>
   <content type="html">&lt;p&gt;So, you want to do version control with &lt;a href='http://git-scm.com/'&gt;git&lt;/a&gt; on your files? But let&amp;#8217;s admit it: git it&amp;#8217;s not all that straight forward for a novice.&lt;/p&gt;

&lt;p&gt;Lots of git explanations you can find on the internet start with a fair share of git internal concepts. I think this is not the one-size-fits-all solution, so I started to write this series of articles as an experiment in which you learn some practical command to get started and then you are exposed to the theory. Let&amp;#8217;s see how much damage I can do :D.&lt;/p&gt;

&lt;p&gt;This article shows you two occasional git commands to get you started. It assumes that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;you already installed git&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id='once_in_a_while_presenting_yourself'&gt;Once in a while: presenting yourself&lt;/h2&gt;

&lt;p&gt;First of all let&amp;#8217;s present ourselves to git:&lt;/p&gt;

&lt;p&gt;Type the following commands, editing the last part to fit your case&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git config --global user.name &lt;span class='s2'&gt;&amp;quot;Your Name&amp;quot;&lt;/span&gt;
&lt;span class='gp'&gt;$&lt;/span&gt; git config --global user.email you@example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;All the previous needs to be done once, especially if you backup your setting files when changing computer, so there&amp;#8217;s no real need to remember.&lt;/p&gt;

&lt;h2 id='once_on_new_project_empty_repository'&gt;Once on new project: empty repository&lt;/h2&gt;

&lt;p&gt;The first thing to start working with git is getting some repository. For the purpose of this series of articles we will start from scratch.&lt;/p&gt;

&lt;p&gt;Like the previous one, this operation is not really something you will do daily, but it happens more times than setting your name.&lt;/p&gt;

&lt;p&gt;Using your terminal, get in the empty directory (create one if you haven&amp;#8217;t one yet) that will hold your repository. Type:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git init
&lt;span class='go'&gt;Initialized empty Git repository in &amp;lt;directory&amp;gt;/.git/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;directory&amp;gt;&lt;/code&gt; is the absolute path of your git repository. At that path a hidden &lt;code&gt;.git&lt;/code&gt; directory is added. This is where the actual repository is stored, the files you will actually work with are outside the &lt;code&gt;.git&lt;/code&gt; dir and are just your current working copy.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.git&lt;/code&gt; directory is very important, you don&amp;#8217;t want to mess with it without knowing what you are doing.&lt;/p&gt;

&lt;h2 id='bonus_two_nice_settings'&gt;Bonus: two nice settings&lt;/h2&gt;

&lt;p&gt;I highly recommend this one, as it will make easier to interpret the command line output at a glance:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='console'&gt;&lt;span class='gp'&gt;$&lt;/span&gt; git config --global color.ui &lt;span class='nb'&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A second nice tip (specific for &lt;a href='http://en.wikipedia.org/wiki/Bash_%28Unix_shell%29'&gt;bash&lt;/a&gt;) is slightly more difficult to add, but is well worth it. Is used to show information about the state of your files to the bash prompt, you will appreciate this in the episode of this series about branches (&lt;a href='http://www.hack-repeat.com/from-zero-to-git-2-branching-merging-and-tagging/'&gt;branching, merging and tagging&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;~/.bashrc&lt;/code&gt; file and add the lines below (appending them at the end should be fine).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;#Checks if the current git branch is in a dirty state (uncommitted work)&lt;/span&gt;
&lt;span class='k'&gt;function &lt;/span&gt;parse_git_dirty &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='o'&gt;[[&lt;/span&gt; &lt;span class='k'&gt;$(&lt;/span&gt;git status 2&amp;gt; /dev/null | tail -n1&lt;span class='k'&gt;)&lt;/span&gt; !&lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;nothing to commit (working directory clean)&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;]]&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;

&lt;span class='nv'&gt;PS1&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1 &amp;quot; (%s$(parse_git_dirty))&amp;quot;)\$ &amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you don&amp;#8217;t have &lt;code&gt;~/.bashrc&lt;/code&gt; and are on a unix operating system you may have to find the right place for this yourself (it&amp;#8217;s probably &lt;code&gt;~/.bash_profile&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Done :D. Don&amp;#8217;t miss the &lt;a href='http://www.hack-repeat.com/from-zero-to-git-1-daily-disconnected-git-commands/'&gt;daily bare minimum git commands&lt;/a&gt; in the next article.&lt;/p&gt;</content>
 </entry>
 
 
</feed>
