Education ClassRoom/Previous Logs/git

From Apache OpenOffice Wiki
Jump to: navigation, search

[18:08] <Garuma> that should be ok, I haven't timed the thing so we will see how fast it goes

[18:08] <Garuma> so *bell and whistles*, git presentation starting up

[18:08] <Garuma> Hello folks. My name is Jérémie Laval and today I'm going to talk a bit about git, the stupid content tracker.

[18:09] <Garuma> First of all let me tell you some information on how this classroom will go

[18:09] <Garuma> For reference purpose I have put online some slides that you are welcome to use to follow this classroom. They are at this address :

[18:09] <Garuma> Since this classroom is demonstration-oriented, you should have a terminal opened up so that you can put the commands contained on the slides while following the classroom.

[18:09] <Garuma> I won't talk about the definitions at the beginning of the slides, there are here for you if you don't know a term.

[18:10] <Garuma> In order for you to sync the slides with the talk, I will insert titles and subtitles in the presentation with hash e.g. ### This is a title ###

[18:10] <Garuma> When I want to introduce a command, I will always enclose them in simple quote e.g. 'git add foo.c'

[18:11] <Garuma> Of course the following classroom isn't intended to be a complete guide to git. For that purpose, I put links at the end of the slides that you should consult if you ever wants to continue learning git.

[18:11] * [1]jPau ( has joined

[18:11] <Garuma> For those who haven't installed git yet, you can do so now. At the 3rd slide you can find how to install it for most operating systems / distribution.

[18:11] <Garuma> I'm going to wait a little so that you can install it

[18:11] <Garuma> if you already have question about how the classroom will go you can also ask them ;)

[18:13] <Garuma> Ok, then I assume I can continue ?

[18:13] <Garuma> Well, now that this is settled, let's begin !

[18:13] <Garuma> ### Introduction ###

[18:14] <Garuma> ## History ##

[18:14] <Garuma> For the historic record, Git was created by Linus Torvalds in 2005 when the Linux kernel team decided to drop BitKeeper, the commercial version control system they were using.

[18:14] <Garuma> The move was mostly due to BitKeeper company stopping to give free licence to the kernel developers and, of course, the fact that the kernel team wouldn't pay for such a service.

[18:14] <Garuma> From the start, git was designed to be fast and scalable which is understandable given the size of the Linux kernel.

[18:14] <Garuma> However, some of the thing used to make it fast involved some kernel blackmagic (like raw inode manipulation) that's why git was initially very tied to Linux systems and almost unportable or unacceptably slow on other systems (On Windows for instance you had to use the Cygwin compatibility layer).

[18:15] <Garuma> Today, this issue is mostly addressed and git is now installable on most operating system.

[18:16] <Garuma> The biggest complain today is the lack of a git library which is one of the reason subversion is so popular today. Indeed, providing a library allows the creation of a plethora of tools and easier integration of the VCS into an existing software (like Trac or Bugzilla).

[18:16] <Garuma> That's why today, it's rather hard to integrate git as one has to directly call git command via, for instance, a system() call and then parse the output.

[18:16] <Garuma> Again this is being worked on in form of a real C library, developed this time by some Google folks who are internally using git a lot and would like to integrate it more in their tools.

[18:16] <Garuma> Yet another traditional user complain was the unfriendliness of the git user interface and indeed in its debut it was quite horrible.

[18:16] <Garuma> This was mostly due to the fact that git was at first thought to be a kind-of super filesystem with versionning support. The actual VCS would have been another software sitting on top of that filesystem and which would provide the interface the users were expected.

[18:17] <Garuma> *were expecting

[18:17] <Garuma> That was the case with Cogito which is obsolete today as git has now evolved into a real VCS.

[18:17] <ericb2> Garuma: not me :)

[18:18] <Garuma> Okay, so let's move on the features of git

[18:18] <Garuma> ## Features of Git ##

[18:18] <Garuma> Ok, so I will assume that pretty much every one here know what a VCS is, what they are used for and how they work.

[18:18] <Garuma> You may have heard that git (among others) falls into a special category of VCS named DVCS which means Distributed VCS.

[18:18] <Garuma> Essentially, distributed means that, instead of relying on a central server for storing your stuff and then doing some network exchange for operations like diff and so on, everybody become a fully fledged repository.

[18:19] <Garuma> This means that things like offline commit becomes possible with a DVCS. Wherever you are on a train, an airplane or any other place without network access, you can continue to commit things, do diffing, get log, etc... like you would normally do.

