Git Rev News: Edition 38 (April 18th, 2018)

Welcome to the 38th edition of Git Rev News, a digest of all things Git. For our goals, the archives, the way we work, and how to contribute or to subscribe, see the Git Rev News page on git.github.io.

This edition covers what happened during the month of March 2018.

Discussions

General

Johannes Schindelin has worked to replace --preserve-merges functionality in git rebase, which has many known flaws, by a new --recreate-merges, which aims to replace the functionality of --preserve-merges in a way that fixes the known issues.

When the patch series was sent to the list, Sergey Organov brought up that --recreate-merges is still (true to its name) recreating the merges from scratch, thus losing any content they might have contained, such as fixes.

He pointed to a strategy for cherry-picking the merge commit. Others chimed in to state that they share concerns and would like to see the ability to preserve the merge resolutions properly.

Johannes replied that this does not make sense because the cherry-pick solution does not work when you drop or re-order commits. The goal of --recreate-merges is to allow the same level of freedom as with regular interactive rebases. Using the --preserve-merges --first-parent strategy of just cherry-picking the merge commit will result in any changes before that merge being dropped.

Junio Hamano, the Git maintainer, chimed in that Johannes was correct, if for example the side branch you are merging dropped a commit during the rebase, you absolutely do not want to use the simple git cherry-pick -m1 original.

Sergey replied that he had only intended the use of cherry-pick as an explanation facility, and that a proper strategy would be required to actually implement and allow history editing.

Some discussion about --preserve-merges and compatibility with scripts (i.e. should we change or fix it? – or should we deprecate it?) followed.

After the discussions in the above article Sergey posted an outline of a potential method for actually rebasing a merge (as opposed to recreating it from scratch) which used a process of git cherry-pick -mN of the merge onto each topic branch being merged, and then merging the result.

Igor Djordjevic and Jacob Keller, alias Jake, chimed in hoping to prove by example that the solution could work. Johannes replied that he was skeptical and pointed out possible flaws.

A few examples were tried, but it was proven that the original algorithm did not work, as dropped commits could end up being replayed into the merge commits, turning them into “evil” merges.

Further suggestions to the strategy were proposed and tested, ultimately resulting in Sergey proposing a fix to his method, specifically using the original merge commit as a merge base during the final step.

Some discussion occurred about merge -s ours and how any rebasing strategy should avoid attempting to understand the semantics of the merges.

Phillip Wood suggested an alternative idea for keeping the merge conflicts by merging the changes from each rebased branch back into the parent merge branch. This was immediately understood by Johannes and suggested as a potential for the default implementation.

Sergey replied that he thinks the solution produces the same result as his updated strategy, at least when none of the strategies produce any conflicts.

Johannes suggested that he was open to using Phillip’s strategy but was worried about syntax. He did not want to introduce inconsistent behavior of the new “merge” command.

Despite Sergey believing that the two strategies were equivalent, Johannes was not convinced.

Discussion about the syntax for the new “rebase a merge” todo command continued. Johannes landed on the idea of adding an option -R to the merge command line to indicate that it was rebasing a merge (vs creating a new merge).

Phillip suggested that we re-use “pick” but thought it might be a bit too magical. He then adjoined that it is indeed too magical, and is basically the --preserve-merges mistake all over again. He suggested it was a shame to have merge mean both recreate a merge and rebase a merge, but didn’t have a good answer.

Igor suggested that “pick” was more natural, and that we should extend it to properly support picking merge commits in a way that was not broken like --perserve-merges.

Johannes stated he did not like the extension of “pick” because it makes it harder to understand which lines are actually merges and which are not.

Johannes replied that Sergey’s strategy is actually worse than Phillip’s from a functional point of view, because it has potential to produce conflicts multiple times. The discussion continued and became heated, with both Johannes and Sergey unable to reach a consensus.

Discussion about “pick” vs merge -R continued, with Igor and Sergey stating that they thought extending “pick” syntax would be better than introducing merge -R syntax.

Some further discussion about backward compatibility of the todo list format and of options for it followed.

Reviews

Kaartic Sivaraam sent a patch to the mailing list that fixed git branch -l output when an interactive rebase is performed and when the interactive rebase was started from a remote branch or when HEAD was detached.

Eric Sunshine replied to Kaartic that -l in git branch -l is a shortcut for --create-reflog not for --list, and suggested some small improvements along with adding a couple of new tests.

Kaartic then wondered why git branch -l prints a list of branch names when -l is not a shorthand for --list, and agreed to implement Eric’s suggestions.

Jeff King, alias Peff, replied to Kaartic that -l just sets the “reflog” variable to 1, and then, as the command defaults to --list when there is no other command line option, the branch names are printed, which just ignores the “reflog” variable.

Peff also explained that -l is probably never used in practice as it is the default to create a reflog, so it’s “historical and quite unfortunate” that -l is a shortcut for --create-reflog and not for --list.

Eric then suggested making -l mean sometimes --create-reflog and sometimes --list, but Peff didn’t like that and suggested instead to either complaining when -l is used in list mode or deprecating and dropping -l first and then maybe after a significant amount of time repurposing it as a shortcut for --list.

Then Eric replied to Kaartic with a few small additional suggestions and with a patch that adds the new tests which Eric had previously suggested.

Meanwhile Kaartic agreed to Peff’s suggestions. Those suggestions were discussed a bit more by Jacob Keller, alias Jake, and Junio Hamano, the Git maintainer, who agreed to the plan to deprecate -l, then to drop it, and eventually re-establish it as shortcut for --list.

Peff then sent a patch series doing all that. The series was reviewed by Eric and Jake.

Kaartic reworked his original patch to improve git branch --list output and sent to the mailing list a second version of it along with Eric’s patch adding new tests.

Peff’s patch series has been merged into the ‘next’ branch and Kaartic’s patch series will probably also be merged there, too.

Developer Spotlight: Jiang Xin

Releases

Other News

Various

Light reading

Git tools and sites

Credits

This edition of Git Rev News was curated by Christian Couder <christian.couder@gmail.com>, Jakub Narębski <jnareb@gmail.com>, Markus Jansen <mja@jansen-preisler.de> and Gabriel Alcaras <gabriel.alcaras@telecom-paristech.fr> with help from Jiang Xin, Jacob Keller, Luca Milanesio, Sergey Organov and Kaartic Sivaraam.