Slide 1

Slide 1 text

GITANTI PATTERNS How To Mess Up With Git and Love It Again LEMi ORHAN ERGiN Agile Software Craftsman, iyzico /lemiorhan lemiorhanergin.com @lemiorhan 28 common git anti-patterns

Slide 2

Slide 2 text

DISCLOSURE There is no formula for using git efficiently. Opinions are my own. It means the opposites might work perfectly for your conditions.

Slide 3

Slide 3 text

git is powerful but you have to know using it properly

Slide 4

Slide 4 text

Are you using git if all you do is commit-push-pull use dropbox instead ANTIPATTERN DANGER as if it is dropbox ? 1 DROPBOX-ISH GIT ANTI-PATTERN

Slide 5

Slide 5 text

learn how git works no worries, I will cover how git behaves

Slide 6

Slide 6 text

the way it keeps FILES & FOLDERS working copy staging area objects database repository the way it keeps REFERENCES directed acyclic graph keeping snapshots traversing graph branches, tags, heads git has 2 mechanisms

Slide 7

Slide 7 text

Source Code Working Copy you want to version changes

Slide 8

Slide 8 text

Source Code Working Copy $ git init Object Database .git Folder / Object Database Cache Staging Area / The Index initializing repo

Slide 9

Slide 9 text

Source Code Working Copy $ git init --bare Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server initializing bare repo

Slide 10

Slide 10 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git add . preparing commits

Slide 11

Slide 11 text

folder folder folder file file file $ git add . preparing commits

Slide 12

Slide 12 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git add . preparing commits

Slide 13

Slide 13 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git commit -m “initial commit” commi!ing

Slide 14

Slide 14 text

$ git commit -m “initial commit” commi!ing folder folder folder file file file commit branch HEAD For more details, refer to book Git Internals by Scott Chacon

Slide 15

Slide 15 text

folder folder folder file file file commit $ git commit -m “second commit” commi!ing folder commit branch HEAD folder file folder For more details, refer to book Git Internals by Scott Chacon

Slide 16

Slide 16 text

folder folder folder file file file commit $ git commit -m “third commit” commi!ing folder commit folder file folder folder commit branch HEAD file For more details, refer to book Git Internals by Scott Chacon

Slide 17

Slide 17 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git commit -m “initial commit” commi!ing

Slide 18

Slide 18 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git remote add origin http://upstream.repo $ git push -u origin master pushing to remote

Slide 19

Slide 19 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy new changes from others are pushed

Slide 20

Slide 20 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git fetch fetching changes

Slide 21

Slide 21 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git merge FETCHED_HEAD updating working copy

Slide 22

Slide 22 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git pull git fetch + git merge ge!ing changes to source code

Slide 23

Slide 23 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy want to update last commit

Slide 24

Slide 24 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git reset --soft $ git commit --amend / so" reseting cannot be reached Only the cache for the commit you reseted is removed from staging area for your current branch

Slide 25

Slide 25 text

folder folder folder file file file commit folder commit folder file folder folder commit branch HEAD file For more details, refer to book Git Internals by Scott Chacon $ git reset --soft $ git commit --amend / so" reseting

Slide 26

Slide 26 text

folder folder folder file file file commit folder commit folder file folder folder commit branch HEAD file For more details, refer to book Git Internals by Scott Chacon $ git reset --soft $ git commit --amend / so" reseting

Slide 27

Slide 27 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy want to squash or change last commits

Slide 28

Slide 28 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git reset --mixed mixed reseting cannot be reached entries for commits, files and folders are removed from staging area

Slide 29

Slide 29 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy want to get rid of last commits

Slide 30

Slide 30 text

Object Database .git Folder / Object Database Cache Staging Area / The Index Remote Upstream Repo / Remote Repo Server Source Code Working Copy $ git reset --hard hard reseting cannot be reached removed from staging area removed from working copy

Slide 31

Slide 31 text

are you brave enough to jump to any commit ? jump to a branch create a branch from a commit create a branch from a tag ANTIPATTERN DANGER $ git checkout feature/PA-121 $ git checkout -b fix/missing-sign-parameter 2449be8 $ git checkout -b hotfix/v1.1 tags/v1 2 BROKEN TIME MACHINE ANTI-PATTERN

Slide 32

Slide 32 text

are you sure? are you brave enough to jump to any commit ?

Slide 33

Slide 33 text

do you have loooooong living topic branches ? ANTIPATTERN DANGER 3 LONG LIVING BRANCHES ANTI-PATTERN

Slide 34

Slide 34 text

do you have loooooong living topic branches ? welcome to merge hell

