Git für Softwareentwickler

Rainer Stropek | time cockpit

rainer@timecockpit.com | Blog | GitHub

Agenda (German)

Git ist heute allgegenwärtig. Egal ob C#, Webseiten, DB-Code etc., mehr und mehr setzen auf die kostenfreie Quellcodeverwaltung. In dieser Session werden die Grundkonzepte von Git vorgestellt und erklärt, wie man in Github und VSTS seinen Quellcode professionell und ganz ohne Zusatzkosten verwalten kann. Der Vortrag ist speziell auf kleine Teams zugeschnitten, oder auch Freiberufler mit einer Hand voll Ansprechpartnern bei Kunden.

Getting Started

What is Git?

Source code management system
Originally developed by Linux kernel developers

  • Distributed version control
    Different devs work on a project without sharing a common network
  • Every Git directory is a fully-fledged repository
    Includes complete history and full version-tracking, can be moved
  • Various Git server implementations available
    E.g. GitHub, Visual Studio Team Services; public (often free) and private repsitories

Important characteristics of Git

  • Support non-linear development
    Brances are very lightweight, branching and merging happens often
  • Distributed development
    Local copy of entire history
  • Publishing of repositories over various protocols
  • Fast, even for large projects
  • Cryptographic authentication of history
    ID of a particular commit depends upon the complete development history
  • Cross-platform

Tools

More complete list of GUI clients.

Documentation

git help verb

Basic Operations

Basic configuration


# Get a list of config settings
git config --list

# Set identity
git config --global user.name "Rainer Stropek"
git config --global user.email rainer@timecockpit.com

# Set editor
git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -nosession"

# Set alias for git commands
git config --global alias.unstage 'reset HEAD --'

# Cache password in memory for 15 minutes
git config --global credential.helper cache
                    

git config
Details about Credential Storage

Getting Started


# Initializing a Repository in an Existing Directory -> note .git directory
git init

# Create a file -> UNTRACKED
echo Hello World > greet.txt

# Check status of git repo after each step with 'git status' or 'git status -s'
# Add the file to the repo -> STAGED
git add greet.txt

# Commit the changes -> UNMODIFIED
git commit -m "Add greeting"

# Change file -> MODIFIED, use 'git add' to save changes to repo
echo ! >> greet.txt

# Overwrite change with last version from repo -> UNMODIFIED
git checkout -- greet.txt
                    

git init, git status, git add, git commit, git checkout

Tips for adding changes

  • Use fileglobs (e.g. *.cs) for multiple files
  • Use directory names
  • --dry-run to see what would happen
  • Use git diff to see changes not yet staged
  • Use git diff --staged to see changes for next commit
  • Use .gitattributes file to customize text/binary detection
  • Use git difftool to change diff tool
    In practice, use a tool like VS for diffing

git add, git diff, git difftool

Ignoring files with .gitignore

  • Comments: # Nuget Packages
  • File or directory names: packages
  • Patterns: [Bb]in, [Tt]est[Rr]esult*
  • Wildcards: *fakes*
  • Comments: # Nuget Packages
  • Exceptions: !Gruntfile.js

*.js
![Gg]runtfile.js
                    

Try this example in command line and VS

Removing files


# Create two additional files and commit them

# Remove file
git rm file1.txt
git status
git commit -m "Delete file"

# Create addittional file and stage it
echo Hello > file3.txt
git add file3.txt
git status

# Remove file from staging area -> UNTRACKED
git rm --cached file3.txt
                    

git rm

Moving files


# Rename greet.txt to else.txt -> STAGED
git mv greet.txt else.txt
git add .
git commit -m "Rename"
git status

# Manual process. Note that this results in a STAGED rename, too
mv else.txt greet.txt
git rm else.txt
git add greet.txt
git status
git add .
git commit -m "Rename"
                    

git mv

Inspect commit history

  • git log -2 to view the last two commits (desc)
    Note sha1 hash of commits
  • -p switch shows differences
  • -p switch shows differences, --stat summary statistics
  • --pretty controls output (e.g. --pretty=oneline)

