Fossil SCM
Removed point 4.0 from the rebaseharm doc: it said that rebase is a problem because Git makes the change immediately to the blockchain, but that's a problem with Git in general, due to its commit-then-push model, not a problem with rebase in particular. If Fossil had a rebase feature, there is no good reason to believe we would do this as well. Therefore, this point is a distraction from the main argument. Besides, we already cover it as fossil-v-git.wiki#testing.
Commit
6e0dba257b226383c8d61e5decfd61231f9f81793d1510eed132d98928e89c8b
Parent
a61ac66b63a3c75…
1 file changed
+10
-27
+10
-27
| --- www/rebaseharm.md | ||
| +++ www/rebaseharm.md | ||
| @@ -251,28 +251,11 @@ | ||
| 251 | 251 | while they're still isolated on a feature branch, or should that vetting |
| 252 | 252 | wait until you finally push a collapsed version of a private working |
| 253 | 253 | branch to the parent repo? Will the many eyeballs even see those errors |
| 254 | 254 | when they’re intermingled with code implementing some compelling new feature? |
| 255 | 255 | |
| 256 | -## <a name="testing"></a>4.0 Rebase commits untested check-ins to the blockchain | |
| 257 | - | |
| 258 | -Rebase adds new check-ins to the blockchain without giving the operator | |
| 259 | -an opportunity to test and verify those check-ins. Just because the | |
| 260 | -underlying three-way merge had no conflict does not mean that the resulting | |
| 261 | -code actually works. Thus, rebase runs the very real risk of adding | |
| 262 | -non-functional check-ins to the permanent record. | |
| 263 | - | |
| 264 | -Of course, a user can also commit untested or broken check-ins without | |
| 265 | -the help of rebase. But at least with an ordinary commit or merge | |
| 266 | -(in Fossil at least), the operator | |
| 267 | -has the *opportunity* to test and verify the merge before it is committed, | |
| 268 | -and a chance to back out or fix the change if it is broken without leaving | |
| 269 | -busted check-ins on the blockchain to complicate future bisects. | |
| 270 | - | |
| 271 | -With rebase, pre-commit testing is not an option. | |
| 272 | - | |
| 273 | -## <a name="timestamps"></a>5.0 Rebase causes timestamp confusion | |
| 256 | +## <a name="timestamps"></a>4.0 Rebase causes timestamp confusion | |
| 274 | 257 | |
| 275 | 258 | Consider the earlier example of rebasing a feature branch: |
| 276 | 259 | |
| 277 | 260 | ~~~ pikchr toggle |
| 278 | 261 | # Copy of second diagram in section 2.2 above |
| @@ -310,11 +293,11 @@ | ||
| 310 | 293 | unique timestamps for C3' and C5' but then you lose the information |
| 311 | 294 | about when those check-ins were originally created, which can make |
| 312 | 295 | historical analysis of changes more difficult. It might also |
| 313 | 296 | complicate the legal defense of prior art claims. |
| 314 | 297 | |
| 315 | -## <a name="lying"></a>6.0 Rebasing is lying about the project history | |
| 298 | +## <a name="lying"></a>5.0 Rebasing is lying about the project history | |
| 316 | 299 | |
| 317 | 300 | By discarding parentage information, rebase attempts to deceive the |
| 318 | 301 | reader about how the code actually came together. |
| 319 | 302 | |
| 320 | 303 | The [Git rebase documentation][gitrebase] admits as much. They acknowledge |
| @@ -369,11 +352,11 @@ | ||
| 369 | 352 | of Git. Git could be enhanced to support editorial changes |
| 370 | 353 | to check-ins. |
| 371 | 354 | Wouldn't it be better to fix the version control tool |
| 372 | 355 | rather than requiring users to fabricate a fictitious project history? |
| 373 | 356 | |
| 374 | -## <a name="collapsing"></a>7.0 Collapsing check-ins throws away valuable information | |
| 357 | +## <a name="collapsing"></a>6.0 Collapsing check-ins throws away valuable information | |
| 375 | 358 | |
| 376 | 359 | One of the oft-cited advantages of rebasing in Git is that it lets you |
| 377 | 360 | collapse multiple check-ins down to a single check-in to make the |
| 378 | 361 | development history “clean.” The intent is that development appear as |
| 379 | 362 | though every feature were created in a single step: no multi-step |
| @@ -384,11 +367,11 @@ | ||
| 384 | 367 | |
| 385 | 368 | The common counterargument is that collapsed check-ins represent a |
| 386 | 369 | better world, the ideal we're striving for. What that argument overlooks |
| 387 | 370 | is that we must throw away valuable information to get there. |
| 388 | 371 | |
| 389 | -### <a name="empathy"></a>7.1 Individual check-ins support developer empathy | |
| 372 | +### <a name="empathy"></a>6.1 Individual check-ins support developer empathy | |
| 390 | 373 | |
| 391 | 374 | Ideally, future developers of our software can understand every feature |
| 392 | 375 | in it using only context available in the version of the code they start |
| 393 | 376 | work with. Prior to widespread version control, developers had no choice |
| 394 | 377 | but to work that way. Pre-existing codebases could only be understood |
| @@ -429,11 +412,11 @@ | ||
| 429 | 412 | that collapses a whole branch's worth of changes down to a single |
| 430 | 413 | finished feature. |
| 431 | 414 | |
| 432 | 415 | [sdm]: ./fossil-v-git.wiki#durable |
| 433 | 416 | |
| 434 | -### <a name="bisecting"></a>7.2 Bisecting works better on small check-ins | |
| 417 | +### <a name="bisecting"></a>6.2 Bisecting works better on small check-ins | |
| 435 | 418 | |
| 436 | 419 | Git lets a developer write a feature in ten check-ins but collapse it |
| 437 | 420 | down to an eleventh check-in and then deliberately push only that final |
| 438 | 421 | collapsed check-in to the parent repo. Someone else may then do a bisect |
| 439 | 422 | that blames the merged check-in as the source of the problem they’re |
| @@ -444,11 +427,11 @@ | ||
| 444 | 427 | An equivalent push in Fossil will send all 11 check-ins to the parent |
| 445 | 428 | repository so that a later investigator doing the same sort of bisect |
| 446 | 429 | sees the complete check-in history. That bisect will point the |
| 447 | 430 | investigator at the single original check-in that caused the problem. |
| 448 | 431 | |
| 449 | -### <a name="comments"></a>7.3 Multiple check-ins require multiple check-in comments | |
| 432 | +### <a name="comments"></a>6.3 Multiple check-ins require multiple check-in comments | |
| 450 | 433 | |
| 451 | 434 | The more comments you have from a given developer on a given body of |
| 452 | 435 | code, the more concise documentation you have of that developer's |
| 453 | 436 | thought process. To resume the bisecting example, a developer trying to |
| 454 | 437 | work out what the original developer was thinking with a given change |
| @@ -456,11 +439,11 @@ | ||
| 456 | 439 | one check-in out of ten blamed by the "bisect" command was trying to |
| 457 | 440 | accomplish than if they must work that out from the eleventh check-in's |
| 458 | 441 | comment, which only explains the "clean" version of the collapsed |
| 459 | 442 | feature. |
| 460 | 443 | |
| 461 | -### <a name="cherrypicking"></a>7.4 Cherry-picks work better with small check-ins | |
| 444 | +### <a name="cherrypicking"></a>6.4 Cherry-picks work better with small check-ins | |
| 462 | 445 | |
| 463 | 446 | While working on a new feature in one branch, you may come across a bug |
| 464 | 447 | in the pre-existing code that you need to fix in order for work on that |
| 465 | 448 | feature to proceed. You could choose to switch briefly back to the |
| 466 | 449 | parent branch, develop the fix there, check it in, then merge the parent |
| @@ -498,20 +481,20 @@ | ||
| 498 | 481 | branch. Even if they manage to do their work without error, it takes |
| 499 | 482 | them more time to do the cherry-pick that way. |
| 500 | 483 | |
| 501 | 484 | [rh]: https://en.wikipedia.org/wiki/Red_Hat |
| 502 | 485 | |
| 503 | -### <a name="backouts"></a>7.5 Back-outs also work better with small check-ins | |
| 486 | +### <a name="backouts"></a>6.5 Back-outs also work better with small check-ins | |
| 504 | 487 | |
| 505 | 488 | The inverse of the cherry-pick merge is the back-out merge. If you push |
| 506 | 489 | only a collapsed version of a private working branch up to the parent |
| 507 | 490 | repo, those working from that parent repo cannot automatically back out |
| 508 | 491 | any of the individual check-ins that went into that private branch. |
| 509 | 492 | Others must either manually disentangle the problematic part of your |
| 510 | 493 | merge check-in or back out the entire feature. |
| 511 | 494 | |
| 512 | -## <a name="better-plan"></a>8.0 Cherry-pick merges work better than rebase | |
| 495 | +## <a name="better-plan"></a>7.0 Cherry-pick merges work better than rebase | |
| 513 | 496 | |
| 514 | 497 | Perhaps there are some cases where a rebase-like transformation |
| 515 | 498 | is actually helpful, but those cases are rare, and when they do |
| 516 | 499 | come up, running a series of cherry-pick merges achieves the same |
| 517 | 500 | topology with several advantages: |
| @@ -529,11 +512,11 @@ | ||
| 529 | 512 | 4. Cherry-picks keep both the original and the revised check-ins, |
| 530 | 513 | so both timestamps are preserved. |
| 531 | 514 | |
| 532 | 515 | [tbc]: ./fossil-v-git.wiki#testing |
| 533 | 516 | |
| 534 | -## <a name="conclusion"></a>9.0 Summary and conclusion | |
| 517 | +## <a name="conclusion"></a>8.0 Summary and conclusion | |
| 535 | 518 | |
| 536 | 519 | Rebasing is an anti-pattern. It is dishonest. It deliberately |
| 537 | 520 | omits historical information. It causes problems for collaboration. |
| 538 | 521 | And it has no offsetting benefits. |
| 539 | 522 | |
| 540 | 523 |
| --- www/rebaseharm.md | |
| +++ www/rebaseharm.md | |
| @@ -251,28 +251,11 @@ | |
| 251 | while they're still isolated on a feature branch, or should that vetting |
| 252 | wait until you finally push a collapsed version of a private working |
| 253 | branch to the parent repo? Will the many eyeballs even see those errors |
| 254 | when they’re intermingled with code implementing some compelling new feature? |
| 255 | |
| 256 | ## <a name="testing"></a>4.0 Rebase commits untested check-ins to the blockchain |
| 257 | |
| 258 | Rebase adds new check-ins to the blockchain without giving the operator |
| 259 | an opportunity to test and verify those check-ins. Just because the |
| 260 | underlying three-way merge had no conflict does not mean that the resulting |
| 261 | code actually works. Thus, rebase runs the very real risk of adding |
| 262 | non-functional check-ins to the permanent record. |
| 263 | |
| 264 | Of course, a user can also commit untested or broken check-ins without |
| 265 | the help of rebase. But at least with an ordinary commit or merge |
| 266 | (in Fossil at least), the operator |
| 267 | has the *opportunity* to test and verify the merge before it is committed, |
| 268 | and a chance to back out or fix the change if it is broken without leaving |
| 269 | busted check-ins on the blockchain to complicate future bisects. |
| 270 | |
| 271 | With rebase, pre-commit testing is not an option. |
| 272 | |
| 273 | ## <a name="timestamps"></a>5.0 Rebase causes timestamp confusion |
| 274 | |
| 275 | Consider the earlier example of rebasing a feature branch: |
| 276 | |
| 277 | ~~~ pikchr toggle |
| 278 | # Copy of second diagram in section 2.2 above |
| @@ -310,11 +293,11 @@ | |
| 310 | unique timestamps for C3' and C5' but then you lose the information |
| 311 | about when those check-ins were originally created, which can make |
| 312 | historical analysis of changes more difficult. It might also |
| 313 | complicate the legal defense of prior art claims. |
| 314 | |
| 315 | ## <a name="lying"></a>6.0 Rebasing is lying about the project history |
| 316 | |
| 317 | By discarding parentage information, rebase attempts to deceive the |
| 318 | reader about how the code actually came together. |
| 319 | |
| 320 | The [Git rebase documentation][gitrebase] admits as much. They acknowledge |
| @@ -369,11 +352,11 @@ | |
| 369 | of Git. Git could be enhanced to support editorial changes |
| 370 | to check-ins. |
| 371 | Wouldn't it be better to fix the version control tool |
| 372 | rather than requiring users to fabricate a fictitious project history? |
| 373 | |
| 374 | ## <a name="collapsing"></a>7.0 Collapsing check-ins throws away valuable information |
| 375 | |
| 376 | One of the oft-cited advantages of rebasing in Git is that it lets you |
| 377 | collapse multiple check-ins down to a single check-in to make the |
| 378 | development history “clean.” The intent is that development appear as |
| 379 | though every feature were created in a single step: no multi-step |
| @@ -384,11 +367,11 @@ | |
| 384 | |
| 385 | The common counterargument is that collapsed check-ins represent a |
| 386 | better world, the ideal we're striving for. What that argument overlooks |
| 387 | is that we must throw away valuable information to get there. |
| 388 | |
| 389 | ### <a name="empathy"></a>7.1 Individual check-ins support developer empathy |
| 390 | |
| 391 | Ideally, future developers of our software can understand every feature |
| 392 | in it using only context available in the version of the code they start |
| 393 | work with. Prior to widespread version control, developers had no choice |
| 394 | but to work that way. Pre-existing codebases could only be understood |
| @@ -429,11 +412,11 @@ | |
| 429 | that collapses a whole branch's worth of changes down to a single |
| 430 | finished feature. |
| 431 | |
| 432 | [sdm]: ./fossil-v-git.wiki#durable |
| 433 | |
| 434 | ### <a name="bisecting"></a>7.2 Bisecting works better on small check-ins |
| 435 | |
| 436 | Git lets a developer write a feature in ten check-ins but collapse it |
| 437 | down to an eleventh check-in and then deliberately push only that final |
| 438 | collapsed check-in to the parent repo. Someone else may then do a bisect |
| 439 | that blames the merged check-in as the source of the problem they’re |
| @@ -444,11 +427,11 @@ | |
| 444 | An equivalent push in Fossil will send all 11 check-ins to the parent |
| 445 | repository so that a later investigator doing the same sort of bisect |
| 446 | sees the complete check-in history. That bisect will point the |
| 447 | investigator at the single original check-in that caused the problem. |
| 448 | |
| 449 | ### <a name="comments"></a>7.3 Multiple check-ins require multiple check-in comments |
| 450 | |
| 451 | The more comments you have from a given developer on a given body of |
| 452 | code, the more concise documentation you have of that developer's |
| 453 | thought process. To resume the bisecting example, a developer trying to |
| 454 | work out what the original developer was thinking with a given change |
| @@ -456,11 +439,11 @@ | |
| 456 | one check-in out of ten blamed by the "bisect" command was trying to |
| 457 | accomplish than if they must work that out from the eleventh check-in's |
| 458 | comment, which only explains the "clean" version of the collapsed |
| 459 | feature. |
| 460 | |
| 461 | ### <a name="cherrypicking"></a>7.4 Cherry-picks work better with small check-ins |
| 462 | |
| 463 | While working on a new feature in one branch, you may come across a bug |
| 464 | in the pre-existing code that you need to fix in order for work on that |
| 465 | feature to proceed. You could choose to switch briefly back to the |
| 466 | parent branch, develop the fix there, check it in, then merge the parent |
| @@ -498,20 +481,20 @@ | |
| 498 | branch. Even if they manage to do their work without error, it takes |
| 499 | them more time to do the cherry-pick that way. |
| 500 | |
| 501 | [rh]: https://en.wikipedia.org/wiki/Red_Hat |
| 502 | |
| 503 | ### <a name="backouts"></a>7.5 Back-outs also work better with small check-ins |
| 504 | |
| 505 | The inverse of the cherry-pick merge is the back-out merge. If you push |
| 506 | only a collapsed version of a private working branch up to the parent |
| 507 | repo, those working from that parent repo cannot automatically back out |
| 508 | any of the individual check-ins that went into that private branch. |
| 509 | Others must either manually disentangle the problematic part of your |
| 510 | merge check-in or back out the entire feature. |
| 511 | |
| 512 | ## <a name="better-plan"></a>8.0 Cherry-pick merges work better than rebase |
| 513 | |
| 514 | Perhaps there are some cases where a rebase-like transformation |
| 515 | is actually helpful, but those cases are rare, and when they do |
| 516 | come up, running a series of cherry-pick merges achieves the same |
| 517 | topology with several advantages: |
| @@ -529,11 +512,11 @@ | |
| 529 | 4. Cherry-picks keep both the original and the revised check-ins, |
| 530 | so both timestamps are preserved. |
| 531 | |
| 532 | [tbc]: ./fossil-v-git.wiki#testing |
| 533 | |
| 534 | ## <a name="conclusion"></a>9.0 Summary and conclusion |
| 535 | |
| 536 | Rebasing is an anti-pattern. It is dishonest. It deliberately |
| 537 | omits historical information. It causes problems for collaboration. |
| 538 | And it has no offsetting benefits. |
| 539 | |
| 540 |
| --- www/rebaseharm.md | |
| +++ www/rebaseharm.md | |
| @@ -251,28 +251,11 @@ | |
| 251 | while they're still isolated on a feature branch, or should that vetting |
| 252 | wait until you finally push a collapsed version of a private working |
| 253 | branch to the parent repo? Will the many eyeballs even see those errors |
| 254 | when they’re intermingled with code implementing some compelling new feature? |
| 255 | |
| 256 | ## <a name="timestamps"></a>4.0 Rebase causes timestamp confusion |
| 257 | |
| 258 | Consider the earlier example of rebasing a feature branch: |
| 259 | |
| 260 | ~~~ pikchr toggle |
| 261 | # Copy of second diagram in section 2.2 above |
| @@ -310,11 +293,11 @@ | |
| 293 | unique timestamps for C3' and C5' but then you lose the information |
| 294 | about when those check-ins were originally created, which can make |
| 295 | historical analysis of changes more difficult. It might also |
| 296 | complicate the legal defense of prior art claims. |
| 297 | |
| 298 | ## <a name="lying"></a>5.0 Rebasing is lying about the project history |
| 299 | |
| 300 | By discarding parentage information, rebase attempts to deceive the |
| 301 | reader about how the code actually came together. |
| 302 | |
| 303 | The [Git rebase documentation][gitrebase] admits as much. They acknowledge |
| @@ -369,11 +352,11 @@ | |
| 352 | of Git. Git could be enhanced to support editorial changes |
| 353 | to check-ins. |
| 354 | Wouldn't it be better to fix the version control tool |
| 355 | rather than requiring users to fabricate a fictitious project history? |
| 356 | |
| 357 | ## <a name="collapsing"></a>6.0 Collapsing check-ins throws away valuable information |
| 358 | |
| 359 | One of the oft-cited advantages of rebasing in Git is that it lets you |
| 360 | collapse multiple check-ins down to a single check-in to make the |
| 361 | development history “clean.” The intent is that development appear as |
| 362 | though every feature were created in a single step: no multi-step |
| @@ -384,11 +367,11 @@ | |
| 367 | |
| 368 | The common counterargument is that collapsed check-ins represent a |
| 369 | better world, the ideal we're striving for. What that argument overlooks |
| 370 | is that we must throw away valuable information to get there. |
| 371 | |
| 372 | ### <a name="empathy"></a>6.1 Individual check-ins support developer empathy |
| 373 | |
| 374 | Ideally, future developers of our software can understand every feature |
| 375 | in it using only context available in the version of the code they start |
| 376 | work with. Prior to widespread version control, developers had no choice |
| 377 | but to work that way. Pre-existing codebases could only be understood |
| @@ -429,11 +412,11 @@ | |
| 412 | that collapses a whole branch's worth of changes down to a single |
| 413 | finished feature. |
| 414 | |
| 415 | [sdm]: ./fossil-v-git.wiki#durable |
| 416 | |
| 417 | ### <a name="bisecting"></a>6.2 Bisecting works better on small check-ins |
| 418 | |
| 419 | Git lets a developer write a feature in ten check-ins but collapse it |
| 420 | down to an eleventh check-in and then deliberately push only that final |
| 421 | collapsed check-in to the parent repo. Someone else may then do a bisect |
| 422 | that blames the merged check-in as the source of the problem they’re |
| @@ -444,11 +427,11 @@ | |
| 427 | An equivalent push in Fossil will send all 11 check-ins to the parent |
| 428 | repository so that a later investigator doing the same sort of bisect |
| 429 | sees the complete check-in history. That bisect will point the |
| 430 | investigator at the single original check-in that caused the problem. |
| 431 | |
| 432 | ### <a name="comments"></a>6.3 Multiple check-ins require multiple check-in comments |
| 433 | |
| 434 | The more comments you have from a given developer on a given body of |
| 435 | code, the more concise documentation you have of that developer's |
| 436 | thought process. To resume the bisecting example, a developer trying to |
| 437 | work out what the original developer was thinking with a given change |
| @@ -456,11 +439,11 @@ | |
| 439 | one check-in out of ten blamed by the "bisect" command was trying to |
| 440 | accomplish than if they must work that out from the eleventh check-in's |
| 441 | comment, which only explains the "clean" version of the collapsed |
| 442 | feature. |
| 443 | |
| 444 | ### <a name="cherrypicking"></a>6.4 Cherry-picks work better with small check-ins |
| 445 | |
| 446 | While working on a new feature in one branch, you may come across a bug |
| 447 | in the pre-existing code that you need to fix in order for work on that |
| 448 | feature to proceed. You could choose to switch briefly back to the |
| 449 | parent branch, develop the fix there, check it in, then merge the parent |
| @@ -498,20 +481,20 @@ | |
| 481 | branch. Even if they manage to do their work without error, it takes |
| 482 | them more time to do the cherry-pick that way. |
| 483 | |
| 484 | [rh]: https://en.wikipedia.org/wiki/Red_Hat |
| 485 | |
| 486 | ### <a name="backouts"></a>6.5 Back-outs also work better with small check-ins |
| 487 | |
| 488 | The inverse of the cherry-pick merge is the back-out merge. If you push |
| 489 | only a collapsed version of a private working branch up to the parent |
| 490 | repo, those working from that parent repo cannot automatically back out |
| 491 | any of the individual check-ins that went into that private branch. |
| 492 | Others must either manually disentangle the problematic part of your |
| 493 | merge check-in or back out the entire feature. |
| 494 | |
| 495 | ## <a name="better-plan"></a>7.0 Cherry-pick merges work better than rebase |
| 496 | |
| 497 | Perhaps there are some cases where a rebase-like transformation |
| 498 | is actually helpful, but those cases are rare, and when they do |
| 499 | come up, running a series of cherry-pick merges achieves the same |
| 500 | topology with several advantages: |
| @@ -529,11 +512,11 @@ | |
| 512 | 4. Cherry-picks keep both the original and the revised check-ins, |
| 513 | so both timestamps are preserved. |
| 514 | |
| 515 | [tbc]: ./fossil-v-git.wiki#testing |
| 516 | |
| 517 | ## <a name="conclusion"></a>8.0 Summary and conclusion |
| 518 | |
| 519 | Rebasing is an anti-pattern. It is dishonest. It deliberately |
| 520 | omits historical information. It causes problems for collaboration. |
| 521 | And it has no offsetting benefits. |
| 522 | |
| 523 |