Disclaimer

The content of this blog is my personal opinion only. Although I am an employee - currently of Nvidia, in the past of other companies such as Iagination Technologies, MIPS, Intellectual Ventures, Intel, AMD, Motorola, and Gould - I reveal this only so that the reader may account for any possible bias I may have towards my employer's products. The statements I make here in no way represent my employer's position, nor am I authorized to speak on behalf of my employer. In fact, this posting may not even represent my personal opinion, since occasionally I play devil's advocate.

See http://docs.google.com/View?id=dcxddbtr_23cg5thdfj for photo credits.

Tuesday, September 29, 2015

Merging in bzr: The git approach vs the bzr approach

Nice comparison of the git vs bzr meeging approaches.  



Git: "The changes appear to emerge fully-formed with no evidence of the process which created them."



Bzr: "the project's revision history will show the actual process the developer went through to create the branch."



comparison



Since some [D]CVSes support both styles - heck, even git and mercurial support both styles, and I think even bzr does - it may be more accurate to call it "clean history" versus "actual history" approaches.



The availability of a "rebase" tool is the main thing that enables the "clean history" approach.





Myself, I am unambiguously an "actual history" advocate.  "Those who cannot remember the past are condemned to repeat it".





But I can understand why so many Linux developers want a clean history.





Myself, I want both: the actual history, and possibly a clean history that is what you see by default, when the actual history is pretty messy.  (And believe me, I have seen the actual history get very messy.)





E.g. if you haven't rebased a task branch before merging, I want to see it in the style that the page depicts as bzr-style.  But I suppose that it is okay to "fold" it into the trunk, if there has ben no trunk activity in the meantime.   And if every checkin on the task branch is release-worthy.   But if there are any checkins on the task-brach that were half-assed, that you might not want to bisect to, then no, I don't want it folded in.



But if you have rebased a task branch, because the trunk has been modified since the task branch was originally forked, and have tested all of the intermediate points on the rebase, then I want to see BOTH in the actual history.



I want to see the original, pre-rebase, task branch.   Where the work was actually done.



But I am okay on seeing the rebased task branch, and even having it folded into the trunk,



I am okay on only presenting ONLY the rebased task branch and/or folded into the trunk, by default, HIDING the original pre-rebased task branch.  But this is by default only.  I would want to have some sort of indication that says "there's more history here".



Why?



Because I don't believe that you can completely test correctness.



Because experience shows that there is always a chance that the rebased task branch, folded into the trunk, will have a bug. A bug that occurred in the rebased task branch, but not in the original pre-rebased task branch. Essentially a bug caused by interference between whatever happened on the trunk and whatever happened on the task branch.



Even if your full test suite has been run on all of the pre- and post- rebase checkins.   Because sometimes the test suite doesn't test for everything.



Sure, oftentimes it will not matter - you bisect on the rebased and folded task checkins, and find what the bug is.   But sometimes  it is good to understand why the bug occurred, not just what it is.





Rebasing, and other history rewriting mechanisms, have two functions IMHO:



1) cleaning up the history



2) as debugging tools



E.g. if you have a task branch, which has passed te test suite at all checkins, and a trunk which has similarly passed the test suite, and you merge - and there is a failure.  But then obviously the failure is due to an interaction.



Creating a rebased clone of the task branch is then a debugging tool - you can see which of the task branch checks, which all passed tests pre-rebasing, causes tests to fail post-rebasing.



This is a damned useful thing to do even if the rebased task branch is not checked in / pushed to some more public repo - even if all you do is a branch merge.



E.g. sometimes I use a rebase just for debugging, and then through out the rebased branch.





What I do object to, however, is rebasing and NOT testing all of the intermediate checkins.













Merging in bzr: The git approach vs the bzr approach: "often"



'via Blog this'