Git workshop

Post on 15-Jul-2015

96 views 1 download

transcript

{Git Basics

A simple introductory workshop for the GDC SDK team

Mateusz Gałażyn

October 29th, 2014

1. What is git? Why do you need it?

2. Repository structure

3. Basic workflow

Exercises!

4. Branches

Exercises!

5. Basic merging

Exercises!

6. Remotes

Exercises!

7. Graphical User Interface

Outline

An open source distributed version control system (VCS).

What is Git?

Imagine a situation, when you’re writing your code...

... and suddenly after deployment on a production ...

Why do you need a VCS?

Why do you need a VCS?

Only working backup can save your life now

You can store your backups in separate folders...

... but it’s not convenient

Why do you need a VCS?

Version Control System will do it for you!

A good VSC has to:

Prevent data loss

Provide history of who did what

Allow commit messages

Ease the creation of diffs / patches

Be fast and scalable

What is Git?

Git is distributed – (almost) everything is local – you can work offline and have backups on your local machine

Git is fast – again, most of your work is local, and network interactions are compressed and minimal

Why Git?

As you learn Git, try to clear your mind of the things you may know about other VCSs.

Git stores and thinks about information much differently than other systems and doing so will help you avoid subtle confusion when using the tool.

Before we get into Git...

A repository is a collection of commits

Repository structure

A repository is a collection of commits

A commit is a snapshot of your working tree at some point of time

Repository structure

A repository is a collection of commits

A commit is a snapshot of your working tree at some point of time

A working tree is a directory (and sub-directories) which has repository associated with it

Repository structure

At the beginning of work with Git we are creating empty repository (or cloning an existing one)

Basic Git workflow

Repository

During our work, we are modyfing file structure inside a Working Tree

Basic Git workflow

Repository

WorkingTree

Changes from the working tree are not registered in the repository directly. Instead, they are registered in the Index. The other name for it is a „staging area”.

Basic Git workflow

Repository

WorkingTree

Index

Changes to the working tree are registered in the index using git add

Once the index contains everything you want to commit, you record the changes in the repository

Basic Git workflow

Repository

WorkingTree

Index

Changes to the working tree are registered in the index using

Changes are commited to the repository from the state of the index using

git commit

git add

git checkout

Basic Git workflow

Repository

WorkingTree

Index

Changes to the working tree are registered in the index using

Changes are commited to the repository from the state of the index using

Earlier states of the working tree may be checked out

from the repository at any time using

git commit

git add

Install Git:

1. Go to git-scm.com

2. Download installer and execute it

3. (IMPORTANT) In the Adjusting your PATH environmentselect first option „Use Git from Git Bash only”

4. For the rest of options you can leave default choices

Exercise #0

TODO:

1. Create an empty repository

2. Make changes in the file system and add to index

3. Commit

4. Make changes in the file system

5. Reset to the clean state

6. Make changes in the file system and add to the index

7. Commit

8. Diff between commits

9. Checkout the first commit

Exercise #1

Before we start we need to configure Git

Exercise #1

git config --global user.name "your-name"git config --global user.email "mail@youremail.com"

1. Create an empty repository locally

2. Make changes in the file system and add them to index

3. Commit

Exercise #1

git init .

echo ”first changes” > file1.txtecho ”a very important message” > file2.txtgit add .

git commit –m ”my first commit”

dot adds whole directory at

once

commit message is obligatory

4. Make changes in the file system

5. Reset only non-staged changes to the clean state (latest commit)

You can use instead of dot, a path to a specific file.

To reset working tree and index:

Exercise #1

echo ”foo foo bar bar” > file2.txtgit statusgit diff

git checkout .

git reset --hard HEAD

a name for the the latest checked out commit

6. Make changes in the file system and add them to the index

7. Commit

Current repository structure:

Exercise #1

echo ”second changes” > file1.txtgit add .

git commit -m ”my second commit”

my first commit

my second commit

HEAD

6. Diff between commits

7. Checkout the first commit

Current repository structure:

Exercise #1

git log --onelinegit diff 933734d f618b84

Your hash ids will be different

git checkout 933734d

my first commit

my second commit

HEAD

So what happens when you checkout a commit from a past, and make another commit?

Detached HEAD???

You are ending in the Detached HEAD state.

After some time such commits in the detached head can be pruned by the garbage collector and your work will be lost.

Detached HEAD???

This can be fixed, requires merging (sometimes a lot).

Golden rule: Always work on the latest commits.

Avoid detached HEADS. Use branches instead.

Detached HEAD???

A branch (reference, ref) is also another name of a commit. It is the name for the last commit in the line. By default, git creates master branch:

Branches

At each point you can easily create your new branch using following command:

Now we have two branches (pointing for the same commit):

Branches

git branch devel

Using branches you can for example store working releases of an application in a master branch and development line in devel one:

... let’s try them out!

Branches

TODO:

1. Create new branch

2. Commit changes

3. Create another branch

4. Diff between branches

5. Delete branch

Exercise #2

1. Create new branch

2. Commit changes

Current repository structure:

Exercise #2git checkout mastergit branch branch-1git checkout branch-1

echo ”b1” >> file1.txtecho ”foo bar bar” > file2.txtgit add .git commit -m ”b1”

my first commit

my second commit

master

b1

branch-1 HEAD

3. Create another branch

Current repository structure:

Exercise #2

git branch branch-2eit checkout branch-2echo ”b2” >> file1.txtgit add .git commit –m ”b2”

my first commit

my second commit

master

b1

branch-1

HEAD

b2

branch-2

4. Diff between branches

5. Delete branch

Current repository structure:

Exercise #2

git checkout mastergit branch -d branch-2

git diff branch-1 branch-2

my first commit

my second commit

master

b1

branch-1

HEAD

What to do when we want to join few different branches?

to the rescue!

Most common merge types:

Fast-forward merge

3-way merge

Rebase

Basic merging

git merge

Let’s assume we have the following repository structure:

We would like to merge

devel into master

Fast-Forward merge

Let’s assume we have the following repository structure:

We would like to merge

devel into master

Fast forward merge moves master pointer forward to the commit 4 and no new commit is created

Fast-Forward merge

Let’s assume we have the following repository structure:

We would like to merge

devel into master

3-way merge

Let’s assume we have the following repository structure:

We would like to merge

devel into master

With Git you can merge files containing conflicts (changed in commits 5 & 6), manually decide which changes should be applied and create merge commit (commit 6).

3-way merge

Let’s assume we have the following repository structure and we would like to merge feature into master:

With rebase you can apply commits from feature branch on top of master and preserve linear structure of repository.

Rebase

TODO:

1. Make a fast-forward merge

2. Undo ff-merge

3. Make commit on master

4. Make 3-way merge

5. Undo merge commit

6. Make rebase

Exercise #3

1. Make a fast-forward merge

Before After

Exercise #3

my first commit

my second commit

master

b1

branch-1

HEAD

my first commit

my second commit

master

b1

branch-1

HEAD

git checkout mastergit merge branch-1

2. Undo fast-forward merge

It moves the HEAD pointer back by 1 commit and resets working tree

3. Make commit on master

Exercise #3

my first commit

my second commit

master

b1 branch-1

HEAD

git reset --hard HEAD~1

echo ”a very unimportant message” > file2.txtgit add file2.txtgit commit -m ”m1”

m1

4. Make 3-way merge

We have merge confilct (contents of file2.txt):

After correcting file2.txt, execute following commands:

Exercise #3

git checkout mastergit merge branch-1git status

<<<<<<< HEADa very unimportant message=======foo bar bar>>>>>>> branch-1

git add file2.txtgit commit -m ”merge commit”

Current repository structure:

Exercise #3

my first commit

my second commit

master

b1

branch-1

HEAD

m1

merge commit

5. Undo 3-way merge

Repository structure after reset:

Exercise #3

my first commit

my second commit

master

b1 branch-1

HEAD

git reset --hard HEAD~1

m1

6. Make git rebase

We have merge confilct (contents of file2.txt):

After correcting file2.txt, execute following commands:

Exercise #3

git checkout branch-1git rebase master

<<<<<<< HEADa very unimportant message=======foo bar bar>>>>>>> branch-1

git add file2.txtgit rebase --continuegit checkout mastergit merge branch-1

Repository structure after rebase:

Exercise #3

my first commit

my second commit

master

b1

branch-1

HEAD

m1

Git remote repositories can be accessed via almost every protocol: SSH, HTTP(S), FTP, Local, Git...

You can clone remote repository using

You can publish your changes using

You can pull changes on remote to your local repo using

Remote repositories

git clone

git push

git pull

TODO:

1. Create new empty local repository

2. Copy local repository to a remote server

3. Add remote to your repository

4. Push changes to a remote repository

5. Clone remote repository

Exercise #4

1. Create new empty local repository

Create new directory with your last name and go there with git bash

2. Copy local repository to a remote serverCopy this directory to \\pol-mgalazyn\gw

3. Add remote to your repositoryNavigate using git bash to your repository from previous exercises

4. Push changes to a remote repository

Exercise #4

git init --bare

git remote add origin file:////pol-mgalazyn/gw/lastname

git push --set-upstream origin master

From now you can push commited changes to the remote using only:

5. Clone remote repositoryUsing git bash go to directory one level higher

Exercise #4

git push

git clone file:////pol-mgalazyn/gw/someoneslastname

GitLab configuration

(if you haven’t done it already)

TODO:

1. Generate SSH keys for authentication without password

When prompted for file to save key - confirm default value with Enter

When prompted for passphrase - leave empty

2. Paste SSH Public key into GitLab

a. Go to https://prod-pol-git/ and log in

b. Navigate to Profile settings > SSH Keys > Add SSH Key

c. Open with notepad file C:\Users\youruser\.ssh\id_rsa.pub

d. Copy its contents and paste to Key field in GitLab

e. Enter Title whatever you want and click Add Key

Exercise #5

ssh-keygen -t rsa

Honestly, I bet you were not convinced by Git Bash.

There are other more user-friendly options with GUI on the market:

SmartGit

EGit (Eclipse plugin)

TortoiseGit

SourceTree

... and many more

Graphical User Interface

Recap - command sequence

Questions?( you can always ask me directly or send an e-mail to:

mgalazyn@microstrategy.com )

git push –f overwrites the remote branch with the state of the branch you are pushing, so using it you can accidentally overwrite commits you want to keep

Don’t be scared of Git! :)