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

Getting more from Git

Getting more from Git

I gave this talk at #FFconf in Brighton in November 2019.
This talk covers:
- What is "good" for Git?
- Why are we not very good at Git?
- A bit of history about Git. Who is she? Where did she come from?
- Some tips for using Git - --patch adding, --amending, using reset and rebase.

Alice Bartlett

November 08, 2019
Tweet

More Decks by Alice Bartlett

Other Decks in Technology

Transcript

  1. Alice Bartlett
    Principal Engineer, Customer Products team
    @alicebartlett
    Getting more
    from Git

    View full-size slide

  2. @alicebartlett
    This talk is about Git

    View full-size slide

  3. @alicebartlett
    I have some humble ambitions

    View full-size slide

  4. @alicebartlett
    1. Let’s all get a bit better at Git
    2. Let’s have an interesting 40 minutes

    View full-size slide

  5. @alicebartlett
    I think we could all do better with our
    Git mastery. To understand what “bad”
    looks like, I have found someone to
    make an example of

    View full-size slide

  6. @alicebartlett
    Me

    View full-size slide

  7. @alicebartlett
    Let’s look at my commits from
    ten years ago…

    View full-size slide

  8. @alicebartlett

    View full-size slide

  9. @alicebartlett
    This is the codebase for the FT’s web
    app. It is 9 years old, and still going
    strong.

    View full-size slide

  10. @alicebartlett
    204 lines of
    code added

    View full-size slide

  11. @alicebartlett
    and the commit
    message reads only:
    “sqlite stuff”

    View full-size slide

  12. @alicebartlett

    View full-size slide

  13. @alicebartlett
    if (false && window.history.pushState) {

    }

    View full-size slide

  14. @alicebartlett
    “Fixes to download”

    View full-size slide

  15. @alicebartlett
    ¯\_(ツ)_/¯

    View full-size slide

  16. @alicebartlett
    So that is what bad looks like

    View full-size slide

  17. @alicebartlett
    What are we aiming for?

    View full-size slide

  18. @alicebartlett
    1. Atomic commits
    2. Meaningful commit messages

    View full-size slide

  19. @alicebartlett
    What are “atomic commits”?

    View full-size slide

  20. @alicebartlett
    One commit per unit of change

    View full-size slide

  21. @alicebartlett
    A style change

    View full-size slide

  22. @alicebartlett
    A whitespace refactor
    A style change

    View full-size slide

  23. @alicebartlett
    A whitespace refactor
    A bug fix (and updated tests)
    A style change

    View full-size slide

  24. @alicebartlett
    A commit should be a single unit of work

    View full-size slide

  25. @alicebartlett
    It should make sense in isolation

    View full-size slide

  26. @alicebartlett
    Then your Git history becomes the story
    of your project, added to incrementally

    View full-size slide

  27. @alicebartlett
    The other thing is commit messages

    View full-size slide

  28. @alicebartlett
    Update link style
    User research showed that
    many people did not spot
    links in the copy. This
    commit updates the link style
    to the new underlined style
    which performed better.

    View full-size slide

  29. @alicebartlett
    // Scannable summary
    // Body that
    // explains
    // *why*
    Update link style
    User research showed that
    many people did not spot
    links in the copy. This
    commit updates the link style
    to the new underlined style
    which performed better.

    View full-size slide

  30. @alicebartlett
    WHY

    View full-size slide

  31. @alicebartlett
    Fixes to download

    View full-size slide

  32. @alicebartlett
    Fix background download
    There is a bug in the
    window.history.pushState
    implementation in Android Honeycomb
    so always use the location hash
    instead until that is fixed.

    View full-size slide

  33. 2. What is Git
    3. Tips for rewriting your Git history
    1. Why should you care

    View full-size slide

  34. 2. What is Git
    3. Tips for rewriting your Git history
    1. Why should you care

    View full-size slide

  35. @alicebartlett
    As you know, Git is a program that runs
    on your computer

    View full-size slide

  36. @alicebartlett
    You use it to manage the process of
    writing code

    View full-size slide

  37. @alicebartlett
    You use it to tell the story of your
    project

    View full-size slide

  38. @alicebartlett
    As engineers, there are lots of things we
    do to manage our codebases

    View full-size slide

  39. @alicebartlett
    1. Bikeshed over naming things

    View full-size slide

  40. @alicebartlett
    1. Bikeshed over naming things
    2. Write documentation

    View full-size slide

  41. @alicebartlett
    1. Bikeshed over naming things
    2. Write documentation
    3. Refactor

    View full-size slide

  42. @alicebartlett
    1. Bikeshed over naming things
    2. Write documentation
    3. Refactor
    4. Write tests
    5. … etc

    View full-size slide

  43. @alicebartlett
    None of these things are necessary to
    ship a feature. But they are necessary
    for helping other people understand our
    code and maintain it.

    View full-size slide

  44. @alicebartlett
    Git commit histories are part of
    this picture

    View full-size slide

  45. @alicebartlett
    Your commits, if you do them well,
    offer unique benefits over other
    ways of explaining your code:

    View full-size slide

  46. @alicebartlett
    1. They never change

    View full-size slide

  47. @alicebartlett
    1. They never change
    2. They live alongside your code

    View full-size slide

  48. @alicebartlett
    1. They never change
    2. They live alongside your code
    3. They’re searchable with Git grep

    View full-size slide

  49. @alicebartlett
    1. They never change
    2. They live alongside your code
    3. They’re searchable with Git grep
    4. They allow you to document your
    change at the time that you made it

    View full-size slide

  50. @alicebartlett
    1. They never change
    2. They live alongside your code
    3. They’re searchable with Git grep
    4. They allow you to document your
    change at the time that you made it
    5. They are hosting independent

    View full-size slide

  51. @alicebartlett
    Public Service Announcement:
    Stop putting all the information
    about a change in GitHub pull
    requests.

    View full-size slide

  52. @alicebartlett
    Public Service Announcement:
    Stop relying on linking to tickets for
    context.

    View full-size slide

  53. @alicebartlett
    PUT IT IN THE
    COMMIT
    MESSAGE

    View full-size slide

  54. @alicebartlett
    My second reason you should care about
    writing good commits is: it will make you
    a better software developer

    View full-size slide

  55. @alicebartlett
    Firstly, you’ll able to debug things
    quicker because your project will have a
    searchable history

    View full-size slide

  56. @alicebartlett
    Secondly, in order to write down why
    you introduced a change to a codebase,
    you have to actually understand why
    you introduced a change

    View full-size slide

  57. @alicebartlett
    Explaining why is an important thing to
    do as an engineer — it forces you to
    understand things you could otherwise
    have gotten away with not
    understanding

    View full-size slide

  58. @alicebartlett
    One of the reasons little
    baby me found writing
    good commits hard was
    that when I started
    writing code, a lot of my
    process was “try things
    until it works”

    View full-size slide

  59. @alicebartlett
    This meant it took me a lot longer to
    gain a deeper understanding of how
    things work

    View full-size slide

  60. @alicebartlett
    Taking the time to figure out why
    something works is a good investment
    in your future

    View full-size slide

  61. 1. Why should you care?
    • The code is better - which is better for you
    because you have to maintain it
    • It makes you smarter

    View full-size slide

  62. 2. What is Git
    3. Tips for rewriting your Git history
    1. Why should you care

    View full-size slide

  63. @alicebartlett
    Did you know that before Git, we all
    using other version control systems?

    View full-size slide

  64. @alicebartlett
    Linus Torvalds developed Git in 2005 to
    manage development of the Linux
    Kernel.

    View full-size slide

  65. @alicebartlett
    Before we get into this, let’s just talk
    about Linus.

    View full-size slide

  66. Alice Bartlett
    http://somewebsite.com
    Linus
    Torvalds

    View full-size slide

  67. @alicebartlett
    He is known for emails to the Linux mailing list
    containing comments that I don’t want to
    repeat here but they are very very unpleasant

    View full-size slide

  68. @alicebartlett
    Part of Linus’s personal brand is that he
    is very smart

    View full-size slide

  69. @alicebartlett
    When he created Git, it was described as
    a tool expressly designed to make you
    feel less intelligent than you thought you
    were

    View full-size slide

  70. @alicebartlett
    Up until 2005, Linux
    development had used a
    version control system
    called BitKeeper, and
    prior to that, they just
    emailed tarballs around

    View full-size slide

  71. @alicebartlett
    The creation of Git was a bit dramatic

    View full-size slide

  72. @alicebartlett
    BitKeeper was a closed source
    proprietary version control system

    View full-size slide

  73. @alicebartlett
    There was a free to use client, but it was
    closed source too.

    View full-size slide

  74. @alicebartlett
    One of the Linux contributors, Andrew
    Tridgell, decided to create an open
    source BitKeeper client as he didn’t
    think it was right to use a closed source
    client to work on an open source project

    View full-size slide

  75. @alicebartlett
    This upset the BitKeeper team, who
    then revoked access to their free to use
    client

    View full-size slide

  76. @alicebartlett
    Which meant development on the Linux
    kernel had to pause while a new version
    control system was found

    View full-size slide

  77. @alicebartlett
    In a talk two years later, Linus called
    Tridgell “stupid and ugly” for doing this

    View full-size slide

  78. @alicebartlett
    So Linus creates Git - he knows a lot
    about file system performance so he’s
    able to make it about an order of
    magnitude faster than its competitors
    across lots of operations — reading,
    committing and diffing

    View full-size slide

  79. @alicebartlett
    Incidentally, the version
    control system for Git is
    (obviously) Git.

    View full-size slide

  80. @alicebartlett
    The world’s first ever Git commit
    message is in the Git repository…

    View full-size slide

  81. @alicebartlett
    https://github.com/git/git/commit/
    e83c5163316f89bfbde7d9ab23ca2e25604af290
    Initial revision of
    "git", the information
    manager from hell
    Linus Torvalds, 7 Apr 2005

    View full-size slide

  82. @alicebartlett
    Git was a big paradigm shift

    View full-size slide

  83. @alicebartlett
    So much so, that thinking about how
    things used to be now is actually quite
    confusing

    View full-size slide

  84. @alicebartlett
    Let’s take a quick look at
    some of the ways Git was
    really different from CVS
    and Subversion, two
    popular alternatives back
    In 2005

    View full-size slide

  85. @alicebartlett
    One of the design choices for Git which
    is very different to its major competitors
    is that it is distributed

    View full-size slide

  86. @alicebartlett
    Git CVS and SVN

    View full-size slide

  87. @alicebartlett
    Git CVS and SVN

    View full-size slide

  88. @alicebartlett
    • No network connection needed

    View full-size slide

  89. @alicebartlett
    • No network connection needed
    • Common operations like committing are
    quicker

    View full-size slide

  90. @alicebartlett
    • No network connection needed
    • Common operations like committing are
    quicker
    • You can try things in private

    View full-size slide

  91. @alicebartlett
    • No network connection needed
    • Common operations like committing are
    quicker
    • You can try things in private
    • There is no single point of failure because
    there’s no central server

    View full-size slide

  92. @alicebartlett
    • No network connection needed
    • Common operations like committing are
    quicker
    • You can try things in private
    • There is no single point of failure because
    there’s no central server
    • Much easier to give people access to noodle
    around

    View full-size slide

  93. @alicebartlett
    Decentralised was radical at the time.

    View full-size slide

  94. @alicebartlett
    In 2007, Linus gave a talk at Google
    about Git and the benefits of distributed
    version control and he got about three
    questions that were all variations of…

    View full-size slide

  95. @alicebartlett
    “Isn’t distributed code bad actually?”

    View full-size slide

  96. Joel Spolksy speaking in 2010
    https://www.joelonsoftware.com/2010/03/17/distributed-version-control-is-here-to-stay-baby/
    “Possibly the biggest
    advance in software
    development
    technology in the
    [past] ten years”

    View full-size slide

  97. @alicebartlett
    Another thing Git does amazingly well is
    branching

    View full-size slide

  98. @alicebartlett
    In both CVS and SVN, branching was
    incredibly tedious

    View full-size slide

  99. @alicebartlett
    All branches existed in a global
    namespace, you couldn’t have a little
    private branch to do your experiments
    on

    View full-size slide

  100. @alicebartlett
    Branches were considered a really
    advanced technique in CVS and SVN, so
    most people just didn’t use them.

    View full-size slide

  101. @alicebartlett
    If you’re not using branches though
    revising your history becomes super
    annoying for your colleagues who will
    already have your first set of changes

    View full-size slide

  102. @alicebartlett
    If you're not using branches, and you
    only have a central repository,
    committing becomes really difficult
    because all the tests have to pass, and
    the commit must make sense in
    isolation

    View full-size slide

  103. @alicebartlett
    So things like atomic commits are not
    possible unless you get things right first
    time!

    View full-size slide

  104. @alicebartlett
    OK so — we agree:
    1. Doing version control properly is
    important
    2. Git is really good, actually.

    View full-size slide

  105. @alicebartlett
    Why are we so bad at Git?

    View full-size slide

  106. @alicebartlett
    Firstly, it is hard to use

    View full-size slide

  107. @alicebartlett

    View full-size slide

  108. @alicebartlett
    Jargon

    View full-size slide

  109. @alicebartlett
    Branches, commits, trees, repositories,
    working tree, staging, remotes, the
    stash, cherry picking, hunks, rebasing...

    View full-size slide

  110. @alicebartlett
    You are in a detached HEAD state

    View full-size slide

  111. @alicebartlett
    So to figure this stuff out you have to go
    read the manual. But the manual is also
    really confusing!

    View full-size slide

  112. @alicebartlett
    Update remote refs with
    associated changes

    View full-size slide

  113. @alicebartlett
    That’s the description for Git push!

    View full-size slide

  114. @alicebartlett
    https://git-man-page-generator.lokaltog.net/

    View full-size slide

  115. @alicebartlett

    View full-size slide

  116. @alicebartlett
    This is why we’re so bad at Git. Because
    its user interface is badly designed.

    View full-size slide

  117. 2. What is Git?
    • A version control system created to manage
    the Linux kernel
    • Radically different to pre-existing version
    control systems
    • Bad user interface

    View full-size slide

  118. 2. What is Git?
    3. Tips for rewriting your Git history
    1. Why should you care

    View full-size slide

  119. @alicebartlett
    Here is what we’re aiming for...

    View full-size slide

  120. @alicebartlett
    1. Atomic commits
    2. Meaningful commit messages

    View full-size slide

  121. @alicebartlett
    Start End

    View full-size slide

  122. @alicebartlett
    Start End
    Start End

    View full-size slide

  123. @alicebartlett
    1.git add --patch
    2.git commit --amend
    3.git reset [sha]

    View full-size slide

  124. @alicebartlett
    Unfortunately I’m going to have to
    explain some jargon here…

    View full-size slide

  125. @alicebartlett
    In Git there are three data structures
    that represent your work

    View full-size slide

  126. @alicebartlett
    // Working directory

    View full-size slide

  127. @alicebartlett
    // Working directory
    // Staging index

    View full-size slide

  128. @alicebartlett
    // Working directory
    // Staging index
    // Commit history

    View full-size slide

  129. @alicebartlett
    Every commit has a
    parent which it points to

    View full-size slide

  130. @alicebartlett
    git add
    git add --patch

    View full-size slide

  131. @alicebartlett
    Before you can commit something, you
    have to add it to the list of things you
    want to commit.

    View full-size slide

  132. @alicebartlett
    In git jargon you “stage” it by using git add

    View full-size slide

  133. @alicebartlett
    // Working directory
    // Staging index
    // Commit history

    View full-size slide

  134. @alicebartlett

    View full-size slide

  135. @alicebartlett
    $ git add

    View full-size slide

  136. @alicebartlett
    $ git commit

    View full-size slide

  137. @alicebartlett
    $ git commit -am "sqlite stuff"

    View full-size slide

  138. @alicebartlett
    When you have some lines in your file
    that you want to commit but some that
    you don’t — use git add --patch

    View full-size slide

  139. @alicebartlett
    Using git add --patch means that
    even if you’ve failed to work atomically,
    ie you have ended up with multiple
    changes in the same file, you can still
    commit atomically

    View full-size slide

  140. @alicebartlett
    Start End
    Start End

    View full-size slide

  141. @alicebartlett
    git add --patch will ask you which
    bits of a file you want to add. It calls
    these “bits” hunks.

    View full-size slide

  142. $ git add --patch

    View full-size slide

  143. $ git add --patch
    diff --git a/config/playlist.js b/config/playlist.js
    index 7e54d1a..eba4bf5 100644
    --- a/config/playlist.js
    +++ b/config/playlist.js
    @@ -28,14 +28,6 @@ const playlistConfigs = {
    videos: byDuration
    })
    },
    - popular: {
    - query: queries['popular-videos'],
    - dataReader: ({ data: { video: { popular = []}} = {}} = {}) => ({
    - videos: popular
    - })
    - },
    section: {
    query: queries['section-videos'],
    dataReader: ({ data: { section = {}} = {}} = {}) => {
    Stage this hunk [y,n,q,s,e,?]?

    View full-size slide

  144. $ git add --patch
    diff --git a/config/playlist.js b/config/playlist.js
    index 7e54d1a..eba4bf5 100644
    --- a/config/playlist.js
    +++ b/config/playlist.js
    @@ -28,14 +28,6 @@ const playlistConfigs = {
    videos: byDuration
    })
    },
    - popular: {
    - query: queries['popular-videos'],
    - dataReader: ({ data: { video: { popular = []}} = {}} = {}) => ({
    - videos: popular
    - })
    - },
    section: {
    query: queries['section-videos'],
    dataReader: ({ data: { section = {}} = {}} = {}) => {
    Stage this hunk [y,n,q,s,e,?]?
    Nice diff of
    your changes

    View full-size slide

  145. $ git add --patch
    diff --git a/config/playlist.js b/config/playlist.js
    index 7e54d1a..eba4bf5 100644
    --- a/config/playlist.js
    +++ b/config/playlist.js
    @@ -28,14 +28,6 @@ const playlistConfigs = {
    videos: byDuration
    })
    },
    - popular: {
    - query: queries['popular-videos'],
    - dataReader: ({ data: { video: { popular = []}} = {}} = {}) => ({
    - videos: popular
    - })
    - },
    section: {
    query: queries['section-videos'],
    dataReader: ({ data: { section = {}} = {}} = {}) => {
    Stage this hunk [y,n,q,s,e,?]?

    View full-size slide

  146. @alicebartlett
    Stage this hunk [y,n,q,s,e,?]?

    View full-size slide

  147. @alicebartlett
    Stage this hunk [y,n,q,s,e,?]?
    y: yes add this to the things I want to commit
    n: no, leave this hunk alone
    q: quit
    s: split this hunk into smaller hunks
    e: manually edit the hunk
    ?: tell me about these options

    View full-size slide

  148. @alicebartlett
    Stage this hunk [y,n,q,s,e,?]?
    y: yes add this to the things I want to commit
    n: no, leave this hunk alone
    q: quit
    s: split this hunk into smaller hunks
    e: manually edit the hunk
    ?: tell me about these options

    View full-size slide

  149. @alicebartlett
    git commit --amend

    View full-size slide

  150. @alicebartlett
    So git commit is something you’ll have
    used many times if you’ve used git.
    git commit --amend lets you amend
    your last commit.

    View full-size slide

  151. @alicebartlett
    Super useful if you committed too soon, or
    you want to modify the commit message

    View full-size slide

  152. @alicebartlett
    When you use git commit --amend you
    completely replace the last commit with a
    new one and it will commit everything
    that’s currently staged.

    View full-size slide

  153. 377dfcd00dd057542b112cf13be6cf1380b292ad
    20-05-2016: Fix broken sign up buttno CSS

    View full-size slide

  154. 377dfcd00dd057542b112cf13be6cf1380b292ad
    20-05-2016: Fix broken sign up buttno CSS
    oops :(

    View full-size slide

  155. 377dfcd00dd057542b112cf13be6cf1380b292ad
    20-05-2016: Fix broken sign up buttno CSS
    $ git commit --amend

    View full-size slide

  156. 377dfcd00dd057542b112cf13be6cf1380b292ad
    20-05-2016: Fix broken sign up buttno CSS
    $ git commit --amend
    439301fe69e8f875c049ad0718386516b4878e22
    20-05-2016: Fix broken sign up button CSS

    View full-size slide

  157. 377dfcd00dd057542b112cf13be6cf1380b292ad
    20-05-2016: Fix broken sign up buttno CSS
    439301fe69e8f875c049ad0718386516b4878e22
    20-05-2016: Fix broken sign up button CSS

    View full-size slide

  158. 377dfcd00dd057542b112cf13be6cf1380b292ad
    20-05-2016: Fix broken sign up buttno CSS
    439301fe69e8f875c049ad0718386516b4878e22
    20-05-2016: Fix broken sign up button CSS

    View full-size slide

  159. @alicebartlett
    git reset

    View full-size slide

  160. @alicebartlett
    Use git reset when you want to undo
    changes

    View full-size slide

  161. @alicebartlett
    $ git commit
    $ git add

    View full-size slide

  162. @alicebartlett
    git reset moves
    changes back
    through these
    structures
    What gets moved
    depends on the
    arguments you call
    reset with

    View full-size slide

  163. @alicebartlett
    Calling git reset with no
    additional arguments moves
    any changes on the Staging
    Index back to the Working
    Directory.
    Nothing happens to the
    commit history.
    git reset

    View full-size slide

  164. @alicebartlett
    Calling git reset will
    move all changes from any
    commit after the id you’ve
    given it back to the Working
    Directory
    git reset

    View full-size slide

  165. @alicebartlett
    Calling git reset will
    move all changes from any
    commit after the id you’ve
    given it back to the Working
    Directory
    git reset
    Commit

    View full-size slide

  166. @alicebartlett
    You can also call git reset with the
    --hard option.
    This will reset the pointers to
    commit and DELETE the
    contents of you working Directory.
    Any uncommitted changes in your
    working directory or staging index
    are lost
    git reset --hard

    View full-size slide

  167. @alicebartlett
    You can also call git reset with the
    --hard option.
    This will reset the pointers to
    commit and DELETE the
    contents of you working Directory.
    Any uncommitted changes in your
    working directory or staging index
    are lost
    git reset --hard
    Gone!

    View full-size slide

  168. @alicebartlett
    1. git add and git add --patch to selectively move
    changes from Working Directory to Staging
    2. git commit --amend to quickly change commit messages
    3. git reset to move work backwards in workflow

    View full-size slide

  169. @alicebartlett
    1.git rebase
    2.git rebase --interactive

    View full-size slide

  170. @alicebartlett
    Start End
    Start End
    In the last bit we covered making and undoing
    commits, now we’re going to look at changing
    larger bits of your commit history

    View full-size slide

  171. @alicebartlett
    git rebase allows you to literally
    rewrite your history. This is very useful
    as often, through making changes, new
    or better ways of doing things or
    ordering changes reveal themselves

    View full-size slide

  172. @alicebartlett
    Rebasing replays your changes over a
    branch.
    You take the patch of one commit and
    apply it to a different commit

    View full-size slide

  173. @alicebartlett
    feature branch
    master
    Rebasing is changing the
    base of your branch from
    one commit to another,
    making it look as if you had
    created a branch from a
    different commit
    HEAD

    View full-size slide

  174. @alicebartlett
    feature branch
    master

    View full-size slide

  175. @alicebartlett
    feature branch
    master

    View full-size slide

  176. @alicebartlett
    feature branch
    master
    HEAD

    View full-size slide

  177. @alicebartlett
    feature branch
    (merge commit)
    master
    feature branch
    master
    Rebase
    Merge

    View full-size slide

  178. @alicebartlett
    feature branch
    If you're working on a feature and want to bring in
    changes from master that happen in the interim,
    rebasing stops you from having lots of merge commits
    merge commit

    View full-size slide

  179. @alicebartlett
    The golden rule of rebasing is:
    ONLY USE IT ON LOCAL UNPUBLISHED
    BRANCHES

    View full-size slide

  180. @alicebartlett
    1.git rebase
    2.git rebase --interactive

    View full-size slide

  181. @alicebartlett
    Rebasing on it’s own is kind of
    interesting, but the really useful stuff
    happens with
    git rebase --interactive

    View full-size slide

  182. @alicebartlett
    git rebase --interactive takes
    rebasing and turns it into a very boring
    text adventure game

    View full-size slide

  183. @alicebartlett
    On the feature branch and we run:
    git rebase --interactive origin/master
    feature branch
    master

    View full-size slide

  184. @alicebartlett
    So - we’re going to replay these
    commits here: feature branch
    master

    View full-size slide

  185. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    pick 637bf758 Add commentwer mock
    pick fb274f86 Whitespace
    # Rebase 66d43b29..fb274f86 onto 66d43b29 (5 commands)
    #
    # 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
    # d, drop = remove commit
    # l, label = label current HEAD with a name
    # t, reset = reset HEAD to a label
    # m, merge [-C | -c ] [# ]
    #
    # [… etc… ]

    View full-size slide

  186. @alicebartlett
    A list of
    commits
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    pick 637bf758 Add commentwer mock
    pick fb274f86 Whitespace
    # Rebase 66d43b29..fb274f86 onto 66d43b29 (5 commands)
    #
    # 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
    # d, drop = remove commit
    # l, label = label current HEAD with a name
    # t, reset = reset HEAD to a label
    # m, merge [-C | -c ] [# ]
    #
    # [… etc… ]

    View full-size slide

  187. @alicebartlett
    A list of
    commands
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    pick 637bf758 Add commentwer mock
    pick fb274f86 Whitespace
    # Rebase 66d43b29..fb274f86 onto 66d43b29 (5 commands)
    #
    # 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
    # d, drop = remove commit
    # l, label = label current HEAD with a name
    # t, reset = reset HEAD to a label
    # m, merge [-C | -c ] [# ]
    #
    # [… etc… ]

    View full-size slide

  188. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    pick 637bf758 Add commentwer mock
    pick fb274f86 Whitespace
    Lets merge these two
    commits as they’re
    both just whitespace
    changes

    View full-size slide

  189. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    pick 637bf758 Add commentwer mock
    We can use “squash”
    to do that

    View full-size slide

  190. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    pick 637bf758 Add commentwer mock
    Let’s also fix this typo
    using the re-word option

    View full-size slide

  191. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    reword 637bf758 Add commentwer mock
    Let’s also fix this typo
    using the re-word option

    View full-size slide

  192. @alicebartlett
    Once you close that rebase file Git will
    step you through each of the commands
    from top to bottom, stopping when your
    input is required

    View full-size slide

  193. @alicebartlett
    feature
    HEAD
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    reword 637bf758 Add commentwer mock

    View full-size slide

  194. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    reword 637bf758 Add commentwer mock
    pick
    feature
    HEAD

    View full-size slide

  195. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    reword 637bf758 Add commentwer mock
    pick
    feature
    HEAD

    View full-size slide

  196. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    reword 637bf758 Add commentwer mock
    squash
    feature
    HEAD

    View full-size slide

  197. @alicebartlett
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    reword 637bf758 Add commentwer mock
    reword
    feature
    HEAD

    View full-size slide

  198. @alicebartlett
    feature
    HEAD
    pick a8f83c27 Remove CommentFactory documentation
    pick cf19c147 Whitespace changes
    squash fb274f86 Whitespace
    reword 637bf758 Add commenter mock

    View full-size slide

  199. @alicebartlett
    OK — time for a more complicated
    rebase example...

    View full-size slide

  200. @alicebartlett
    This is about the nursery rhyme
    “Old Mac Donald”

    View full-size slide

  201. @alicebartlett
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    and on that farm he had some cows
    eee-eye-eee-eye-oh!
    With a moo moo here!
    and a moo moo there!
    here a moo!
    there a moo!
    everywhere a moo moo!
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh

    View full-size slide

  202. @alicebartlett
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    and on that farm he had some cows
    eee-eye-eee-eye-oh!
    With a moo moo here!
    and a moo moo there!
    here a moo!
    there a moo!
    everywhere a moo moo!
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    Initial commit

    View full-size slide

  203. @alicebartlett
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    and on that farm she had some cows
    eee-eye-eee-eye-oh!
    With a moo moo here!
    and a moo moo there!
    here a moo!
    there a moo!
    everywhere a moo moo!
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    Initial commit
    Change gender"

    View full-size slide

  204. @alicebartlett
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    and on that farm she had some wheat
    eee-eye-eee-eye-oh!
    With a swish swish here!
    and a swish swish there!
    here a swish!
    there a swish!
    everywhere a swish swish!
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    Initial commit
    Change gender"
    Farm wheat

    View full-size slide

  205. @alicebartlett
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    and on that farm they had some wheat
    eee-eye-eee-eye-oh!
    With a swish swish here!
    and a swish swish there!
    here a swish!
    there a swish!
    everywhere a swish swish!
    Old Mac Donald had a farm
    eee-eye-eee-eye-oh
    Initial commit
    Change gender"
    Farm wheat
    Use singular they

    View full-size slide

  206. @alicebartlett
    Initial commit
    Change gender"
    Farm wheat
    Use singular they
    Let’s delete this
    from commit. We
    don't need it, it
    doesn’t help tell the
    story of our project

    View full-size slide

  207. @alicebartlett
    $ git rebase -i HEAD~4

    View full-size slide

  208. @alicebartlett
    pick a Initial commit
    pick b Change gender "
    pick c Farm wheat
    pick d Use singular they
    Initial commit
    Change gender"
    Farm wheat
    Use singular they

    View full-size slide

  209. @alicebartlett
    Initial commit
    Change gender"
    Farm wheat
    Use singular they
    pick a Initial commit
    pick c Farm wheat
    pick d Use singular they

    View full-size slide

  210. @alicebartlett
    Auto-merging old-mac-donald.txt
    CONFLICT (content): Merge conflict in old-mac-donald.txt
    error: could not apply C... Farm wheat
    Resolve all conflicts manually, mark them as resolved with
    "git add/rm ", then run "git rebase --continue".
    You can instead skip this commit: run "git rebase --skip".
    To abort and get back to the state before "git rebase", run "git
    rebase --abort".
    Could not apply C... Farm wheat

    View full-size slide

  211. MERGE
    CONFLICT!!!

    View full-size slide

  212. @alicebartlett
    $ git rebase --abort

    View full-size slide

  213. @alicebartlett
    Auto-merging old-mac-donald.txt
    CONFLICT (content): Merge conflict in old-mac-
    donald.txt
    error: could not apply C... Farm wheat
    Resolve all conflicts manually, mark them as
    resolved with
    "git add/rm ", then run "git
    rebase --continue".
    You can instead skip this commit: run "git rebase
    --skip".
    To abort and get back to the state before "git
    rebase", run "git rebase --abort".
    Could not apply C... Farm wheat
    Initial commit
    Change gender"
    Farm wheat
    Use singular they

    View full-size slide

  214. @alicebartlett
    Why has
    this happened?
    Initial commit
    Change gender"
    Farm wheat
    Use singular they

    View full-size slide

  215. @alicebartlett
    Initial commit
    Change gender"
    Farm wheat
    Use singular they
    We deleted our
    “Change gender”
    commit

    View full-size slide

  216. @alicebartlett
    Initial commit
    Change gender"
    Farm wheat
    Use singular they
    But our “Farm wheat”
    change expected it

    View full-size slide

  217. @alicebartlett
    $ git show b
    commit b
    [...]
    eee-eye-eee-eye-oh
    -and on that farm he had some cows
    +and on that farm she had some cows
    eee-eye-eee-eye-oh!
    [...]

    View full-size slide

  218. @alicebartlett
    $ git show c
    commit c
    [...]
    eee-eye-eee-eye-oh
    -and on that farm she had some cows
    +and on that farm she had some wheat
    eee-eye-eee-eye-oh!
    [...]

    View full-size slide

  219. @alicebartlett
    eee-eye-eee-eye-oh
    <<<<<<< HEAD
    and on that farm he had some cows
    =======
    and on that farm she had some wheat
    >>>>>>> c... Switch to wheat
    eee-eye-eee-eye-oh!

    View full-size slide

  220. @alicebartlett
    eee-eye-eee-eye-oh
    and on that farm he had some wheat
    eee-eye-eee-eye-oh!

    View full-size slide

  221. @alicebartlett
    eee-eye-eee-eye-oh
    and on that farm he had some wheat
    eee-eye-eee-eye-oh!
    And now we’re good to go — we can
    add that change and continue run
    git rebase --continue

    View full-size slide

  222. @alicebartlett
    And you have single handedly
    saved the planet and destroyed the
    gender binary in a two commit
    messages while also overcoming a
    merge conflict and maintaining a
    clean Git history. Not bad.
    Initial commit
    Farm wheat
    Use singular they

    View full-size slide

  223. @alicebartlett
    1. git rebase to pull in any changes from another branch for
    a neater history without any merge commits
    2. git rebase --interactive to edit and restructure
    multiple commits before you push them

    View full-size slide

  224. 3. Tips for Git history management
    • Use git add --patch to help iron out your
    messy working process from the history
    • Gateway drug: git commit --amend
    • Use git reset to undo things in the history
    • Use git rebase for redo things in the history

    View full-size slide

  225. 2. What is Git
    3. Tips for rewriting your Git history
    1. Why should you care

    View full-size slide

  226. @alicebartlett
    Start End
    Start End

    View full-size slide

  227. @alicebartlett
    Thank you
    @alicebartlett

    View full-size slide

  228. @alicebartlett
    1. Noun Project Faces by Sarah Rudkin: https://
    thenounproject.com/sarahdrudkin/collection/faces/
    2. Linus Torvalds at Google 2007: https://www.youtube.com/
    watch?v=4XpnKHJAok8
    3. Tekin Süleyman’s A Branch In Time: https://
    www.youtube.com/watch?v=1NoNTqank_U
    4. Git man page generator: https://git-man-page-
    generator.lokaltog.net/

    View full-size slide