1 of 62

How not to be a Git

Tips and tricks for a good workflow

2 of 62

Who am I?

3 of 62

What is a Git?

  1. A distributed revision control and source code management (SCM) system with an emphasis on speed, data integrity, and support for distributed, non-linear workflows.
  2. A mild profanity with origins in British English for a silly, incompetent, stupid, annoying, senile, elderly or childish person.

4 of 62

Still lost?

5 of 62

Microsoft + GitHub

6 of 62

Still lost?

7 of 62

Let’s start with tips

8 of 62

Listing tracked files

List all tracked files

$ git ls-files

List all tracked files in a given branch

$ git ls-tree -r <branch> --name-only

9 of 62

Ignoring tracked files

First we need to remove the file from Git

$ git rm --cached <filename>

Then add the file to the ignore file

$ echo ‘filename’ >> $projectRoot/.gitignore

10 of 62

Ignoring tracked files

$ git update-index --assume-unchanged <filename>

To tell git to ignore changes to a file, but not delete it, run:

11 of 62

Ignoring files

Use Global Gitignore files� $ git config --global core.excludesfile ~/.gitignore_global

Good starter: https://gist.github.com/octocat/9257657

Gitignore templates: https://www.gitignore.io/

12 of 62

Ignoring files for a repo

Add the file(s) name to .git/info/exclude

NOTE: This only affects that repository, and should only be used for files you don’t want in the repos ignore file.

13 of 62

Always name remotes

When doing pushes or pulls always name the remote server and branch.

$ git pull <remote> <branch>

$ git push <remote> <branch>

14 of 62

But that is hard!

  • That is extra typing that I have to do!
  • I only ever work with one remote/branch anyways!
  • etc...

15 of 62

Solution