# Get log history and select a specific commit hash
git log -5

# Get specific commit (replace hash with your value!)
git checkout a0bd8

# Back to last commit
git checkout master
                    

git log
How to specify revisions and ranges

Undoing


# Create a new repo
git init
echo Hello World > greet.txt
echo Hello World 2 > greet2.txt
git add .
git commit -m "Initial"

echo ! >> greet.txt
git add .

# Add additional change to previous commit
git commit --amend
git log -p
                    

Undoing


# Create a new repo, create a file and change it three times
git init
echo . > demo.txt; git add demo.txt; git commit -m "Change 1";
echo . >> demo.txt; git add demo.txt; git commit -m "Change 2";
echo . >> demo.txt; git add demo.txt; git commit -m "Change 3";
git log --oneline --decorate

# Soft reset -> undo COMMIT
git reset --soft HEAD~
git log --oneline --decorate
type demo.txt
git status

# Now try the same with --mixed (default) -> undo COMMIT and ADD
# Now try the same with --hard -> undo COMMIT, ADD and local change
                    

git reset

Inspect commit history

  • git log -2 to view the last two commits (desc)
  • --since=[...] to view commits in a specific time period
  • -p switch shows differences
  • -p switch shows differences, --stat summary statistics
  • --pretty=[...] controls output (e.g. --pretty=oneline)

git log

Tagging

Lightweight (just pointer to a commit) and annotated
-a argument for git tag


# Open a repo that has some commits
# Create an annotated tag
git tag -a v1.0 -m "This is our initial release"

# Inspect tags
git tag
git tag -l "v1.*"
git show v1.0

# Create a tag for a previous commit (replace with your own commit hash)
git tag -a v0.9 -m "This was beta 1" a0b9f
git tag

# Get specific version
git checkout v0.9
                    

Tags are not automatically shared, need to explicitly push them
Details about pushing changes see later

git tag
How to specify revisions and ranges

Remote Repositories

What are remote repositories?

Git repositories stored on servers
E.g. GitHub, Visual Studio Team Services, Microsoft Azure App Services

Getting an existing repository


# Start in an empty directory
# Get existing code from GitHub
git clone https://github.com/rstropek/Samples.git
cd Samples

# View remotes
git remote -v
                    

git clone, git remote

Managing Remotes

Demo: Azure App Services Git integration


# Create new local repo and commit some changes (e.g. static HTML files)
# Add a remote
git remote add azure <path_to_azure_git>
git remote -v
git remote show azure

# Push changes
git push azure master
                    

git remote, git push

Managing Content

  • Use git fetch to fetch all changes into local repo
    Does not merge changes into your working directory.
  • Use git pull to fetch and merge.
  • Use git push to push your changes to remote repo
    See example on previous page

git fetch, git merge, git push

Pushing Tags


# Create remote repo (e.g. on GitHub) and push some changes
# Create a tag
git tag -a v1.0

# Push tag (use 'git push origin --tags' to push mulitple tags in one statement)
git push origin v1.0

# View tags in remote repo (e.g. on GitHub)
                    

git tag, git push

Branching and Merging

Branching Basics

Demo using Learn Git Branching

Branching Merging


# Create file.txt with two lines
git add .
git commit -m "Initial"

# Create feature branch
git checkout -b feature
# Change first line in file.txt and commit
                             
# Create feature branch
git checkout master
git checkout -b hotfix
# Change second line in file.txt and commit

# Merge with both branches -> results in conflict
git checkout master
git merge hotfix
git merge feature
git status

# Look in file.txt and resolve conflict
                    

Remote Branches

  • Local branches are not synchronized to remotes
  • Use git push <remote-name> <branche-name> to push a branch
  • Tracked branches: Local branches with a related remote branch
    E.g. origin/master after git clone
  • Get list of tracked branches with git branch -vv
  • Delete server branch with git push origin --delete <branch-name>

git push, git clone, git branch

Rebase Basics

Demo using Learn Git Branching

Details about rebasing

Demos

Thank you for attending!

See you next SNEK!