Fork of Git, same baseline, more features
C Shell Perl Tcl Python C++ Other
Pull request Compare This branch is 972 commits ahead, 1723 commits behind git:master.
Latest commit 3ce268d May 20, 2016 @felipec test: remove httpd tests that ask for user
Until we figure a way to pass the user correctly.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Permalink
Failed to load latest commit information.
Documentation Merge tag 'v2.8.0' May 19, 2016
block-sha1
builtin
compat
contrib
ewah
git-gui
gitk-git
gitweb
mergetools
perl
po
ppc
refs
shared
t
templates
vcs-svn
xdiff
.gitattributes
.gitignore
.mailmap
.travis.yml
COPYING
GIT-VERSION-GEN
INSTALL
LGPL-2.1
Makefile
README.md
README.upstream
RelNotes
abspath.c
aclocal.m4
advice.c
advice.h
alias.c
alloc.c
archive-tar.c
archive-zip.c
archive.c use st_add and st_mult for allocation size computation Feb 22, 2016
archive.h
argv-array.c
argv-array.h argv-array: add detach function Feb 22, 2016
attr.c
attr.h
base85.c
bisect.c
bisect.h
blob.c
blob.h
branch.c
branch.h
builtin.h Merge tag 'v2.7.0' May 18, 2016
bulk-checkin.c use xsnprintf for generating git object headers Sep 25, 2015
bulk-checkin.h
bundle.c
bundle.h
cache-tree.c
cache-tree.h
cache.h
check-builtins.sh
check-racy.c
check_bindir
color.c
color.h
column.c
column.h column: support piping stdout to external git-column process Apr 27, 2012
combine-diff.c
command-list.txt Merge branch 'nd/multiple-work-trees' Jul 13, 2015
commit-slab.h Merge branch 'jc/commit-slab' Aug 3, 2015
commit.c
commit.h
config.c
config.mak.in
config.mak.uname
configure.ac
connect.c Merge branch 'cn/deprecate-ssh-git-url' Mar 16, 2016
connect.h
connected.c
connected.h
convert.c
convert.h
copy.c
credential-cache--daemon.c
credential-cache.c
credential-store.c
credential.c
credential.h
csum-file.c
csum-file.h Merge branch 'jk/pack-bitmap' Dec 12, 2014
ctype.c
daemon.c
date.c
decorate.c
decorate.h
delta.h
diff-delta.c
diff-lib.c
diff-no-index.c
diff.c
diff.h
diffcore-break.c
diffcore-delta.c
diffcore-order.c
diffcore-pickaxe.c
diffcore-rename.c
diffcore.h
dir.c
dir.h
editor.c
entry.c
environment.c
exec_cmd.c
exec_cmd.h
fast-import.c
fetch-pack.c
fetch-pack.h
fmt-merge-msg.h
fsck.c
fsck.h
generate-cmdlist.sh
gettext.c
gettext.h
git-add--interactive.perl
git-archimport.perl
git-bisect.sh
git-compat-util.h
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl
git-difftool--helper.sh
git-difftool.perl
git-filter-branch.sh
git-instaweb.sh
git-merge-octopus.sh
git-merge-one-file.sh
git-merge-resolve.sh
git-mergetool--lib.sh
git-mergetool.sh
git-p4.py
git-parse-remote.sh
git-quiltimport.sh git-quiltimport: add commandline option --series <file> Sep 1, 2015
git-rb-setup.rb
git-rebase--am.sh
git-rebase--interactive.sh
git-rebase--merge.sh *.sh: avoid hardcoding $GIT_DIR/hooks/... Dec 1, 2014
git-rebase.sh
git-relink.perl
git-remote-bzr.py
git-remote-hg.py
git-remote-testgit.sh
git-request-pull.sh
git-send-email.perl
git-sh-i18n.sh
git-sh-setup.sh
git-stash.sh
git-submodule.sh
git-svn.perl git-svn: fix URL canonicalization during init w/ SVN 1.7+ Mar 16, 2016
git-update.sh
git-web--browse.sh
git.c
git.rc
git.spec.in
gpg-interface.c
gpg-interface.h
graph.c
graph.h
grep.c
grep.h
hashmap.c
hashmap.h
help.c
help.h
hex.c
http-backend.c
http-fetch.c
http-push.c
http-walker.c
http.c
http.h
ident.c
imap-send.c
khash.h
kwset.c
kwset.h kwset: use unsigned char to store values with high-bit set Mar 2, 2015
levenshtein.c
levenshtein.h
line-log.c
line-log.h
line-range.c
line-range.h
list-objects.c
list-objects.h
ll-merge.c
ll-merge.h
lockfile.c
lockfile.h
log-tree.c
log-tree.h
mailinfo.c
mailinfo.h
mailmap.c
mailmap.h
match-trees.c
merge-blobs.c
merge-blobs.h
merge-recursive.c
merge-recursive.h
merge.c
mergesort.c
mergesort.h
name-hash.c
notes-cache.c
notes-cache.h
notes-merge.c
notes-merge.h
notes-utils.c
notes-utils.h
notes.c Merge branch 'jk/tighten-alloc' Feb 26, 2016
notes.h
object.c
object.h
pack-bitmap-write.c
pack-bitmap.c
pack-bitmap.h
pack-check.c
pack-objects.c
pack-objects.h
pack-revindex.c
pack-revindex.h
pack-write.c
pack.h
pager.c
parse-options-cb.c Merge branch 'kn/for-each-tag-branch' Oct 5, 2015
parse-options.c
parse-options.h
patch-delta.c
patch-ids.c
patch-ids.h
path.c
pathspec.c convert trivial cases to ALLOC_ARRAY Feb 22, 2016
pathspec.h
pkt-line.c
pkt-line.h
preload-index.c
pretty.c
prio-queue.c
prio-queue.h
progress.c
progress.h
prompt.c
prompt.h
quote.c
quote.h ls-tree: remove path filtering logic in show_tree Dec 1, 2014
reachable.c
reachable.h
read-cache.c
ref-filter.c
ref-filter.h
reflog-walk.c
reflog-walk.h
refs.c
refs.h
remote-curl.c
remote-testsvn.c
remote.c
remote.h
replace_object.c
rerere.c
rerere.h
resolve-undo.c
resolve-undo.h
revision.c
revision.h
rewrite.c builtin: rewrite: add copy_rewrite_notes() May 18, 2016
rewrite.h
ruby.c
run-command.c
run-command.h
send-pack.c
send-pack.h
sequencer.c
sequencer.h
server-info.c
setup.c
sh-i18n--envsubst.c
sha1-array.c
sha1-array.h
sha1-lookup.c
sha1-lookup.h
sha1_file.c
sha1_name.c
shallow.c
shell.c
shortlog.c
shortlog.h
show-index.c
sideband.c
sideband.h
sigchain.c
sigchain.h
split-index.c ewah: add convenient wrapper ewah_serialize_strbuf() Mar 12, 2015
split-index.h split-index: the reading part Jun 13, 2014
strbuf.c
strbuf.h
streaming.c
streaming.h
string-list.c
string-list.h
submodule-config.c
submodule-config.h
submodule.c
submodule.h
symlinks.c
tag.c
tag.h
tar.h
tempfile.c register_tempfile(): new function to handle an existing temporary file Aug 10, 2015
tempfile.h
test-chmtime.c
test-config.c
test-ctype.c
test-date.c
test-delta.c
test-dump-cache-tree.c
test-dump-split-index.c
test-dump-untracked-cache.c
test-fake-ssh.c
test-genrandom.c
test-hashmap.c
test-index-version.c
test-line-buffer.c
test-match-trees.c
test-mergesort.c
test-mktemp.c
test-parse-options.c parse-options: move unsigned long option parsing out of pack-objects.c Jun 22, 2015
test-path-utils.c
test-prio-queue.c
test-read-cache.c
test-regex.c
test-revision-walking.c
test-run-command.c
test-scrap-cache-tree.c
test-sha1-array.c
test-sha1.c test-sha1: add a binary output mode Aug 22, 2013
test-sha1.sh
test-sigchain.c
test-string-list.c
test-submodule-config.c
test-subprocess.c
test-svn-fe.c
test-urlmatch-normalization.c
test-wildmatch.c
thread-utils.c
thread-utils.h
trace.c
trace.h
trailer.c
trailer.h
transport-helper.c
transport.c Merge tag 'v2.8.0' May 19, 2016
transport.h
tree-diff.c Merge branch 'maint-2.4' into maint-2.5 Mar 17, 2016
tree-walk.c
tree-walk.h
tree.c
tree.h
unicode_width.h Update of unicode_width.h to Unicode Version 7.0 Jun 18, 2014
unimplemented.sh
unix-socket.c
unix-socket.h
unpack-trees.c
unpack-trees.h
update_unicode.sh
upload-pack.c
url.c
url.h
urlmatch.c
urlmatch.h
usage.c
userdiff.c
userdiff.h
utf8.c
utf8.h
varint.c
varint.h
version.c
version.h
versioncmp.c
walker.c
walker.h
wildmatch.c
wildmatch.h
worktree.c
worktree.h
wrap-for-bin.sh
wrapper.c
write_or_die.c
ws.c
wt-status.c
wt-status.h
xdiff-interface.c
xdiff-interface.h
zlib.c

