git-fc is a fork of Junio Hamano's git.

It's targeted to the users of the git tool.

It contains improvements to the UI that have been discussed for decades,
but Junio refuses to merge.

There's a more extensive version of this announcement in my blog:

Take for example the "staging area", a term literally
everyone agrees [1] is superior to "the index". Not just people from the
teaching industry, but even the Pro Git book (which isn't endorsed by
Junio), countless tutorials, and even Git developers themselves. Not one
Git developer is against the term... except Junio.

In addition to a much more versatile `git stage` command, there's a new
`git update` command which does what many people expect `git pull` to
do, except it does it correctly.

These features are not something I came up with out of the blue, they
have been debated for more than a decade, and various versions of these
patches have been sent to the git mailing list multiple times.

Even Linus Torvalds argued for a `git update` command that does a
fast-forward by default [2]:

  Maybe we could just tell people to have something like

        git config --global alias.update pull --ff-only

  and use that for "try to update to upstream".

For the full history behind `git update`, see my blog post:
git update: the odyssey for a sensible git pull [3].

Junio once again chose to ignore all the proposals to improve
`git pull`.

There's also a new `git fast-forward` command which does as the name
suggests. But it also has the advantage that you can do
`git help fast-forward` [4] to learn what a fast-forward is, and ways to
resolve a situation when one isn't possible.

The third important addition is the notion of the publish tracking
branch. Like the upstream tracking branch it can be used to specify the
location you want to push to by default, but it does not affect
`git rebase`. De-conflating the upstream branch allows proper support
for triangular workflows, where you rebase to one branch, and push to

Various tools are updated to make use of this information. For example,
this is the output of git branch -vv, which shows many branches ahead of
master with the symbol ">" but up-to-date with the publish branch in the
gh repo, with the "=" symbol.

* master  ... [gh/master=] Merge branch 'cleanup' into master
  publish ... [master>, gh/publish=] remote: show published status and help
  stage   ... [master>, gh/stage=] stage: add prefix test
  update  ... [master>, gh/update>] fast-forward: update documentation

I had already implemented all of these and many more around 2014, when I
departed from the project and created the initial version of my fork,
but now things have changed.

git-fc was a friendly fork, which meant I rebased all my changes on top
of Junio's master branch. Doing this version after version is incredibly
tedious, but it maximized the chances of the patches eventually being
merged. This turned out to be a mistake, as Junio gave zero
considerations to the patches, and perhaps merged only a handful. On the
other hand it became increasingly difficult for me to rebase the
hundreds of patches for many of these features.

It makes no sense to maintain a friendly fork if Junio doesn't
collaborate with anyone. Not git-fc, not libgit2, not JGit, not Pro Git,
not sharness, not git-flow, not maggit, not fugitive.vim, nothing.

Junio himself shot the door to any sort of collaboration, since he
permanently banned me from the project with no warning and no recourse
whatsoever for simply daring to disagree with him [5].

After 15 years of contributions, he didn't even pretend to conduct a
fair process in which I would receive a warning and an opportunity to
defend myself. I received **nothing**. Not even a single reply notifying
me that they (the Git PLC) wouldn't respond to me anymore: I patiently
waited several days for a reply until I realized it was never going to
come. They just sent a singe email notifying me of the permanent ban,
ignored my requests for clarification, and that was that.

So, Git 2.40.0 will be the last version I merge.

git-fc is now a true (unfriendly) fork.

I spent the last week cleaning up many patches that I had not ported
yet, and all the main features are ready for a true v0.1 version of the
new fork.

Fortunately since git repositories are meant to be compatible with
ancient versions of git clients, they will work with git-fc too. All git
development is concentrated on server-side features anyway (i.e. GitHub
and GitLab), so you as a user won't be missing anything from Git 2.41.0,
or any subsequent releases. If there's anything of actual real value,
I'll just backport it.

Completely forking the code opens the doors to many possibilities, for
example moving to saner defaults, such as zdiff3 and rebase preserve
merges. Using libgit2, or rewriting the commands to Rust or another
modern language. Also moving to a modern asciidoctor documentation, and
rewriting it for humans.

Keep in mind that these are not my ideas, these are ideas that have been
discussed for many years. Just recently Google announced a project to
convert parts of the code to a library [6], a project which after years
of work (both internal and public) doesn't show any light at the end of
the tunnel. And of course Junio has provided *zero* support for.


Linus Torvalds created git with the promise of being the first truly
open source *distributed* version control system.

Today there's zero members of the open source community contributing to
the git project regularly. All of the regular developers are being paid
by big corporations to improve the efficiency of their server solutions.
The last community contributor championing for the needs of users
(i.e. me) was permanently banned with no recourse using "rudeness" as
an excuse, when the maintainer himself is much more rude regularly, as
you can see in my defense [5] I was not allowed to present.

It's very clear that the two areas where git needs the most improvement

 * User interface
 * Documentation

And it's very clear those are the two areas big corporations care about
the least.

It's time for the open source community to regain control of the project
by doing what distributed version control systems are best used for:
a *fork*.

There is no reason for any user to use Junio's version of git, which has
no UI improvements to speak of since at least the last decade. Junio's
git is for GitHub servers, not users.

git-fc 0.1 has more improvements to the UI in its initial release than
Junio's git has had in the past 10 years, and this is just the
beginning, as I have literally hundreds of patches that Junio has
ignored over the years.

