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

Git merge in depth

Anton Chikin
November 29, 2016

Git merge in depth

How exactly 3-way recursive merge and rebase work.

Anton Chikin

November 29, 2016
Tweet

Other Decks in Technology

Transcript

  1. master branch ? var a = “foo” def getData(string path)

    var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data
  2. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data master branch
  3. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data master branch ?
  4. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data master branch ? ?
  5. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data master branch ? ? ?
  6. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data master branch ? ? ? ?
  7. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data master branch ? ? ? ? Nearest common ancestor var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data
  8. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor master branch
  9. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch
  10. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch def getData(string path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo”
  11. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch def getData(string path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo”
  12. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var data = {} for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) def getData(string path)
  13. ? var a = “foo” def getData(string path) var data

    = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var data = {} for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) def getData(string path)
  14. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {}
  15. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} ?????????????
  16. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} ?????????????
  17. def getData(string path) <<<<<<< HEAD var data = Map() |||||||

    merged common ancestors var data = {} ======= var data = Array() >>>>>>> branch
  18. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} var data = Map() for l in visit(path)
  19. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} var data = Map() for l in visit(path)
  20. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} var data = Map() for l in visit(path) data[l.id] = l.data
  21. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} var data = Map() for l in visit(path) data[l.id] = l.data
  22. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} var data = Map() for l in visit(path) data[l.id] = l.data return data.JSON()
  23. def getData(string path) ? var a = “foo” def getData(string

    path) var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() var a = “foo” def getData(URI path) var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” def getData(string path) var data = {} for l in visit(path) data[l.slot] = l.data return data ancestor merge ancestor master branch var data = Map() for l in visit(path) data[l.slot] = l.data return data.JSON() for l in visit(path) data[l.slot] = l.data return data var data = Array() for l in visit(path) data[l.id] = l.data return data var a = “foo” var a = “foo” var a = “foo” var a = “foo” def getData(string path) def getData(URI path) var data = {} var data = Map() for l in visit(path) data[l.id] = l.data return data.JSON()
  24. master M M ? hotfix feature Let’s take a look

    at a more complicated picture
  25. master M M ? hotfix feature Let’s take a look

    at a more complicated picture nearest common ancestor
  26. master M M ? hotfix feature How to deal with

    two nearest common ancestors? nearest common ancestor nearest common ancestor
  27. master M M ? hotfix nearest common ancestor Step 1:

    find nearest common ancestor of those ancestors
  28. master M M ? hotfix Step 2: merge them into

    “fake” commit nearest common ancestor
  29. master M M ? hotfix Step 3: Merge our commits

    using that “fake” ancestor nearest common ancestor
  30. master branch master diff B diff C diff A A

    B C Create diffs between each commits starting from NCO
  31. master branch master A B C diff B diff C

    diff A Move branch head to master
  32. master branch master A B C A’ diff B diff

    C Apply each diff on top of latest master commit
  33. master branch master A B C A’ B’ diff C

    Apply each diff on top of latest master commit
  34. master branch master A B C A’ B’ C’ Apply

    each diff on top of latest master commit
  35. @1,1 - A + B What does it mean to

    “apply diff”? Diff format is quite simple: In the first line
  36. @1,1 - A + B Diff format is quite simple:

    In the first line replace “A” What does it mean to “apply diff”?
  37. @1,1 - A + B Diff format is quite simple:

    In the first line replace “A” with “B” What does it mean to “apply diff”?
  38. A B C @1,1 - A + B B B

    C What does it mean to “apply diff”?
  39. D B C @1,1 - A + B ???????? B

    C What if first line in file is not “A” but “D”? Same as in merge - conflict! What does it mean to “apply diff”?
  40. D B C @1,1 - A + B ???????? B

    C What if first line in file is not “A” but “D”? Same as in merge - conflict! What does it mean to “apply diff”?
  41. master branch branch master A’ B’ C’ A B C

    M Merge and rebase give you different branch structure but the same result
  42. Finally - don’t be afraid of recursive merge - merge

    a ->b == merge b ->a - merge == rebase - prefer merge over rebase - merge will never never let you down