README.md

git-fc

git-fc is a friendly fork of Git, which means it's a fork that won't deviate from the mainline; it is more like a branch in Git terms. This branch will move forward close to Git's mainline, and it could be merged at any point in time, if the maintainer wished to do so.

git-fc doesn't include experimental code, or half-assed features, so you can expect the same level of stability as Git's mainline. Also, it doesn't remove any feature, or do any backwards incompatible changes, so you can replace git with git-fc and you wouldn't notice the difference. The difference comes in the extra features, that is all.

Maintenance

Each release of Git is merged directly into git-fc, so if there's a new feature in Git, git-fc will get it as well.

Every extra feature is maintained individually in a separate branch, so if you are interested in a specific feature and don't trust the rest of git-fc, you can use that branch instead. For example the publish tracking branch feature is maintained in the 'fc/publish' branch which sits on top of git.git's v1.9.2. You can grab the specific branch and do whatever you want with it.

Extra features

Streamlined remote helpers

git-remote-hg and git-remote-bzr are remote helpers that allow two-way communication between Git and Mercurial/Bazaar. They have been proven to be very reliable and solid, and used by many people. In order to use them in Git mainline you might need a bit of tinkering.

With git-fc they are installed by default, and in the right way. Plus there are fixes in the remote helper infrastructure so they always work better than in Git mainline.

