{"thread":{"id":"35221","subject":"[ANNOUNCE] git-fc, a friendly fork of Git","startedAt":"2013-10-28T09:20:57Z","lastAt":"2013-10-28T09:20:57Z","messageCount":1,"participants":["Felipe Contreras"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"229635","messageId":"CAMP44s2_bcXT36rwhge4texy7eEUn1h7-efGriK9Be9E_V39Dw@mail.gmail.com","threadId":"35221","inReplyTo":null,"subject":"[ANNOUNCE] git-fc, a friendly fork of Git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-28T09:20:57Z","receivedAt":"2013-10-28T09:20:57Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nWhy a fork? Well, the short answer is; my patches are not being applied.\n\nWhat is git-fc? It is a friendly fork, and by that I mean that it's a\nfork that won't deviate from the mainline, it is more like a branch.\nThis branch will move forward close to Git's mainline, and it could be\nmerged at any point in time, if the maintainer wished to do so.\n\ngit-fc doesn't include experimental code, or half-assed features, so\nyou can expect the same level of stability as Git's mainline. Also, it\ndoesn't remove any feature, or do any backwards incompatible changes,\nso you can replace git with git-fc and you wouldn't notice the\ndifference. The delta comes in the extra features, that is all.\n\nWhat do you get if you use git-fc?\n\n=== @ shortcut ===\n\nMany people have suggested a shortcut for the\nnon-particularly-intuitive \"HEAD\", but none of these suggestions\nseemed very appealing, or feasible.\n\nBecause Git already has an ref@op revision syntax, where if you remove\nthe ref, HEAD is implied, I thought @ could be thought as HEAD.\n\nThis change was welcome and accepted by the Git mainline, and it even\nwas on track for v1.8.4 but it was dropped last minute because of some\nissues that are fixed now, and you probably will see it in v1.8.5. But\nwhy wait? :)\n\n=== Nice 'branch -v' ===\n\nIf you have configured the upstream tracking branch for your branches\n(I wrote a blog post about them), when you do 'git branch -v' you see\nsomething like this:\n\n  fc/branch/fast      177dcad [ahead 2] branch: reorganize verbose options\n  fc/stage            abb6ad5 [ahead 14] completion: update 'git reset' ...\n  fc/transport/improv eb4d3c7 [ahead 10] transport-helper: don't update ...\n\nWhile that provides useful information, it doesn't show the upstream\ntracking branch, just says \"ahead 2\" but \"ahead 2\" compared to what?\n\nIf you do 'git branch -vv', then you see the answer:\n\n  fc/branch/fast      177dcad [master: ahead 2] branch: reorganize ...\n  fc/stage            abb6ad5 [master: ahead 14] completion: update ...\n  fc/transport/improv eb4d3c7 [master: ahead 10] transport-helper: don't ...\n\nUnfortunately both options take a lot of time (relative to most Git\ncommands which are instantaneous), because computing the \"ahead 2\"\ntakes a lot of time. So I decided to switch things around, so 'git\nbranch -v' gives you:\n\n  fc/branch/fast      177dcad [master] branch: reorganize verbose options\n  fc/stage            abb6ad5 [master] completion: update 'git reset' new ...\n  fc/transport/improv eb4d3c7 [master] transport-helper: don't update refs ...\n\nAnd it does so instantaneously.\n\n=== Default aliases ===\n\nMany (if not all) version control system tools have shortcuts for\ntheir most common operations; hg ci, svn co, cvs st. But not Git. You\ncan configure your own aliases manually, but you might have some\ntrouble if you use somebody else's machine.\n\nAdding default aliases is trivial, it helps everyone, and it doesn't\nhurt anyone, yet the patch to do so was rejected.\n\nFor now, there are only four aliases, but more can be added later if\nthey are requested.\n\n  co = checkout\n  ci = commit\n  rb = rebase\n  st = status\n\nIf you have already these aliases, or mapped to something else, your\naliases would take precedence over the default ones, so you won't have\nany problems.\n\n=== Streamlined remote helpers ===\n\nI have spent a lot of time working on git-remote-hg and\ngit-remote-bzr, and although they are relatively new, they have proven\nto be quite stable and solid, yet they are only part of the \"contrib\"\narea side by side with much simpler and way less solid scripts.\n\nIn order these in Git mainline you might need a bit of tinkering, and\nit's not straight-forward to package them for distributions.\n\nWith git-fc they are installed by default, and in the right way,\nmaking things easier for distributions.\n\n=== Improvements to the transport helper ===\n\nThe two way bridges between Git and Mercurial/Bazaar already work\nquite well, but they lack some features, specifically you cannot do\n--force, or --dry-run, or use an old:new refspec. If you are not\nfamiliar with the old:new refspec; you can do 'git push\nmaster:my-master', which would push your 'master' branch, as if it was\nnamed 'my-master' in the remote repository.\n\nThis is extremely useful if you are really serious about using Git as\na transparent client to access a Mercurial repository.\n\n=== New core.mode configuration ===\n\nGit is already preparing users for the v2.0 release which would bring\nminor backward compatibility breakage, but some people would rather\nget rid of the warnings which are going to stay probably for many\nreleases more and just move to the new behavior already.\n\nTesting Git v2.0 behavior today would not only help git-fc, but also\nthe Git mainline, and you can do that by setting core.mode = next, so\nif you do this and provide feedback about any issues, that would be\ngreatly appreciated. Unfortunately you cannot test the v2.0 behavior\nin Git mainline because they rejected the patches, but you can in\ngit-fc.\n\nPlease note that the v2.0 behavior might change in the future, before\nv2.0 is released, so if you enable this mode you need to be aware of\nthat. Chances are you are not going to notice any difference anyway.\n\nIn addition to the \"next\" (v2.0) mode, there's the \"progress\" mode.\nThis mode enables \"next\" plus other configurations that have been\nproposed to change by default in v2.0, but hasn't yet been agreed.\n\nIn particular, you get these:\n\n  merge.defaulttoupstream = true\n  branch.autosetupmerge = always\n  mergetool.prompt = false\n\nThere might be more in the future, and suggestions are welcome.\n\nIt is recommended that you setup this mode for git-fc:\n\n  git config --global core.mode progress\n\n=== Non-ff pulls rejected by default ===\n\nEven in the Git project everybody has agreed this is the way to go in\norder to avoid the typical Git newbie making the mistake of doing a\nmerge, when perhaps (s)he wanted to do git reset, or git rebase. With\nthis change git complains that that a non-fast-forward branch is being\npulled, so the user has to decide what to do.\n\nThe user would have to do either `git pull --merge` or `git pull\n--rebase`, the former being what Git mainline currently does.\n\nThe user can of course choose the old behavior, which is easy to configure:\n\n  git config --global pull.mode merge\n\n=== Official staging area ===\n\nEverybody already uses the term \"staging area\" already, and Git\ndevelopers also agreed it the best term to what is officially referred\nto as \"the index\". So git-fc has new options for all commands that\nmodify the staging area (e.g. git grep --staged, git rm --staged), and\nalso adds a new git stage command that makes it easier to work with\nthe staging area.\n\n  'git stage' [options] [--] [<paths>...]\n  'git stage add' [options] [--] [<paths>...]\n  'git stage reset' [-q|--patch] [--] [<paths>...]\n  'git stage diff' [options] [<commit>] [--] [<paths>...]\n  'git stage rm' [options] [--] [<paths>...]\n  'git stage apply' [options] [--] [<paths>...]\n  'git stage edit'\n\nWithout any command, git stage adds files to the stage, same as git\nadd, same as in Git mainline.\n\n=== New fetch.default configuration ===\n\nWhen you have configured the upstream tracking branch for all your\nbranches, you will probably have tracking branches that point to a\nlocal branch, for example feature-a pointing to master, in which case\nyou would get something like:\n\n  % git fetch\n  From .\n   * branch            master     -> FETCH_HEAD\n\nWhich makes absolutely no sense, since the '.' repository is not even\ndocumented, and FETCH_HEAD is a marginally known concept. In this case\ngit fetch is basically doing nothing from the user’s point of view.\n\nSo the user can configure `fetch.default = simple` to get a simple\nsensible default; `git fetch` will always use origin by default, which\nis not ideal for everyone, but it's better than the current\nalternative.\n\nIf you use the \"progress\" mode, this option is also enabled.\n\n=== Publish tracking branch ===\n\nGit mainline doesn't have the greatest support for triangular\nworkflows, a good solution for that is to introduce a second\n\"upstream\" tracking branch which is for the reverse; the branch you\nnormally push to.\n\nSay you clone a repository (libgit2) in GitHub, then create a branch\n(feature-a) and push it to your personal repository, you would want to\ntrack two branches (origin/master), and (mine/feature-a), but Git\nmainline only provides support for a single upstream tracking branch.\n\nIf you setup your upstream tracking branch to origin/master, then you\ncan just do git rebase without arguments and git will pick the right\nbranch (origin/master) to rebase to. However, git push by default will\nalso try to push to origin/master, which is not what you want. Plus\ngit branch -v will show how ahead/behind your branch is compared to\norigin/master, not mine/feature-a.\n\nIf you set up your upstream to mine/feature-a, then git push will\nwork, but git rebase won’t.\n\nWith this option, git rebase uses the upstream branch, and git push\nuses the publish branch.\n\nSetting the publish tracking branch is easy:\n\n  git push --set-publish mine feature-a\n\nOr:\n\n  git branch --set-publish mine/feature-a\n\nAnd `git branch -v` will show it as well:\n\n  fc/branch/fast      177dcad [master, gh/fc/branch/fast] branch:\nreorganize verbose options\n  fc/stage            abb6ad5 [master, gh/fc/stage] completion: update\n'git reset' new stage options\n  fc/transport/improv eb4d3c7 [master, gh/fc/transport/improv]\ntransport-helper: don't update refs in dry-run\n\n=== Support for Ruby ===\n\nBy far the most complex and interesting feature, but unfortunately\nalso the one that is not yet 100% complete.\n\nThere is partial optional support for Ruby. Git already has tooling so\nany language can use it’s plumbing and achieve plenty of tasks:\n\n  IO.popen(%w[git for-each-ref]) do |io|\n    io.each do |line|\n      sha1, kind, name = line.split()\n      # stuff\n    end\n  end\n\nHowever, this a) requires a process fork, and b) requires I/O\ncommunication to get the desired data. While this is not a big deal on\nmany systems, it is in Windows systems where forks are slow, and many\nGit core programs don’t work as well as they do in Linux.\n\nGit has a goal to replace all the core scripts with native C versions,\nbut it’s a goal only in name that is not actually pursued. In\naddition, that still leaves out any third party tools since Git\ndoesn’t provide a shared libgit library, which is why an independent\nlibgit2 was needed in the first place.\n\nRuby bindings solve these problems:\n\n  for_each_ref() do |name, sha1, flags|\n    # stuff\n  end\n\nThe command `git ruby` can use this script by providing the bindings\nfor many Git’s internal C functions (though not all), which makes it\neasier to write Ruby programs that take full advantage of Git without\nany need of forks, or I/O communication.\n\n== For more information ==\n\nThe code is in Github[1], the home page is in Google code[2], and the\nmailing list in Google groups (git-fc@googlegroups.com). All comments\nand patches are welcome.\n\nYou can find future comments and releases in my blog [3].\n\nEnjoy ;)\n\n[1] https://github.com/felipec/git\n[2] https://code.google.com/p/git-fc/\n[3] http://felipec.wordpress.com/tag/git-fc/\n\n-- \nFelipe Contreras\n"}]}