Slide 35

Slide 35 text

before merging do you validate commits back to source ? ANTIPATTERN DANGER code review, continuous integration, automated testing… 4 TOO LATE TO VALIDATE ANTI-PATTERN

Slide 36

Slide 36 text

before merging do you validate commits back to source ? are you sure?

Slide 37

Slide 37 text

merge and unmerge do you o!en want to just before releases ? ANTIPATTERN DANGER 5 CHERRY-PICK OBSSESSION ANTI-PATTERN

Slide 38

Slide 38 text

merge and unmerge do you o!en want to just before releases ? master HEAD TAG/v13 version 14 $ git cherry-pick Every-Single-Commit-We-Want-To-Deploy

Slide 39

Slide 39 text

the commit graph ? do you fully understand ANTIPATTERN DANGER 6 DEATH ON COMMIT GRAPH ANTI-PATTERN

Slide 40

Slide 40 text

the commit graph ? do you fully understand topic and shared branches, tracking branches, tags, HEADs, merge commits, reverted commits…

Slide 41

Slide 41 text

Cure?

Slide 42

Slide 42 text

Commit Early, Commit O"en Perfect Later, Publish Once

Slide 43

Slide 43 text

STEP 0 split your big feature into mini shippable tasks master HEAD TOPIC ORIGIN/master refactorings tasks, like rest endpoints testable, deployable each task will have a branch, not a feature

Slide 44

Slide 44 text

STEP 1 commit early commit o!en no need to compile no need for CI it’s only for versioning do not push master HEAD TOPIC ORIGIN/master

Slide 45

Slide 45 text

always pull with rebase $ git pull --rebase origin master to get forced pushes securely to rebase your commits master HEAD TOPIC STEP 2 ORIGIN/master

Slide 46

Slide 46 text

always pull with rebase $ git pull --rebase origin master to get forced pushes securely to rebase your commits master HEAD TOPIC STEP 2 ORIGIN/master

Slide 47

Slide 47 text

always pull with rebase $ git pull --rebase origin master to get forced pushes securely to rebase your commits master HEAD TOPIC STEP 2 ORIGIN/master if you branch is pushed already $ git push -f

Slide 48

Slide 48 text

always pull with rebase $ git pull --rebase origin master to get forced pushes securely to rebase your commits master HEAD TOPIC STEP 2 ORIGIN/master if you branch is pushed already $ git push -f Sync source branch a!erwards $ git fetch origin master:master

Slide 49

Slide 49 text

perfect later make it single commit $ git reset HEAD~3 or $ git rebase -i HEAD~3 HEAD TOPIC STEP 3 ORIGIN/master tests are passing app is working code is reviewed (*) master

Slide 50

Slide 50 text

$ git reset HEAD~3 (then commit) or $ git rebase -i HEAD~3 HEAD TOPIC STEP 3 ORIGIN/master perfect later make it single commit tests are passing app is working code is reviewed (*) master

Slide 51

Slide 51 text

Use feature flags/toggles HEAD TOPIC STEP 4 ORIGIN/master if feature should be disabled merge back to source $ git checkout master $ git merge topic master

Slide 52

Slide 52 text

Use feature flags/toggles master HEAD TOPIC STEP 4 ORIGIN/master if feature should be disabled merge back to source $ git checkout master $ git merge topic

Slide 53

Slide 53 text

Continuous Integration validates master branch continuously master HEAD TOPIC ORIGIN/master Pull requests can be used to review code and to validate before merging back to master Scrum tasks are mapped to commits, not stories Github Flow can be used to govern overall TAMING THE POWER OF GIT make git the king again Feature flags should be used whenever possible Commit early & o"en perfect later, publish once philosophy Deliver frequently be prepared to send every single commit Deleting branches a"er merge will make your commit graph readable

Slide 54

Slide 54 text

use terminal GUIs are prison balls of developers it’s ok to use GUIs while checking diffs, resolving conflicts and viewing commit graph BUTTON ADDICT ANTI-PATTERN 7 ANTIPATTERN DANGER

Slide 55

Slide 55 text

do not lose take extra care while using hard reset $ git reset --merge HEAD~ Use stash $ git stash save “updates local settings to keep db safe” $ git reset --hard HEAD~ $ git stash apply stash@{0} Create a new branch $ git checkout -b feature/PA-121 $ git add settings.xml $ git commit -m “adds new settings config” Use hard reset with merge and commit into it uncommited changes CODE LOSING SYNDROME ANTI-PATTERN 8 ANTIPATTERN DANGER

Slide 56

Slide 56 text