New 'git update' tool

Everybody has agreed the git pull command is broken for most use-cases, which is why most seasoned Git users avoid it, and it is recommended for new users to avoid it.

A new tool is necessary for the most common use case, which is fetch all the updates and update the current branch if possible.

The new git update will fast-forward to the latest commit in the remote branch if there's no divergence (you haven't made extra commits). But if you have made extra commits you will be told to either merge or rebase, or run git update --merge or git update --rebase.

This ensures that new users won't be making merges by mistake.

Additionally, when doing a merge the order of the parents will be reversed, so it would appear as if you are merging your local branch to the remote one, and not the other way around like git pull does. Everybody has agreed this is a problem with git pull.

Publish tracking branch

Git mainline doesn't have the greatest support for triangular workflows, a good solution for that is to introduce a second "upstream" tracking branch which is for the reverse; the branch you normally push to.

Say you clone a repository (libgit2) in GitHub, then create a branch (feature-a) and push it to your personal repository, you would want to track two branches (origin/master), and (mine/feature-a), but Git mainline only provides support for a single upstream tracking branch.

If you setup your upstream tracking branch to 'origin/master', then you can just do git rebase without arguments and git will pick the right branch (origin/master) to rebase to. However, git push by default will also try to push to 'origin/master', which is not what you want. Plus git branch -v will show how ahead/behind your branch is compared to origin/master, not mine/feature-a.

If you set up your upstream to 'mine/feature-a', then git push will work, but git rebase won't.

With this option, git rebase uses the upstream branch, and git push uses the publish branch.

Setting the upstream tracking branch is easy:

git push --set-publish mine feature-a

Or:

git branch --set-publish mine/feature-a

