Why does reordering using git rebase -i not ruin the story?

As I understand it, commits are snapshots of files, so if I make a change to A and then change B, changing the commit file B already includes changes to change A, will reordering make the change redundant?

+5
source share
1 answer

That is, in fact, a very good question, because commits are snapshots.

The reason rebase works is because rebase actually repeats git cherry-pick (with a bit of wrapping in the front to figure out what to choose, and more at the end to move the branch labels), and git cherry-pick works turning the commit into a set of changes.

Suppose, for example, that you have this sequence of commits:

  A--B--C <-- topic / ...--o--*--o--o <-- mainline 

To reorder the topic on mainline , we need (1) to find the commits that are on the topic , but not on the mainline (which are C , B and A along the top line, ending with the commit marked with * ), and then (2) copy them to the new ones the commits that we add below the tip of mainline .

At the beginning of the search, three post- * transactions complete and put them on the list (reverse ordered: A , B , C ) (it also omits the default commands, but there are no merges here). Then he picks a cherry for each fixation.

To make cherry pick A , Git differs A from * . This turns two snapshots into a set of changes. Git then applies the changes to the maximum declaration of mainline and commits a new commit, let it call A' , on an anonymous branch:

  A--B--C <-- topic / ...--o--*--o--o <-- mainline \ A' <-- HEAD 

In cherry pick B , Git diffs B vs. A Applying these changes to A' , another commit B' occurs. Repeat for C to get C' :

  A--B--C <-- topic / ...--o--*--o--o <-- mainline \ A'-B'-C' <-- HEAD 

Finally, Git unsticks the topic label from C and instead points to C' . The old chain is abandoned (although you can still find it via reflogs, and rebase copies the C identifier to the special name ORIG_HEAD ):

  A--B--C [abandoned] / ...--o--*--o--o <-- mainline \ A'-B'-C' <-- topic 

and now the overflow is complete.

Note that each copy is performed using Git merge mechanisms, if necessary (if the differences are not applied immediately). Each of these can lead to a merge conflict, requiring rebase to stop and get help from you. (Or, even worse, you may get the wrong merge, although this is rare in practice.)

And, of course, if you reorder the commits (by moving the pick lines in an interactive permutation), we simply change the order we select and apply each commit. Sweet cherry operations still work the same: compare the selected commit with its parent ( C vs B , A vs * , B vs A ).

+5
source

All Articles