TOPIC HEAD MASTER $ git merge --squash fix Squash commit -- not updating HEAD Automatic merge went well; stopped before committing as requested $ git add . $ git commit -m “adds a feature” $ git branch -D topic TRASH HOUSE ANTI-PATTERN 9 long living branches with care handle ANTIPATTERN DANGER Squash all commits in your topic branch and 
 make them available in working copy

Slide 57

Slide 57 text

long living branches with care handle TOPIC HEAD MASTER $ git merge --squash fix Squash commit -- not updating HEAD Automatic merge went well; stopped before committing as requested $ git add . $ git commit -m “adds a feature” $ git branch -D topic Squash all commits in your topic branch and 
 make them available in working copy

Slide 58

Slide 58 text

stop adding prevent commits from being big ball of muds every change OMNIBUS BILL ANTI-PATTERN 10 ANTIPATTERN DANGER

Slide 59

Slide 59 text

stop adding prevent commits from being big ball of muds every change local change sets at JetBrains IDEs

Slide 60

Slide 60 text

stop adding every change partial add

Slide 61

Slide 61 text

messages are read! # WHAT # (this commit will...) # WHY and HOW # Explain why this change is being made # RELATED # Provide links or keys to any relevant issues or other resources # REMEMBER # use lower case in the subject line # start with a verb in imperative tone in the subject line # do not end the subject line with a period # separate subject from body with a blank line # use the body to explain what and why vs. how # can use multiple lines with "-" for bullet points in body $ git config --global commit.template ~/.git-commit-template.txt $ git config --global commit.cleanup strip use git commit templates to create be"er commit messages com t m i F*CKING COMMIT MESSAGES ANTI-PATTERN 11 ANTIPATTERN DANGER

Slide 62

Slide 62 text

messages are read! use git commit templates to create be"er commit messages com t m i

Slide 63

Slide 63 text

by adding new commits ? do you rollback your mistakes ANTIPATTERN DANGER 12 MESS UP WITH THE ROLLBACK ANTI-PATTERN

Slide 64

Slide 64 text

hard reset the merge commit $ git reset --hard HEAD~ if you haven't pushed yet HEAD MASTER Bug fıx

Slide 65

Slide 65 text

never force push and change the history if you already pushed to shared branch Bug fıx HEAD MASTER

Slide 66

Slide 66 text

revert the merge commit $ git revert 8f937c6 -m 1 if you already pushed Bug fıx HEAD MASTER

Slide 67

Slide 67 text

is not the only method pushing commits to server ANTIPATTERN DANGER for sharing your code 13 CENTRALIZED GIT ANTI-PATTERN

Slide 68

Slide 68 text

Git Pong Pairing $ git remote add personA $ git fetch personA $ git checkout personA/master $ git checkout -b feature/PA-231 add your changes and commit $ git push personA feature/PA-231 A B $ git checkout feature/PA-231 add your changes and commit $ git pull personA feature/PA-231

Slide 69

Slide 69 text

with the ones in source branch ? how do you sync your commits ANTIPATTERN DANGER 14 MERGE FANATIC ANTI-PATTERN

Slide 70

Slide 70 text

Bug fıx ladder pa!ern occurs when premature merge happens HEAD MASTER

Slide 71

Slide 71 text

FIX master c1 c2 c3 c4 c7 HEAD c5 c6 c5 c6 use rebase $ git rebase master

Slide 72

Slide 72 text

FIX master c1 c2 c3 c4 c7 HEAD c5 c6 c5 c6 use rebase $ git rebase master

Slide 73

Slide 73 text

FIX master c1 c2 c3 c4 c7 HEAD c5 c6 c5 c6 use rebase $ git rebase master

Slide 74

Slide 74 text

FIX master c1 c2 c3 c4 c7 HEAD c5 c6 c5 c6 use rebase $ git rebase master c5 REPLAY #1

Slide 75

Slide 75 text

FIX master c1 c2 c3 c4 c7 HEAD c5 c6 c5 c6 use rebase $ git rebase master c5 REPLAY #2 c6 c6

Slide 76

Slide 76 text

FIX master c1 c2 c3 c4 c7 HEAD c5 c6 c5 c6 use rebase $ git rebase master c5 REWIND c6 c6

Slide 77

Slide 77 text

FIX master c1 c2 c3 c4 c7 HEAD use rebase $ git rebase master c5 FINALIZE c6 c6

Slide 78

Slide 78 text

deleting branches? are you scared of ANTIPATTERN DANGER 15 BRANCH CEMETERY ANTI-PATTERN

Slide 79

Slide 79 text