[18:20] <Garuma> To summarize, everybody working on a git-ified project is itself a repository and can interact and be interacted with other working on the same project (we will see that later).

[18:20] <Garuma> One of the big strength of git is also its support for branching and intelligent merging of branches.

[18:20] <Garuma> Git branching here is real branching as opposed to subversion for instance which basically do folder copies and which make it hard to do merge between branches.

[18:20] <Garuma> Git also allows to do quite complex commit history manipulation but we won't cover them in this classroom

[18:21] <Garuma> Anybody needs clarification ? Maybe I passed something to quickly ?

[18:21] <Garuma> Ok, so now we will see how to actually use git

[18:22] <Garuma> ### Using Git ###

[18:22] <Garuma> ## Basic Usage ##

[18:22] <Garuma> First of all, if at any time there is a git command that is confusing you, know that each of them has its own man page that you can access with the 'help' command e.g. 'git help commit'

[18:22] * jsc has quit (Read error: 110 (Connection timed out))

[18:22] <Garuma> The set of command to execute are contained in the slides. You can copy&paste them in your terminal and see what actually happens as the presentation goes on.

[18:22] <Garuma> # Initializing a new repository #

[18:22] <Garuma> The key command that we are using here is 'git init'. You must use this command each time you want to create a new git repository in a folder.

[18:22] * ericb2 installed git-core using port on Mac

[18:23] <Garuma> Basically, 'git init' create an hidden folder, .git, where git will store all his stuff.

[18:23] <Garuma> In fact this .git directory is the core of your repository. Indeed there is in fact the whole repository information contained inside.

[18:23] <Garuma> In practise, when someone else want to work on your project, what they do is that they copy this folder on their machine which gives them access to everything you have ever done on it.

[18:24] <Garuma> Now we will see how to make our first commit

[18:24] <Garuma> First of all, download the file hello.c located at with 'wget' for example and put it in our new git-tutorial folder.

[18:24] <Garuma> If you issue a 'git status' command you will see that git see hello.c but put it under "Untracked files:".

[18:27] <ericb2> Garuma: exact :)

[18:28] * andreasma ( has joined

[18:28] <Garuma> The 'git add' command tells git which files it should track for changes, in our case since hello.c was never committed, git will simply add the whole content. If you now issue 'git status' you will see that the file is now under "Changes to be committed:"

[18:28] <Garuma> To finish the process, use the 'git commit' command. The -m switch allows to put directly a commit message in the command.

[18:28] <Garuma> If you don't use that switch, git will open a text editor (vi by default, use $EDITOR environment variable to change e.g export EDITOR='emacs -nw ') so that you can type the commit message.

[18:28] * jPau has quit (Read error: 110 (Connection timed out))

[18:28] * [1]jPau is now known as jPau

[18:28] <Garuma> # First changes #

[18:28] <Garuma> Now, do some change to the hello.c file (something simple like adding a new line is ok). Save up the file and close your editor.

[18:28] <Garuma> Now issue again a 'git status' command. You will notice that git now put hello.c under "Changed but not updated". Remark that it's not the same as the previous message ("Changes to be committed").

[18:29] <Garuma> Indeed, if you fire 'git commit' git will simply answer with git status output or an error message. The reason is that git doesn't automatically treats file changes as changes to be committed.

[18:29] <Garuma> To tell git that you really want the changes to be committed, you use again the 'git add' command which will put the file under "Changes to be committed". Then the 'git commit' command will work as expected.

[18:29] <Garuma> Since it's quite usual that you want to commit all your changes in a row without manually git add'ing each files, 'git commit' accepts a -a switch that will automagically commit all modified files.

[18:29] <Garuma> Note that, this time, I deliberately didn't put the -m switch on the commit command line located in the slide. Thus, you should see your favorite editor opening up after issuing the command.

[18:30] <Garuma> In the editor, type a commit message, save it and exit the editor and git should report that he created a new commit successfully. If you close the editor without saving, the commit will be aborted.

[18:30] <Garuma> After git has correctly committed your changes you can see the revision history by typing 'git log'. It will return some useful information like the commit message, author, date and commit sha1 hash which identify uniquely the commit (btw, if you ever need to point out a specific commit in a git command, use that hash).

[18:31] <Garuma> Okay, now that we have covered the basic usage let's move on to some team work.

[18:31] <Garuma> ## Working with others ##

[18:31] <Garuma> Now we will focus on some possible way to work with other developer and contributor on a project with git.

[18:32] <Garuma> Firstly, you will simulate that you are a contributor by cloning what we have done before as, in the git world, when you want to work on a project, the first thing you do is to clone its repository.

[18:32] * ericb2 tested git diff after a modification

[18:32] <Garuma> ericb2: we see that later ;)

