Pro Yearly is on sale from $80 to $50! »

Branch in Time

73f812133e01dac8eb9b67746fe27393?s=47 Tekin Suleyman
November 15, 2018
420

Branch in Time

In one timeline a quick path to clarity. In the other a painful journey trying to uncover the obscure intent of a line of code. The only difference between these two realities? The revision history…

This is a story about revision histories and their impact on software maintainability. Think Sliding Doors, but with more Git!

73f812133e01dac8eb9b67746fe27393?s=128

Tekin Suleyman

November 15, 2018
Tweet

Transcript

  1. Branch in Time A story about revision histories @tekin

  2. Docs-R-Us Seema

  3. Seema Docs-R-Us

  4. class PatientsController < ApplicationController before_action :load_doctor def index @patients =

    sorted_patients end def show @patient = @doctor.patients.find(params[:id]) end private def sorted_patients @doctor.patients.sort { |patient| patient.name } end def load_doctor @doctor = doctor_from_current_session
  5. class PatientsController < ApplicationController before_action :load_doctor def index @patients =

    sorted_patients end def show @patient = @doctor.patients.find(params[:id]) end private def sorted_patients @doctor.patients.sort { |patient| patient.name } end def load_doctor @doctor = doctor_from_current_session
  6. class PatientsController < ApplicationController before_action :load_doctor def index @patients =

    sorted_patients end def show @patient = @doctor.patients.find(params[:id]) end private def sorted_patients @doctor.patients.order(:name) end def load_doctor @doctor = doctor_from_current_session
  7. class PatientsController < ApplicationController before_action :load_doctor def index @patients =

    sorted_patients end def show @patient = @doctor.patients.find(params[:id]) end private def sorted_patients @doctor.patients.order(:name) end def load_doctor @doctor = doctor_from_current_session $ rake Run options: --seed 45260 # Running: .................................................................... .................................................................... .................................................................... .................................... Finished in 123.299088s, 23.8629 runs/s, 34.6397 assertions/s. 3311 runs, 45124 assertions, 0 failures, 0 errors, 0 skips
  8. class Patient < ApplicationRecord has_many :appointments validates_presence_of :name, :address, :date_of_birth

    end class Doctor < ApplicationRecord has_many :appointments has_many :patients, through: :appointments belongs_to :practice validates_presence_of :name, :practice end
  9. Git Fu 1. git blame

  10. $ git blame app/controllers/patients_controller.rb Git Fu: git blame

  11. 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 1) # Controller for

    listing a doctor's pa 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 2) class PatientsController < Application 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 3) before_filter :load_doctor 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 4) 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 5) def index 6047246d (Josie P 2010-10-29 09:32:25 +0100 6) @patients = sorted_patients 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 7) end 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 8) 9598514f (Josie P 2010-06-28 17:03:21 +0100 9) def show 9598514f (Josie P 2010-06-28 17:03:21 +0100 10) @patient = @doctor.patients.find(p 9598514f (Josie P 2010-06-28 17:03:21 +0100 11) end 9598514f (Richard E 2010-06-28 17:03:21 +0100 12) 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 13) private dbdd0fb9 (Josie P 2010-10-29 09:31:52 +0100 18) 6047246d (Josie P 2010-10-29 09:32:25 +0100 19) def sorted_patients dbdd0fb9 (Josie P 2010-10-29 09:31:52 +0100 20) @doctor.patients.sort {|patient| p dbdd0f69 (Josie P 2010-10-29 09:31:52 +0100 21) end 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 14) $ git blame app/controllers/patients_controller.rb Git Fu: git blame
  12. --patch Git Fu: git blame $ git log dbdd0fb9

  13. $ git log dbdd0fb9 --patch commit dbdd0fb9e870b91e6925903553f07df3becc9414 Author: Josie Pickford<josie@docs-r-us.com>

    Date: Fri Oct 29 09:31:52 2010 +0100 PR Feedback: Fixed a typo diff --git a/app/controllers/patients_controller.rb b/app/controllers/patients_controller index d7c6df5..1e3debb 100644 --- a/app/controllers/patients_controller.rb +++ b/app/controllers/patients_controller.rb @@ -13,7 +13,7 @@ class PatientsController < ApplicationController private def sorted_patients - @doctor.patients.sort {|pateint| pateint.name } + @doctor.patients.sort {|patient| patient.name } end Git Fu: git blame
  14. Git Fu 1. git blame 2. git log -S (AKA

    The Pickaxe)
  15. Git Fu: git log -S (AKA The Pickaxe) $ git

    log -S "sorted_patients" --patch --reverse
  16. Git Fu: git log -S (AKA The Pickaxe) $ git

    log -S "sorted_patients" --patch --reverse commit 23b6e0c6a9a7a392c312d4f0c51153e0769ebffc Author: Josie Pickford<josie@docs-r-us.com> Date: Thurs Oct 28 17:55:32 2010 +0100 Rename method diff --git a/app/controllers/patients_controller.rb b/app/controllers/ patients_controller.rb index 51fbd8a..d7c6df5 100644 --- a/app/controllers/patients_controller.rb +++ b/app/controllers/patients_controller.rb @@ -3,7 +3,7 @@ class PatientsController < ApplicationController before_filter :load_doctor def index - @patients = load_patients + @patients = sorted_patients end
  17. Git Fu 1. git blame 2. git log -S (AKA

    The Pickaxe) 3. Pickaxe Round 2
  18. Git Fu: Pickaxe Round 2 $ git log -S "load_patients"

    --patch --reverse commit 66f95816017b1c6582034d074333fa18884ad3c3 Author: Josie Pickford<josie@docs-r-us.com> Date: Thurs Oct 28 17:00:43 2010 +0100 Fix patient ordering bug diff --git a/app/controllers/patients_controller.rb b/app/controllers/patients_controller index cb0e69c..51fbd8a 100644 --- a/app/controllers/patients_controller.rb +++ b/app/controllers/patients_controller.rb @@ -3,7 +3,7 @@ class PatientsController < ApplicationController before_filter :load_doctor def index - @patients = @doctor.patients.order(:name) + @patients = load_patients end
  19. Git Fu 1. git blame 2. git log -S (AKA

    The Pickaxe) 3. Pickaxe Round 2 4. Find the Pull Request
  20. Git Fu: Find the Pull Request

  21. Git Fu: Find the Pull Request

  22. Git Fu: Find the Pull Request

  23. Git Fu: Find the Pull Request

  24. None
  25. 8 years ago...

  26. Docs-R-Us Josie 8 years ago...

  27. Doh! ☕ 8 years ago... Josie

  28. Y U NO ALPHABETICAL!?

  29. class PatientsController < ApplicationController before_filter :load_doctor def index @patients =

    @doctor.patients.order(:name) end def show @patient = @doctor.patients.find(params[:id]) end private def load_doctor @doctor = doctor_from_current_session end end
  30. class PatientsController < ApplicationController before_filter :load_doctor def index @patients =

    @doctor.patients.order(:name) end def show @patient = @doctor.patients.find(params[:id]) end private def load_doctor @doctor = doctor_from_current_session end end
  31. class Doctor < ApplicationRecord has_many :appointments, order: :appointment_date has_many :patients,

    through: :appointments belongs_to :practice validates_presence_of :name, :practice end
  32. class Doctor < ApplicationRecord has_many :appointments, order: :appointment_date has_many :patients,

    through: :appointments belongs_to :practice validates_presence_of :name, :practice end
  33. class Doctor < ApplicationRecord has_many :appointments, order: :appointment_date has_many :patients,

    through: :appointments belongs_to :practice validates_presence_of :name, :practice end doctor.patients.order(:name) Patients Load (1.0ms) SELECT "patients".* FROM "patients" INNER JOIN "appointments" ON "patients"."id" = "appointments"."patient_id" WHERE “appointments"."doctor_id" = $1 ORDER BY “appointments"."appointment_date" ASC, "patients"."name" ASC irb(main):003:0>
  34. class Doctor < ApplicationRecord has_many :appointments has_many :patients, through: :appointments

    belongs_to :practice validates_presence_of :name, :practice end , order: :appointment_date
  35. class Doctor < ApplicationRecord has_many :appointments has_many :patients, through: :appointments

    belongs_to :practice validates_presence_of :name, :practice end $ rake Run options: --seed 45260 # Running: .....F..........FFFF.........F..........FF..............FFFFFFFFF... ..............FFFFFFFFFFFFFFFFFF............................FFFF Finished in 1.273019s, 24.3516 runs/s, 35.3490 assertions/s.
  36. class PatientsController < ApplicationController before_filter :load_doctor def index @patients =

    @doctor.patients.order(:name) end def show @patient = @doctor.patients.find(params[:id]) end private def load_doctor @doctor = doctor_from_current_session end end
  37. class PatientsController < ApplicationController before_filter :load_doctor def index @patients =

    end def show @patient = @doctor.patients.find(params[:id]) end private def load_patients @doctor.patients.sort { |pateint| pateint.name } end def load_doctor @doctor = doctor_from_current_session load_patients
  38. Branch history

  39. Pull Request (YOLO)

  40. Build broke...

  41. Build broke...

  42. Just one more commit...

  43. ... and another

  44. Ship it!

  45. Intermission

  46. Intermission

  47. No reorder( ) in Rails 2.3.8 Intermission

  48. 8 years ago...

  49. Docs-R-Us 8 years ago... Josie

  50. Damn fine coffee! 8 years ago... ☕ Josie

  51. Y U NO ALPHABETICAL!?

  52. Branch history

  53. Branch history

  54. Branch history

  55. Git Fu 1. git rebase --interactive

  56. git rebase --interactive head~3 Git Fu: git rebase --interactive $

  57. git rebase --interactive head~3 Git Fu: git rebase --interactive $

  58. git rebase --interactive head~3 Git Fu: git rebase --interactive $

  59. Git Fu: git rebase --interactive git rebase --interactive head~3 $

  60. Pull Request

  61. Build broke...

  62. Fix the build git add test/integration $ $ [fix-patient-order-bug ee74d2f]

    Fix patient ordering bug Date: Fri Oct 29 09:36:08 2010 +0100 3 files changed, 44 insertions(+), 3 deletion(-) $ git commit --amend --no-edit
  63. Fix the build git push --force-with-lease git add test/integration $

    $ [fix-patient-order-bug ee74d2f] Fix patient ordering bug Date: Fri Oct 29 09:36:08 2010 +0100 3 files changed, 44 insertions(+), 3 deletion(-) $ git commit --amend --no-edit
  64. Ship it!

  65. Back to the future...

  66. Docs-R-Us Seema Seema

  67. class PatientsController < ApplicationController before_action :load_doctor def index @patients =

    sorted_patients end def show @patient = @doctor.patients.find(params[:id]) end private def sorted_patients @doctor.patients.sort { |patient| patient.name } end def load_doctor @doctor = doctor_from_current_session
  68. 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 1) # Controller for

    listing a doctor's pa 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 2) class PatientsController < Application 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 3) before_filter :load_doctor 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 4) 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 5) def index 6047246d (Josie P 2010-10-29 09:32:25 +0100 6) @patients = sorted_patients 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 7) end 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 8) 9598514f (Josie P 2010-06-28 17:03:21 +0100 9) def show 9598514f (Josie P 2010-06-28 17:03:21 +0100 10) @patient = @doctor.patients.find(p 9598514f (Josie P 2010-06-28 17:03:21 +0100 11) end 9598514f (Richard E 2010-06-28 17:03:21 +0100 12) 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 13) private dbdd0fb9 (Josie P 2010-10-29 09:31:52 +0100 18) 6047246d (Josie P 2010-10-29 09:32:25 +0100 19) def sorted_patients 33ec144e (Josie P 2010-10-29 09:31:52 +0100 20) @doctor.patients.sort {|patient| p dbdd0f69 (Josie P 2010-10-29 09:31:52 +0100 21) end 3fc122c2 (Richard E 2010-06-28 17:02:54 +0100 14) $ git blame app/controllers/patients_controller.rb Git Fu: git blame
  69. $ git log 33ec144e --patch commit 33ec144e70b91e6925903553f07df3becc9414 Author: Josie Pickford<josie@docs-r-us.com>

    Date: Friday Oct 29 09:44:49 2010 +0100 Fix patient ordering bug The patients association is returning patients in appointment date order, even when called with an explicit `order(:name)` scope. This is because the patients association is a has_many :through the appointments association, which has a default order by appointment_date. This causes any queries on the association to always sort first by appointment date: ORDER BY “appointments"."appointment_date" ASC, "patients"."name" ASC) Removing the default ordering from the appointments association is going to take a bit of unpicking. To get the bug resolved in the meantime we can re-sort the patient records after they've been loaded. Separate work has been planned to remove the default ordering altogether. Git Fu: git blame
  70. class Doctor < ApplicationRecord has_many :appointments has_many :patients, through: :appointments

    belongs_to :practice validates_presence_of :name, :practice end
  71. None
  72. • Naming things • Automated tests • Abstractions • Refactoring

  73. Your software is more than the code

  74. None
  75. Programming as Theory Building Peter Naur

  76. Revision History as Theory Capturing

  77. None
  78. None
  79. None
  80. Git Fu 1. Configure an environment for good commit messages

  81. Configure an environment for good commit messages $ git commit

    -m "Did a thing"
  82. Configure an environment for good commit messages $ git config

    --global core.editor “subl -w”
  83. Configure an environment for good commit messages $ git config

    --global commit.verbose true
  84. Git Fu 1. Configure an environment for good commit messages

    2. Capture the why, not the what
  85. Capture the why, not the what

  86. Git Fu 1. Configure an environment for good commit messages

    2. Capture the why, not the what 3. Shape each commit
  87. Shape each commit • Create small atomic commits • Shape

    as you go, not at the end • $ git add --patch / -p
  88. Shape each commit dd3b43c Refactor Foo 44b4bd8 Add Bar to

    Foo
  89. Git Fu 1. Configure an environment for good commit messages

    2. Capture the why, not the what 4. Treat (local) commits as mutable 3. Shape each commit
  90. Treat (local) commits as mutable • $ git commit --amend

    • $ git rebase --interactive • $ git rebase --abort • --fixup / --autosquash
  91. Git Fu 1. Configure an environment for good commit messages

    2. Capture the why, not the what 5. Build your instincts; search your histories 4. Treat (local) commits as mutable 3. Shape each commit
  92. Build your instincts; search your histories • $ git blame

    file.rb • $ git log -S "some_code" • $ git annotate file.rb
  93. Git Fu 1. Configure an environment for good commit messages

    2. Capture the why, not the what 5. Treat (local) commits as mutable 4. Build your instincts; search your histories 3. Shape each commit
  94. tekin.co.uk

  95. None
  96. None
  97. Thanks for the Git Fu @dgheath21 @angelajtodd @grahamashton

  98. Help each other Git Better

  99. Seema Memoji Josie Memoji Created by Inspiration for the story-based

    approach Talk Feedback and Advice Slide Advisor Git Fu Indent Hospital Icon Winding Road Photo Sound Effects TEKIN SULEYMAN TEKIN SULEYMAN TEKIN SULEYMAN NADIA ODUNAYO ANDY CROLL ANGELA TODD GRAHAM ASHTON MURRAY STEELE NADIA ODUNAYO KATRINA OWEN BRUCE LEE, ENTER THE DRAGON (1972) FLATICON.COM JESSE BOWSER ON UNSPLASH LEGEND OF ZELDA, A LINK TO THE PAST Cast
  100. Branch in Time A story about revision histories @tekin