delete merged local branches $ git branch --merged | grep -v '^* master$' | grep -v '^ master$' | xargs git branch -d delete remote branches $ git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin

Slide 80

Slide 80 text

delete all merged local branches $ git branch --merged | grep -v '^* master$' | grep -v '^ master$' | xargs git branch -d delete all merged remote branches $ git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin

Slide 81

Slide 81 text

wri!en in any form? anyone can push any code ANTIPATTERN DANGER 16 UNCONTROLLED POWER ANTI-PATTERN

Slide 82

Slide 82 text

use pre-receive hooks

Slide 83

Slide 83 text

Depend on each other Too many repositories ANTIPATTERN DANGER for sharing your code 17 WEB OF REPOSITORIES ANTI-PATTERN

Slide 84

Slide 84 text

Mono Repository System Even though our services are still developed and deployed independently, the code for all services lives in one repository The repository contains more than one logical project (e.g. an iOS client and a web-application) These projects are most likely unrelated, loosely connected or can be connected by other means (e.g via dependency management tools) Twi#er, Facebook, Google, Digital Ocean, Foursquare, Etsy, Shippable, Plataformatec, Ravelin

Slide 85

Slide 85 text

You can not do CI without using monorepos - Xebia “When you start a new project,” Potvin tells WIRED, “you have a wealth of libraries already available to you. Almost everything has already been done.” - Rachel Potvin, Engineering Manager at Google Our productivity has increased at least 5x. - Shippable

Slide 86

Slide 86 text

v1, v2, v3… having branch for every release ANTIPATTERN DANGER 18 ORACLE SYNDROME ANTI-PATTERN at the same time

Slide 87

Slide 87 text

Commit early & o"en perfect later, publish once philosophy Deploy frequently be prepared to send every single commit Newer keep release branches for a long time master branch should be enough for all your needs

Slide 88

Slide 88 text

to git repo you pushed confidential info ANTIPATTERN DANGER 19 WAITING FOR HACKERS ANTI-PATTERN

Slide 89

Slide 89 text

Ref: https://help.github.com/articles/remove-sensitive-data/

Slide 90

Slide 90 text

Do you know what evil merge is? ANTIPATTERN DANGER 20 EVIL MERGE ANTI-PATTERN

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

do you use feature branches when there is no product at all ANTIPATTERN DANGER 21 BRANCH OVERDOSE ANTI-PATTERN

Slide 93

Slide 93 text

use single branch topic branches simply make everything more complex

Slide 94

Slide 94 text

Scared on using git commands ANTIPATTERN DANGER 22 CHUCKY THE COMMAND ANTI-PATTERN

Slide 95

Slide 95 text

push add dosya güncelleme committed Track ediliyor untracked unmodified pushed modified staged Staging Alanında Local Repoda Uzak Repoda added add commit commit

Slide 96

Slide 96 text

hard reset committed Track ediliyor untracked unmodified pushed modified staged Staging Alanında Local Repoda Uzak Repoda added hard reset hard reset mixed reset mixed reset soft reset rm --cached rm x

Slide 97

Slide 97 text

h"ps://github.com/lemiorhan/git-kata

Slide 98

Slide 98 text

no one knows git perfect do you suffer? ANTIPATTERN DANGER 23 NO HERO TO SAVE LIVES ANTI-PATTERN

Slide 99

Slide 99 text

have a git-man at least one developer should expertise on git for supporting the others

Slide 100

Slide 100 text

Having duplicate commits & Having irrelevant merge commits if you haven’t pushed yet ANTIPATTERN DANGER 24 DUPLICATE COMMITS ANTI-PATTERN

Slide 101

Slide 101 text

No content

Slide 102

Slide 102 text

UPSTREAM LOCAL master c1 c2 c3 c4 c7 c5 c6 c5 c6 FIX HEAD master c1 c2 c3 c4 c7 c5 c6 c5 c6 FIX rebase and push

Slide 103

Slide 103 text

UPSTREAM LOCAL master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX HEAD master c1 c2 c3 c4 c7 c5 c6 c5 c6 FIX $ git rebase master rebase and push

Slide 104

Slide 104 text

UPSTREAM LOCAL master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX HEAD master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX $ git push -f rebase and push

Slide 105

Slide 105 text

UPSTREAM LOCAL master c1 c2 c3 c4 c7 c5 c6 c5 c6 FIX HEAD master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX pull rebased branch

Slide 106

Slide 106 text

UPSTREAM LOCAL master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX HEAD master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX $ git pull --rebase pull rebased branch

Slide 107

Slide 107 text