Why not give it a try?

For Arch Linux users I created a package so you can easily replace
Junio's git:


Felipe Contreras (135):
      stage: add proper 'stage' command
      stage: add helper to run commands
      stage: add 'add' subcommand
      stage: add 'remove' subcommand
      unstage: add 'unstage' command
      stage: add 'diff' subcommand
      stage: add 'edit' command
      stage: add prefix test
      test: stage: workaround lint bullshit
      merge: improve fatal fast-forward message
      merge: split cmd_merge()
      fast-forward: add new builtin
      doc: fast-forward: explain what it is
      advice: add diverging advice for novices
      fast-forward: add help about merge vs. rebase
      update: new built-in
      update: add options and usage skeleton
      update: add --ff option
      update: add --merge mode
      commit: support for multiple MERGE_MODE
      merge: add --reverse-parents option
      update: reverse the order of parents
      update: fake a reverse order of parents in message
      update: add --rebase mode
      update: add mode configuration
      update: add per-branch mode configuration
      rebase: add REBASE_DEFAULT
      test: pull: fix precedence bullshit
      pull: move configuration fetches
      pull: don't consider --ff options especially
      pull: introduce --merge option
      pull: add pull.mode
      pull: add per-branch mode configuration
      pull: add pull.mode=fast-forward
      pull: improve --rebase and pull.rebase interaction
      pull: remove divergent advice
      push: trivial cleanup
      fast-forward: update documentation
      guideline: allow declaration after statement
      Add concept of 'publish' branch
      remote: export remote_read_config
      remote: add remote_for_each()
      readme: use our own
      readme: unfriendly fork
      readme: add comment about stage
      readme: add publish information
      branch: add --set-publish-to option
      remote: add branch_get_publish
      sha1_name: add support for @{publish} marks
      for-each-ref: accept "%(publish)" format
      branch: prioritize upstream in -v
      branch: refactor list format
      branch: simplify track info
      version-gen: reorganize
      version-gen: generate proper interim versions
      version-gen: use tags
      Rename project to git-fc
      gitk: remove support for ancient versions
      CoC: remove authoritarian document
      github: remove l10n
      git-gui: remove support for ancient versions
      branch: display publish branch
      ref-filter: simplify atom check
      remote: add branch.upstream shortcut
      push: add --set-publish option
      remote: show published status and help
      test: remove HTTP/2 test
      test: mergetool: unset environment variable
      readme: cleanups and fixes
      test: fix build for zsh
      test: completion: add zsh tests
      test: completion add test for __git_cmd_idx
      completion: bash: trivial cleanup
      zsh: remove version
      completion: bash: trivial grammar fix
      completion: zsh: add higher-priority location
      zsh: simplify realpath dirname idiom
      test: completion: use global config
      completion: fix __git_cmd_idx regression for zsh
      completion: fix for suboptions with value
      completion: zsh: trivial improvement
      completion: bash: do not modify COMP_WORDBREAKS
      test: completion: fix currently typed words
      test: completion: switch __gitcomp_nl prefix test
      test: completion: add run_func() helper
      completion: bash: remove non-append functionality
      completion: bash: get rid of _append() functions
      completion: bash: get rid of any non-append code
      completion: zsh: fix options with arguments
      completion: zsh: expand --git-dir file argument
      completion: zsh: add support for general -C opts
      completion: zsh: fix for undefined completions
      completion: zsh: add support for general -c opts
      completion: zsh: fix extra space on foo=
      completion: zsh: add excluded options
      completion: zsh: always set compset
      completion: factor out check in __gitcomp
      completion: simplify equal suffix check
      completion: refactor __gitcomp
      completion: simplify __gitcomp
      completion: bash: change suffix check in __gitcomp
      completion: improve __gitcomp suffix code
      test: completion: add missing test
      completion: bash: simplify config_variable_name
      completion: bash: improve __gitcomp description
      completion: add __gitcomp_opts
      completion: bash: cleanup __gitcomp* invocations
      completion: bash: shuffle __gitcomp functions
      completion: zsh: simplify __gitcomp_direct
      completion: zsh: shuffle __gitcomp* functions
      completion: zsh: fix direct quoting
      completion: zsh: add elements individually in __gitcomp_opts
      completion: zsh: add __gitcompadd helper
      completion: zsh: add correct removable suffix
      completion: bash: simplify _get_comp_words_by_ref()
      completion: bash: refactor _get_comp_words_by_ref()
      completion: bash: cleanup _get_comp_words_by_ref()
      completion: bash: trivial cleanup
      completion: bash: rename _get_comp_words_by_ref()
      fetch: add new fetch.default configuration
      fetch: turn on `fetch.default` sane behavior
      completion: zsh: workaround lint bug
      push: reorganize get_upstream_ref
      push: make default consistent
      readme: update pending stuff
      Merge branch 'stage' into master
      Merge branch 'update' into master
      Merge branch 'publish' into master
      Merge branch 'fetch/sane-default' into master
      Merge branch 'push/default-fix' into master
      Merge branch 'completion' into master
      Merge branch 'fixes' into master
      Merge branch 'readme' into master
      Merge branch 'version' into master
      Merge branch 'cleanup' into master

Michael Bianco (1):
      zsh: resolve symlink of script


Felipe Contreras

You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
To view this discussion on the web visit

Reply via email to