[18:32] <ericb2> Garuma: sorry :)

[18:32] <Garuma> If you remember correctly what I said previously about the .git folder you may have guessed that 'git clone' basically copy this folder to your local filesystem (in case the source repository is on a network place).

[18:33] <Garuma> By induction, cloning is a far heavier operation than, for instance, a 'svn checkout' with Subversion as here we are copying the whole repository and not only the last revision.

[18:33] <Garuma> However, you will notice that due to git speed this isn't a troublesome operation as it's most of time pretty fast.

[18:34] <Garuma> For very very large project, you may mimic the behavior of 'svn checkout' by only mirroring a top part of the revision tree with the --depth switch.

[18:34] * mmu_laptop has quit ("Vision[0.9.7-H-090423]: i've been blurred!")

[18:34] <Garuma> But, note that doing so prevent anyone from interacting with your repository directly as it is considered as a shallow clone. The only way you will be able to interact back with the source is by sending patches.

[18:34] <Garuma> That's why most of time you should take the time to clone the whole repository and not a part of it.

[18:34] <Garuma> Talking about patches, let's see how this work in git.

[18:35] <Garuma> # Using patches #

[18:35] <Garuma> First of all let's make some change from a contributor point of view. A command to do that is in the slide but you can do any other modification you like.

[18:35] <Garuma> (of course, you should cd to the new repository where we just cloned prio to changing anything)

[18:35] <Garuma> *prior

[18:36] <Garuma> Now, if you execute 'git diff', you should see the changes you have made in a unified patch format. Simply redirect this output to a file to get your patch !

[18:36] * [1]jPau ( has joined

[18:36] <Garuma> Then, let's revert back to our main developer role by going back to the main project directory.

[18:37] <Garuma> (i.e. : cd ..)

[18:37] <Garuma> Git patchs mostly follow the unified patch format, however there are some extensions specific to git (like permission changes), that's why instead of using the traditional 'patch' command I advise you to use 'git apply' instead.

[18:38] <Garuma> Apart from the command change, the usage is pretty much the same than with 'patch'

[18:38] <Garuma> Finally, the only thing remaining to do is test up if the patch is good (compile, run, unit test suite, ...) and commit the changes as before. If the patch is bad, you have the possibility to reverse it with the -R switch to 'git apply' (just like 'patch').

[18:39] <Garuma> So, we have seen how to work with patch in git

[18:39] <Garuma> However, if you are a frequent contributor, managing patch will quickly become bothersome

[18:39] <Garuma> That's why we are going to see an other way of contributing changes with git in a more "distributed" way !

[18:40] <Garuma> # With a distributed workflow #

[18:40] <Garuma> For this manipulation we are going to clone again the current repository to a new one and cd to it. Apply some changes to hello.c to mimic that you added some features and commit them normally.

[18:41] <Garuma> Now, imagine that, after some work (we committed only one thing here but it may have been several commits), you ask the main developer to pull your changes.

[18:41] <Garuma> Going back to our main developer role ('cd ..'), we can now pull these changes with the 'git pull' command. Normally, there should be no conflicts and git will happily report that the merge succeed.

[18:42] <Garuma> Now, if you look at the output of 'git log' you will see that the commits the contributor made are now on the top of your own history and are thus an integral part of your repository !

[18:42] <Garuma> Taadaa, bye bye patches :)

[18:42] <Garuma> As you can see, this workflow is quite flexible. There is also a push action ('git push') that allows you to do the same thing but the other way around (i.e. you send changes to a repository rather than getting them from it).

[18:43] <Garuma> As an example, this 'git pull' command is the base of the workflow used in the Linux kernel development. The so called "Merge frame" is, in fact, Linus pulling out changes from each of his trusted developers repository where each of this developer is responsible of a subsystem of the kernel (arch, driver, net, whatever).

[18:44] <Garuma> In turn, these trusted developers may have pulled changes from others developers trees, integrated patches from contributor, made themselves improvements, etc...

[18:45] <Garuma> When Linus has stabilized all these changes in his own git repository it becames yet another Linux release.