UPSTREAM LOCAL master c1 c2 c3 c4 c7 c5 c6 c5 c6 FIX HEAD master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX c5 c6 c5’ c6’ ORIGIN/FIX $ git pull pull rebased branch:(

Slide 108

Slide 108 text

UPSTREAM LOCAL c1 c2 c3 c4 c7 c5 c6 c5 c6 master c1 c2 c3 c4 c7 c5 c6 c5’ c6’ FIX c5 c6 c5’ c6’ c8 $ git pull master FIX HEAD ORIGIN/FIX pull rebased branch:(

Slide 109

Slide 109 text

we commit when we have something big ANTIPATTERN DANGER 25 BIG FAT COMMIT ANTI-PATTERN

Slide 110

Slide 110 text

use TDD style whenever tests pass, commit that makes you commit early and o!en

Slide 111

Slide 111 text

are you scared of using rebase? ANTIPATTERN DANGER 26 REBASE-FOBIA ANTI-PATTERN

Slide 112

Slide 112 text

rebase not to merge your unpushed commits with the fetched ones use pull with prepared by @lemiorhan rebase to get rebased commits from upstream safely use pull with REBASE feature branches to integrate into public branches that you pushed or that you pulled from another person Never use Rebase USE

Slide 113

Slide 113 text

do you know when we get conflicts and how to resolve it? ANTIPATTERN DANGER 27 CONFLICT-FOBIA ANTI-PATTERN

Slide 114

Slide 114 text

No content

Slide 115

Slide 115 text

No content

Slide 116

Slide 116 text

RECAP what was really happened at that time? LET’S

Slide 117

Slide 117 text

master TAG/v1.1 login HEAD DETACHED HEAD STATE $ git checkout cecd95914 Note: checking out 'cecd95914'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. LIVING AT DETACHED HEAD STATE ANTI-PATTERN 28 ANTIPATTERN DANGER

Slide 118

Slide 118 text

master TAG/v1.1 login HEAD DETACHED HEAD STATE $ git rebase (and conflicts happen) $ git checkout HEAD~2 $ git checkout 43e3ab01 $ git checkout tags/v1.1 WHEN IT HAPPENS

Slide 119

Slide 119 text

master TAG/v1.1 login HEAD poor little developer...

Slide 120

Slide 120 text

master TAG/v1.1 login HEAD $ git checkout master

Slide 121

Slide 121 text

master TAG/v1.1 login HEAD $ git reflog aa67e3a2c HEAD@{0}: rebase finished: returning to refs/heads/fix/java-sql-Date-violates-LSR aa67e3a2c HEAD@{1}: rebase: fixes UnsupportedOperationException while calling toIstant() method of java.sql.Date a45f3c4e5 HEAD@{2}: rebase: checkout develop 630ddad6e HEAD@{3}: checkout: moving from develop to fix/java-sql-Date-violates-LSR b26cf7a1a HEAD@{4}: rebase: checkout develop 630ddad6e HEAD@{5}: checkout: moving from develop to fix/java-sql-Date-violates-LSR b26cf7a1a HEAD@{6}: pull: Fast-forward 8b59f8f50 HEAD@{7}: checkout: moving from fix/java-sql-Date-violates-LSR to develop

Slide 122

Slide 122 text

$ git reflog 630ddad6e the one we are searching for master TAG/v1.1 login HEAD aa67e3a2c HEAD@{0}: rebase finished: returning to refs/heads/fix/java-sql-Date-violates-LSR aa67e3a2c HEAD@{1}: rebase: fixes UnsupportedOperationException while calling toIstant() method of java.sql.Date a45f3c4e5 HEAD@{2}: rebase: checkout develop 630ddad6e HEAD@{3}: checkout: moving from develop to fix/java-sql-Date-violates-LSR b26cf7a1a HEAD@{4}: rebase: checkout develop 630ddad6e HEAD@{5}: checkout: moving from develop to fix/java-sql-Date-violates-LSR b26cf7a1a HEAD@{6}: pull: Fast-forward 8b59f8f50 HEAD@{7}: checkout: moving from fix/java-sql-Date-violates-LSR to develop

Slide 123

Slide 123 text

master typofix TAG/v1.1 login HEAD $ git branch typofix 630ddad6e

Slide 124

Slide 124 text

master typofix TAG/v1.1 login HEAD $ git branch typofix 630ddad6e KEEP CALM, NOTHING WILL BE LOST

Slide 125

Slide 125 text

LEMi ORHAN ERGiN agile software craftsman @ iyzico /lemiorhan lemiorhanergin.com @lemiorhan ANTIPATTERN DANGER