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.
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.
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.
Who are you and what do you do?
I am a Chinese, live in Beijing, China. Almost at the same time when Linus wrote the first line of code for Git, I started to work as a self-employed open source consultant. At that time, I didn’t know Git yet, so I chose SVN and Redmine as the main products to start my consultant career. After working as a Git consultant for Huawei for one year, I accepted Huawei’s offer in Dec, 2015.
What would you name your most important contribution to Git?
As a developer, the most important contribution to Git is interactive
git clean
. One day a guy (reader of my book) lost his work by running
git clean -f
and asked me for help. I wanted to do something, so I
sent patches to Git, and it became this feature: git clean --interactive
.
As a Huaweier, I also have contributed some fixes for corner cases I met at work:
As a Chinese, the most important work I have done is that I wrote a book on Git, and the book was published in 2011. As soon as I received the first copy of my book, I sent one to Junio. :) I open-sourced the book in https://github.com/gotgit/gotgit, and you can read it from http://www.worldhello.net/gotgit/. Meanwhile, I wrote an e-book for GitHub: http://www.worldhello.net/gotgithub; it is also written in Chinese, but did not publish it because I feel it is hard to track changes of the GitHub UI, and the book might become obsolete very quickly.
I became Git l10n coordinator to help Junio for l10n management in early 2012. Now there are 11 fully supported language packs for Git, and this work is very valuable for those who are not good at English.
What are you doing on the Git project these days, and why?
Now I am working in Huawei for the internal Git platform with multiple data centers distributed in China. There are many cool features I am working on. For example: Git central workflow and Git-CDN.
Git central workflow is something like Gerrit. No forking before sending pull request, no special git hook on client side, no “Change-ID” in the commit message, and we use pull request for review. We also developed a client side program named “git-mm” to help our users to manage multiple git modules, or just a single git repository.
Git-CDN is a reverse proxy for Git. I wrote a program named
git-upload-pack-proxy
to handle data syncing and data caching
across different data centers.
We have also some enhancements on Git, and I wish I can contribute them back to Git one day.
If you could get a team of expert developers to work full time on something in Git for a full year, what would it be?
When I was developing the Git reverse proxy, I found the Git protocol is a bit complicated and not very efficient. For example, if a client wants to fetch a single branch, the server still needs to send thousands of references as refs-advertisement. We can improve it.
(EDIT: Stefan Beller pointed out that there would be great improvements in protocol v2, a simpler and less wasteful protocol, which had already been merged from the bw/protocol-v2 topic branch to Git next branch.)
If you could remove something from Git without worrying about backwards compatibility, what would it be?
git-gc
, I think. If a repository is as big as 10 GB, git-gc
will be
quite slow. If we designed a new storage model for Git without
garbage collection, it would be great.
What is your favorite Git-related tool/library, outside of Git itself?
Various
Light reading
Git tools and sites
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.