Fossil SCM
Assorted improvements to rebaseharm, mainly grammar and clarity, but also some typo fixes.
Commit
5a7cda57cb9fbe7817472f298aeaf45296e382475b1476d50a493be7a80d890c
Parent
9b068a39799f83a…
1 file changed
+26
-24
+26
-24
| --- www/rebaseharm.md | ||
| +++ www/rebaseharm.md | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | # Rebase Considered Harmful |
| 2 | 2 | |
| 3 | -Fossil deliberately omits a "rebase" command, because the original | |
| 3 | +Fossil deliberately omits a "rebase" command because the original | |
| 4 | 4 | designer of Fossil (and [original author][vhist] of this article) considers rebase to be |
| 5 | 5 | an anti-pattern to be avoided. This article attempts to |
| 6 | 6 | explain that point of view. |
| 7 | 7 | |
| 8 | 8 | [vhist]: /finfo?name=www/rebaseharm.md&ubg |
| @@ -9,11 +9,11 @@ | ||
| 9 | 9 | |
| 10 | 10 | ## 1.0 Rebasing is dangerous |
| 11 | 11 | |
| 12 | 12 | Most people, even strident advocates of rebase, agree that rebase can |
| 13 | 13 | cause problems when misused. The Git rebase documentation talks about the |
| 14 | -[golden rule of rebase][golden]: that it should never be used on a public | |
| 14 | +[golden rule of rebasing][golden]: never rebase on a public | |
| 15 | 15 | branch. Horror stories of misused rebase abound, and the rebase |
| 16 | 16 | documentation devotes considerable space toward explaining how to |
| 17 | 17 | recover from rebase errors and/or misuse. |
| 18 | 18 | |
| 19 | 19 | ## <a name="cap-loss"></a>2.0 Rebase provides no new capabilities |
| @@ -57,11 +57,11 @@ | ||
| 57 | 57 | important. |
| 58 | 58 | |
| 59 | 59 | So, another way of thinking about rebase is that it is a kind of |
| 60 | 60 | merge that intentionally forgets some details in order to |
| 61 | 61 | not overwhelm the weak history display mechanisms available in Git. |
| 62 | -Wouldn't it be better, less error-prone, and easier on users, | |
| 62 | +Wouldn't it be better, less error-prone, and easier on users | |
| 63 | 63 | to enhance the history display mechanisms in Git so that rebasing |
| 64 | 64 | for a clean, linear history became unnecessary? |
| 65 | 65 | |
| 66 | 66 | ### <a name="clean-diffs"></a>2.2 Rebase does not actually provide better feature-branch diffs |
| 67 | 67 | |
| @@ -73,32 +73,33 @@ | ||
| 73 | 73 |  |
| 74 | 74 | |
| 75 | 75 | In the above, a feature branch consisting of check-ins C3 and C5 is |
| 76 | 76 | run concurrently with the main line in check-ins C4 and C6. Advocates |
| 77 | 77 | for rebase say that you should rebase the feature branch to the tip |
| 78 | -of main like the following: | |
| 78 | +of main in order to remove main-line development differences from | |
| 79 | +the feature branch's history: | |
| 79 | 80 | |
| 80 | 81 |  |
| 81 | 82 | |
| 82 | 83 | You could choose to collapse C3\' and C5\' into a single check-in |
| 83 | 84 | as part of this rebase, but that's a side issue we'll deal with |
| 84 | 85 | [separately](#collapsing). |
| 85 | 86 | |
| 86 | -If only merge is available, one would do a merge from the concurrent | |
| 87 | -mainline changes into the feature branch as follows: | |
| 87 | +Fossil lacks rebase, so the closest you can get to this same check-in | |
| 88 | +history is the following merge: | |
| 88 | 89 | |
| 89 | 90 |  |
| 90 | 91 | |
| 91 | 92 | Check-ins C5\' and C7 check-ins hold identical code. The only |
| 92 | 93 | difference is in their history. |
| 93 | 94 | |
| 94 | 95 | The argument from rebase advocates |
| 95 | 96 | is that with merge it is difficult to see only the changes associated |
| 96 | 97 | with the feature branch without the commingled mainline changes. |
| 97 | -In other words, diff(C2,C7) shows changes associated both the feature | |
| 98 | +In other words, diff(C2,C7) shows changes from both the feature | |
| 98 | 99 | branch and from the mainline, whereas in the rebase case |
| 99 | -diff(C6,C5\') should only the feature branch changes. | |
| 100 | +diff(C6,C5\') shows only the feature branch changes. | |
| 100 | 101 | |
| 101 | 102 | But that argument is comparing apples to oranges, since the two diffs |
| 102 | 103 | do not have the same baseline. The correct way to see only the feature |
| 103 | 104 | branch changes in the merge case is not diff(C2,C7) but rather diff(C6,C7). |
| 104 | 105 | |
| @@ -116,20 +117,21 @@ | ||
| 116 | 117 | branch, perhaps what is needed is not rebase but rather better tools to |
| 117 | 118 | help users identify an appropriate baseline for their diffs. |
| 118 | 119 | |
| 119 | 120 | ## <a name="siloing"></a>3.0 Rebase encourages siloed development |
| 120 | 121 | |
| 121 | -The [golden rule of rebase][golden] is that you should never do it | |
| 122 | +The [golden rule of rebasing][golden] is that you should never do it | |
| 122 | 123 | on public branches, so if you are using rebase as intended, that means |
| 123 | 124 | you are keeping private branches. Or, to put it another way, you are |
| 124 | 125 | doing siloed development. You are not sharing your intermediate work |
| 125 | 126 | with collaborators. This is not good for product quality. |
| 126 | 127 | |
| 127 | 128 | [Nagappan, et. al][nagappan] studied bugs in Windows Vista and found |
| 128 | 129 | that best predictor of bugs is the distance on the org-chart between |
| 129 | -the stake-holders. Or, bugs are reduced when the engineers talk to | |
| 130 | -one another. Similar findings arise in other disciplines. Keeping | |
| 130 | +the stake-holders. The bug rate is inversely related to the | |
| 131 | +amount of communication among the engineers. | |
| 132 | +Similar findings arise in other disciplines. Keeping | |
| 131 | 133 | private branches does not prove that developers are communicating |
| 132 | 134 | insufficiently, but it is a key symptom that problem. |
| 133 | 135 | |
| 134 | 136 | [Weinberg][weinberg] argues programming should be "egoless." That |
| 135 | 137 | is to say, programmers should avoid linking their code with their sense of |
| @@ -136,11 +138,11 @@ | ||
| 136 | 138 | self, as that makes it more difficult for them to find and respond |
| 137 | 139 | to bugs, and hence makes them less productive. Many developers are |
| 138 | 140 | drawn to private branches out of sense of ego. "I want to get the |
| 139 | 141 | code right before I publish it." I sympathize with this sentiment, |
| 140 | 142 | and am frequently guilty of it myself. It is humbling to display |
| 141 | -your stupid mistake to the whole world on an internet that | |
| 143 | +your stupid mistake to the whole world on an Internet that | |
| 142 | 144 | never forgets. And yet, humble programmers generate better code. |
| 143 | 145 | |
| 144 | 146 | What is the fastest path to solid code? Is it to continue staring at |
| 145 | 147 | your private branch to seek out every last bug, or is it to publish it |
| 146 | 148 | as-is, whereupon the many eyeballs will immediately see that last stupid |
| @@ -164,11 +166,11 @@ | ||
| 164 | 166 | |
| 165 | 167 | Of course, a user can also commit untested or broken check-ins without |
| 166 | 168 | the help of rebase. But at least with an ordinary commit or merge |
| 167 | 169 | (in Fossil at least), the operator |
| 168 | 170 | has the *opportunity* to test and verify the merge before it is committed, |
| 169 | -and a chance to back out or fix the change if it is broken, without leaving | |
| 171 | +and a chance to back out or fix the change if it is broken without leaving | |
| 170 | 172 | busted check-ins on the blockchain to complicate future bisects. |
| 171 | 173 | |
| 172 | 174 | With rebase, pre-commit testing is not an option. |
| 173 | 175 | |
| 174 | 176 | ## <a name="timestamps"></a>5.0 Rebase causes timestamp confusion |
| @@ -179,16 +181,16 @@ | ||
| 179 | 181 | |
| 180 | 182 | What timestamps go on the C3\' and C5\' check-ins? If you choose |
| 181 | 183 | the same timestamps as the original C3 and C5, then you have the |
| 182 | 184 | odd situation C3' is older than its parent C6. We call that a |
| 183 | 185 | "timewarp" in Fossil. Timewarps can also happen due to misconfigured |
| 184 | -system clocks, so they are not unique to rebase. But they are very | |
| 185 | -confusing and best avoided. The other option is to provide new | |
| 186 | -unique timestamps for C3' and C5'. But then you lose the information | |
| 186 | +system clocks, so they are not unique to rebase, but they are very | |
| 187 | +confusing and so best avoided. The other option is to provide new | |
| 188 | +unique timestamps for C3' and C5' but then you lose the information | |
| 187 | 189 | about when those check-ins were originally created, which can make |
| 188 | -historical analysis of changes more difficult, and might also | |
| 189 | -complicate prior art claims. | |
| 190 | +historical analysis of changes more difficult. It might also | |
| 191 | +complicate the legal defense of prior art claims. | |
| 190 | 192 | |
| 191 | 193 | ## <a name="lying"></a>6.0 Rebasing is lying about the project history |
| 192 | 194 | |
| 193 | 195 | By discarding parentage information, rebase attempts to deceive the |
| 194 | 196 | reader about how the code actually came together. |
| @@ -210,11 +212,11 @@ | ||
| 210 | 212 | |
| 211 | 213 | In fairness to the Git documentation authors, changing the |
| 212 | 214 | project history appears to be the only way to make editorial |
| 213 | 215 | changes in Git. |
| 214 | 216 | But it does not have to be that way. |
| 215 | -Fossil demonstrations how "the story of your project" | |
| 217 | +Fossil demonstrates how "the story of your project" | |
| 216 | 218 | can be enhanced without changing the actual history |
| 217 | 219 | by allowing users to: |
| 218 | 220 | |
| 219 | 221 | 1. Edit check-in comments to fix typos or enhance clarity |
| 220 | 222 | 2. Attach supplemental notes to check-ins or whole branches |
| @@ -272,11 +274,11 @@ | ||
| 272 | 274 | develop software that was easy to understand retrospectively, even if |
| 273 | 275 | they were selfish people, because they knew they might end up being |
| 274 | 276 | those future developers! |
| 275 | 277 | |
| 276 | 278 | Yet, sometimes we come upon a piece of code that we simply cannot |
| 277 | -understand. If you have never asked yourself,a "What was this code's | |
| 279 | +understand. If you have never asked yourself, "What was this code's | |
| 278 | 280 | developer thinking?" you haven't been developing software for very long. |
| 279 | 281 | |
| 280 | 282 | When a developer can go back to the individual check-ins leading up to |
| 281 | 283 | the current code, they can work out the answers to such questions using |
| 282 | 284 | only the level of empathy necessary to be a good developer. To |
| @@ -323,11 +325,11 @@ | ||
| 323 | 325 | the problem. |
| 324 | 326 | |
| 325 | 327 | ### <a name="comments"></a>7.3 Multiple check-ins require multiple check-in comments |
| 326 | 328 | |
| 327 | 329 | The more comments you have from a given developer on a given body of |
| 328 | -code, the more concise documentation you have of that developer'as | |
| 330 | +code, the more concise documentation you have of that developer's | |
| 329 | 331 | thought process. To resume the bisecting example, a developer trying to |
| 330 | 332 | work out what the original developer was thinking with a given change |
| 331 | 333 | will have more success given a check-in comment that explains what the |
| 332 | 334 | one check-in out of ten blamed by the "bisect" command was trying to |
| 333 | 335 | accomplish than if they must work that out from the eleventh check-in's |
| @@ -386,13 +388,13 @@ | ||
| 386 | 388 | merge check-in or back out the entire feature. |
| 387 | 389 | |
| 388 | 390 | ## <a name="better-plan"></a>8.0 Cherry-pick merges work better than rebase |
| 389 | 391 | |
| 390 | 392 | Perhaps there are some cases where a rebase-like transformation |
| 391 | -is actually helpful. But those cases are rare. And when they do | |
| 392 | -come up, running a series of cherry-pick merges achieve the same | |
| 393 | -topology, but with advantages: | |
| 393 | +is actually helpful, but those cases are rare, and when they do | |
| 394 | +come up, running a series of cherry-pick merges achieves the same | |
| 395 | +topology with several advantages: | |
| 394 | 396 | |
| 395 | 397 | 1. Cherry-pick merges preserve an honest record of history. |
| 396 | 398 | (They do in Fossil at least. Git's file format does not have |
| 397 | 399 | a slot to record cherry-pick merge history, unfortunately.) |
| 398 | 400 | |
| 399 | 401 |
| --- www/rebaseharm.md | |
| +++ www/rebaseharm.md | |
| @@ -1,8 +1,8 @@ | |
| 1 | # Rebase Considered Harmful |
| 2 | |
| 3 | Fossil deliberately omits a "rebase" command, because the original |
| 4 | designer of Fossil (and [original author][vhist] of this article) considers rebase to be |
| 5 | an anti-pattern to be avoided. This article attempts to |
| 6 | explain that point of view. |
| 7 | |
| 8 | [vhist]: /finfo?name=www/rebaseharm.md&ubg |
| @@ -9,11 +9,11 @@ | |
| 9 | |
| 10 | ## 1.0 Rebasing is dangerous |
| 11 | |
| 12 | Most people, even strident advocates of rebase, agree that rebase can |
| 13 | cause problems when misused. The Git rebase documentation talks about the |
| 14 | [golden rule of rebase][golden]: that it should never be used on a public |
| 15 | branch. Horror stories of misused rebase abound, and the rebase |
| 16 | documentation devotes considerable space toward explaining how to |
| 17 | recover from rebase errors and/or misuse. |
| 18 | |
| 19 | ## <a name="cap-loss"></a>2.0 Rebase provides no new capabilities |
| @@ -57,11 +57,11 @@ | |
| 57 | important. |
| 58 | |
| 59 | So, another way of thinking about rebase is that it is a kind of |
| 60 | merge that intentionally forgets some details in order to |
| 61 | not overwhelm the weak history display mechanisms available in Git. |
| 62 | Wouldn't it be better, less error-prone, and easier on users, |
| 63 | to enhance the history display mechanisms in Git so that rebasing |
| 64 | for a clean, linear history became unnecessary? |
| 65 | |
| 66 | ### <a name="clean-diffs"></a>2.2 Rebase does not actually provide better feature-branch diffs |
| 67 | |
| @@ -73,32 +73,33 @@ | |
| 73 |  |
| 74 | |
| 75 | In the above, a feature branch consisting of check-ins C3 and C5 is |
| 76 | run concurrently with the main line in check-ins C4 and C6. Advocates |
| 77 | for rebase say that you should rebase the feature branch to the tip |
| 78 | of main like the following: |
| 79 | |
| 80 |  |
| 81 | |
| 82 | You could choose to collapse C3\' and C5\' into a single check-in |
| 83 | as part of this rebase, but that's a side issue we'll deal with |
| 84 | [separately](#collapsing). |
| 85 | |
| 86 | If only merge is available, one would do a merge from the concurrent |
| 87 | mainline changes into the feature branch as follows: |
| 88 | |
| 89 |  |
| 90 | |
| 91 | Check-ins C5\' and C7 check-ins hold identical code. The only |
| 92 | difference is in their history. |
| 93 | |
| 94 | The argument from rebase advocates |
| 95 | is that with merge it is difficult to see only the changes associated |
| 96 | with the feature branch without the commingled mainline changes. |
| 97 | In other words, diff(C2,C7) shows changes associated both the feature |
| 98 | branch and from the mainline, whereas in the rebase case |
| 99 | diff(C6,C5\') should only the feature branch changes. |
| 100 | |
| 101 | But that argument is comparing apples to oranges, since the two diffs |
| 102 | do not have the same baseline. The correct way to see only the feature |
| 103 | branch changes in the merge case is not diff(C2,C7) but rather diff(C6,C7). |
| 104 | |
| @@ -116,20 +117,21 @@ | |
| 116 | branch, perhaps what is needed is not rebase but rather better tools to |
| 117 | help users identify an appropriate baseline for their diffs. |
| 118 | |
| 119 | ## <a name="siloing"></a>3.0 Rebase encourages siloed development |
| 120 | |
| 121 | The [golden rule of rebase][golden] is that you should never do it |
| 122 | on public branches, so if you are using rebase as intended, that means |
| 123 | you are keeping private branches. Or, to put it another way, you are |
| 124 | doing siloed development. You are not sharing your intermediate work |
| 125 | with collaborators. This is not good for product quality. |
| 126 | |
| 127 | [Nagappan, et. al][nagappan] studied bugs in Windows Vista and found |
| 128 | that best predictor of bugs is the distance on the org-chart between |
| 129 | the stake-holders. Or, bugs are reduced when the engineers talk to |
| 130 | one another. Similar findings arise in other disciplines. Keeping |
| 131 | private branches does not prove that developers are communicating |
| 132 | insufficiently, but it is a key symptom that problem. |
| 133 | |
| 134 | [Weinberg][weinberg] argues programming should be "egoless." That |
| 135 | is to say, programmers should avoid linking their code with their sense of |
| @@ -136,11 +138,11 @@ | |
| 136 | self, as that makes it more difficult for them to find and respond |
| 137 | to bugs, and hence makes them less productive. Many developers are |
| 138 | drawn to private branches out of sense of ego. "I want to get the |
| 139 | code right before I publish it." I sympathize with this sentiment, |
| 140 | and am frequently guilty of it myself. It is humbling to display |
| 141 | your stupid mistake to the whole world on an internet that |
| 142 | never forgets. And yet, humble programmers generate better code. |
| 143 | |
| 144 | What is the fastest path to solid code? Is it to continue staring at |
| 145 | your private branch to seek out every last bug, or is it to publish it |
| 146 | as-is, whereupon the many eyeballs will immediately see that last stupid |
| @@ -164,11 +166,11 @@ | |
| 164 | |
| 165 | Of course, a user can also commit untested or broken check-ins without |
| 166 | the help of rebase. But at least with an ordinary commit or merge |
| 167 | (in Fossil at least), the operator |
| 168 | has the *opportunity* to test and verify the merge before it is committed, |
| 169 | and a chance to back out or fix the change if it is broken, without leaving |
| 170 | busted check-ins on the blockchain to complicate future bisects. |
| 171 | |
| 172 | With rebase, pre-commit testing is not an option. |
| 173 | |
| 174 | ## <a name="timestamps"></a>5.0 Rebase causes timestamp confusion |
| @@ -179,16 +181,16 @@ | |
| 179 | |
| 180 | What timestamps go on the C3\' and C5\' check-ins? If you choose |
| 181 | the same timestamps as the original C3 and C5, then you have the |
| 182 | odd situation C3' is older than its parent C6. We call that a |
| 183 | "timewarp" in Fossil. Timewarps can also happen due to misconfigured |
| 184 | system clocks, so they are not unique to rebase. But they are very |
| 185 | confusing and best avoided. The other option is to provide new |
| 186 | unique timestamps for C3' and C5'. But then you lose the information |
| 187 | about when those check-ins were originally created, which can make |
| 188 | historical analysis of changes more difficult, and might also |
| 189 | complicate prior art claims. |
| 190 | |
| 191 | ## <a name="lying"></a>6.0 Rebasing is lying about the project history |
| 192 | |
| 193 | By discarding parentage information, rebase attempts to deceive the |
| 194 | reader about how the code actually came together. |
| @@ -210,11 +212,11 @@ | |
| 210 | |
| 211 | In fairness to the Git documentation authors, changing the |
| 212 | project history appears to be the only way to make editorial |
| 213 | changes in Git. |
| 214 | But it does not have to be that way. |
| 215 | Fossil demonstrations how "the story of your project" |
| 216 | can be enhanced without changing the actual history |
| 217 | by allowing users to: |
| 218 | |
| 219 | 1. Edit check-in comments to fix typos or enhance clarity |
| 220 | 2. Attach supplemental notes to check-ins or whole branches |
| @@ -272,11 +274,11 @@ | |
| 272 | develop software that was easy to understand retrospectively, even if |
| 273 | they were selfish people, because they knew they might end up being |
| 274 | those future developers! |
| 275 | |
| 276 | Yet, sometimes we come upon a piece of code that we simply cannot |
| 277 | understand. If you have never asked yourself,a "What was this code's |
| 278 | developer thinking?" you haven't been developing software for very long. |
| 279 | |
| 280 | When a developer can go back to the individual check-ins leading up to |
| 281 | the current code, they can work out the answers to such questions using |
| 282 | only the level of empathy necessary to be a good developer. To |
| @@ -323,11 +325,11 @@ | |
| 323 | the problem. |
| 324 | |
| 325 | ### <a name="comments"></a>7.3 Multiple check-ins require multiple check-in comments |
| 326 | |
| 327 | The more comments you have from a given developer on a given body of |
| 328 | code, the more concise documentation you have of that developer'as |
| 329 | thought process. To resume the bisecting example, a developer trying to |
| 330 | work out what the original developer was thinking with a given change |
| 331 | will have more success given a check-in comment that explains what the |
| 332 | one check-in out of ten blamed by the "bisect" command was trying to |
| 333 | accomplish than if they must work that out from the eleventh check-in's |
| @@ -386,13 +388,13 @@ | |
| 386 | merge check-in or back out the entire feature. |
| 387 | |
| 388 | ## <a name="better-plan"></a>8.0 Cherry-pick merges work better than rebase |
| 389 | |
| 390 | Perhaps there are some cases where a rebase-like transformation |
| 391 | is actually helpful. But those cases are rare. And when they do |
| 392 | come up, running a series of cherry-pick merges achieve the same |
| 393 | topology, but with advantages: |
| 394 | |
| 395 | 1. Cherry-pick merges preserve an honest record of history. |
| 396 | (They do in Fossil at least. Git's file format does not have |
| 397 | a slot to record cherry-pick merge history, unfortunately.) |
| 398 | |
| 399 |
| --- www/rebaseharm.md | |
| +++ www/rebaseharm.md | |
| @@ -1,8 +1,8 @@ | |
| 1 | # Rebase Considered Harmful |
| 2 | |
| 3 | Fossil deliberately omits a "rebase" command because the original |
| 4 | designer of Fossil (and [original author][vhist] of this article) considers rebase to be |
| 5 | an anti-pattern to be avoided. This article attempts to |
| 6 | explain that point of view. |
| 7 | |
| 8 | [vhist]: /finfo?name=www/rebaseharm.md&ubg |
| @@ -9,11 +9,11 @@ | |
| 9 | |
| 10 | ## 1.0 Rebasing is dangerous |
| 11 | |
| 12 | Most people, even strident advocates of rebase, agree that rebase can |
| 13 | cause problems when misused. The Git rebase documentation talks about the |
| 14 | [golden rule of rebasing][golden]: never rebase on a public |
| 15 | branch. Horror stories of misused rebase abound, and the rebase |
| 16 | documentation devotes considerable space toward explaining how to |
| 17 | recover from rebase errors and/or misuse. |
| 18 | |
| 19 | ## <a name="cap-loss"></a>2.0 Rebase provides no new capabilities |
| @@ -57,11 +57,11 @@ | |
| 57 | important. |
| 58 | |
| 59 | So, another way of thinking about rebase is that it is a kind of |
| 60 | merge that intentionally forgets some details in order to |
| 61 | not overwhelm the weak history display mechanisms available in Git. |
| 62 | Wouldn't it be better, less error-prone, and easier on users |
| 63 | to enhance the history display mechanisms in Git so that rebasing |
| 64 | for a clean, linear history became unnecessary? |
| 65 | |
| 66 | ### <a name="clean-diffs"></a>2.2 Rebase does not actually provide better feature-branch diffs |
| 67 | |
| @@ -73,32 +73,33 @@ | |
| 73 |  |
| 74 | |
| 75 | In the above, a feature branch consisting of check-ins C3 and C5 is |
| 76 | run concurrently with the main line in check-ins C4 and C6. Advocates |
| 77 | for rebase say that you should rebase the feature branch to the tip |
| 78 | of main in order to remove main-line development differences from |
| 79 | the feature branch's history: |
| 80 | |
| 81 |  |
| 82 | |
| 83 | You could choose to collapse C3\' and C5\' into a single check-in |
| 84 | as part of this rebase, but that's a side issue we'll deal with |
| 85 | [separately](#collapsing). |
| 86 | |
| 87 | Fossil lacks rebase, so the closest you can get to this same check-in |
| 88 | history is the following merge: |
| 89 | |
| 90 |  |
| 91 | |
| 92 | Check-ins C5\' and C7 check-ins hold identical code. The only |
| 93 | difference is in their history. |
| 94 | |
| 95 | The argument from rebase advocates |
| 96 | is that with merge it is difficult to see only the changes associated |
| 97 | with the feature branch without the commingled mainline changes. |
| 98 | In other words, diff(C2,C7) shows changes from both the feature |
| 99 | branch and from the mainline, whereas in the rebase case |
| 100 | diff(C6,C5\') shows only the feature branch changes. |
| 101 | |
| 102 | But that argument is comparing apples to oranges, since the two diffs |
| 103 | do not have the same baseline. The correct way to see only the feature |
| 104 | branch changes in the merge case is not diff(C2,C7) but rather diff(C6,C7). |
| 105 | |
| @@ -116,20 +117,21 @@ | |
| 117 | branch, perhaps what is needed is not rebase but rather better tools to |
| 118 | help users identify an appropriate baseline for their diffs. |
| 119 | |
| 120 | ## <a name="siloing"></a>3.0 Rebase encourages siloed development |
| 121 | |
| 122 | The [golden rule of rebasing][golden] is that you should never do it |
| 123 | on public branches, so if you are using rebase as intended, that means |
| 124 | you are keeping private branches. Or, to put it another way, you are |
| 125 | doing siloed development. You are not sharing your intermediate work |
| 126 | with collaborators. This is not good for product quality. |
| 127 | |
| 128 | [Nagappan, et. al][nagappan] studied bugs in Windows Vista and found |
| 129 | that best predictor of bugs is the distance on the org-chart between |
| 130 | the stake-holders. The bug rate is inversely related to the |
| 131 | amount of communication among the engineers. |
| 132 | Similar findings arise in other disciplines. Keeping |
| 133 | private branches does not prove that developers are communicating |
| 134 | insufficiently, but it is a key symptom that problem. |
| 135 | |
| 136 | [Weinberg][weinberg] argues programming should be "egoless." That |
| 137 | is to say, programmers should avoid linking their code with their sense of |
| @@ -136,11 +138,11 @@ | |
| 138 | self, as that makes it more difficult for them to find and respond |
| 139 | to bugs, and hence makes them less productive. Many developers are |
| 140 | drawn to private branches out of sense of ego. "I want to get the |
| 141 | code right before I publish it." I sympathize with this sentiment, |
| 142 | and am frequently guilty of it myself. It is humbling to display |
| 143 | your stupid mistake to the whole world on an Internet that |
| 144 | never forgets. And yet, humble programmers generate better code. |
| 145 | |
| 146 | What is the fastest path to solid code? Is it to continue staring at |
| 147 | your private branch to seek out every last bug, or is it to publish it |
| 148 | as-is, whereupon the many eyeballs will immediately see that last stupid |
| @@ -164,11 +166,11 @@ | |
| 166 | |
| 167 | Of course, a user can also commit untested or broken check-ins without |
| 168 | the help of rebase. But at least with an ordinary commit or merge |
| 169 | (in Fossil at least), the operator |
| 170 | has the *opportunity* to test and verify the merge before it is committed, |
| 171 | and a chance to back out or fix the change if it is broken without leaving |
| 172 | busted check-ins on the blockchain to complicate future bisects. |
| 173 | |
| 174 | With rebase, pre-commit testing is not an option. |
| 175 | |
| 176 | ## <a name="timestamps"></a>5.0 Rebase causes timestamp confusion |
| @@ -179,16 +181,16 @@ | |
| 181 | |
| 182 | What timestamps go on the C3\' and C5\' check-ins? If you choose |
| 183 | the same timestamps as the original C3 and C5, then you have the |
| 184 | odd situation C3' is older than its parent C6. We call that a |
| 185 | "timewarp" in Fossil. Timewarps can also happen due to misconfigured |
| 186 | system clocks, so they are not unique to rebase, but they are very |
| 187 | confusing and so best avoided. The other option is to provide new |
| 188 | unique timestamps for C3' and C5' but then you lose the information |
| 189 | about when those check-ins were originally created, which can make |
| 190 | historical analysis of changes more difficult. It might also |
| 191 | complicate the legal defense of prior art claims. |
| 192 | |
| 193 | ## <a name="lying"></a>6.0 Rebasing is lying about the project history |
| 194 | |
| 195 | By discarding parentage information, rebase attempts to deceive the |
| 196 | reader about how the code actually came together. |
| @@ -210,11 +212,11 @@ | |
| 212 | |
| 213 | In fairness to the Git documentation authors, changing the |
| 214 | project history appears to be the only way to make editorial |
| 215 | changes in Git. |
| 216 | But it does not have to be that way. |
| 217 | Fossil demonstrates how "the story of your project" |
| 218 | can be enhanced without changing the actual history |
| 219 | by allowing users to: |
| 220 | |
| 221 | 1. Edit check-in comments to fix typos or enhance clarity |
| 222 | 2. Attach supplemental notes to check-ins or whole branches |
| @@ -272,11 +274,11 @@ | |
| 274 | develop software that was easy to understand retrospectively, even if |
| 275 | they were selfish people, because they knew they might end up being |
| 276 | those future developers! |
| 277 | |
| 278 | Yet, sometimes we come upon a piece of code that we simply cannot |
| 279 | understand. If you have never asked yourself, "What was this code's |
| 280 | developer thinking?" you haven't been developing software for very long. |
| 281 | |
| 282 | When a developer can go back to the individual check-ins leading up to |
| 283 | the current code, they can work out the answers to such questions using |
| 284 | only the level of empathy necessary to be a good developer. To |
| @@ -323,11 +325,11 @@ | |
| 325 | the problem. |
| 326 | |
| 327 | ### <a name="comments"></a>7.3 Multiple check-ins require multiple check-in comments |
| 328 | |
| 329 | The more comments you have from a given developer on a given body of |
| 330 | code, the more concise documentation you have of that developer's |
| 331 | thought process. To resume the bisecting example, a developer trying to |
| 332 | work out what the original developer was thinking with a given change |
| 333 | will have more success given a check-in comment that explains what the |
| 334 | one check-in out of ten blamed by the "bisect" command was trying to |
| 335 | accomplish than if they must work that out from the eleventh check-in's |
| @@ -386,13 +388,13 @@ | |
| 388 | merge check-in or back out the entire feature. |
| 389 | |
| 390 | ## <a name="better-plan"></a>8.0 Cherry-pick merges work better than rebase |
| 391 | |
| 392 | Perhaps there are some cases where a rebase-like transformation |
| 393 | is actually helpful, but those cases are rare, and when they do |
| 394 | come up, running a series of cherry-pick merges achieves the same |
| 395 | topology with several advantages: |
| 396 | |
| 397 | 1. Cherry-pick merges preserve an honest record of history. |
| 398 | (They do in Fossil at least. Git's file format does not have |
| 399 | a slot to record cherry-pick merge history, unfortunately.) |
| 400 | |
| 401 |