Catalyst – Git



Catalyst – Git

1 0


git-basic-slides

The intro slides for the basic git course

On Github catalyst-training / git-basic-slides

Git

Revision control for humans

The presentation content is licensed under a Creative Commons Attribution 3.0 License. (http://creativecommons.org/licenses/by/3.0) The presentation display is licensed seperately by Hakim El Hattab / @hakimel Theme: Dark / Light # Make sure the server has a working SSH daemon running # Set up shared git repo mkdir /tmp/test2.git cd /tmp/test2.git git init --bare cd /tmp git clone /tmp/test2.git /tmp/work cd /tmp/work echo 'evanwashere' > evan.txt git add evan.txt git commit -m 'initial commit - one file' git push origin master
## Introduction * The format of this course is mostly a tutorial (with some lecturing thrown in) * The tutorial uses a linux command line, but git is available on other platforms * The tutorial is designed to uncover the concepts * Not necessarily to provide all the command syntax * Hopefully if you are armed with the concepts, the internet will help you find the specifics you need
## Why use revision control software? #### You (should) want it if... * You are sick of keeping *.bak files * You might ever want to look at how something used to be * You might ever want to know why something changed * You might like to review what you have just changed
## Why use revision control software? #### You need it if... * You are working with other people who use it * You want to maintain multiple versions of the same thing * You want to work on separate changes at the "same time" * You need to make a single change which covers several files - and keep things in sync
## What does revision control provide? * Track changes (to almost anything) * View history * Look back to find when bugs were created * Find the reasoning behind why something is how it is * Roll back changes * Apply kudos for effort * Backups of your important stuff
## What options are there? * RCS * CVS * Subversion * Darcs * Perforce * Bzr * ...
## Why should you use Git? * It is fast * Branching is trivial * Merging of branches actually makes sense * You can be disconnected from the network, yet still continue working * It does not dictate your workflow * [It protects your data](http://git-scm.com/about/info-assurance) * Once you master the concepts, you can do some really creative (and useful!) stuff * The cool kids use it
## Installing ```bash # Required $ sudo aptitude install git ``` ```bash # Recommended $ sudo aptitude install gitk git-gui ``` ```bash # FYI... $ sudo aptitude search git ```
Pause here to explain the way we are showing commands - talk about '$' as the prompt, etc
## Installing (alternative OS) * Go to [git-scm.org](http://git-scm.org "The home of git") * Find the [Install instructions](http://git-scm.com/book/en/Getting-Started-Installing-Git "Find the install instructions") * Which will lead you to [the windows package](http://msysgit.github.io/) * Once you have it installed, you are looking for "Git BASH"
## Create a new repository Use ```git init``` ```bash $ mkdir /tmp/test ``` ```bash $ cd /tmp/test ``` ```bash $ git init Initialized empty Git repository in .git/ ``` Check the status with ```git status``` ```bash $ git status # On branch master # # Initial commit # nothing to commit (create/copy files and use "git add" to track) ```
## Global configuration settings This will stop Git nagging you later ```bash $ git config --global user.name "Your Name" $ git config --global user.email "null@catalyst.net.nz" ``` If you think ```nano``` is crap, you can choose vim, or gedit ```bash $ git config --global core.editor gedit ```
## Project configuration settings This will tell Git you like to see pretty colours on the screen ```bash $ git config color.ui always ```
These settings will override the global settings - but only within the current repository (which is /tmp/test)
## Accessing the configuration settings Global data is stored in ```$HOME/.gitconfig``` Project data is stored in ```$PROJECT/.git/config``` Use ```git config``` to see it ```bash $ git config -l ``` ..or just edit the files ```bash $ gedit ~/.gitconfig /tmp/test/.git/config ```
## Some concepts to begin with Git is just a bit different from other revision control systems ![overview](images/local-remote-small.png "overview")
The 'staging area' is often called the 'index'
## Managing Files - Add Make some changes... ```bash $ touch super-script.pl ``` ```bash $ git status # On branch master # # Initial commit # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # super-script.pl nothing added to commit but untracked files present (use "git add" to track) ```
## Tell Git to track those files Use ```git add``` ```bash $ git add super-script.pl ``` ```bash $ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: super-script.pl # ```
## Change an existing file Make some changes... ```bash $ echo DATA > super-script.pl ``` ```bash $ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: super-script.pl # # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: super-script.pl # ```
## Change an existing file We need to tell Git that you intend to commit the checked out version, with ```git add``` ```bash $ git add super-script.pl ``` ```bash $ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: super-script.pl # ```
## Committing changes We need to commit our changes to make them permanent. Commit with ```git commit``` ```bash $ git commit super-script.pl Created commit ae54011: Add a message. 1 files changed, 3 insertions(+), 0 deletions(-) create mode 100644 super-script.pl ``` You will be stuck in an editor so you can input a commit message Normally, you WILL make your commit message meaningful
We have told git about our changes, but we haven't actually committed anything yet. This is deliberate - so you can build up more complex commits.
## Committing changes - some options You don't have to ```git add``` all your changes manually ```bash $ git commit <file> ``` ```bash $ git commit -a ``` You can have an easier editor... ```bash $ EDITOR=gedit git commit -a ``` You don't have to use an editor at all... ```bash $ git commit -m 'commit message goes here' ```
## Managing Files - Permissions Oops, that file isn't executable ```bash $ chmod 755 super-script.pl ``` ```bash $ git commit super-script.pl Created commit 378af93: Make it executable. 0 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 super-script.pl ```
## Managing Files - Move To rename a file use ```git mv``` ```bash $ git mv super-script.pl silly-script.pl ``` ```bash $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # renamed: super-script.pl -> silly-script.pl # ``` This has changed our checkout, and the index, so we are ready to commit the change ```bash $ git commit Created commit fabd446: Rename the file. 1 files changed, 0 insertions(+), 0 deletions(-) rename super-script.pl => silly-script.pl (100%) ```
## Managing Files - Delete To delete a file use ```git rm``` ```bash # This won't actually work, because we haven't # created "another-script.pl" # ... but you can try it, if you like.... $ git rm -f another-script.pl ``` ```bash $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: another-script.pl # ``` And commit the change ```bash $ git commit Created commit bd10c5f: Remove another-script.pl 0 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 another-script.pl ```
## Change Logs Use ```git log``` ```bash $ git log commit 09f90bc2a74f7ca2f825c4a386e168649b9fec97 Author: Evan Giles Date: Thu Dec 16 11:53:48 2010 +1300 Rename the file. commit f7123c5ffdccbed11b50b0b74a181186e1a13028 Author: Evan Giles Date: Thu Dec 16 11:53:25 2010 +1300 Make it executable commit 8657bea3230587abdcbe39e6bf699c9ee8f505a6 Author: Evan Giles Date: Thu Dec 16 11:52:51 2010 +1300 Add a message. ``` By default the output is piped into $PAGER @catalyst.net.nz>@catalyst.net.nz>@catalyst.net.nz>
## Change Logs You can also specify a file or directory ```bash $ git log silly-script.pl ```
## Change Logs - Annotate Show who made changes to what line Also known as the blame log ```bash $ git blame silly-script.pl b61863c8 (Andrew Ruthven 2008-05-09 17:01:41 +1200 1) #!/usr/bin/perl -w b61863c8 (Andrew Ruthven 2008-05-09 17:01:41 +1200 2) b61863c8 (Andrew Ruthven 2008-05-09 17:01:41 +1200 3) print "silly script\n"; 9c08faf4 (Bad Coder 2008-05-09 17:18:18 +1200 4) I'm in ur code, breaking ur stuff. ``` Who is this Bad Coder fella?
## Change logs - GUI Not strictly change logs, but... gitk / qgit / gitg / etc ![image](images/gitk.png "gitk")
## Some more concepts - commits * It is important to understand that git thinks in ```commits``` * Each commit refers to a previous commit (its parent) * Commits can be referenced by their SHA1 checksum * or an abbreviation of it * or by a number of things that might refer to them * ```gitk``` lets you visualise the commit history, which helps a lot

Commits are....

Totally unchangeable
## Branching - List To show branches use ```git branch``` ```bash $ git branch * master ``` Only one branch, called ```master``` The '*' indicates that it is your current branch
You can also use 'git status'
## Branching - Create Use ```git branch``` (or ```git checkout -b```) ```bash $ git checkout -b new-branch Switched to a new branch "new-branch" ``` Will create "new-branch", and check it out for you ```bash $ git branch master * new-branch ```
mention that 'git checkout' is a convenience interface ...it does several things in one step
## Branching - Create somewhere else By default a new branch will be created at the commit you already have checked out You can also create a new branch at another commit ```bash $ git checkout -b another-branch master Switched to a new branch "another-branch" ``` ```bash $ git branch * another-branch master new-branch ```
Here, the checkout command is actually doing 3 things - go the the master branch - make a branch there (callled 'another-branch') - checkout the 'another-branch' branch
## Branching - Change Branch Use ```git checkout``` ```bash $ git checkout new-branch Switched to branch "new-branch" ``` ```bash $ git branch another-branch master * new-branch ``` Don't forget to see how this is shown in ```gitk```
## Branching - What's the deal? ```bash # Make a change to a file (and commit that change) $ echo "... From new-branch" >> silly-script.pl $ git commit silly-script.pl Created commit a6ed2cf: From new-branch 1 files changed, 1 insertions(+), 0 deletions(-) ``` ```bash # Check the file.. $ cat silly-script.pl DATA ... From new-branch ``` ```bash # Jump to another branch $ git checkout master Switched to branch "master" ``` ```bash # The text we added ain't there $ cat silly-script.pl DATA ```
## Branching - Why? * Many (most) projects have a branch for each release * Branches are useful for experimental features / refactoring * Branches happen (without even trying) when several people try to work on the same project - but I'll explain that soon ;)
It is useful to think of branches as an 'alternative reality'
## Merging - Simple Case You should now be on the master branch ```bash $ git status # On branch master nothing to commit (working directory clean) ``` Use ```git merge``` ```bash $ git merge new-branch Updating e766bfb..a6ed2cf Fast forward silly-script.pl | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) ``` In this case, we have done a ```fast forward``` merge If there are no conflicts, this may make a new commit object use ```gitk``` to see what happened
* We are merging changes *IN*, from somewhere else * explain the fast forward bit * talk about merges being line by line, so not for binary data
## Merging - get ready for a conflict Conflicts are more difficult (lets create one) ```bash # Make a change to a file, commit that change to 'master' $ echo "New value for data" > silly-script.pl $ git commit -a -m 'update script with a new value' # Change branches, make a change, and commit $ git checkout new-branch $ echo "different value for data" > silly-script.pl $ git commit -a -m 'update script with a different value' # Go back to the master branch, if we try to merge - there # will be a problem! $ git checkout master ```
Sorry about the wall of text! Also, explain the fast forward bit
## Merging - you can't do that If there is a conflict then git will stop and make you fix it. ```bash $ git merge new-branch Auto-merged silly-script.pl CONFLICT (content): Merge conflict in silly-script.pl Automatic merge failed; fix conflicts and then commit the result. ``` ```bash $ git status # On branch master # Unmerged paths: # (use "git add/rm <file>..." as appropriate to mark resolution) # # both modified: silly-script.pl # no changes added to commit (use "git add" and/or "git commit -a") ``` ```bash $ cat silly-script.pl <<<<<<< HEAD:silly-script.pl New value for data ======= different value for data >>>>>>> new-branch:silly-script.pl ```
## Merging - Fixing conflicts Lots of tools to help fix things up. Hand edit, xxdiff, smartmerge, etc We'll just fix it by editing the file ```bash $ gedit silly-script.pl $ cat silly-script.pl New, different value for data ``` But Git still won't allow us to continue... ```bash $ git commit U silly-script.pl fatal: 'commit' is not possible because you have unmerged files. Please, fix them up in the work tree, and then use 'git add/rm <file>' as appropriate to mark resolution and make a commit, or use 'git commit -a'. ```
## Merging - Success at last We need to tell Git that it has been fixed before we commit ```bash $ git add silly-script.pl $ git commit Created commit a411f2a: Merge branch 'new-branch' ``` In this case the commit message is automatically created, but you can edit it if you want. ```bash Merge branch 'new-branch' Conflicts: silly-script.pl ```
## Merging - How does it look? Looking at the trees in gitk helps you understand stuff. ```bash gitk ```

A quick recap

Sharing your changes with others

Finish with: What is the opposite of push?

A gentle recommendation...

  • git push
  • git fetch
  • git pull git fetch; git merge

Ways to work with git (1)

  • Corporate Workflow
  • Catalyst uses this a lot
  • You will use this

Ways to work with git (2)

  • Integration Manager Workflow
  • A quick diversion: http://www.github.com

Ways to work with git (3)

  • Dictator Workflow
  • This is how the Linux kernel is managed

Ways to work with git (4)

  • Peer to peer Workflow
## Creating Repositories - Revisited We already know how to create a new repositry ```bash $ git init Initialized empty Git repository in .git/ ``` ...but normally, you want to join in with an existing project
## Clone an existing repository In practise, you're more likely to use ```git clone``` To check out the source code of a random project ```bash $ cd /tmp ``` ```bash $ git clone https://github.com/libgit2/libgit2 Cloning into libget2... remote: Counting objects: 90, done. remote: Compressing objects: 100% (43/43), done. remote: Total 90 (delta 44), reused 90 (delta 44) Receiving objects: 100% (90/90), 31.62 KiB, done. Resolving deltas: 100% (44/44), done. ``` ```bash $ cd libget2 ``` ```bash $ ls ``` ```bash $ gitk ```
git remote git remote -v
## Remote repositories - URLs Clone an existing repository via HTTP ```bash $ git clone http://git.catalyst.net.nz/git.git ``` Clone an existing repository via SSH ```bash $ git clone ssh://git.catalyst.net.nz/git/public/git.git ``` Clone an existing local repository (this is just a bit mad) ```bash $ git clone test test2 ```
## Remote branches Remote branches are references (pointers) to the state of branches in your remote repositories. They're local branches that you can't move; they're moved automatically for you whenever you do any network communication. Remote branches act as bookmarks to remind you where the branches on your remote repositories were the last time you connected to them.
## Origin You can see all branches (including the remote ones) with the ```git branch``` command ```bash $ git branch -a * master remotes/origin/master ```
origin is not special you don't need to type 'remotes' to refer to these branches

Once upon a time....

.. Alice and Bob wanted to do some work

So they both made some changes....

Alice pushes her changes...

But Bob has a problem...

Now Bob needs to fetch the changes from Alice

and merge them with his work

They all lived happily ever after...

## Now we can try it ```bash # Clone a new repository $ cd /tmp $ git clone $IP:/tmp/test2.git $ cd /tmp/test2 ``` ```bash # Create a new file (and commit) $ gedit $YOURNAME.txt $ git add $YOURNAME.txt $ git commit ``` ```bash # Push your changes to the shared repository $ git push origin master ``` ```bash # You are now Bob! $ git fetch $ git merge origin/master ```
Explain What is going on with "origin" and "master" here: - git push origin master - git merge origin/master
## Tags Tags work pretty much like you would expect. They allow you to tag specific points in history as being important. Often people use this functionality to mark release points. ```bash $ git tag v1.0 $ git tag v1.0-production -m 'this might be important later!' ``` ```bash $ git tag $ git show v1.0 $ git show v1.0-production ```
2 types of tags: lightweight and annotated Tags don't get shared, by default.
## Changing your commits You can 'change' the most recent commit using ```git commit``` ```bash $ git commit --amend ```
Will someone please pull me up on this?! Explain how this works - That you are not changing anything here - just making a new commit which is quite like the old one - and then moving the labels around
## A preview of the intermediate course ;) * git cherrypick * git revert * git reset * git stash * git clean * git commit --amend * git rebase * git rebase --interactive * Changes with gitk * git gui
Explain: - that you shouldn't change commits that have been shared

The End

Questions?