And git branch -v will show it as well:

  fc/branch/fast      177dcad [master, gh/fc/branch/fast] branch: ...
  fc/stage            abb6ad5 [master, gh/fc/stage] completion: ..
  fc/transport/improv eb4d3c7 [master, gh/fc/transport/improv] ...

Official staging area

Everybody already uses the term "staging area" already, and Git developers also agreed it the best term to what is officially referred to as "the index". So git-fc has new options for all commands that modify the staging area (e.g. git grep --staged, git rm --staged), and also adds a new git stage command that makes it easier to work with the staging area.

'git stage' [options] [--] [<paths>...]
'git stage add' [options] [--] [<paths>...]
'git stage reset' [-q|--patch] [--] [<paths>...]
'git stage diff' [options] [<commit>] [--] [<paths>...]
'git stage rm' [options] [--] [<paths>...]
'git stage apply' [options] [--] [<paths>...]
'git stage edit'

Without any command, git stage adds files to the stage, same as git add, same as in Git mainline.

Nice 'branch -v'

Currently git branch -v will show you the tracking status (ahead/behind), but wouldn't show you which from which branch, and it takes considerable amount of time (compared to most Git commands).

This is fixed so the branch is showed instead, which is more useful and faster. If you want the tracking status, you can use git branch -vv which shows everything, as with Git mainline.

  fc/branch/fast      177dcad [master] branch: ...
  fc/stage            abb6ad5 [master] completion: ...
  fc/transport/improv eb4d3c7 [master] transport-helper: ...

Default aliases

Many (if not all) version control system tools have shortcuts for their most common operations; hg ci, svn co, cvs st, but not Git... git-fc does:

co = checkout
ci = commit
rb = rebase
st = status
br = branch
pi = cherry-pick
mt = mergetool

If you have already these aliases, or mapped to something else, your aliases would take precedence over the default ones, so you won't have any problems.

New core.mode configuration

The behavior of Git v2.0 is already being defined, but there's no way to test it, if you want to test it, along with all future behaviors, you can enable it on git-fc by setting the configuration core.mode = next.

In addition to the "next" (v2.0) mode, there's the "progress" mode. This mode enables "next" plus other configurations that are saner.

It is recommended that you setup this mode for git-fc:

git config --global core.mode progress

New fetch.default configuration

When you have configured the upstream tracking branch for all your branches, you will probably have tracking branches that point to a local branch, for example 'feature-a' pointing to 'master', in which case you would get something like:

% git fetch
From .
 * branch            master     -> FETCH_HEAD

Which makes absolutely no sense, since the '.' repository is not even documented, and FETCH_HEAD is a marginally known concept. In this case git fetch is basically doing nothing from the user's point of view.

So the user can configure fetch.default = simple to get a simple sensible default; git fetch will always use 'origin' by default.

If you use the "progress" mode, this option is also enabled.

Support for Ruby

There is partial optional support for Ruby. Git already has tooling so any language can use it's plumbing and achieve plenty of tasks:

IO.popen(%w[git for-each-ref]) do |io|
  io.each do |line|
    sha1, kind, name = line.split()
    # stuff
  end
end

However, this a) requires a process fork, and b) requires I/O communication to get the desired data. While this is not a big deal on many systems, it is in Windows systems where forks are slow, and many Git core programs don't work as well as they do in Linux.

Git has a goal to replace all the core scripts with native C versions, but it's a goal only in name that is not actually pursued. In addition, that still leaves out any third party tools since Git doesn't provide a shared libgit library, which is why an independent libgit2 was needed in the first place.

Ruby bindings solve these problems:

for_each_ref() do |name, sha1, flags|
  # stuff
end

The command git ruby can use this script by providing the bindings for many Git's internal C functions (though not all), which makes it easier to write Ruby programs that take full advantage of Git without any need of forks, or I/O communication.

Contributions

All these patches were written by me, Felipe Contreras, but contributions from other people are welcome, as long as they follow these guidelines:

  1. Follows Git coding guidelines and is technically correct according to Git standards
  2. Doesn't break backwards compatibility
  3. It doesn't conflict with other Git features so it can be rebased on newer versions of Git without much maintenance burden

Patches should be sent using git send-email to the mailing list git-fc@googlegroups.com.