[18:45] * mmu_laptop ( has joined

[18:45] <Garuma> *becomes

[18:45] <Garuma> That's all for this part. Keep in mind that here we have done most of our stuff (clone, pull, etc...) on the same local filesystem, but of course git has a number of transport protocol that it can use like git:// (homemade and fastest), http://, ssh:// or rsync:// to interact over a network or Internet.

[18:46] <Garuma> Then we are gonna move on to another of the prominent feature of git : branches

[18:46] <Garuma> ## Branching ##

[18:46] <Garuma> The concept of branch is rather simple and can be thought of the same as a tree. The trunk is called, in git, the master branch and, at any time (i.e. starting from any commit in this master branch), you can have a so-called branch (each one identified with a name) that pile up some other changes (i.e. commits).

[18:47] <Garuma> (a picture of such a tree is in the corresponding slide)

[18:47] <Garuma> In turn, each of these branch commits may have been branched and some branches may rejoin later at a specified point in master or in another branch (that's what we call merging).

[18:47] <Garuma> This is a pretty powerful way to model your repository. Indeed, a lot of workflow can be imagined from this branch philosophy.

[18:47] <Garuma> For instance, you may decide that the master branch should remain stable, thus every single feature you want to add to the next version of you software can live in its own branch and then they are merged back into master when everything is ready for the next release.

[18:48] <Garuma> You can also say that the master branch is considered unstable (i.e. you will do your work in it) and each stable release you made get their own branch (i.e. when you release a version, you start a branch from the corresponding commit).

[18:48] * [2]jPau ( has joined

[18:48] <Garuma> That way, bugs can be fixed inside these release branches and be merged back in your master tree (or the other way around). That allows you to do further releases (so-called bug-fix release) without having half-finished unstable features standing in the middle.

[18:49] <Garuma> Now, let's do some branch hacking

[18:49] <Garuma> # Basics #

[18:49] <Garuma> First of all, to work on branches we need to create them. This is done with the 'git checkout' command by passing a -b flag to it.

[18:50] <Garuma> After you have called that command, you are automatically switched to the new branch. Now all commits you will do will live in this branch. You can see at anytime in which branch you are working by using the 'git branch' command which prints all the existing branch. The one you are currently in is preceded by an asterisk.

[18:50] <Garuma> Now, do some change again to hello.c (which we will say is a crazy new feature that breaks everything) and commit it normally.

[18:51] <Garuma> If you fire up the 'gitk --all' command you will see a visual representation of your repository with all the commits and branches. Normally in this case you should see the two different branch (master and the other) with the other containing a commit more than master.

[18:52] <Garuma> *one more commit than master

[18:52] <Garuma> # Diverging #

[18:52] <Garuma> Go back to our master branch with 'git checkout' (without the -b switch as the branch exists already). Notice that the changes you made back in other branch have disappeared from the hello.c file.

[18:53] <Garuma> (this is normal, don't panick :))

[18:54] <Garuma> Then, do some other changes to the actual hello.c (preferably to a different place than when you were in the experimental branch). We will say you just made an important bug fix. After making the change, commit it.

[18:54] <Garuma> Fire up again 'gitk --all', you should now clearly see two different branches in the revision history corresponding to master and the experimental branch we made. At this point we say that the branches have diverged.

[18:55] <Garuma> # Merging #

[18:55] <Garuma> Ok, now that we committed an important fix on the master branch, we have to backport it to our experimental branch. To do that, first let's move on to the experimental branch with 'git checkout experimental'.

[18:56] <Garuma> There, you just have to merge master in experimental i.e. copy the set of commit done after we had branched back onto experimental. This is made with the 'git merge' command which take in argument the branch you wish to merge from.

[18:56] <Garuma> That is to say, "master" in our case

[18:56] <Garuma> After executing that command you will see that your hello.c file now contains both the new experimental feature and the bug fix you made on master. Launching 'gitk --all' will show you that both master and experimental joins back to the same point.

[18:57] <Garuma> If somehow, git answer you with a sentence like "Automatic merge failed; fix conflicts and then commit the result.", then edit manually the hello.c file to remove the conflict (symbolized by lines between >>>>, ===== and <<<<<<) and commit the result with 'git commit -a' (the commit message is already filed, just save and exit).

[18:58] <Garuma> If the conflict is unexpected and you don't have time right now to resolve it, yo ucan also use the 'git reset --hard' command which will put you back in the state your were before the pull

[18:58] <Garuma> Of course, merging hasn't destroyed any of our two branches. You can still continue to commit in each one independently and thus the two branches will diverge again.

[18:59] <Garuma> Then after another period of time (like after another bugfix) you can re-merge the two branches

[19:00] <Garuma> What I described here is a possible way to merge changes back and forth between branches. I call it the safe way as doing like this add over your existing commit history and don't change it.

[19:00] <Garuma> However, if you recall what I said about git history rewriting abilities, there is another way to do the same thing probably more powerful except that it *rewrites* your history. The command to use in that case is the 'git rebase' one. You should look at its man page for more information. Interactive rebasing is also one of the most powerful feature of git.

[19:01] <Garuma> But, a side-effect of this history rewrite is that if someone had mirrored your repository before the history rewrite he won't be able to pull any further changes as git becomes confused over the history mismatch between you and the source.

[19:02] <Garuma> So only use 'git rebase' or other "rewriting" command if you haven't yet shared this part your history with others

[19:03] <Garuma> Also, much of time, where you have a "destroying" command, there is a "safe" counterpart

[19:03] * [1]jPau has quit (Read error: 110 (Connection timed out))

[19:03] <Garuma> For instance, imagine you want to undo a commit you have done before

[19:04] <Garuma> One possible way would be to rewrite your history and remove that single commit (this is possible with 'git rebase' for example)

[19:04] <Garuma> But if you had already made that commit publicly available, all of you contributor would have strange things on their side.

[19:05] <Garuma> So a nice and safer way to actually do that operation is by using the 'git revert' command which will simply create a "anti-commit" of your undesirable commit and add it to the top of your history.

[19:06] <Garuma> That way both the contributor and you are happy. The contributor because they can continue to work and you because you vanquished the bad commit.

[19:06] <Garuma> ## Conclusion ##

[19:06] <Garuma> Ok, this classroom is now concluded. I hope I gave you a good introduction to git and its basic features. For more information on git, you can follow the links I put in my last slide and go wild with the 'git help' command, it's your best friend.

[19:07] <Garuma> If you have questions I will be happy to answer them

[19:07] <ericb2> Garuma: first over all, I'd say it was impressive. Thank you very much for all the time you used to prepare us such a good introduction to git

[19:08] <Garuma> my pleasure

[19:08] <ericb2> Garuma: there is a lot of information, but we can imagine you are used to git. Since when do you use it ?

[19:08] <Garuma> Hum, good question, I would say something like 2 or 3 years ?

[19:09] <Garuma> I still remember the cogito days when git was all crappy with its UI :)

[19:09] <ericb2> Garuma: when the change was made, I was a bk user, since I did a lot of hacks in the Linux PowerPC kernel

[19:09] <ericb2> Garuma: but I didn't make the step for the git. Now, I think I can :)

[19:10] <ericb2> @all : please ask if you have questions. For the one who want to practice quietly afterwards, he log is available at :

[19:10] <Garuma> well, if you already used a dvcs I would say most of the hard part is done

[19:10] <Garuma> the main difficulty for a beginner is to grasp the DVCS philosophy imho

[19:11] <ericb2> Garuma: I think so. e.g. svn has similar commands. The point is to practice, but I was really surprised to see how easy it is to create and merge branchs

[19:11] <Garuma> after that, the blackmagic abilities of git are just a matter of practise

[19:12] <Garuma> :)

[19:13] <ericb2> Garuma: if you need help for a workout at UTBM (e.g. during intersemester), just ask me

[19:13] <Garuma> it's the number 2 strength of git for me

[19:14] <Garuma> the first being git rebase

[19:14] * mib_sv39ojkx (i=8242d06f@gateway/web/ajax/ has joined

[19:14] * ericb2 experimented svn rebase nightmare

[19:14] <Garuma> @all, if you are a Subversion user there is a good tutorial for migrating here :

[19:15] <ericb2> @all : any question ?

[19:15] <Garuma> ericb2: I think their problem at root is that branches are simply directory

[19:15] <Garuma> you can't do interesting things with that

[19:16] <ericb2> Garuma: we had other issues, caused by bad commits (I did one myself), and reverse the m properly

[19:16] <Garuma> git rebase is pretty nice for that

[19:17] <Garuma> it's very easy to rewrite your history with the interactive mode

[19:17] <Garuma> of course provided you didn't share it

[19:17] <Garuma> but still, git revert as a backup solution works too

[19:17] * mib_sv39ojkx (i=8242d06f@gateway/web/ajax/ has left

[19:18] * jPau has quit (Read error: 104 (Connection reset by peer))

[19:19] * jPau ( has joined

[19:19] <ericb2> I think the ClassRoom is now finished. Thanks to Jeremie Laval for the presentation, and to all for coming

[19:19] <ericb2> We'll announce the next ClassRoom soon

[19:19] <ericb2> see you :)

Personal tools