Upgrade to Pro — share decks privately, control downloads, hide ads and more …

git for smartasses

git for smartasses

A continuation of my internal presentation at Celtra Technologies Inc.

Klemen Slavič

July 30, 2012
Tweet

More Decks by Klemen Slavič

Other Decks in Programming

Transcript

  1. GIT FOR
    SMARTASSES

    View full-size slide

  2. SCRIPTING GIT
    You can execute operations on a git repository
    without cd-ing into it. You can specify it using
    the $GIT_DIR or --git-dir options:
    • GIT_DIR=~/myproject/.git \
    git
    You can also specify a dislocated work tree
    using $GIT_WORK_TREE or --work-tree.

    View full-size slide

  3. WALKING AROUND WITH
    A DETACHED HEAD
    Checking out a revision results in a detached
    head state. This means that the current
    working copy isn‘t the HEAD revision of any
    named branch.
    To create a branch at that point, simply:
    • git checkout -b new-branch-name

    View full-size slide

  4. SHORTCUTS
    • HEAD always refers to the current branch‘s
    last commit
    • ^ means one commit before the preceding
    • ~n means n commits before
    Examples:
    • git checkout HEAD^^^

    View full-size slide

  5. MOAR SHORTCUTS
    Get an object prior to a point in time:
    • @{}
    Find the first object preceding another object:
    • ^{}
    Find the first object that contains a message:
    • ^{/}
    Find the youngest commit by message:
    • :/

    View full-size slide

  6. EVEN MOARER SHORTCUTS
    • man gitrevisions

    View full-size slide

  7. SEARCHING FOR COMMITS
    You can use regexes to search commit
    messages:
    • git log -E --grep='(fuck|shit)'
    More filtering options:
    • git help log

    View full-size slide

  8. SPECIFYING RANGES
    List commits reachable from r2 but not from
    r1:
    • git log ^r1 r2
    • git log r1..r2
    To get a list of commits that are reachable by
    either but not both:
    • git log r1 r2 --not
    • git log r1...r2

    View full-size slide

  9. „WAS THIS MERGED?“
    To get a list of commits not yet in master:
    • git log feature-branch ^master
    Outgoing changes?
    • git fetch
    • git log ^origin/master master
    Incoming?
    • git fetch
    • git log origin/master ^master

    View full-size slide

  10. BONUS: GIT CHERRY
    Get all commits not merged upstream (usually
    origin/master):
    • git cherry [ []]
    This is essentially a log of outgoing commits.

    View full-size slide

  11. HAVE YOU EVER
    DONE THIS?
    $ git history
    * 23e0ccc Klemen Slavič (2 seconds ago): If this doesn't work, I quit
    * e8782f5 Klemen Slavič (35 seconds ago): Reverting commit 8f314b9
    * 8f314b9 Klemen Slavič (60 seconds ago): Really really fixes #313
    * 9e7b3d6 Klemen Slavič (78 seconds ago): FOR FUCK'S SAKE I MUST BE BLIND
    * 6e410ba Klemen Slavič (2 minutes ago): FML, Samsung won't cooperate
    * fdc13c4 Klemen Slavič (2 minutes ago): Whoops, forgot to add dependency
    * 046e13b Klemen Slavič (2 minutes ago): Resolves issue #313
    * ca59d46 Klemen Slavič (2 hours ago): Added greeting
    * 310008b Klemen Slavič (3 hours ago): Initial commit
    Wish you hadn‘t?

    View full-size slide

  12. AMENDING A COMMIT
    After commiting a faulty commit, modify the
    working copy and stage the changes:
    • git add .
    Commit the changes using the --amend option:
    • git commit --amend
    Don‘t amend a commit you‘ve already pushed.
    Unless you know what you‘re doing.

    View full-size slide

  13. INTERACTIVE ADDING
    If you happen to have applied two or more
    fixes in one go, you can pick and choose
    individual hunks to stage them for commits:
    • git add -i

    View full-size slide

  14. DEMO:
    INTERACTIVE ADDING

    View full-size slide

  15. FORENSIC INVESTIGATION:
    PINPOINTING FAILURES
    Git provides the bisect command which helps
    you search for changes that introduced a bug.
    • git bisect start
    • git bisect bad
    • git bisect good d34db33f
    • ... git checks out out next revision, test...
    • git bisect (good|bad)
    • git bisect reset

    View full-size slide

  16. AUTOMATIC PERSONELL
    EXECUTION ON BUILD FAIL
    If you have test scripts available, you can use
    bisect to automate this:
    • git bisect run script [arguments]
    If the script exits with a 0, the revision is
    marked as good, otherwise a code between 1
    and 127 means bad. 125 means untestable.
    After finding the commit, run
    server/bin/execute [username] to notify the
    firing squad.

    View full-size slide

  17. REVERTING A COMMIT
    To undo the effects of a commit in history, use
    the revert command:
    • git revert (|...)
    This creates a new commit that applies an
    inverse patch of all the listed commits.
    Sometimes it‘s preferable to take out the merge
    commit instead of re-reverting it.

    View full-size slide

  18. RESETTING
    Resetting moves the branch pointer to the
    given SHA-1 hash, effectively leaving behind a
    dangling branch:
    • git reset --hard
    You can then create a named branch:
    • git checkout -b
    This is the preferred way of reverting a merge.
    This modifies history, think before pushing!

    View full-size slide

  19. CHANGING HISTORY

    View full-size slide

  20. FORCE PUSHING

    View full-size slide

  21. FORCE PUSHING
    If for some reason you‘d like to overwrite
    history on the remote, use the force flag:
    • git push origin branch-name -f
    DO NOT DO THIS!
    This overwrites all history for the pushed branch,
    effectively obliterating anything on the remote
    your history does not already contain.

    View full-size slide

  22. SERIOUSLY, DON‘T.

    View full-size slide

  23. RECOVERING FROM A
    CATASTROPHIC FUCKUP
    So you didn‘t heed my warning and force pushed
    modified history or deleted your own.
    Don‘t panic.
    Every git operation is logged in the reflog and
    can be navigated by simply checking out the
    logged history. Just don‘t run git gc.

    View full-size slide

  24. REMINISCING ON YOUR
    PAST TRANSGRESSIONS
    To see a log of operations applied to your
    repository in the past few days:
    • git reflog [log options] [--verbose]
    You can then use git reset to return to the state
    at the moment you decided that drinking a
    bottle of absinthe yourself merging an
    unfinished branch was a good idea.

    View full-size slide

  25. THE GHOSTS OF
    CHRISTMAS PAST
    Ever dropped, reset or lost a commit? Not to
    worry. Git fuck fsck to the rescue:
    • git fsck
    To idenfity dropped stashes:
    • git fsck --unreachable | \
    grep commit | cut -d\ -f3 | \
    xargs git log --merges --no-walk --grep=WIP

    View full-size slide

  26. DEMO: RECOVERING FROM
    AN EPIC FAIL

    View full-size slide

  27. CODE SURGERY
    (TOILET/SMOKE BREAK)

    View full-size slide

  28. CREATING AND APPLYING
    PATCHES
    To make a series of patches from commits:
    • git format-patch [|]
    selects all commits from that commit
    up to the current revision (even if detached).
    To apply a patch:
    • git am < 0001-commit-message

    View full-size slide

  29. CHERRYPICKING COMMITS
    Cherrypicking is essentially just an automated
    way of creating patches out of commits and
    applying them to the current branch as
    commits.
    • git cherry-pick (|...) \
    [--edit] [-x] [--no-commit]
    For each merge conflict, resolve and run:
    • git cherry-pick --continue

    View full-size slide

  30. CHERRYPICKING EXAMPLE
    To forward-port code from legacy to master:
    • git checkout master
    • git cherry-pick ^master legacy -x
    This creates one commit per cherrypicked
    commit. If you want a single commit:
    • git cherry-pick ^master legacy -n
    • (review, edit and TEST!)
    • git commit

    View full-size slide

  31. BONUS: COPY CONTENTS
    OF A FILE FROM A BRANCH
    If you want to overwrite a file‘s contents with a
    specific commit or branch, you can check out
    that file directly:
    • git checkout my-branch -- ...
    • git add .
    • git commit

    View full-size slide

  32. REBASING
    A cut-and-paste operation that takes a range
    of commits and appends them to the target.
    It‘s like merging, but avoids merge commits in
    favour of a more linear history.
    Works exactly like cherry-pick, but can be used
    automatically when pulling changes from
    upstream.

    View full-size slide

  33. REBASING
    00 01 02
    03 04
    new-feature
    master

    View full-size slide

  34. REBASING
    00 01 02
    05 06
    new-feature
    master

    View full-size slide

  35. REBASING A BRANCH
    You‘re working on a branch and need to sync
    with upstream. No worries:
    • git rebase
    You can do the same if you‘re working on the
    same branch and pulling from remote:
    • git pull origin my-branch --rebase
    This will only rebase outgoing commits onto
    the appended upstream history.

    View full-size slide

  36. A CAUTIONARY TALE
    DANGER, WILL ROBINSON, DANGER!
    Avoid rebasing a branch that has another
    branch attached.
    Rebasing the base branch will rebase that
    branch but leave the other unchanged
    (duplicated history).
    You need to rebase that branch separately to
    avoid duplicating and mangling history for
    everyone.

    View full-size slide

  37. AUTOMATICALLY REBASING
    WHEN PULLING
    Git can be configured to automatically rebase
    instead of merge.
    This avoids merge commits each time
    someone pushes to the same branch.
    • git config branch.autosetuprebase always
    • git config branch..rebase true
    • git pull origin my-branch
    Caution. May cause cancer.

    View full-size slide

  38. NOT FOR THE
    FAINT OF HEART
    https://github.com/aanand/git-up

    View full-size slide

  39. ADVANCED REBASE:
    SPLITTING BRANCHES
    Say you have the following situation:
    00 01 02
    03 04
    master
    05 06
    new-feature bugfix
    Problem is, you need bugfix in master before new-feature.

    View full-size slide

  40. ADVANCED REBASE:
    SPLITTING BRANCHES
    git rebase --onto master bugfix new-feature
    00 01 02
    03 04
    master
    07 08
    new-feature
    bugfix

    View full-size slide

  41. ADVANCED REBASE:
    SPLICING COMMITS
    Say 01-02 are commits that don‘t belong in
    master.
    00 01 02 03 04
    master

    View full-size slide

  42. ADVANCED REBASE:
    SPLICING COMMITS
    git rebase --onto 00 02 master
    00 05 06
    01 02
    master
    This will produce dangling commits that we
    can use to create a branch with:
    • git checkout -b spliced 02

    View full-size slide

  43. SKILL LEVEL ASIAN:
    INTERACTIVE REBASING

    View full-size slide

  44. SKILL LEVEL ASIAN:
    INTERACTIVE REBASING
    $ git rebase -i
    pick 7f3019b Removed APASUT overrides from all SDKs
    pick f83aba2 Added APASUT flag to all SDKs
    pick 5c335bc Flag checking
    pick 8363137 typo
    # Commands:
    # p, pick = use commit
    # r, reword = use commit, but edit the commit message
    # e, edit = use commit, but stop for amending
    # s, squash = use commit, but meld into previous commit
    # f, fixup = like "squash", but discard this commit's log message
    # x, exec = run command (the rest of the line) using shell

    View full-size slide

  45. SKILL LEVEL ASIAN:
    SQUASHING COMMITS
    You would like to squash the last 3 commits
    into a single commit.
    $ git rebase -i HEAD~3
    pick 01 Added README
    squash 02 Added heading
    squash 03 Added first paragraph

    View full-size slide

  46. SKILL LEVEL ASIAN:
    SQUASHING COMMITS
    Alternatively, you can use fixup to discard
    subsequent commit messages without editing.
    $ git rebase -i HEAD~3
    pick 01 Resolves 404 errors
    fixup 02 Forgot to update config
    fixup 03 Fixes glitch on Samsung

    View full-size slide

  47. GRAMMAR NAZI MANUAL:
    FIXING COMMIT MESSAGES
    You would like to fix the commit messages for
    the last 3 commits.
    $ git rebase -i HEAD~3
    reword 01 Added you‘re keyring
    reword 02 Fcuk u Smasung!
    reword 03 fixed alot of bugz

    View full-size slide

  48. DEMO:
    INTERACTIVE REBASING

    View full-size slide

  49. CONGRATS.
    YOU KNOW GIT FU.

    View full-size slide