function current_branch() {

ref=$(git symbolic-ref HEAD 2> /dev/null) || \

ref=$(git rev-parse --short HEAD 2> /dev/null) || return

echo ${ref#refs/heads/}

}

# these aliases take advantage of the previous function

alias ggpull='git pull origin $(current_branch)'

alias ggpur='git pull --rebase origin $(current_branch)'

alias ggpush='git push origin $(current_branch)'

16 of 62

Autocorrect

$ git plush origin master�git: 'plush' is not a git-command.

See 'git --help'.��Did you mean this?� push

17 of 62

To have Git fix this

$ git config --global help.autocorrect = 1

18 of 62

Removing whitespace

Create a $HOME/.config/git/attributes file and add:

* filter=trimWhitespace

19 of 62

Removing whitespace

Next we need to tell Git about this filter

$ git config --global filter.trimWhitespace.clean trim_whitespace

20 of 62

Removing whitespace

Now create the “trim_whitespace” command

#!/usr/bin/env ruby� lines = STDIN.readlines� lines.each do |line|� puts line.rstrip� end

21 of 62

Prettier log output

Add the following to $~/.gitconfig under the [alias] section

lg = log --color --graph \ --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --

22 of 62

What does that do

* aba0786 - (HEAD -> master, origin/master, origin/HEAD) correctly target flexbox from view (46 minutes ago) <Lee Walker>

* 86c5c99 - Updated ...block--field-social-source.tpl.php (19 hours ago) <Adam Jimerson>

23 of 62

Another log

alias glogf='git log --graph --color'

24 of 62

What does that do?

* commit 437a491f99f30e14ecb63af6f07e540af3fd9e00

|\ Merge: 770a155 defc9bd

| | Author: John Smith <jsmith@example.com>

| | Date: Thu Aug 13 16:15:22 2015 -0400

| |

| | Merge branch 'master' of ssh://codeserver.dev.6ad151bf-f855-4e85-b698-52983a55a2d2.drush.in:2222/~/repository

25 of 62

Diffing for Humans

Diff-So-Fancy: https://github.com/so-fancy/diff-so-fancy

$ git diff --color | diff-so-fancy

OR

$ git config --global interactive.diffFilter = ‘diff-so-fancy’

(Requires Git 2.[6,7,8])

26 of 62

What it looks like

27 of 62

Handling multiple emails

  • What if you have repos you need associated with different email addresses?
  • Edit .git/config file for each repository manually
  • Create a Git command to set email addresses for you.

28 of 62

Profile command

In the global Git config file add the following under the [alias] tag

workprofile = config user.email \"adam@codejourneymen.com\"

Then run

$ git workprofile

29 of 62

Speed up slow net

If you have problems with slow network connections. Edit ~/.ssh/config add:

ControlMaster auto� ControlPath /tmp/%r@%h:%p� ControlPersist yes

30 of 62

Stop working around Git

Git implements several commands that interact with the filesystem as well as its own tracking info.

  • mv => git mv
  • rm => git rm

31 of 62

Moving files

$ git mv <oldFilename> <newFilename>

is the same as

$ mv <oldFilename> <newFilename>

$ git add <newFilename>

32 of 62

Removing files

$ git rm <filename>

is the same as

$ rm <filename>

$ git rm <filename>

33 of 62

Recovering/Restoring Files

Discarding changes

$ git checkout <file>

Rolling a file back

$ git checkout master~N <file>

Working on all files with a certain extension

$ git checkout -- ‘*.php’

34 of 62

Copying files from one branch to another

To copy files or directories from one branch to the current branch

$ git checkout <branch> -- <file>

35 of 62

And now for something completely different...

36 of 62

Branching

  • How to work with �branches.
  • Why you should work�with branches.

37 of 62

What is a branch anyways?

A branch is a copy

of the code base, where

changes can be made

that doesn’t affect copies.

*Very simple explanation

38 of 62

Listing branches

Using the branch command with no arguments

displays a list of branches and marks the current branch

$ git branch

develop

*master

39 of 62

Creating branches

Create a new branch by giving a single argument to branch

$ git branch <name>

40 of 62

Switching branches

To switch branches give the name of the branch as an argument to checkout

$ git checkout <branch_name>

41 of 62

Doing both at once

To create and switch to the branch

$ git checkout -b <name>

42 of 62

Deleting a branch

To delete a branch after it has been merged

$ git branch -d <name>

To delete a branch without merging

$ git branch -D <name>

43 of 62

Recovering deleted branch

$ git reflog

793d399 HEAD@{0}: rebase finished: returning to refs/heads/develop�793d399 HEAD@{1}: rebase: checkout feature/test2�2d1a343 HEAD@{2}: checkout: moving from feature/test2 to develop�793d399 HEAD@{3}: checkout: moving from feature/test1 to feature/test2

$ git checkout -b <branch> HEAD@{N}

44 of 62

Working with branches

  • Separate code changes when adding a feature or making a change.
  • Easier context switches.

45 of 62

Squashing commits

Say you have two commits that really should have been one. What can you do?

46 of 62

Word of warning

Don’t do the following if a push has been done between the commits being squashed/merged.

If you do try this things are guaranteed to break.

47 of 62

Word of warning

48 of 62

git commit --amend

$ git add file1 file2� $ git commit -m 'Adding some files'

...� $ ls� file1 file2 file3

49 of 62

git commit --amend

$ git add file3

$ git commit --amend

50 of 62

Merging commits

$ git rebase --interactive HEAD~2

51 of 62

Warning about rebase

  • Rebasing alters the history of the repository.
  • Constantly mixing merges and rebases can cause issues with upstream repos.

52 of 62

Yay visuals!

53 of 62

Rebasing commits

54 of 62

Merging branches

$ git checkout <branch to merge into>

$ git merge <branch to merge>

55 of 62

Merging branches

56 of 62

Rebasing branches

$ git checkout <branch to merge into>

$ git rebase <branch to merge>

57 of 62

Rebasing branches

58 of 62

Merging vs Rebasing

  • There are two camps about this matter.
  • Merging keeps the commit structure (branch info) intact, but creates empty commits.
  • Rebasing flattens the commit structure, and avoids creating empty commits.

59 of 62

Finding bugs (and who introduced them)

Useful Git tools:

  • git bisect
  • git blame

60 of 62

Git Bisect

$ git bisect start <bad> <good>

$ git bisect bad or $ git bisect good

$ git bisect reset

This is just the start of what bisect can do!

61 of 62

Git Blame

$ git blame <file or commit SHA>

62 of 62

Thank you!