git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/17] contrib: cleanup
@ 2014-05-09 19:11 Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 01/17] contrib: remove outdated README Felipe Contreras
                   ` (15 more replies)
  0 siblings, 16 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

The contrib area is full of accumulatted cruft. Let's remove what is not used
and what is already maintained externay.


Felipe Contreras (17):
  contrib: remove outdated README
  contrib: remove 'vim'
  contrib: remove 'emacs'
  contrib: remove 'diffall'
  contrib: remove 'hg-to-git'
  contrib: remove 'hooks/multimail'
  contrib: remove 'stats'
  contrib: remove 'convert-objects'
  contrib: remove 'git-shell-commands'
  contrib: reomve 'thunderbird-patch-inline'
  contrib: remove 'workdir'
  contrib: remove 'svn-fe'
  contrib: remove 'rerere-train'
  contrib: remove 'remotes2config'
  contrib: remove 'persistent-https'
  contrib: remove 'git-resurrect'
  contrib: remove 'contacts'

 contrib/README                                     |   43 -
 contrib/contacts/git-contacts                      |  203 --
 contrib/contacts/git-contacts.txt                  |   94 -
 contrib/convert-objects/convert-objects.c          |  329 ---
 contrib/convert-objects/git-convert-objects.txt    |   29 -
 contrib/diffall/README                             |   31 -
 contrib/diffall/git-diffall                        |  257 --
 contrib/emacs/.gitignore                           |    1 -
 contrib/emacs/Makefile                             |   21 -
 contrib/emacs/README                               |   39 -
 contrib/emacs/git-blame.el                         |  484 ----
 contrib/emacs/git.el                               | 1705 -------------
 contrib/git-resurrect.sh                           |  182 --
 contrib/git-shell-commands/README                  |   18 -
 contrib/git-shell-commands/help                    |   18 -
 contrib/git-shell-commands/list                    |   10 -
 contrib/hg-to-git/hg-to-git.py                     |  255 --
 contrib/hg-to-git/hg-to-git.txt                    |   21 -
 contrib/hooks/multimail/CHANGES                    |   33 -
 contrib/hooks/multimail/README                     |  500 ----
 contrib/hooks/multimail/README.Git                 |   15 -
 .../README.migrate-from-post-receive-email         |  145 --
 contrib/hooks/multimail/git_multimail.py           | 2539 --------------------
 contrib/hooks/multimail/migrate-mailhook-config    |  269 ---
 contrib/hooks/multimail/post-receive               |   90 -
 contrib/persistent-https/LICENSE                   |  202 --
 contrib/persistent-https/Makefile                  |   38 -
 contrib/persistent-https/README                    |   62 -
 contrib/persistent-https/client.go                 |  189 --
 contrib/persistent-https/main.go                   |   82 -
 contrib/persistent-https/proxy.go                  |  190 --
 contrib/persistent-https/socket.go                 |   97 -
 contrib/remotes2config.sh                          |   33 -
 contrib/rerere-train.sh                            |   52 -
 contrib/stats/git-common-hash                      |   26 -
 contrib/stats/mailmap.pl                           |   70 -
 contrib/stats/packinfo.pl                          |  212 --
 contrib/svn-fe/.gitignore                          |    4 -
 contrib/svn-fe/Makefile                            |   63 -
 contrib/svn-fe/svn-fe.c                            |   18 -
 contrib/svn-fe/svn-fe.txt                          |   71 -
 contrib/svn-fe/svnrdump_sim.py                     |   57 -
 contrib/thunderbird-patch-inline/README            |   20 -
 contrib/thunderbird-patch-inline/appp.sh           |   55 -
 contrib/vim/README                                 |   22 -
 contrib/workdir/git-new-workdir                    |   82 -
 46 files changed, 8976 deletions(-)
 delete mode 100644 contrib/README
 delete mode 100755 contrib/contacts/git-contacts
 delete mode 100644 contrib/contacts/git-contacts.txt
 delete mode 100644 contrib/convert-objects/convert-objects.c
 delete mode 100644 contrib/convert-objects/git-convert-objects.txt
 delete mode 100644 contrib/diffall/README
 delete mode 100755 contrib/diffall/git-diffall
 delete mode 100644 contrib/emacs/.gitignore
 delete mode 100644 contrib/emacs/Makefile
 delete mode 100644 contrib/emacs/README
 delete mode 100644 contrib/emacs/git-blame.el
 delete mode 100644 contrib/emacs/git.el
 delete mode 100755 contrib/git-resurrect.sh
 delete mode 100644 contrib/git-shell-commands/README
 delete mode 100755 contrib/git-shell-commands/help
 delete mode 100755 contrib/git-shell-commands/list
 delete mode 100755 contrib/hg-to-git/hg-to-git.py
 delete mode 100644 contrib/hg-to-git/hg-to-git.txt
 delete mode 100644 contrib/hooks/multimail/CHANGES
 delete mode 100644 contrib/hooks/multimail/README
 delete mode 100644 contrib/hooks/multimail/README.Git
 delete mode 100644 contrib/hooks/multimail/README.migrate-from-post-receive-email
 delete mode 100755 contrib/hooks/multimail/git_multimail.py
 delete mode 100755 contrib/hooks/multimail/migrate-mailhook-config
 delete mode 100755 contrib/hooks/multimail/post-receive
 delete mode 100644 contrib/persistent-https/LICENSE
 delete mode 100644 contrib/persistent-https/Makefile
 delete mode 100644 contrib/persistent-https/README
 delete mode 100644 contrib/persistent-https/client.go
 delete mode 100644 contrib/persistent-https/main.go
 delete mode 100644 contrib/persistent-https/proxy.go
 delete mode 100644 contrib/persistent-https/socket.go
 delete mode 100755 contrib/remotes2config.sh
 delete mode 100755 contrib/rerere-train.sh
 delete mode 100755 contrib/stats/git-common-hash
 delete mode 100755 contrib/stats/mailmap.pl
 delete mode 100755 contrib/stats/packinfo.pl
 delete mode 100644 contrib/svn-fe/.gitignore
 delete mode 100644 contrib/svn-fe/Makefile
 delete mode 100644 contrib/svn-fe/svn-fe.c
 delete mode 100644 contrib/svn-fe/svn-fe.txt
 delete mode 100755 contrib/svn-fe/svnrdump_sim.py
 delete mode 100644 contrib/thunderbird-patch-inline/README
 delete mode 100755 contrib/thunderbird-patch-inline/appp.sh
 delete mode 100644 contrib/vim/README
 delete mode 100755 contrib/workdir/git-new-workdir

-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 01/17] contrib: remove outdated README
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:58   ` Junio C Hamano
  2014-05-09 19:11 ` [PATCH v2 02/17] contrib: remove 'vim' Felipe Contreras
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

There is no guideline as for what should be part of contrib.

Some tools are actively maintained, others consist of a single commit.
Some tools have active user-base, some aren't used by anyone. Some tools
are on the path towards the core, others will never get there. Some
tools are already out-of-tree and simply mirrored, others probably
wouldn't survive out-of-tree. Some tools are production-ready, others
don't even run. Some tools have tests, most don't.

Junio has explained that he wrote this a long time ago, when Git was a
different beast, now this no longer applies.

The only way to find out if a tool belongs in contrib or not is to as
Junio.

Cc: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/README | 43 -------------------------------------------
 1 file changed, 43 deletions(-)
 delete mode 100644 contrib/README

diff --git a/contrib/README b/contrib/README
deleted file mode 100644
index 05f291c..0000000
--- a/contrib/README
+++ /dev/null
@@ -1,43 +0,0 @@
-Contributed Software
-
-Although these pieces are available as part of the official git
-source tree, they are in somewhat different status.  The
-intention is to keep interesting tools around git here, maybe
-even experimental ones, to give users an easier access to them,
-and to give tools wider exposure, so that they can be improved
-faster.
-
-I am not expecting to touch these myself that much.  As far as
-my day-to-day operation is concerned, these subdirectories are
-owned by their respective primary authors.  I am willing to help
-if users of these components and the contrib/ subtree "owners"
-have technical/design issues to resolve, but the initiative to
-fix and/or enhance things _must_ be on the side of the subtree
-owners.  IOW, I won't be actively looking for bugs and rooms for
-enhancements in them as the git maintainer -- I may only do so
-just as one of the users when I want to scratch my own itch.  If
-you have patches to things in contrib/ area, the patch should be
-first sent to the primary author, and then the primary author
-should ack and forward it to me (git pull request is nicer).
-This is the same way as how I have been treating gitk, and to a
-lesser degree various foreign SCM interfaces, so you know the
-drill.
-
-I expect that things that start their life in the contrib/ area
-to graduate out of contrib/ once they mature, either by becoming
-projects on their own, or moving to the toplevel directory.  On
-the other hand, I expect I'll be proposing removal of disused
-and inactive ones from time to time.
-
-If you have new things to add to this area, please first propose
-it on the git mailing list, and after a list discussion proves
-there are some general interests (it does not have to be a
-list-wide consensus for a tool targeted to a relatively narrow
-audience -- for example I do not work with projects whose
-upstream is svn, so I have no use for git-svn myself, but it is
-of general interest for people who need to interoperate with SVN
-repositories in a way git-svn works better than git-svnimport),
-submit a patch to create a subdirectory of contrib/ and put your
-stuff there.
-
--jc
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 02/17] contrib: remove 'vim'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 01/17] contrib: remove outdated README Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 03/17] contrib: remove 'emacs' Felipe Contreras
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras, Jonathan Nieder, Jeff King

There are only instructions for old versions of vim (<7.2) which don't
apply since six years.

The vast majority of people don't need these instructions.

Let's remove them.

Cc: Jonathan Nieder <jrnieder@gmail.com>
Cc: Jeff King <peff@peff.net>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/vim/README | 22 ----------------------
 1 file changed, 22 deletions(-)
 delete mode 100644 contrib/vim/README

diff --git a/contrib/vim/README b/contrib/vim/README
deleted file mode 100644
index 8f16d06..0000000
--- a/contrib/vim/README
+++ /dev/null
@@ -1,22 +0,0 @@
-Syntax highlighting for git commit messages, config files, etc. is
-included with the vim distribution as of vim 7.2, and should work
-automatically.
-
-If you have an older version of vim, you can get the latest syntax
-files from the vim project:
-
-  http://ftp.vim.org/pub/vim/runtime/syntax/git.vim
-  http://ftp.vim.org/pub/vim/runtime/syntax/gitcommit.vim
-  http://ftp.vim.org/pub/vim/runtime/syntax/gitconfig.vim
-  http://ftp.vim.org/pub/vim/runtime/syntax/gitrebase.vim
-  http://ftp.vim.org/pub/vim/runtime/syntax/gitsendemail.vim
-
-These files are also available via FTP at the same location.
-
-To install:
-
-  1. Copy these files to vim's syntax directory $HOME/.vim/syntax
-  2. To auto-detect the editing of various git-related filetypes:
-
-	$ curl http://ftp.vim.org/pub/vim/runtime/filetype.vim |
-		sed -ne '/^" Git$/, /^$/ p' >>$HOME/.vim/filetype.vim
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 03/17] contrib: remove 'emacs'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 01/17] contrib: remove outdated README Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 02/17] contrib: remove 'vim' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 04/17] contrib: remove 'diffall' Felipe Contreras
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Felipe Contreras, Alexandre Julliard,
	David Kågedal, Jakub Narębski

These tools are already part of emacs in different forms, either generic
vc support, or external tools like Magit.

Cc: Alexandre Julliard <julliard@winehq.org>
Cc: David Kågedal <davidk@lysator.liu.se>
Cc: Jakub Narębski <jnareb@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/emacs/.gitignore   |    1 -
 contrib/emacs/Makefile     |   21 -
 contrib/emacs/README       |   39 -
 contrib/emacs/git-blame.el |  484 -------------
 contrib/emacs/git.el       | 1705 --------------------------------------------
 5 files changed, 2250 deletions(-)
 delete mode 100644 contrib/emacs/.gitignore
 delete mode 100644 contrib/emacs/Makefile
 delete mode 100644 contrib/emacs/README
 delete mode 100644 contrib/emacs/git-blame.el
 delete mode 100644 contrib/emacs/git.el

diff --git a/contrib/emacs/.gitignore b/contrib/emacs/.gitignore
deleted file mode 100644
index c531d98..0000000
--- a/contrib/emacs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.elc
diff --git a/contrib/emacs/Makefile b/contrib/emacs/Makefile
deleted file mode 100644
index 24d9312..0000000
--- a/contrib/emacs/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-## Build and install stuff
-
-EMACS = emacs
-
-ELC = git.elc git-blame.elc
-INSTALL ?= install
-INSTALL_ELC = $(INSTALL) -m 644
-prefix ?= $(HOME)
-emacsdir = $(prefix)/share/emacs/site-lisp
-RM ?= rm -f
-
-all: $(ELC)
-
-install: all
-	$(INSTALL) -d $(DESTDIR)$(emacsdir)
-	$(INSTALL_ELC) $(ELC:.elc=.el) $(ELC) $(DESTDIR)$(emacsdir)
-
-%.elc: %.el
-	$(EMACS) -batch -f batch-byte-compile $<
-
-clean:; $(RM) $(ELC)
diff --git a/contrib/emacs/README b/contrib/emacs/README
deleted file mode 100644
index 82368bd..0000000
--- a/contrib/emacs/README
+++ /dev/null
@@ -1,39 +0,0 @@
-This directory contains various modules for Emacs support.
-
-To make the modules available to Emacs, you should add this directory
-to your load-path, and then require the modules you want. This can be
-done by adding to your .emacs something like this:
-
-  (add-to-list 'load-path ".../git/contrib/emacs")
-  (require 'git)
-  (require 'git-blame)
-
-
-The following modules are available:
-
-* git.el:
-
-  Status manager that displays the state of all the files of the
-  project, and provides easy access to the most frequently used git
-  commands. The user interface is as far as possible compatible with
-  the pcl-cvs mode. It can be started with `M-x git-status'.
-
-* git-blame.el:
-
-  Emacs implementation of incremental git-blame.  When you turn it on
-  while viewing a file, the editor buffer will be updated by setting
-  the background of individual lines to a color that reflects which
-  commit it comes from.  And when you move around the buffer, a
-  one-line summary will be shown in the echo area.
-
-* vc-git.el:
-
-  This file used to contain the VC-mode backend for git, but it is no
-  longer distributed with git. It is now maintained as part of Emacs
-  and included in standard Emacs distributions starting from version
-  22.2.
-
-  If you have an earlier Emacs version, upgrading to Emacs 22 is
-  recommended, since the VC mode in older Emacs is not generic enough
-  to be able to support git in a reasonable manner, and no attempt has
-  been made to backport vc-git.el.
diff --git a/contrib/emacs/git-blame.el b/contrib/emacs/git-blame.el
deleted file mode 100644
index e671f6c..0000000
--- a/contrib/emacs/git-blame.el
+++ /dev/null
@@ -1,484 +0,0 @@
-;;; git-blame.el --- Minor mode for incremental blame for Git  -*- coding: utf-8 -*-
-;;
-;; Copyright (C) 2007  David Kågedal
-;;
-;; Authors:    David Kågedal <davidk@lysator.liu.se>
-;; Created:    31 Jan 2007
-;; Message-ID: <87iren2vqx.fsf@morpheus.local>
-;; License:    GPL
-;; Keywords:   git, version control, release management
-;;
-;; Compatibility: Emacs21, Emacs22 and EmacsCVS
-;;                Git 1.5 and up
-
-;; This file is *NOT* part of GNU Emacs.
-;; This file is distributed under the same terms as GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2 of
-;; the License, or (at your option) any later version.
-
-;; This program is distributed in the hope that it will be
-;; useful, but WITHOUT ANY WARRANTY; without even the implied
-;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-;; PURPOSE.  See the GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public
-;; License along with this program; if not, write to the Free
-;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-;; MA 02111-1307 USA
-
-;; http://www.fsf.org/copyleft/gpl.html
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-;;
-;; Here is an Emacs implementation of incremental git-blame.  When you
-;; turn it on while viewing a file, the editor buffer will be updated by
-;; setting the background of individual lines to a color that reflects
-;; which commit it comes from.  And when you move around the buffer, a
-;; one-line summary will be shown in the echo area.
-
-;;; Installation:
-;;
-;; To use this package, put it somewhere in `load-path' (or add
-;; directory with git-blame.el to `load-path'), and add the following
-;; line to your .emacs:
-;;
-;;    (require 'git-blame)
-;;
-;; If you do not want to load this package before it is necessary, you
-;; can make use of the `autoload' feature, e.g. by adding to your .emacs
-;; the following lines
-;;
-;;    (autoload 'git-blame-mode "git-blame"
-;;              "Minor mode for incremental blame for Git." t)
-;;
-;; Then first use of `M-x git-blame-mode' would load the package.
-
-;;; Compatibility:
-;;
-;; It requires GNU Emacs 21 or later and Git 1.5.0 and up
-;;
-;; If you'are using Emacs 20, try changing this:
-;;
-;;            (overlay-put ovl 'face (list :background
-;;                                         (cdr (assq 'color (cddddr info)))))
-;;
-;; to
-;;
-;;            (overlay-put ovl 'face (cons 'background-color
-;;                                         (cdr (assq 'color (cddddr info)))))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Code:
-
-(eval-when-compile (require 'cl))			      ; to use `push', `pop'
-(require 'format-spec)
-
-(defface git-blame-prefix-face
-  '((((background dark)) (:foreground "gray"
-                          :background "black"))
-    (((background light)) (:foreground "gray"
-                           :background "white"))
-    (t (:weight bold)))
-  "The face used for the hash prefix."
-  :group 'git-blame)
-
-(defgroup git-blame nil
-  "A minor mode showing Git blame information."
-  :group 'git
-  :link '(function-link git-blame-mode))
-
-
-(defcustom git-blame-use-colors t
-  "Use colors to indicate commits in `git-blame-mode'."
-  :type 'boolean
-  :group 'git-blame)
-
-(defcustom git-blame-prefix-format
-  "%h %20A:"
-  "The format of the prefix added to each line in `git-blame'
-mode. The format is passed to `format-spec' with the following format keys:
-
-  %h - the abbreviated hash
-  %H - the full hash
-  %a - the author name
-  %A - the author email
-  %c - the committer name
-  %C - the committer email
-  %s - the commit summary
-"
-  :group 'git-blame)
-
-(defcustom git-blame-mouseover-format
-  "%h %a %A: %s"
-  "The format of the description shown when pointing at a line in
-`git-blame' mode. The format string is passed to `format-spec'
-with the following format keys:
-
-  %h - the abbreviated hash
-  %H - the full hash
-  %a - the author name
-  %A - the author email
-  %c - the committer name
-  %C - the committer email
-  %s - the commit summary
-"
-  :group 'git-blame)
-
-
-(defun git-blame-color-scale (&rest elements)
-  "Given a list, returns a list of triples formed with each
-elements of the list.
-
-a b => bbb bba bab baa abb aba aaa aab"
-  (let (result)
-    (dolist (a elements)
-      (dolist (b elements)
-        (dolist (c elements)
-          (setq result (cons (format "#%s%s%s" a b c) result)))))
-    result))
-
-;; (git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c") =>
-;; ("#3c3c3c" "#3c3c14" "#3c3c34" "#3c3c2c" "#3c3c1c" "#3c3c24"
-;; "#3c3c04" "#3c3c0c" "#3c143c" "#3c1414" "#3c1434" "#3c142c" ...)
-
-(defmacro git-blame-random-pop (l)
-  "Select a random element from L and returns it. Also remove
-selected element from l."
-  ;; only works on lists with unique elements
-  `(let ((e (elt ,l (random (length ,l)))))
-     (setq ,l (remove e ,l))
-     e))
-
-(defvar git-blame-log-oneline-format
-  "format:[%cr] %cn: %s"
-  "*Formatting option used for describing current line in the minibuffer.
-
-This option is used to pass to git log --pretty= command-line option,
-and describe which commit the current line was made.")
-
-(defvar git-blame-dark-colors
-  (git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c")
-  "*List of colors (format #RGB) to use in a dark environment.
-
-To check out the list, evaluate (list-colors-display git-blame-dark-colors).")
-
-(defvar git-blame-light-colors
-  (git-blame-color-scale "c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")
-  "*List of colors (format #RGB) to use in a light environment.
-
-To check out the list, evaluate (list-colors-display git-blame-light-colors).")
-
-(defvar git-blame-colors '()
-  "Colors used by git-blame. The list is built once when activating git-blame
-minor mode.")
-
-(defvar git-blame-ancient-color "dark green"
-  "*Color to be used for ancient commit.")
-
-(defvar git-blame-autoupdate t
-  "*Automatically update the blame display while editing")
-
-(defvar git-blame-proc nil
-  "The running git-blame process")
-(make-variable-buffer-local 'git-blame-proc)
-
-(defvar git-blame-overlays nil
-  "The git-blame overlays used in the current buffer.")
-(make-variable-buffer-local 'git-blame-overlays)
-
-(defvar git-blame-cache nil
-  "A cache of git-blame information for the current buffer")
-(make-variable-buffer-local 'git-blame-cache)
-
-(defvar git-blame-idle-timer nil
-  "An idle timer that updates the blame")
-(make-variable-buffer-local 'git-blame-cache)
-
-(defvar git-blame-update-queue nil
-  "A queue of update requests")
-(make-variable-buffer-local 'git-blame-update-queue)
-
-;; FIXME: docstrings
-(defvar git-blame-file nil)
-(defvar git-blame-current nil)
-
-(defvar git-blame-mode nil)
-(make-variable-buffer-local 'git-blame-mode)
-
-(defvar git-blame-mode-line-string " blame"
-  "String to display on the mode line when git-blame is active.")
-
-(or (assq 'git-blame-mode minor-mode-alist)
-    (setq minor-mode-alist
-	  (cons '(git-blame-mode git-blame-mode-line-string) minor-mode-alist)))
-
-;;;###autoload
-(defun git-blame-mode (&optional arg)
-  "Toggle minor mode for displaying Git blame
-
-With prefix ARG, turn the mode on if ARG is positive."
-  (interactive "P")
-  (cond
-   ((null arg)
-    (if git-blame-mode (git-blame-mode-off) (git-blame-mode-on)))
-   ((> (prefix-numeric-value arg) 0) (git-blame-mode-on))
-   (t (git-blame-mode-off))))
-
-(defun git-blame-mode-on ()
-  "Turn on git-blame mode.
-
-See also function `git-blame-mode'."
-  (make-local-variable 'git-blame-colors)
-  (if git-blame-autoupdate
-      (add-hook 'after-change-functions 'git-blame-after-change nil t)
-    (remove-hook 'after-change-functions 'git-blame-after-change t))
-  (git-blame-cleanup)
-  (let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
-    (if (eq bgmode 'dark)
-	(setq git-blame-colors git-blame-dark-colors)
-      (setq git-blame-colors git-blame-light-colors)))
-  (setq git-blame-cache (make-hash-table :test 'equal))
-  (setq git-blame-mode t)
-  (git-blame-run))
-
-(defun git-blame-mode-off ()
-  "Turn off git-blame mode.
-
-See also function `git-blame-mode'."
-  (git-blame-cleanup)
-  (if git-blame-idle-timer (cancel-timer git-blame-idle-timer))
-  (setq git-blame-mode nil))
-
-;;;###autoload
-(defun git-reblame ()
-  "Recalculate all blame information in the current buffer"
-  (interactive)
-  (unless git-blame-mode
-    (error "Git-blame is not active"))
-
-  (git-blame-cleanup)
-  (git-blame-run))
-
-(defun git-blame-run (&optional startline endline)
-  (if git-blame-proc
-      ;; Should maybe queue up a new run here
-      (message "Already running git blame")
-    (let ((display-buf (current-buffer))
-          (blame-buf (get-buffer-create
-                      (concat " git blame for " (buffer-name))))
-          (args '("--incremental" "--contents" "-")))
-      (if startline
-          (setq args (append args
-                             (list "-L" (format "%d,%d" startline endline)))))
-      (setq args (append args
-                         (list (file-name-nondirectory buffer-file-name))))
-      (setq git-blame-proc
-            (apply 'start-process
-                   "git-blame" blame-buf
-                   "git" "blame"
-                   args))
-      (with-current-buffer blame-buf
-        (erase-buffer)
-        (make-local-variable 'git-blame-file)
-        (make-local-variable 'git-blame-current)
-        (setq git-blame-file display-buf)
-        (setq git-blame-current nil))
-      (set-process-filter git-blame-proc 'git-blame-filter)
-      (set-process-sentinel git-blame-proc 'git-blame-sentinel)
-      (process-send-region git-blame-proc (point-min) (point-max))
-      (process-send-eof git-blame-proc))))
-
-(defun remove-git-blame-text-properties (start end)
-  (let ((modified (buffer-modified-p))
-        (inhibit-read-only t))
-    (remove-text-properties start end '(point-entered nil))
-    (set-buffer-modified-p modified)))
-
-(defun git-blame-cleanup ()
-  "Remove all blame properties"
-    (mapc 'delete-overlay git-blame-overlays)
-    (setq git-blame-overlays nil)
-    (remove-git-blame-text-properties (point-min) (point-max)))
-
-(defun git-blame-update-region (start end)
-  "Rerun blame to get updates between START and END"
-  (let ((overlays (overlays-in start end)))
-    (while overlays
-      (let ((overlay (pop overlays)))
-        (if (< (overlay-start overlay) start)
-            (setq start (overlay-start overlay)))
-        (if (> (overlay-end overlay) end)
-            (setq end (overlay-end overlay)))
-        (setq git-blame-overlays (delete overlay git-blame-overlays))
-        (delete-overlay overlay))))
-  (remove-git-blame-text-properties start end)
-  ;; We can be sure that start and end are at line breaks
-  (git-blame-run (1+ (count-lines (point-min) start))
-                 (count-lines (point-min) end)))
-
-(defun git-blame-sentinel (proc status)
-  (with-current-buffer (process-buffer proc)
-    (with-current-buffer git-blame-file
-      (setq git-blame-proc nil)
-      (if git-blame-update-queue
-          (git-blame-delayed-update))))
-  ;;(kill-buffer (process-buffer proc))
-  ;;(message "git blame finished")
-  )
-
-(defvar in-blame-filter nil)
-
-(defun git-blame-filter (proc str)
-  (with-current-buffer (process-buffer proc)
-    (save-excursion
-      (goto-char (process-mark proc))
-      (insert-before-markers str)
-      (goto-char (point-min))
-      (unless in-blame-filter
-        (let ((more t)
-              (in-blame-filter t))
-          (while more
-            (setq more (git-blame-parse))))))))
-
-(defun git-blame-parse ()
-  (cond ((looking-at "\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)\n")
-         (let ((hash (match-string 1))
-               (src-line (string-to-number (match-string 2)))
-               (res-line (string-to-number (match-string 3)))
-               (num-lines (string-to-number (match-string 4))))
-           (delete-region (point) (match-end 0))
-           (setq git-blame-current (list (git-blame-new-commit hash)
-                                         src-line res-line num-lines)))
-         t)
-        ((looking-at "\\([a-z-]+\\) \\(.+\\)\n")
-         (let ((key (match-string 1))
-               (value (match-string 2)))
-           (delete-region (point) (match-end 0))
-           (git-blame-add-info (car git-blame-current) key value)
-           (when (string= key "filename")
-             (git-blame-create-overlay (car git-blame-current)
-                                       (caddr git-blame-current)
-                                       (cadddr git-blame-current))
-             (setq git-blame-current nil)))
-         t)
-        (t
-         nil)))
-
-(defun git-blame-new-commit (hash)
-  (with-current-buffer git-blame-file
-    (or (gethash hash git-blame-cache)
-        ;; Assign a random color to each new commit info
-        ;; Take care not to select the same color multiple times
-        (let* ((color (if git-blame-colors
-                          (git-blame-random-pop git-blame-colors)
-                        git-blame-ancient-color))
-               (info `(,hash (color . ,color))))
-          (puthash hash info git-blame-cache)
-          info))))
-
-(defun git-blame-create-overlay (info start-line num-lines)
-  (with-current-buffer git-blame-file
-    (save-excursion
-      (let ((inhibit-point-motion-hooks t)
-            (inhibit-modification-hooks t))
-        (goto-char (point-min))
-        (forward-line (1- start-line))
-        (let* ((start (point))
-               (end (progn (forward-line num-lines) (point)))
-               (ovl (make-overlay start end))
-               (hash (car info))
-               (spec `((?h . ,(substring hash 0 6))
-                       (?H . ,hash)
-                       (?a . ,(git-blame-get-info info 'author))
-                       (?A . ,(git-blame-get-info info 'author-mail))
-                       (?c . ,(git-blame-get-info info 'committer))
-                       (?C . ,(git-blame-get-info info 'committer-mail))
-                       (?s . ,(git-blame-get-info info 'summary)))))
-          (push ovl git-blame-overlays)
-          (overlay-put ovl 'git-blame info)
-          (overlay-put ovl 'help-echo
-                       (format-spec git-blame-mouseover-format spec))
-          (if git-blame-use-colors
-              (overlay-put ovl 'face (list :background
-                                           (cdr (assq 'color (cdr info))))))
-          (overlay-put ovl 'line-prefix
-                       (propertize (format-spec git-blame-prefix-format spec)
-                                   'face 'git-blame-prefix-face)))))))
-
-(defun git-blame-add-info (info key value)
-  (nconc info (list (cons (intern key) value))))
-
-(defun git-blame-get-info (info key)
-  (cdr (assq key (cdr info))))
-
-(defun git-blame-current-commit ()
-  (let ((info (get-char-property (point) 'git-blame)))
-    (if info
-        (car info)
-      (error "No commit info"))))
-
-(defun git-describe-commit (hash)
-  (with-temp-buffer
-    (call-process "git" nil t nil
-                  "log" "-1"
-		  (concat "--pretty=" git-blame-log-oneline-format)
-                  hash)
-    (buffer-substring (point-min) (point-max))))
-
-(defvar git-blame-last-identification nil)
-(make-variable-buffer-local 'git-blame-last-identification)
-(defun git-blame-identify (&optional hash)
-  (interactive)
-  (let ((info (gethash (or hash (git-blame-current-commit)) git-blame-cache)))
-    (when (and info (not (eq info git-blame-last-identification)))
-      (message "%s" (nth 4 info))
-      (setq git-blame-last-identification info))))
-
-;; (defun git-blame-after-save ()
-;;   (when git-blame-mode
-;;     (git-blame-cleanup)
-;;     (git-blame-run)))
-;; (add-hook 'after-save-hook 'git-blame-after-save)
-
-(defun git-blame-after-change (start end length)
-  (when git-blame-mode
-    (git-blame-enq-update start end)))
-
-(defvar git-blame-last-update nil)
-(make-variable-buffer-local 'git-blame-last-update)
-(defun git-blame-enq-update (start end)
-  "Mark the region between START and END as needing blame update"
-  ;; Try to be smart and avoid multiple callouts for sequential
-  ;; editing
-  (cond ((and git-blame-last-update
-              (= start (cdr git-blame-last-update)))
-         (setcdr git-blame-last-update end))
-        ((and git-blame-last-update
-              (= end (car git-blame-last-update)))
-         (setcar git-blame-last-update start))
-        (t
-         (setq git-blame-last-update (cons start end))
-         (setq git-blame-update-queue (nconc git-blame-update-queue
-                                             (list git-blame-last-update)))))
-  (unless (or git-blame-proc git-blame-idle-timer)
-    (setq git-blame-idle-timer
-          (run-with-idle-timer 0.5 nil 'git-blame-delayed-update))))
-
-(defun git-blame-delayed-update ()
-  (setq git-blame-idle-timer nil)
-  (if git-blame-update-queue
-      (let ((first (pop git-blame-update-queue))
-            (inhibit-point-motion-hooks t))
-        (git-blame-update-region (car first) (cdr first)))))
-
-(provide 'git-blame)
-
-;;; git-blame.el ends here
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
deleted file mode 100644
index 5ffc506..0000000
--- a/contrib/emacs/git.el
+++ /dev/null
@@ -1,1705 +0,0 @@
-;;; git.el --- A user interface for git
-
-;; Copyright (C) 2005, 2006, 2007, 2008, 2009 Alexandre Julliard <julliard@winehq.org>
-
-;; Version: 1.0
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2 of
-;; the License, or (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be
-;; useful, but WITHOUT ANY WARRANTY; without even the implied
-;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-;; PURPOSE.  See the GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public
-;; License along with this program; if not, write to the Free
-;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-;; MA 02111-1307 USA
-
-;;; Commentary:
-
-;; This file contains an interface for the git version control
-;; system. It provides easy access to the most frequently used git
-;; commands. The user interface is as far as possible identical to
-;; that of the PCL-CVS mode.
-;;
-;; To install: put this file on the load-path and place the following
-;; in your .emacs file:
-;;
-;;    (require 'git)
-;;
-;; To start: `M-x git-status'
-;;
-;; TODO
-;;  - diff against other branch
-;;  - renaming files from the status buffer
-;;  - creating tags
-;;  - fetch/pull
-;;  - revlist browser
-;;  - git-show-branch browser
-;;
-
-;;; Compatibility:
-;;
-;; This file works on GNU Emacs 21 or later. It may work on older
-;; versions but this is not guaranteed.
-;;
-;; It may work on XEmacs 21, provided that you first install the ewoc
-;; and log-edit packages.
-;;
-
-(eval-when-compile (require 'cl))
-(require 'ewoc)
-(require 'log-edit)
-(require 'easymenu)
-
-
-;;;; Customizations
-;;;; ------------------------------------------------------------
-
-(defgroup git nil
-  "A user interface for the git versioning system."
-  :group 'tools)
-
-(defcustom git-committer-name nil
-  "User name to use for commits.
-The default is to fall back to the repository config,
-then to `add-log-full-name' and then to `user-full-name'."
-  :group 'git
-  :type '(choice (const :tag "Default" nil)
-                 (string :tag "Name")))
-
-(defcustom git-committer-email nil
-  "Email address to use for commits.
-The default is to fall back to the git repository config,
-then to `add-log-mailing-address' and then to `user-mail-address'."
-  :group 'git
-  :type '(choice (const :tag "Default" nil)
-                 (string :tag "Email")))
-
-(defcustom git-commits-coding-system nil
-  "Default coding system for the log message of git commits."
-  :group 'git
-  :type '(choice (const :tag "From repository config" nil)
-                 (coding-system)))
-
-(defcustom git-append-signed-off-by nil
-  "Whether to append a Signed-off-by line to the commit message before editing."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-reuse-status-buffer t
-  "Whether `git-status' should try to reuse an existing buffer
-if there is already one that displays the same directory."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-per-dir-ignore-file ".gitignore"
-  "Name of the per-directory ignore file."
-  :group 'git
-  :type 'string)
-
-(defcustom git-show-uptodate nil
-  "Whether to display up-to-date files."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-show-ignored nil
-  "Whether to display ignored files."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-show-unknown t
-  "Whether to display unknown files."
-  :group 'git
-  :type 'boolean)
-
-
-(defface git-status-face
-  '((((class color) (background light)) (:foreground "purple"))
-    (((class color) (background dark)) (:foreground "salmon")))
-  "Git mode face used to highlight added and modified files."
-  :group 'git)
-
-(defface git-unmerged-face
-  '((((class color) (background light)) (:foreground "red" :bold t))
-    (((class color) (background dark)) (:foreground "red" :bold t)))
-  "Git mode face used to highlight unmerged files."
-  :group 'git)
-
-(defface git-unknown-face
-  '((((class color) (background light)) (:foreground "goldenrod" :bold t))
-    (((class color) (background dark)) (:foreground "goldenrod" :bold t)))
-  "Git mode face used to highlight unknown files."
-  :group 'git)
-
-(defface git-uptodate-face
-  '((((class color) (background light)) (:foreground "grey60"))
-    (((class color) (background dark)) (:foreground "grey40")))
-  "Git mode face used to highlight up-to-date files."
-  :group 'git)
-
-(defface git-ignored-face
-  '((((class color) (background light)) (:foreground "grey60"))
-    (((class color) (background dark)) (:foreground "grey40")))
-  "Git mode face used to highlight ignored files."
-  :group 'git)
-
-(defface git-mark-face
-  '((((class color) (background light)) (:foreground "red" :bold t))
-    (((class color) (background dark)) (:foreground "tomato" :bold t)))
-  "Git mode face used for the file marks."
-  :group 'git)
-
-(defface git-header-face
-  '((((class color) (background light)) (:foreground "blue"))
-    (((class color) (background dark)) (:foreground "blue")))
-  "Git mode face used for commit headers."
-  :group 'git)
-
-(defface git-separator-face
-  '((((class color) (background light)) (:foreground "brown"))
-    (((class color) (background dark)) (:foreground "brown")))
-  "Git mode face used for commit separator."
-  :group 'git)
-
-(defface git-permission-face
-  '((((class color) (background light)) (:foreground "green" :bold t))
-    (((class color) (background dark)) (:foreground "green" :bold t)))
-  "Git mode face used for permission changes."
-  :group 'git)
-
-
-;;;; Utilities
-;;;; ------------------------------------------------------------
-
-(defconst git-log-msg-separator "--- log message follows this line ---")
-
-(defvar git-log-edit-font-lock-keywords
-  `(("^\\(Author:\\|Date:\\|Merge:\\|Signed-off-by:\\)\\(.*\\)$"
-     (1 font-lock-keyword-face)
-     (2 font-lock-function-name-face))
-    (,(concat "^\\(" (regexp-quote git-log-msg-separator) "\\)$")
-     (1 font-lock-comment-face))))
-
-(defun git-get-env-strings (env)
-  "Build a list of NAME=VALUE strings from a list of environment strings."
-  (mapcar (lambda (entry) (concat (car entry) "=" (cdr entry))) env))
-
-(defun git-call-process (buffer &rest args)
-  "Wrapper for call-process that sets environment strings."
-  (apply #'call-process "git" nil buffer nil args))
-
-(defun git-call-process-display-error (&rest args)
-  "Wrapper for call-process that displays error messages."
-  (let* ((dir default-directory)
-         (buffer (get-buffer-create "*Git Command Output*"))
-         (ok (with-current-buffer buffer
-               (let ((default-directory dir)
-                     (buffer-read-only nil))
-                 (erase-buffer)
-                 (eq 0 (apply #'git-call-process (list buffer t) args))))))
-    (unless ok (display-message-or-buffer buffer))
-    ok))
-
-(defun git-call-process-string (&rest args)
-  "Wrapper for call-process that returns the process output as a string,
-or nil if the git command failed."
-  (with-temp-buffer
-    (and (eq 0 (apply #'git-call-process t args))
-         (buffer-string))))
-
-(defun git-call-process-string-display-error (&rest args)
-  "Wrapper for call-process that displays error message and returns
-the process output as a string, or nil if the git command failed."
-  (with-temp-buffer
-    (if (eq 0 (apply #'git-call-process (list t t) args))
-        (buffer-string)
-      (display-message-or-buffer (current-buffer))
-      nil)))
-
-(defun git-run-process-region (buffer start end program args)
-  "Run a git process with a buffer region as input."
-  (let ((output-buffer (current-buffer))
-        (dir default-directory))
-    (with-current-buffer buffer
-      (cd dir)
-      (apply #'call-process-region start end program
-             nil (list output-buffer t) nil args))))
-
-(defun git-run-command-buffer (buffer-name &rest args)
-  "Run a git command, sending the output to a buffer named BUFFER-NAME."
-  (let ((dir default-directory)
-        (buffer (get-buffer-create buffer-name)))
-    (message "Running git %s..." (car args))
-    (with-current-buffer buffer
-      (let ((default-directory dir)
-            (buffer-read-only nil))
-        (erase-buffer)
-        (apply #'git-call-process buffer args)))
-    (message "Running git %s...done" (car args))
-    buffer))
-
-(defun git-run-command-region (buffer start end env &rest args)
-  "Run a git command with specified buffer region as input."
-  (with-temp-buffer
-    (if (eq 0 (if env
-                  (git-run-process-region
-                   buffer start end "env"
-                   (append (git-get-env-strings env) (list "git") args))
-                (git-run-process-region buffer start end "git" args)))
-        (buffer-string)
-      (display-message-or-buffer (current-buffer))
-      nil)))
-
-(defun git-run-hook (hook env &rest args)
-  "Run a git hook and display its output if any."
-  (let ((dir default-directory)
-        (hook-name (expand-file-name (concat ".git/hooks/" hook))))
-    (or (not (file-executable-p hook-name))
-        (let (status (buffer (get-buffer-create "*Git Hook Output*")))
-          (with-current-buffer buffer
-            (erase-buffer)
-            (cd dir)
-            (setq status
-                  (if env
-                      (apply #'call-process "env" nil (list buffer t) nil
-                             (append (git-get-env-strings env) (list hook-name) args))
-                    (apply #'call-process hook-name nil (list buffer t) nil args))))
-          (display-message-or-buffer buffer)
-          (eq 0 status)))))
-
-(defun git-get-string-sha1 (string)
-  "Read a SHA1 from the specified string."
-  (and string
-       (string-match "[0-9a-f]\\{40\\}" string)
-       (match-string 0 string)))
-
-(defun git-get-committer-name ()
-  "Return the name to use as GIT_COMMITTER_NAME."
-  ; copied from log-edit
-  (or git-committer-name
-      (git-config "user.name")
-      (and (boundp 'add-log-full-name) add-log-full-name)
-      (and (fboundp 'user-full-name) (user-full-name))
-      (and (boundp 'user-full-name) user-full-name)))
-
-(defun git-get-committer-email ()
-  "Return the email address to use as GIT_COMMITTER_EMAIL."
-  ; copied from log-edit
-  (or git-committer-email
-      (git-config "user.email")
-      (and (boundp 'add-log-mailing-address) add-log-mailing-address)
-      (and (fboundp 'user-mail-address) (user-mail-address))
-      (and (boundp 'user-mail-address) user-mail-address)))
-
-(defun git-get-commits-coding-system ()
-  "Return the coding system to use for commits."
-  (let ((repo-config (git-config "i18n.commitencoding")))
-    (or git-commits-coding-system
-        (and repo-config
-             (fboundp 'locale-charset-to-coding-system)
-             (locale-charset-to-coding-system repo-config))
-      'utf-8)))
-
-(defun git-get-logoutput-coding-system ()
-  "Return the coding system used for git-log output."
-  (let ((repo-config (or (git-config "i18n.logoutputencoding")
-                         (git-config "i18n.commitencoding"))))
-    (or git-commits-coding-system
-        (and repo-config
-             (fboundp 'locale-charset-to-coding-system)
-             (locale-charset-to-coding-system repo-config))
-      'utf-8)))
-
-(defun git-escape-file-name (name)
-  "Escape a file name if necessary."
-  (if (string-match "[\n\t\"\\]" name)
-      (concat "\""
-              (mapconcat (lambda (c)
-                   (case c
-                     (?\n "\\n")
-                     (?\t "\\t")
-                     (?\\ "\\\\")
-                     (?\" "\\\"")
-                     (t (char-to-string c))))
-                 name "")
-              "\"")
-    name))
-
-(defun git-success-message (text files)
-  "Print a success message after having handled FILES."
-  (let ((n (length files)))
-    (if (equal n 1)
-        (message "%s %s" text (car files))
-      (message "%s %d files" text n))))
-
-(defun git-get-top-dir (dir)
-  "Retrieve the top-level directory of a git tree."
-  (let ((cdup (with-output-to-string
-                (with-current-buffer standard-output
-                  (cd dir)
-                  (unless (eq 0 (git-call-process t "rev-parse" "--show-cdup"))
-                    (error "cannot find top-level git tree for %s." dir))))))
-    (expand-file-name (concat (file-name-as-directory dir)
-                              (car (split-string cdup "\n"))))))
-
-;stolen from pcl-cvs
-(defun git-append-to-ignore (file)
-  "Add a file name to the ignore file in its directory."
-  (let* ((fullname (expand-file-name file))
-         (dir (file-name-directory fullname))
-         (name (file-name-nondirectory fullname))
-         (ignore-name (expand-file-name git-per-dir-ignore-file dir))
-         (created (not (file-exists-p ignore-name))))
-  (save-window-excursion
-    (set-buffer (find-file-noselect ignore-name))
-    (goto-char (point-max))
-    (unless (zerop (current-column)) (insert "\n"))
-    (insert "/" name "\n")
-    (sort-lines nil (point-min) (point-max))
-    (save-buffer))
-  (when created
-    (git-call-process nil "update-index" "--add" "--" (file-relative-name ignore-name)))
-  (git-update-status-files (list (file-relative-name ignore-name)))))
-
-; propertize definition for XEmacs, stolen from erc-compat
-(eval-when-compile
-  (unless (fboundp 'propertize)
-    (defun propertize (string &rest props)
-      (let ((string (copy-sequence string)))
-        (while props
-          (put-text-property 0 (length string) (nth 0 props) (nth 1 props) string)
-          (setq props (cddr props)))
-        string))))
-
-;;;; Wrappers for basic git commands
-;;;; ------------------------------------------------------------
-
-(defun git-rev-parse (rev)
-  "Parse a revision name and return its SHA1."
-  (git-get-string-sha1
-   (git-call-process-string "rev-parse" rev)))
-
-(defun git-config (key)
-  "Retrieve the value associated to KEY in the git repository config file."
-  (let ((str (git-call-process-string "config" key)))
-    (and str (car (split-string str "\n")))))
-
-(defun git-symbolic-ref (ref)
-  "Wrapper for the git-symbolic-ref command."
-  (let ((str (git-call-process-string "symbolic-ref" ref)))
-    (and str (car (split-string str "\n")))))
-
-(defun git-update-ref (ref newval &optional oldval reason)
-  "Update a reference by calling git-update-ref."
-  (let ((args (and oldval (list oldval))))
-    (when newval (push newval args))
-    (push ref args)
-    (when reason
-     (push reason args)
-     (push "-m" args))
-    (unless newval (push "-d" args))
-    (apply 'git-call-process-display-error "update-ref" args)))
-
-(defun git-for-each-ref (&rest specs)
-  "Return a list of refs using git-for-each-ref.
-Each entry is a cons of (SHORT-NAME . FULL-NAME)."
-  (let (refs)
-    (with-temp-buffer
-      (apply #'git-call-process t "for-each-ref" "--format=%(refname)" specs)
-      (goto-char (point-min))
-      (while (re-search-forward "^[^/\n]+/[^/\n]+/\\(.+\\)$" nil t)
-	(push (cons (match-string 1) (match-string 0)) refs)))
-    (nreverse refs)))
-
-(defun git-read-tree (tree &optional index-file)
-  "Read a tree into the index file."
-  (let ((process-environment
-         (append (and index-file (list (concat "GIT_INDEX_FILE=" index-file))) process-environment)))
-    (apply 'git-call-process-display-error "read-tree" (if tree (list tree)))))
-
-(defun git-write-tree (&optional index-file)
-  "Call git-write-tree and return the resulting tree SHA1 as a string."
-  (let ((process-environment
-         (append (and index-file (list (concat "GIT_INDEX_FILE=" index-file))) process-environment)))
-    (git-get-string-sha1
-     (git-call-process-string-display-error "write-tree"))))
-
-(defun git-commit-tree (buffer tree parent)
-  "Create a commit and possibly update HEAD.
-Create a commit with the message in BUFFER using the tree with hash TREE.
-Use PARENT as the parent of the new commit. If PARENT is the current \"HEAD\",
-update the \"HEAD\" reference to the new commit."
-  (let ((author-name (git-get-committer-name))
-        (author-email (git-get-committer-email))
-        (subject "commit (initial): ")
-        author-date log-start log-end args coding-system-for-write)
-    (when parent
-      (setq subject "commit: ")
-      (push "-p" args)
-      (push parent args))
-    (with-current-buffer buffer
-      (goto-char (point-min))
-      (if
-          (setq log-start (re-search-forward (concat "^" (regexp-quote git-log-msg-separator) "\n") nil t))
-          (save-restriction
-            (narrow-to-region (point-min) log-start)
-            (goto-char (point-min))
-            (when (re-search-forward "^Author: +\\(.*?\\) *<\\(.*\\)> *$" nil t)
-              (setq author-name (match-string 1)
-                    author-email (match-string 2)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Date: +\\(.*\\)$" nil t)
-              (setq author-date (match-string 1)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Merge: +\\(.*\\)" nil t)
-              (setq subject "commit (merge): ")
-              (dolist (parent (split-string (match-string 1) " +" t))
-                (push "-p" args)
-                (push parent args))))
-        (setq log-start (point-min)))
-      (setq log-end (point-max))
-      (goto-char log-start)
-      (when (re-search-forward ".*$" nil t)
-        (setq subject (concat subject (match-string 0))))
-      (setq coding-system-for-write buffer-file-coding-system))
-    (let ((commit
-           (git-get-string-sha1
-            (let ((env `(("GIT_AUTHOR_NAME" . ,author-name)
-                         ("GIT_AUTHOR_EMAIL" . ,author-email)
-                         ("GIT_COMMITTER_NAME" . ,(git-get-committer-name))
-                         ("GIT_COMMITTER_EMAIL" . ,(git-get-committer-email)))))
-              (when author-date (push `("GIT_AUTHOR_DATE" . ,author-date) env))
-              (apply #'git-run-command-region
-                     buffer log-start log-end env
-                     "commit-tree" tree (nreverse args))))))
-      (when commit (git-update-ref "HEAD" commit parent subject))
-      commit)))
-
-(defun git-empty-db-p ()
-  "Check if the git db is empty (no commit done yet)."
-  (not (eq 0 (git-call-process nil "rev-parse" "--verify" "HEAD"))))
-
-(defun git-get-merge-heads ()
-  "Retrieve the merge heads from the MERGE_HEAD file if present."
-  (let (heads)
-    (when (file-readable-p ".git/MERGE_HEAD")
-      (with-temp-buffer
-        (insert-file-contents ".git/MERGE_HEAD" nil nil nil t)
-        (goto-char (point-min))
-        (while (re-search-forward "[0-9a-f]\\{40\\}" nil t)
-          (push (match-string 0) heads))))
-    (nreverse heads)))
-
-(defun git-get-commit-description (commit)
-  "Get a one-line description of COMMIT."
-  (let ((coding-system-for-read (git-get-logoutput-coding-system)))
-    (let ((descr (git-call-process-string "log" "--max-count=1" "--pretty=oneline" commit)))
-      (if (and descr (string-match "\\`\\([0-9a-f]\\{40\\}\\) *\\(.*\\)$" descr))
-          (concat (substring (match-string 1 descr) 0 10) " - " (match-string 2 descr))
-        descr))))
-
-;;;; File info structure
-;;;; ------------------------------------------------------------
-
-; fileinfo structure stolen from pcl-cvs
-(defstruct (git-fileinfo
-            (:copier nil)
-            (:constructor git-create-fileinfo (state name &optional old-perm new-perm rename-state orig-name marked))
-            (:conc-name git-fileinfo->))
-  marked              ;; t/nil
-  state               ;; current state
-  name                ;; file name
-  old-perm new-perm   ;; permission flags
-  rename-state        ;; rename or copy state
-  orig-name           ;; original name for renames or copies
-  needs-update        ;; whether file needs to be updated
-  needs-refresh)      ;; whether file needs to be refreshed
-
-(defvar git-status nil)
-
-(defun git-set-fileinfo-state (info state)
-  "Set the state of a file info."
-  (unless (eq (git-fileinfo->state info) state)
-    (setf (git-fileinfo->state info) state
-	  (git-fileinfo->new-perm info) (git-fileinfo->old-perm info)
-          (git-fileinfo->rename-state info) nil
-          (git-fileinfo->orig-name info) nil
-          (git-fileinfo->needs-update info) nil
-          (git-fileinfo->needs-refresh info) t)))
-
-(defun git-status-filenames-map (status func files &rest args)
-  "Apply FUNC to the status files names in the FILES list.
-The list must be sorted."
-  (when files
-    (let ((file (pop files))
-          (node (ewoc-nth status 0)))
-      (while (and file node)
-        (let* ((info (ewoc-data node))
-               (name (git-fileinfo->name info)))
-          (if (string-lessp name file)
-              (setq node (ewoc-next status node))
-            (if (string-equal name file)
-                (apply func info args))
-            (setq file (pop files))))))))
-
-(defun git-set-filenames-state (status files state)
-  "Set the state of a list of named files. The list must be sorted"
-  (when files
-    (git-status-filenames-map status #'git-set-fileinfo-state files state)
-    (unless state  ;; delete files whose state has been set to nil
-      (ewoc-filter status (lambda (info) (git-fileinfo->state info))))))
-
-(defun git-state-code (code)
-  "Convert from a string to a added/deleted/modified state."
-  (case (string-to-char code)
-    (?M 'modified)
-    (?? 'unknown)
-    (?A 'added)
-    (?D 'deleted)
-    (?U 'unmerged)
-    (?T 'modified)
-    (t nil)))
-
-(defun git-status-code-as-string (code)
-  "Format a git status code as string."
-  (case code
-    ('modified (propertize "Modified" 'face 'git-status-face))
-    ('unknown  (propertize "Unknown " 'face 'git-unknown-face))
-    ('added    (propertize "Added   " 'face 'git-status-face))
-    ('deleted  (propertize "Deleted " 'face 'git-status-face))
-    ('unmerged (propertize "Unmerged" 'face 'git-unmerged-face))
-    ('uptodate (propertize "Uptodate" 'face 'git-uptodate-face))
-    ('ignored  (propertize "Ignored " 'face 'git-ignored-face))
-    (t "?       ")))
-
-(defun git-file-type-as-string (old-perm new-perm)
-  "Return a string describing the file type based on its permissions."
-  (let* ((old-type (lsh (or old-perm 0) -9))
-	 (new-type (lsh (or new-perm 0) -9))
-	 (str (case new-type
-		(64  ;; file
-		 (case old-type
-		   (64 nil)
-		   (80 "   (type change symlink -> file)")
-		   (112 "   (type change subproject -> file)")))
-		 (80  ;; symlink
-		  (case old-type
-		    (64 "   (type change file -> symlink)")
-		    (112 "   (type change subproject -> symlink)")
-		    (t "   (symlink)")))
-		  (112  ;; subproject
-		   (case old-type
-		     (64 "   (type change file -> subproject)")
-		     (80 "   (type change symlink -> subproject)")
-		     (t "   (subproject)")))
-                  (72 nil)  ;; directory (internal, not a real git state)
-		  (0  ;; deleted or unknown
-		   (case old-type
-		     (80 "   (symlink)")
-		     (112 "   (subproject)")))
-		  (t (format "   (unknown type %o)" new-type)))))
-    (cond (str (propertize str 'face 'git-status-face))
-          ((eq new-type 72) "/")
-          (t ""))))
-
-(defun git-rename-as-string (info)
-  "Return a string describing the copy or rename associated with INFO, or an empty string if none."
-  (let ((state (git-fileinfo->rename-state info)))
-    (if state
-        (propertize
-         (concat "   ("
-                 (if (eq state 'copy) "copied from "
-                   (if (eq (git-fileinfo->state info) 'added) "renamed from "
-                     "renamed to "))
-                 (git-escape-file-name (git-fileinfo->orig-name info))
-                 ")") 'face 'git-status-face)
-      "")))
-
-(defun git-permissions-as-string (old-perm new-perm)
-  "Format a permission change as string."
-  (propertize
-   (if (or (not old-perm)
-           (not new-perm)
-           (eq 0 (logand ?\111 (logxor old-perm new-perm))))
-       "  "
-     (if (eq 0 (logand ?\111 old-perm)) "+x" "-x"))
-  'face 'git-permission-face))
-
-(defun git-fileinfo-prettyprint (info)
-  "Pretty-printer for the git-fileinfo structure."
-  (let ((old-perm (git-fileinfo->old-perm info))
-	(new-perm (git-fileinfo->new-perm info)))
-    (insert (concat "   " (if (git-fileinfo->marked info) (propertize "*" 'face 'git-mark-face) " ")
-		    " " (git-status-code-as-string (git-fileinfo->state info))
-		    " " (git-permissions-as-string old-perm new-perm)
-		    "  " (git-escape-file-name (git-fileinfo->name info))
-		    (git-file-type-as-string old-perm new-perm)
-		    (git-rename-as-string info)))))
-
-(defun git-update-node-fileinfo (node info)
-  "Update the fileinfo of the specified node. The names are assumed to match already."
-  (let ((data (ewoc-data node)))
-    (setf
-     ;; preserve the marked flag
-     (git-fileinfo->marked info) (git-fileinfo->marked data)
-     (git-fileinfo->needs-update data) nil)
-    (when (not (equal info data))
-      (setf (git-fileinfo->needs-refresh info) t
-            (ewoc-data node) info))))
-
-(defun git-insert-info-list (status infolist files)
-  "Insert a sorted list of file infos in the status buffer, replacing existing ones if any."
-  (let* ((info (pop infolist))
-         (node (ewoc-nth status 0))
-         (name (and info (git-fileinfo->name info)))
-         remaining)
-    (while info
-      (let ((nodename (and node (git-fileinfo->name (ewoc-data node)))))
-        (while (and files (string-lessp (car files) name))
-          (push (pop files) remaining))
-        (when (and files (string-equal (car files) name))
-          (setq files (cdr files)))
-        (cond ((not nodename)
-               (setq node (ewoc-enter-last status info))
-               (setq info (pop infolist))
-               (setq name (and info (git-fileinfo->name info))))
-              ((string-lessp nodename name)
-               (setq node (ewoc-next status node)))
-              ((string-equal nodename name)
-               ;; preserve the marked flag
-               (git-update-node-fileinfo node info)
-               (setq info (pop infolist))
-               (setq name (and info (git-fileinfo->name info))))
-              (t
-               (setq node (ewoc-enter-before status node info))
-               (setq info (pop infolist))
-               (setq name (and info (git-fileinfo->name info)))))))
-    (nconc (nreverse remaining) files)))
-
-(defun git-run-diff-index (status files)
-  "Run git-diff-index on FILES and parse the results into STATUS.
-Return the list of files that haven't been handled."
-  (let (infolist)
-    (with-temp-buffer
-      (apply #'git-call-process t "diff-index" "-z" "-M" "HEAD" "--" files)
-      (goto-char (point-min))
-      (while (re-search-forward
-	      ":\\([0-7]\\{6\\}\\) \\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} [0-9a-f]\\{40\\} \\(\\([ADMUT]\\)\0\\([^\0]+\\)\\|\\([CR]\\)[0-9]*\0\\([^\0]+\\)\0\\([^\0]+\\)\\)\0"
-              nil t 1)
-        (let ((old-perm (string-to-number (match-string 1) 8))
-              (new-perm (string-to-number (match-string 2) 8))
-              (state (or (match-string 4) (match-string 6)))
-              (name (or (match-string 5) (match-string 7)))
-              (new-name (match-string 8)))
-          (if new-name  ; copy or rename
-              (if (eq ?C (string-to-char state))
-                  (push (git-create-fileinfo 'added new-name old-perm new-perm 'copy name) infolist)
-                (push (git-create-fileinfo 'deleted name 0 0 'rename new-name) infolist)
-                (push (git-create-fileinfo 'added new-name old-perm new-perm 'rename name) infolist))
-            (push (git-create-fileinfo (git-state-code state) name old-perm new-perm) infolist)))))
-    (setq infolist (sort (nreverse infolist)
-                         (lambda (info1 info2)
-                           (string-lessp (git-fileinfo->name info1)
-                                         (git-fileinfo->name info2)))))
-    (git-insert-info-list status infolist files)))
-
-(defun git-find-status-file (status file)
-  "Find a given file in the status ewoc and return its node."
-  (let ((node (ewoc-nth status 0)))
-    (while (and node (not (string= file (git-fileinfo->name (ewoc-data node)))))
-      (setq node (ewoc-next status node)))
-    node))
-
-(defun git-run-ls-files (status files default-state &rest options)
-  "Run git-ls-files on FILES and parse the results into STATUS.
-Return the list of files that haven't been handled."
-  (let (infolist)
-    (with-temp-buffer
-      (apply #'git-call-process t "ls-files" "-z" (append options (list "--") files))
-      (goto-char (point-min))
-      (while (re-search-forward "\\([^\0]*?\\)\\(/?\\)\0" nil t 1)
-        (let ((name (match-string 1)))
-          (push (git-create-fileinfo default-state name 0
-                                     (if (string-equal "/" (match-string 2)) (lsh ?\110 9) 0))
-                infolist))))
-    (setq infolist (nreverse infolist))  ;; assume it is sorted already
-    (git-insert-info-list status infolist files)))
-
-(defun git-run-ls-files-cached (status files default-state)
-  "Run git-ls-files -c on FILES and parse the results into STATUS.
-Return the list of files that haven't been handled."
-  (let (infolist)
-    (with-temp-buffer
-      (apply #'git-call-process t "ls-files" "-z" "-s" "-c" "--" files)
-      (goto-char (point-min))
-      (while (re-search-forward "\\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} 0\t\\([^\0]+\\)\0" nil t)
-	(let* ((new-perm (string-to-number (match-string 1) 8))
-	       (old-perm (if (eq default-state 'added) 0 new-perm))
-	       (name (match-string 2)))
-	  (push (git-create-fileinfo default-state name old-perm new-perm) infolist))))
-    (setq infolist (nreverse infolist))  ;; assume it is sorted already
-    (git-insert-info-list status infolist files)))
-
-(defun git-run-ls-unmerged (status files)
-  "Run git-ls-files -u on FILES and parse the results into STATUS."
-  (with-temp-buffer
-    (apply #'git-call-process t "ls-files" "-z" "-u" "--" files)
-    (goto-char (point-min))
-    (let (unmerged-files)
-      (while (re-search-forward "[0-7]\\{6\\} [0-9a-f]\\{40\\} [123]\t\\([^\0]+\\)\0" nil t)
-        (push (match-string 1) unmerged-files))
-      (setq unmerged-files (nreverse unmerged-files))  ;; assume it is sorted already
-      (git-set-filenames-state status unmerged-files 'unmerged))))
-
-(defun git-get-exclude-files ()
-  "Get the list of exclude files to pass to git-ls-files."
-  (let (files
-        (config (git-config "core.excludesfile")))
-    (when (file-readable-p ".git/info/exclude")
-      (push ".git/info/exclude" files))
-    (when (and config (file-readable-p config))
-      (push config files))
-    files))
-
-(defun git-run-ls-files-with-excludes (status files default-state &rest options)
-  "Run git-ls-files on FILES with appropriate --exclude-from options."
-  (let ((exclude-files (git-get-exclude-files)))
-    (apply #'git-run-ls-files status files default-state "--directory" "--no-empty-directory"
-           (concat "--exclude-per-directory=" git-per-dir-ignore-file)
-           (append options (mapcar (lambda (f) (concat "--exclude-from=" f)) exclude-files)))))
-
-(defun git-update-status-files (&optional files mark-files)
-  "Update the status of FILES from the index.
-The FILES list must be sorted."
-  (unless git-status (error "Not in git-status buffer."))
-  ;; set the needs-update flag on existing files
-  (if files
-      (git-status-filenames-map
-       git-status (lambda (info) (setf (git-fileinfo->needs-update info) t)) files)
-    (ewoc-map (lambda (info) (setf (git-fileinfo->needs-update info) t) nil) git-status)
-    (git-call-process nil "update-index" "--refresh")
-    (when git-show-uptodate
-      (git-run-ls-files-cached git-status nil 'uptodate)))
-  (let ((remaining-files
-          (if (git-empty-db-p) ; we need some special handling for an empty db
-	      (git-run-ls-files-cached git-status files 'added)
-            (git-run-diff-index git-status files))))
-    (git-run-ls-unmerged git-status files)
-    (when (or remaining-files (and git-show-unknown (not files)))
-      (setq remaining-files (git-run-ls-files-with-excludes git-status remaining-files 'unknown "-o")))
-    (when (or remaining-files (and git-show-ignored (not files)))
-      (setq remaining-files (git-run-ls-files-with-excludes git-status remaining-files 'ignored "-o" "-i")))
-    (unless files
-      (setq remaining-files (git-get-filenames (ewoc-collect git-status #'git-fileinfo->needs-update))))
-    (when remaining-files
-      (setq remaining-files (git-run-ls-files-cached git-status remaining-files 'uptodate)))
-    (git-set-filenames-state git-status remaining-files nil)
-    (when mark-files (git-mark-files git-status files))
-    (git-refresh-files)
-    (git-refresh-ewoc-hf git-status)))
-
-(defun git-mark-files (status files)
-  "Mark all the specified FILES, and unmark the others."
-  (let ((file (and files (pop files)))
-        (node (ewoc-nth status 0)))
-    (while node
-      (let ((info (ewoc-data node)))
-        (if (and file (string-equal (git-fileinfo->name info) file))
-            (progn
-              (unless (git-fileinfo->marked info)
-                (setf (git-fileinfo->marked info) t)
-                (setf (git-fileinfo->needs-refresh info) t))
-              (setq file (pop files))
-              (setq node (ewoc-next status node)))
-          (when (git-fileinfo->marked info)
-            (setf (git-fileinfo->marked info) nil)
-            (setf (git-fileinfo->needs-refresh info) t))
-          (if (and file (string-lessp file (git-fileinfo->name info)))
-              (setq file (pop files))
-            (setq node (ewoc-next status node))))))))
-
-(defun git-marked-files ()
-  "Return a list of all marked files, or if none a list containing just the file at cursor position."
-  (unless git-status (error "Not in git-status buffer."))
-  (or (ewoc-collect git-status (lambda (info) (git-fileinfo->marked info)))
-      (list (ewoc-data (ewoc-locate git-status)))))
-
-(defun git-marked-files-state (&rest states)
-  "Return a sorted list of marked files that are in the specified states."
-  (let ((files (git-marked-files))
-        result)
-    (dolist (info files)
-      (when (memq (git-fileinfo->state info) states)
-        (push info result)))
-    (nreverse result)))
-
-(defun git-refresh-files ()
-  "Refresh all files that need it and clear the needs-refresh flag."
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map
-   (lambda (info)
-     (let ((refresh (git-fileinfo->needs-refresh info)))
-       (setf (git-fileinfo->needs-refresh info) nil)
-       refresh))
-   git-status)
-  ; move back to goal column
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-refresh-ewoc-hf (status)
-  "Refresh the ewoc header and footer."
-  (let ((branch (git-symbolic-ref "HEAD"))
-        (head (if (git-empty-db-p) "Nothing committed yet"
-                (git-get-commit-description "HEAD")))
-        (merge-heads (git-get-merge-heads)))
-    (ewoc-set-hf status
-                 (format "Directory:  %s\nBranch:     %s\nHead:       %s%s\n"
-                         default-directory
-                         (if branch
-                             (if (string-match "^refs/heads/" branch)
-                                 (substring branch (match-end 0))
-                               branch)
-                           "none (detached HEAD)")
-                         head
-                         (if merge-heads
-                             (concat "\nMerging:    "
-                                     (mapconcat (lambda (str) (git-get-commit-description str)) merge-heads "\n            "))
-                           ""))
-                 (if (ewoc-nth status 0) "" "    No changes."))))
-
-(defun git-get-filenames (files)
-  (mapcar (lambda (info) (git-fileinfo->name info)) files))
-
-(defun git-update-index (index-file files)
-  "Run git-update-index on a list of files."
-  (let ((process-environment (append (and index-file (list (concat "GIT_INDEX_FILE=" index-file)))
-                                     process-environment))
-        added deleted modified)
-    (dolist (info files)
-      (case (git-fileinfo->state info)
-        ('added (push info added))
-        ('deleted (push info deleted))
-        ('modified (push info modified))))
-    (and
-     (or (not added) (apply #'git-call-process-display-error "update-index" "--add" "--" (git-get-filenames added)))
-     (or (not deleted) (apply #'git-call-process-display-error "update-index" "--remove" "--" (git-get-filenames deleted)))
-     (or (not modified) (apply #'git-call-process-display-error "update-index" "--" (git-get-filenames modified))))))
-
-(defun git-run-pre-commit-hook ()
-  "Run the pre-commit hook if any."
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((files (git-marked-files-state 'added 'deleted 'modified)))
-    (or (not files)
-        (not (file-executable-p ".git/hooks/pre-commit"))
-        (let ((index-file (make-temp-file "gitidx")))
-          (unwind-protect
-            (let ((head-tree (unless (git-empty-db-p) (git-rev-parse "HEAD^{tree}"))))
-              (git-read-tree head-tree index-file)
-              (git-update-index index-file files)
-              (git-run-hook "pre-commit" `(("GIT_INDEX_FILE" . ,index-file))))
-          (delete-file index-file))))))
-
-(defun git-do-commit ()
-  "Perform the actual commit using the current buffer as log message."
-  (interactive)
-  (let ((buffer (current-buffer))
-        (index-file (make-temp-file "gitidx")))
-    (with-current-buffer log-edit-parent-buffer
-      (if (git-marked-files-state 'unmerged)
-          (message "You cannot commit unmerged files, resolve them first.")
-        (unwind-protect
-            (let ((files (git-marked-files-state 'added 'deleted 'modified))
-                  head tree head-tree)
-              (unless (git-empty-db-p)
-                (setq head (git-rev-parse "HEAD")
-                      head-tree (git-rev-parse "HEAD^{tree}")))
-              (message "Running git commit...")
-              (when
-                  (and
-                   (git-read-tree head-tree index-file)
-                   (git-update-index nil files)         ;update both the default index
-                   (git-update-index index-file files)  ;and the temporary one
-                   (setq tree (git-write-tree index-file)))
-                (if (or (not (string-equal tree head-tree))
-                        (yes-or-no-p "The tree was not modified, do you really want to perform an empty commit? "))
-                    (let ((commit (git-commit-tree buffer tree head)))
-                      (when commit
-                        (condition-case nil (delete-file ".git/MERGE_HEAD") (error nil))
-                        (condition-case nil (delete-file ".git/MERGE_MSG") (error nil))
-                        (with-current-buffer buffer (erase-buffer))
-                        (git-update-status-files (git-get-filenames files))
-                        (git-call-process nil "rerere")
-                        (git-call-process nil "gc" "--auto")
-                        (message "Committed %s." commit)
-                        (git-run-hook "post-commit" nil)))
-                  (message "Commit aborted."))))
-          (delete-file index-file))))))
-
-
-;;;; Interactive functions
-;;;; ------------------------------------------------------------
-
-(defun git-mark-file ()
-  "Mark the file that the cursor is on and move to the next one."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((pos (ewoc-locate git-status))
-         (info (ewoc-data pos)))
-    (setf (git-fileinfo->marked info) t)
-    (ewoc-invalidate git-status pos)
-    (ewoc-goto-next git-status 1)))
-
-(defun git-unmark-file ()
-  "Unmark the file that the cursor is on and move to the next one."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((pos (ewoc-locate git-status))
-         (info (ewoc-data pos)))
-    (setf (git-fileinfo->marked info) nil)
-    (ewoc-invalidate git-status pos)
-    (ewoc-goto-next git-status 1)))
-
-(defun git-unmark-file-up ()
-  "Unmark the file that the cursor is on and move to the previous one."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((pos (ewoc-locate git-status))
-         (info (ewoc-data pos)))
-    (setf (git-fileinfo->marked info) nil)
-    (ewoc-invalidate git-status pos)
-    (ewoc-goto-prev git-status 1)))
-
-(defun git-mark-all ()
-  "Mark all files."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map (lambda (info) (unless (git-fileinfo->marked info)
-                             (setf (git-fileinfo->marked info) t))) git-status)
-  ; move back to goal column after invalidate
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-unmark-all ()
-  "Unmark all files."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map (lambda (info) (when (git-fileinfo->marked info)
-                             (setf (git-fileinfo->marked info) nil)
-                             t)) git-status)
-  ; move back to goal column after invalidate
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-toggle-all-marks ()
-  "Toggle all file marks."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map (lambda (info) (setf (git-fileinfo->marked info) (not (git-fileinfo->marked info))) t) git-status)
-  ; move back to goal column after invalidate
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-next-file (&optional n)
-  "Move the selection down N files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-goto-next git-status n))
-
-(defun git-prev-file (&optional n)
-  "Move the selection up N files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-goto-prev git-status n))
-
-(defun git-next-unmerged-file (&optional n)
-  "Move the selection down N unmerged files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((last (ewoc-locate git-status))
-         (node (ewoc-next git-status last)))
-    (while (and node (> n 0))
-      (when (eq 'unmerged (git-fileinfo->state (ewoc-data node)))
-        (setq n (1- n))
-        (setq last node))
-      (setq node (ewoc-next git-status node)))
-    (ewoc-goto-node git-status last)))
-
-(defun git-prev-unmerged-file (&optional n)
-  "Move the selection up N unmerged files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((last (ewoc-locate git-status))
-         (node (ewoc-prev git-status last)))
-    (while (and node (> n 0))
-      (when (eq 'unmerged (git-fileinfo->state (ewoc-data node)))
-        (setq n (1- n))
-        (setq last node))
-      (setq node (ewoc-prev git-status node)))
-    (ewoc-goto-node git-status last)))
-
-(defun git-insert-file (file)
-  "Insert file(s) into the git-status buffer."
-  (interactive "fInsert file: ")
-  (git-update-status-files (list (file-relative-name file))))
-
-(defun git-add-file ()
-  "Add marked file(s) to the index cache."
-  (interactive)
-  (let ((files (git-get-filenames (git-marked-files-state 'unknown 'ignored 'unmerged))))
-    ;; FIXME: add support for directories
-    (unless files
-      (push (file-relative-name (read-file-name "File to add: " nil nil t)) files))
-    (when (apply 'git-call-process-display-error "update-index" "--add" "--" files)
-      (git-update-status-files files)
-      (git-success-message "Added" files))))
-
-(defun git-ignore-file ()
-  "Add marked file(s) to the ignore list."
-  (interactive)
-  (let ((files (git-get-filenames (git-marked-files-state 'unknown))))
-    (unless files
-      (push (file-relative-name (read-file-name "File to ignore: " nil nil t)) files))
-    (dolist (f files) (git-append-to-ignore f))
-    (git-update-status-files files)
-    (git-success-message "Ignored" files)))
-
-(defun git-remove-file ()
-  "Remove the marked file(s)."
-  (interactive)
-  (let ((files (git-get-filenames (git-marked-files-state 'added 'modified 'unknown 'uptodate 'ignored))))
-    (unless files
-      (push (file-relative-name (read-file-name "File to remove: " nil nil t)) files))
-    (if (yes-or-no-p
-         (if (cdr files)
-             (format "Remove %d files? " (length files))
-           (format "Remove %s? " (car files))))
-        (progn
-          (dolist (name files)
-            (ignore-errors
-              (if (file-directory-p name)
-                  (delete-directory name)
-                (delete-file name))))
-          (when (apply 'git-call-process-display-error "update-index" "--remove" "--" files)
-            (git-update-status-files files)
-            (git-success-message "Removed" files)))
-      (message "Aborting"))))
-
-(defun git-revert-file ()
-  "Revert changes to the marked file(s)."
-  (interactive)
-  (let ((files (git-marked-files-state 'added 'deleted 'modified 'unmerged))
-        added modified)
-    (when (and files
-               (yes-or-no-p
-                (if (cdr files)
-                    (format "Revert %d files? " (length files))
-                  (format "Revert %s? " (git-fileinfo->name (car files))))))
-      (dolist (info files)
-        (case (git-fileinfo->state info)
-          ('added (push (git-fileinfo->name info) added))
-          ('deleted (push (git-fileinfo->name info) modified))
-          ('unmerged (push (git-fileinfo->name info) modified))
-          ('modified (push (git-fileinfo->name info) modified))))
-      ;; check if a buffer contains one of the files and isn't saved
-      (dolist (file modified)
-        (let ((buffer (get-file-buffer file)))
-          (when (and buffer (buffer-modified-p buffer))
-            (error "Buffer %s is modified. Please kill or save modified buffers before reverting." (buffer-name buffer)))))
-      (let ((ok (and
-                 (or (not added)
-                     (apply 'git-call-process-display-error "update-index" "--force-remove" "--" added))
-                 (or (not modified)
-                     (apply 'git-call-process-display-error "checkout" "HEAD" modified))))
-            (names (git-get-filenames files)))
-        (git-update-status-files names)
-        (when ok
-          (dolist (file modified)
-            (let ((buffer (get-file-buffer file)))
-              (when buffer (with-current-buffer buffer (revert-buffer t t t)))))
-          (git-success-message "Reverted" names))))))
-
-(defun git-remove-handled ()
-  "Remove handled files from the status list."
-  (interactive)
-  (ewoc-filter git-status
-               (lambda (info)
-                 (case (git-fileinfo->state info)
-                   ('ignored git-show-ignored)
-                   ('uptodate git-show-uptodate)
-                   ('unknown git-show-unknown)
-                   (t t))))
-  (unless (ewoc-nth git-status 0)  ; refresh header if list is empty
-    (git-refresh-ewoc-hf git-status)))
-
-(defun git-toggle-show-uptodate ()
-  "Toogle the option for showing up-to-date files."
-  (interactive)
-  (if (setq git-show-uptodate (not git-show-uptodate))
-      (git-refresh-status)
-    (git-remove-handled)))
-
-(defun git-toggle-show-ignored ()
-  "Toogle the option for showing ignored files."
-  (interactive)
-  (if (setq git-show-ignored (not git-show-ignored))
-      (progn
-        (message "Inserting ignored files...")
-        (git-run-ls-files-with-excludes git-status nil 'ignored "-o" "-i")
-        (git-refresh-files)
-        (git-refresh-ewoc-hf git-status)
-        (message "Inserting ignored files...done"))
-    (git-remove-handled)))
-
-(defun git-toggle-show-unknown ()
-  "Toogle the option for showing unknown files."
-  (interactive)
-  (if (setq git-show-unknown (not git-show-unknown))
-      (progn
-        (message "Inserting unknown files...")
-        (git-run-ls-files-with-excludes git-status nil 'unknown "-o")
-        (git-refresh-files)
-        (git-refresh-ewoc-hf git-status)
-        (message "Inserting unknown files...done"))
-    (git-remove-handled)))
-
-(defun git-expand-directory (info)
-  "Expand the directory represented by INFO to list its files."
-  (when (eq (lsh (git-fileinfo->new-perm info) -9) ?\110)
-    (let ((dir (git-fileinfo->name info)))
-      (git-set-filenames-state git-status (list dir) nil)
-      (git-run-ls-files-with-excludes git-status (list (concat dir "/")) 'unknown "-o")
-      (git-refresh-files)
-      (git-refresh-ewoc-hf git-status)
-      t)))
-
-(defun git-setup-diff-buffer (buffer)
-  "Setup a buffer for displaying a diff."
-  (let ((dir default-directory))
-    (with-current-buffer buffer
-      (diff-mode)
-      (goto-char (point-min))
-      (setq default-directory dir)
-      (setq buffer-read-only t)))
-  (display-buffer buffer)
-  ; shrink window only if it displays the status buffer
-  (when (eq (window-buffer) (current-buffer))
-    (shrink-window-if-larger-than-buffer)))
-
-(defun git-diff-file ()
-  "Diff the marked file(s) against HEAD."
-  (interactive)
-  (let ((files (git-marked-files)))
-    (git-setup-diff-buffer
-     (apply #'git-run-command-buffer "*git-diff*" "diff-index" "-p" "-M" "HEAD" "--" (git-get-filenames files)))))
-
-(defun git-diff-file-merge-head (arg)
-  "Diff the marked file(s) against the first merge head (or the nth one with a numeric prefix)."
-  (interactive "p")
-  (let ((files (git-marked-files))
-        (merge-heads (git-get-merge-heads)))
-    (unless merge-heads (error "No merge in progress"))
-    (git-setup-diff-buffer
-     (apply #'git-run-command-buffer "*git-diff*" "diff-index" "-p" "-M"
-            (or (nth (1- arg) merge-heads) "HEAD") "--" (git-get-filenames files)))))
-
-(defun git-diff-unmerged-file (stage)
-  "Diff the marked unmerged file(s) against the specified stage."
-  (let ((files (git-marked-files)))
-    (git-setup-diff-buffer
-     (apply #'git-run-command-buffer "*git-diff*" "diff-files" "-p" stage "--" (git-get-filenames files)))))
-
-(defun git-diff-file-base ()
-  "Diff the marked unmerged file(s) against the common base file."
-  (interactive)
-  (git-diff-unmerged-file "-1"))
-
-(defun git-diff-file-mine ()
-  "Diff the marked unmerged file(s) against my pre-merge version."
-  (interactive)
-  (git-diff-unmerged-file "-2"))
-
-(defun git-diff-file-other ()
-  "Diff the marked unmerged file(s) against the other's pre-merge version."
-  (interactive)
-  (git-diff-unmerged-file "-3"))
-
-(defun git-diff-file-combined ()
-  "Do a combined diff of the marked unmerged file(s)."
-  (interactive)
-  (git-diff-unmerged-file "-c"))
-
-(defun git-diff-file-idiff ()
-  "Perform an interactive diff on the current file."
-  (interactive)
-  (let ((files (git-marked-files-state 'added 'deleted 'modified)))
-    (unless (eq 1 (length files))
-      (error "Cannot perform an interactive diff on multiple files."))
-    (let* ((filename (car (git-get-filenames files)))
-           (buff1 (find-file-noselect filename))
-           (buff2 (git-run-command-buffer (concat filename ".~HEAD~") "cat-file" "blob" (concat "HEAD:" filename))))
-      (ediff-buffers buff1 buff2))))
-
-(defun git-log-file ()
-  "Display a log of changes to the marked file(s)."
-  (interactive)
-  (let* ((files (git-marked-files))
-         (coding-system-for-read git-commits-coding-system)
-         (buffer (apply #'git-run-command-buffer "*git-log*" "rev-list" "--pretty" "HEAD" "--" (git-get-filenames files))))
-    (with-current-buffer buffer
-      ; (git-log-mode)  FIXME: implement log mode
-      (goto-char (point-min))
-      (setq buffer-read-only t))
-    (display-buffer buffer)))
-
-(defun git-log-edit-files ()
-  "Return a list of marked files for use in the log-edit buffer."
-  (with-current-buffer log-edit-parent-buffer
-    (git-get-filenames (git-marked-files-state 'added 'deleted 'modified))))
-
-(defun git-log-edit-diff ()
-  "Run a diff of the current files being committed from a log-edit buffer."
-  (with-current-buffer log-edit-parent-buffer
-    (git-diff-file)))
-
-(defun git-append-sign-off (name email)
-  "Append a Signed-off-by entry to the current buffer, avoiding duplicates."
-  (let ((sign-off (format "Signed-off-by: %s <%s>" name email))
-        (case-fold-search t))
-    (goto-char (point-min))
-    (unless (re-search-forward (concat "^" (regexp-quote sign-off)) nil t)
-      (goto-char (point-min))
-      (unless (re-search-forward "^Signed-off-by: " nil t)
-        (setq sign-off (concat "\n" sign-off)))
-      (goto-char (point-max))
-      (insert sign-off "\n"))))
-
-(defun git-setup-log-buffer (buffer &optional merge-heads author-name author-email subject date msg)
-  "Setup the log buffer for a commit."
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((dir default-directory)
-        (committer-name (git-get-committer-name))
-        (committer-email (git-get-committer-email))
-        (sign-off git-append-signed-off-by))
-    (with-current-buffer buffer
-      (cd dir)
-      (erase-buffer)
-      (insert
-       (propertize
-        (format "Author: %s <%s>\n%s%s"
-                (or author-name committer-name)
-                (or author-email committer-email)
-                (if date (format "Date: %s\n" date) "")
-                (if merge-heads
-                    (format "Merge: %s\n"
-                            (mapconcat 'identity merge-heads " "))
-                  ""))
-        'face 'git-header-face)
-       (propertize git-log-msg-separator 'face 'git-separator-face)
-       "\n")
-      (when subject (insert subject "\n\n"))
-      (cond (msg (insert msg "\n"))
-            ((file-readable-p ".git/rebase-apply/msg")
-             (insert-file-contents ".git/rebase-apply/msg"))
-            ((file-readable-p ".git/MERGE_MSG")
-             (insert-file-contents ".git/MERGE_MSG")))
-      ; delete empty lines at end
-      (goto-char (point-min))
-      (when (re-search-forward "\n+\\'" nil t)
-        (replace-match "\n" t t))
-      (when sign-off (git-append-sign-off committer-name committer-email)))
-    buffer))
-
-(define-derived-mode git-log-edit-mode log-edit-mode "Git-Log-Edit"
-  "Major mode for editing git log messages.
-
-Set up git-specific `font-lock-keywords' for `log-edit-mode'."
-  (set (make-local-variable 'font-lock-defaults)
-       '(git-log-edit-font-lock-keywords t t)))
-
-(defun git-commit-file ()
-  "Commit the marked file(s), asking for a commit message."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (when (git-run-pre-commit-hook)
-    (let ((buffer (get-buffer-create "*git-commit*"))
-          (coding-system (git-get-commits-coding-system))
-          author-name author-email subject date)
-      (when (eq 0 (buffer-size buffer))
-        (when (file-readable-p ".git/rebase-apply/info")
-          (with-temp-buffer
-            (insert-file-contents ".git/rebase-apply/info")
-            (goto-char (point-min))
-            (when (re-search-forward "^Author: \\(.*\\)\nEmail: \\(.*\\)$" nil t)
-              (setq author-name (match-string 1))
-              (setq author-email (match-string 2)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Subject: \\(.*\\)$" nil t)
-              (setq subject (match-string 1)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Date: \\(.*\\)$" nil t)
-              (setq date (match-string 1)))))
-        (git-setup-log-buffer buffer (git-get-merge-heads) author-name author-email subject date))
-      (if (boundp 'log-edit-diff-function)
-	  (log-edit 'git-do-commit nil '((log-edit-listfun . git-log-edit-files)
-					 (log-edit-diff-function . git-log-edit-diff)) buffer 'git-log-edit-mode)
-	(log-edit 'git-do-commit nil 'git-log-edit-files buffer
-                  'git-log-edit-mode))
-      (setq paragraph-separate (concat (regexp-quote git-log-msg-separator) "$\\|Author: \\|Date: \\|Merge: \\|Signed-off-by: \\|\f\\|[ 	]*$"))
-      (setq buffer-file-coding-system coding-system)
-      (re-search-forward (regexp-quote (concat git-log-msg-separator "\n")) nil t))))
-
-(defun git-setup-commit-buffer (commit)
-  "Setup the commit buffer with the contents of COMMIT."
-  (let (parents author-name author-email subject date msg)
-    (with-temp-buffer
-      (let ((coding-system (git-get-logoutput-coding-system)))
-        (git-call-process t "log" "-1" "--pretty=medium" "--abbrev=40" commit)
-        (goto-char (point-min))
-        (when (re-search-forward "^Merge: *\\(.*\\)$" nil t)
-          (setq parents (cdr (split-string (match-string 1) " +"))))
-        (when (re-search-forward "^Author: *\\(.*\\) <\\(.*\\)>$" nil t)
-          (setq author-name (match-string 1))
-          (setq author-email (match-string 2)))
-        (when (re-search-forward "^Date: *\\(.*\\)$" nil t)
-          (setq date (match-string 1)))
-        (while (re-search-forward "^    \\(.*\\)$" nil t)
-          (push (match-string 1) msg))
-        (setq msg (nreverse msg))
-        (setq subject (pop msg))
-        (while (and msg (zerop (length (car msg))) (pop msg)))))
-    (git-setup-log-buffer (get-buffer-create "*git-commit*")
-                          parents author-name author-email subject date
-                          (mapconcat #'identity msg "\n"))))
-
-(defun git-get-commit-files (commit)
-  "Retrieve a sorted list of files modified by COMMIT."
-  (let (files)
-    (with-temp-buffer
-      (git-call-process t "diff-tree" "-m" "-r" "-z" "--name-only" "--no-commit-id" "--root" commit)
-      (goto-char (point-min))
-      (while (re-search-forward "\\([^\0]*\\)\0" nil t 1)
-        (push (match-string 1) files)))
-    (sort files #'string-lessp)))
-
-(defun git-read-commit-name (prompt &optional default)
-  "Ask for a commit name, with completion for local branch, remote branch and tag."
-  (completing-read prompt
-                   (list* "HEAD" "ORIG_HEAD" "FETCH_HEAD" (mapcar #'car (git-for-each-ref)))
-		   nil nil nil nil default))
-
-(defun git-checkout (branch &optional merge)
-  "Checkout a branch, tag, or any commit.
-Use a prefix arg if git should merge while checking out."
-  (interactive
-   (list (git-read-commit-name "Checkout: ")
-         current-prefix-arg))
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((args (list branch "--")))
-    (when merge (push "-m" args))
-    (when (apply #'git-call-process-display-error "checkout" args)
-      (git-update-status-files))))
-
-(defun git-branch (branch)
-  "Create a branch from the current HEAD and switch to it."
-  (interactive (list (git-read-commit-name "Branch: ")))
-  (unless git-status (error "Not in git-status buffer."))
-  (if (git-rev-parse (concat "refs/heads/" branch))
-      (if (yes-or-no-p (format "Branch %s already exists, replace it? " branch))
-          (and (git-call-process-display-error "branch" "-f" branch)
-               (git-call-process-display-error "checkout" branch))
-        (message "Canceled."))
-    (git-call-process-display-error "checkout" "-b" branch))
-    (git-refresh-ewoc-hf git-status))
-
-(defun git-amend-commit ()
-  "Undo the last commit on HEAD, and set things up to commit an
-amended version of it."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (when (git-empty-db-p) (error "No commit to amend."))
-  (let* ((commit (git-rev-parse "HEAD"))
-         (files (git-get-commit-files commit)))
-    (when (if (git-rev-parse "HEAD^")
-              (git-call-process-display-error "reset" "--soft" "HEAD^")
-            (and (git-update-ref "ORIG_HEAD" commit)
-                 (git-update-ref "HEAD" nil commit)))
-      (git-update-status-files files t)
-      (git-setup-commit-buffer commit)
-      (git-commit-file))))
-
-(defun git-cherry-pick-commit (arg)
-  "Cherry-pick a commit."
-  (interactive (list (git-read-commit-name "Cherry-pick commit: ")))
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((commit (git-rev-parse (concat arg "^0"))))
-    (unless commit (error "Not a valid commit '%s'." arg))
-    (when (git-rev-parse (concat commit "^2"))
-      (error "Cannot cherry-pick a merge commit."))
-    (let ((files (git-get-commit-files commit))
-          (ok (git-call-process-display-error "cherry-pick" "-n" commit)))
-      (git-update-status-files files ok)
-      (with-current-buffer (git-setup-commit-buffer commit)
-        (goto-char (point-min))
-        (if (re-search-forward "^\n*Signed-off-by:" nil t 1)
-            (goto-char (match-beginning 0))
-          (goto-char (point-max)))
-        (insert "(cherry picked from commit " commit ")\n"))
-      (when ok (git-commit-file)))))
-
-(defun git-revert-commit (arg)
-  "Revert a commit."
-  (interactive (list (git-read-commit-name "Revert commit: ")))
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((commit (git-rev-parse (concat arg "^0"))))
-    (unless commit (error "Not a valid commit '%s'." arg))
-    (when (git-rev-parse (concat commit "^2"))
-      (error "Cannot revert a merge commit."))
-    (let ((files (git-get-commit-files commit))
-          (subject (git-get-commit-description commit))
-          (ok (git-call-process-display-error "revert" "-n" commit)))
-      (git-update-status-files files ok)
-      (when (string-match "^[0-9a-f]+ - \\(.*\\)$" subject)
-        (setq subject (match-string 1 subject)))
-      (git-setup-log-buffer (get-buffer-create "*git-commit*")
-                            (git-get-merge-heads) nil nil (format "Revert \"%s\"" subject) nil
-                            (format "This reverts commit %s.\n" commit))
-      (when ok (git-commit-file)))))
-
-(defun git-find-file ()
-  "Visit the current file in its own buffer."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (unless (git-expand-directory info)
-      (find-file (git-fileinfo->name info))
-      (when (eq 'unmerged (git-fileinfo->state info))
-        (smerge-mode 1)))))
-
-(defun git-find-file-other-window ()
-  "Visit the current file in its own buffer in another window."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (find-file-other-window (git-fileinfo->name info))
-    (when (eq 'unmerged (git-fileinfo->state info))
-      (smerge-mode))))
-
-(defun git-find-file-imerge ()
-  "Visit the current file in interactive merge mode."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (find-file (git-fileinfo->name info))
-    (smerge-ediff)))
-
-(defun git-view-file ()
-  "View the current file in its own buffer."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (view-file (git-fileinfo->name info))))
-
-(defun git-refresh-status ()
-  "Refresh the git status buffer."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (message "Refreshing git status...")
-  (git-update-status-files)
-  (message "Refreshing git status...done"))
-
-(defun git-status-quit ()
-  "Quit git-status mode."
-  (interactive)
-  (bury-buffer))
-
-;;;; Major Mode
-;;;; ------------------------------------------------------------
-
-(defvar git-status-mode-hook nil
-  "Run after `git-status-mode' is setup.")
-
-(defvar git-status-mode-map nil
-  "Keymap for git major mode.")
-
-(defvar git-status nil
-  "List of all files managed by the git-status mode.")
-
-(unless git-status-mode-map
-  (let ((map (make-keymap))
-        (commit-map (make-sparse-keymap))
-        (diff-map (make-sparse-keymap))
-        (toggle-map (make-sparse-keymap)))
-    (suppress-keymap map)
-    (define-key map "?"   'git-help)
-    (define-key map "h"   'git-help)
-    (define-key map " "   'git-next-file)
-    (define-key map "a"   'git-add-file)
-    (define-key map "c"   'git-commit-file)
-    (define-key map "\C-c" commit-map)
-    (define-key map "d"    diff-map)
-    (define-key map "="   'git-diff-file)
-    (define-key map "f"   'git-find-file)
-    (define-key map "\r"  'git-find-file)
-    (define-key map "g"   'git-refresh-status)
-    (define-key map "i"   'git-ignore-file)
-    (define-key map "I"   'git-insert-file)
-    (define-key map "l"   'git-log-file)
-    (define-key map "m"   'git-mark-file)
-    (define-key map "M"   'git-mark-all)
-    (define-key map "n"   'git-next-file)
-    (define-key map "N"   'git-next-unmerged-file)
-    (define-key map "o"   'git-find-file-other-window)
-    (define-key map "p"   'git-prev-file)
-    (define-key map "P"   'git-prev-unmerged-file)
-    (define-key map "q"   'git-status-quit)
-    (define-key map "r"   'git-remove-file)
-    (define-key map "t"    toggle-map)
-    (define-key map "T"   'git-toggle-all-marks)
-    (define-key map "u"   'git-unmark-file)
-    (define-key map "U"   'git-revert-file)
-    (define-key map "v"   'git-view-file)
-    (define-key map "x"   'git-remove-handled)
-    (define-key map "\C-?" 'git-unmark-file-up)
-    (define-key map "\M-\C-?" 'git-unmark-all)
-    ; the commit submap
-    (define-key commit-map "\C-a" 'git-amend-commit)
-    (define-key commit-map "\C-b" 'git-branch)
-    (define-key commit-map "\C-o" 'git-checkout)
-    (define-key commit-map "\C-p" 'git-cherry-pick-commit)
-    (define-key commit-map "\C-v" 'git-revert-commit)
-    ; the diff submap
-    (define-key diff-map "b" 'git-diff-file-base)
-    (define-key diff-map "c" 'git-diff-file-combined)
-    (define-key diff-map "=" 'git-diff-file)
-    (define-key diff-map "e" 'git-diff-file-idiff)
-    (define-key diff-map "E" 'git-find-file-imerge)
-    (define-key diff-map "h" 'git-diff-file-merge-head)
-    (define-key diff-map "m" 'git-diff-file-mine)
-    (define-key diff-map "o" 'git-diff-file-other)
-    ; the toggle submap
-    (define-key toggle-map "u" 'git-toggle-show-uptodate)
-    (define-key toggle-map "i" 'git-toggle-show-ignored)
-    (define-key toggle-map "k" 'git-toggle-show-unknown)
-    (define-key toggle-map "m" 'git-toggle-all-marks)
-    (setq git-status-mode-map map))
-  (easy-menu-define git-menu git-status-mode-map
-    "Git Menu"
-    `("Git"
-      ["Refresh" git-refresh-status t]
-      ["Commit" git-commit-file t]
-      ["Checkout..." git-checkout t]
-      ["New Branch..." git-branch t]
-      ["Cherry-pick Commit..." git-cherry-pick-commit t]
-      ["Revert Commit..." git-revert-commit t]
-      ("Merge"
-	["Next Unmerged File" git-next-unmerged-file t]
-	["Prev Unmerged File" git-prev-unmerged-file t]
-	["Interactive Merge File" git-find-file-imerge t]
-	["Diff Against Common Base File" git-diff-file-base t]
-	["Diff Combined" git-diff-file-combined t]
-	["Diff Against Merge Head" git-diff-file-merge-head t]
-	["Diff Against Mine" git-diff-file-mine t]
-	["Diff Against Other" git-diff-file-other t])
-      "--------"
-      ["Add File" git-add-file t]
-      ["Revert File" git-revert-file t]
-      ["Ignore File" git-ignore-file t]
-      ["Remove File" git-remove-file t]
-      ["Insert File" git-insert-file t]
-      "--------"
-      ["Find File" git-find-file t]
-      ["View File" git-view-file t]
-      ["Diff File" git-diff-file t]
-      ["Interactive Diff File" git-diff-file-idiff t]
-      ["Log" git-log-file t]
-      "--------"
-      ["Mark" git-mark-file t]
-      ["Mark All" git-mark-all t]
-      ["Unmark" git-unmark-file t]
-      ["Unmark All" git-unmark-all t]
-      ["Toggle All Marks" git-toggle-all-marks t]
-      ["Hide Handled Files" git-remove-handled t]
-      "--------"
-      ["Show Uptodate Files" git-toggle-show-uptodate :style toggle :selected git-show-uptodate]
-      ["Show Ignored Files" git-toggle-show-ignored :style toggle :selected git-show-ignored]
-      ["Show Unknown Files" git-toggle-show-unknown :style toggle :selected git-show-unknown]
-      "--------"
-      ["Quit" git-status-quit t])))
-
-
-;; git mode should only run in the *git status* buffer
-(put 'git-status-mode 'mode-class 'special)
-
-(defun git-status-mode ()
-  "Major mode for interacting with Git.
-Commands:
-\\{git-status-mode-map}"
-  (kill-all-local-variables)
-  (buffer-disable-undo)
-  (setq mode-name "git status"
-        major-mode 'git-status-mode
-        goal-column 17
-        buffer-read-only t)
-  (use-local-map git-status-mode-map)
-  (let ((buffer-read-only nil))
-    (erase-buffer)
-  (let ((status (ewoc-create 'git-fileinfo-prettyprint "" "")))
-    (set (make-local-variable 'git-status) status))
-  (set (make-local-variable 'list-buffers-directory) default-directory)
-  (make-local-variable 'git-show-uptodate)
-  (make-local-variable 'git-show-ignored)
-  (make-local-variable 'git-show-unknown)
-  (run-hooks 'git-status-mode-hook)))
-
-(defun git-find-status-buffer (dir)
-  "Find the git status buffer handling a specified directory."
-  (let ((list (buffer-list))
-        (fulldir (expand-file-name dir))
-        found)
-    (while (and list (not found))
-      (let ((buffer (car list)))
-        (with-current-buffer buffer
-          (when (and list-buffers-directory
-                     (string-equal fulldir (expand-file-name list-buffers-directory))
-		     (eq major-mode 'git-status-mode))
-            (setq found buffer))))
-      (setq list (cdr list)))
-    found))
-
-(defun git-status (dir)
-  "Entry point into git-status mode."
-  (interactive "DSelect directory: ")
-  (setq dir (git-get-top-dir dir))
-  (if (file-exists-p (concat (file-name-as-directory dir) ".git"))
-      (let ((buffer (or (and git-reuse-status-buffer (git-find-status-buffer dir))
-                        (create-file-buffer (expand-file-name "*git-status*" dir)))))
-        (switch-to-buffer buffer)
-        (cd dir)
-        (git-status-mode)
-        (git-refresh-status)
-        (goto-char (point-min))
-        (add-hook 'after-save-hook 'git-update-saved-file))
-    (message "%s is not a git working tree." dir)))
-
-(defun git-update-saved-file ()
-  "Update the corresponding git-status buffer when a file is saved.
-Meant to be used in `after-save-hook'."
-  (let* ((file (expand-file-name buffer-file-name))
-         (dir (condition-case nil (git-get-top-dir (file-name-directory file)) (error nil)))
-         (buffer (and dir (git-find-status-buffer dir))))
-    (when buffer
-      (with-current-buffer buffer
-        (let ((filename (file-relative-name file dir)))
-          ; skip files located inside the .git directory
-          (unless (string-match "^\\.git/" filename)
-            (git-call-process nil "add" "--refresh" "--" filename)
-            (git-update-status-files (list filename))))))))
-
-(defun git-help ()
-  "Display help for Git mode."
-  (interactive)
-  (describe-function 'git-status-mode))
-
-(provide 'git)
-;;; git.el ends here
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 04/17] contrib: remove 'diffall'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (2 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 03/17] contrib: remove 'emacs' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:27   ` Tim Henigan
  2014-05-09 19:11 ` [PATCH v2 05/17] contrib: remove 'hg-to-git' Felipe Contreras
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras, Tim Henigan

There is no more need for this tool since the --dir-dirr option was
introduced.

Cc: Tim Henigan <tim.henigan@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/diffall/README      |  31 ------
 contrib/diffall/git-diffall | 257 --------------------------------------------
 2 files changed, 288 deletions(-)
 delete mode 100644 contrib/diffall/README
 delete mode 100755 contrib/diffall/git-diffall

diff --git a/contrib/diffall/README b/contrib/diffall/README
deleted file mode 100644
index 507f17d..0000000
--- a/contrib/diffall/README
+++ /dev/null
@@ -1,31 +0,0 @@
-The git-diffall script provides a directory based diff mechanism
-for git.
-
-To determine what diff viewer is used, the script requires either
-the 'diff.tool' or 'merge.tool' configuration option to be set.
-
-This script is compatible with most common forms used to specify a
-range of revisions to diff:
-
-  1. git diffall: shows diff between working tree and staged changes
-  2. git diffall --cached [<commit>]: shows diff between staged
-     changes and HEAD (or other named commit)
-  3. git diffall <commit>: shows diff between working tree and named
-     commit
-  4. git diffall <commit> <commit>: show diff between two named commits
-  5. git diffall <commit>..<commit>: same as above
-  6. git diffall <commit>...<commit>: show the changes on the branch
-     containing and up to the second, starting at a common ancestor
-     of both <commit>
-
-Note: all forms take an optional path limiter [-- <path>*]
-
-The '--extcmd=<command>' option allows the user to specify a custom
-command for viewing diffs.  When given, configured defaults are
-ignored and the script runs $command $LOCAL $REMOTE.  Additionally,
-$BASE is set in the environment.
-
-This script is based on an example provided by Thomas Rast on the
-Git list [1]:
-
-[1] http://thread.gmane.org/gmane.comp.version-control.git/124807
diff --git a/contrib/diffall/git-diffall b/contrib/diffall/git-diffall
deleted file mode 100755
index 84f2b65..0000000
--- a/contrib/diffall/git-diffall
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/bin/sh
-# Copyright 2010 - 2012, Tim Henigan <tim.henigan@gmail.com>
-#
-# Perform a directory diff between commits in the repository using
-# the external diff or merge tool specified in the user's config.
-
-USAGE='[--cached] [--copy-back] [-x|--extcmd=<command>] <commit>{0,2} [-- <path>*]
-
-    --cached     Compare to the index rather than the working tree.
-
-    --copy-back  Copy files back to the working tree when the diff
-                 tool exits (in case they were modified by the
-                 user).  This option is only valid if the diff
-                 compared with the working tree.
-
-    -x=<command>
-    --extcmd=<command>  Specify a custom command for viewing diffs.
-                 git-diffall ignores the configured defaults and
-                 runs $command $LOCAL $REMOTE when this option is
-                 specified. Additionally, $BASE is set in the
-                 environment.
-'
-
-SUBDIRECTORY_OK=1
-. "$(git --exec-path)/git-sh-setup"
-
-TOOL_MODE=diff
-. "$(git --exec-path)/git-mergetool--lib"
-
-merge_tool="$(get_merge_tool)"
-if test -z "$merge_tool"
-then
-	echo "Error: Either the 'diff.tool' or 'merge.tool' option must be set."
-	usage
-fi
-
-start_dir=$(pwd)
-
-# All the file paths returned by the diff command are relative to the root
-# of the working copy. So if the script is called from a subdirectory, it
-# must switch to the root of working copy before trying to use those paths.
-cdup=$(git rev-parse --show-cdup) &&
-cd "$cdup" || {
-	echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree"
-	exit 1
-}
-
-# set up temp dir
-tmp=$(perl -e 'use File::Temp qw(tempdir);
-	$t=tempdir("/tmp/git-diffall.XXXXX") or exit(1);
-	print $t') || exit 1
-trap 'rm -rf "$tmp"' EXIT
-
-left=
-right=
-paths=
-dashdash_seen=
-compare_staged=
-merge_base=
-left_dir=
-right_dir=
-diff_tool=
-copy_back=
-
-while test $# != 0
-do
-	case "$1" in
-	-h|--h|--he|--hel|--help)
-		usage
-		;;
-	--cached)
-		compare_staged=1
-		;;
-	--copy-back)
-		copy_back=1
-		;;
-	-x|--e|--ex|--ext|--extc|--extcm|--extcmd)
-		if test $# = 1
-		then
-			echo You must specify the tool for use with --extcmd
-			usage
-		else
-			diff_tool=$2
-			shift
-		fi
-		;;
-	--)
-		dashdash_seen=1
-		;;
-	-*)
-		echo Invalid option: "$1"
-		usage
-		;;
-	*)
-		# could be commit, commit range or path limiter
-		case "$1" in
-		*...*)
-			left=${1%...*}
-			right=${1#*...}
-			merge_base=1
-			;;
-		*..*)
-			left=${1%..*}
-			right=${1#*..}
-			;;
-		*)
-			if test -n "$dashdash_seen"
-			then
-				paths="$paths$1 "
-			elif test -z "$left"
-			then
-				left=$1
-			elif test -z "$right"
-			then
-				right=$1
-			else
-				paths="$paths$1 "
-			fi
-			;;
-		esac
-		;;
-	esac
-	shift
-done
-
-# Determine the set of files which changed
-if test -n "$left" && test -n "$right"
-then
-	left_dir="cmt-$(git rev-parse --short $left)"
-	right_dir="cmt-$(git rev-parse --short $right)"
-
-	if test -n "$compare_staged"
-	then
-		usage
-	elif test -n "$merge_base"
-	then
-		git diff --name-only "$left"..."$right" -- $paths >"$tmp/filelist"
-	else
-		git diff --name-only "$left" "$right" -- $paths >"$tmp/filelist"
-	fi
-elif test -n "$left"
-then
-	left_dir="cmt-$(git rev-parse --short $left)"
-
-	if test -n "$compare_staged"
-	then
-		right_dir="staged"
-		git diff --name-only --cached "$left" -- $paths >"$tmp/filelist"
-	else
-		right_dir="working_tree"
-		git diff --name-only "$left" -- $paths >"$tmp/filelist"
-	fi
-else
-	left_dir="HEAD"
-
-	if test -n "$compare_staged"
-	then
-		right_dir="staged"
-		git diff --name-only --cached -- $paths >"$tmp/filelist"
-	else
-		right_dir="working_tree"
-		git diff --name-only -- $paths >"$tmp/filelist"
-	fi
-fi
-
-# Exit immediately if there are no diffs
-if test ! -s "$tmp/filelist"
-then
-	exit 0
-fi
-
-if test -n "$copy_back" && test "$right_dir" != "working_tree"
-then
-	echo "--copy-back is only valid when diff includes the working tree."
-	exit 1
-fi
-
-# Create the named tmp directories that will hold the files to be compared
-mkdir -p "$tmp/$left_dir" "$tmp/$right_dir"
-
-# Populate the tmp/right_dir directory with the files to be compared
-while read name
-do
-	if test -n "$right"
-	then
-		ls_list=$(git ls-tree $right "$name")
-		if test -n "$ls_list"
-		then
-			mkdir -p "$tmp/$right_dir/$(dirname "$name")"
-			git show "$right":"$name" >"$tmp/$right_dir/$name" || true
-		fi
-	elif test -n "$compare_staged"
-	then
-		ls_list=$(git ls-files -- "$name")
-		if test -n "$ls_list"
-		then
-			mkdir -p "$tmp/$right_dir/$(dirname "$name")"
-			git show :"$name" >"$tmp/$right_dir/$name"
-		fi
-	else
-		if test -e "$name"
-		then
-			mkdir -p "$tmp/$right_dir/$(dirname "$name")"
-			cp "$name" "$tmp/$right_dir/$name"
-		fi
-	fi
-done < "$tmp/filelist"
-
-# Populate the tmp/left_dir directory with the files to be compared
-while read name
-do
-	if test -n "$left"
-	then
-		ls_list=$(git ls-tree $left "$name")
-		if test -n "$ls_list"
-		then
-			mkdir -p "$tmp/$left_dir/$(dirname "$name")"
-			git show "$left":"$name" >"$tmp/$left_dir/$name" || true
-		fi
-	else
-		if test -n "$compare_staged"
-		then
-			ls_list=$(git ls-tree HEAD "$name")
-			if test -n "$ls_list"
-			then
-				mkdir -p "$tmp/$left_dir/$(dirname "$name")"
-				git show HEAD:"$name" >"$tmp/$left_dir/$name"
-			fi
-		else
-			mkdir -p "$tmp/$left_dir/$(dirname "$name")"
-			git show :"$name" >"$tmp/$left_dir/$name"
-		fi
-	fi
-done < "$tmp/filelist"
-
-LOCAL="$tmp/$left_dir"
-REMOTE="$tmp/$right_dir"
-
-if test -n "$diff_tool"
-then
-	export BASE
-	eval $diff_tool '"$LOCAL"' '"$REMOTE"'
-else
-	run_merge_tool "$merge_tool" false
-fi
-
-# Copy files back to the working dir, if requested
-if test -n "$copy_back" && test "$right_dir" = "working_tree"
-then
-	cd "$start_dir"
-	git_top_dir=$(git rev-parse --show-toplevel)
-	find "$tmp/$right_dir" -type f |
-	while read file
-	do
-		cp "$file" "$git_top_dir/${file#$tmp/$right_dir/}"
-	done
-fi
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 05/17] contrib: remove 'hg-to-git'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (3 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 04/17] contrib: remove 'diffall' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 07/17] contrib: remove 'stats' Felipe Contreras
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras, Miklos Vajna

There hasn't been any real activity on it since 2010.

Plus there are better out-of-tree tools.

No tests and no real documentation either.

Cc: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/hg-to-git/hg-to-git.py  | 255 ----------------------------------------
 contrib/hg-to-git/hg-to-git.txt |  21 ----
 2 files changed, 276 deletions(-)
 delete mode 100755 contrib/hg-to-git/hg-to-git.py
 delete mode 100644 contrib/hg-to-git/hg-to-git.txt

diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py
deleted file mode 100755
index 60dec86..0000000
--- a/contrib/hg-to-git/hg-to-git.py
+++ /dev/null
@@ -1,255 +0,0 @@
-#!/usr/bin/env python
-
-""" hg-to-git.py - A Mercurial to GIT converter
-
-    Copyright (C)2007 Stelian Pop <stelian@popies.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2, or (at your option)
-    any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-"""
-
-import os, os.path, sys
-import tempfile, pickle, getopt
-import re
-
-if sys.hexversion < 0x02030000:
-   # The behavior of the pickle module changed significantly in 2.3
-   sys.stderr.write("hg-to-git.py: requires Python 2.3 or later.\n")
-   sys.exit(1)
-
-# Maps hg version -> git version
-hgvers = {}
-# List of children for each hg revision
-hgchildren = {}
-# List of parents for each hg revision
-hgparents = {}
-# Current branch for each hg revision
-hgbranch = {}
-# Number of new changesets converted from hg
-hgnewcsets = 0
-
-#------------------------------------------------------------------------------
-
-def usage():
-
-        print """\
-%s: [OPTIONS] <hgprj>
-
-options:
-    -s, --gitstate=FILE: name of the state to be saved/read
-                         for incrementals
-    -n, --nrepack=INT:   number of changesets that will trigger
-                         a repack (default=0, -1 to deactivate)
-    -v, --verbose:       be verbose
-
-required:
-    hgprj:  name of the HG project to import (directory)
-""" % sys.argv[0]
-
-#------------------------------------------------------------------------------
-
-def getgitenv(user, date):
-    env = ''
-    elems = re.compile('(.*?)\s+<(.*)>').match(user)
-    if elems:
-        env += 'export GIT_AUTHOR_NAME="%s" ;' % elems.group(1)
-        env += 'export GIT_COMMITTER_NAME="%s" ;' % elems.group(1)
-        env += 'export GIT_AUTHOR_EMAIL="%s" ;' % elems.group(2)
-        env += 'export GIT_COMMITTER_EMAIL="%s" ;' % elems.group(2)
-    else:
-        env += 'export GIT_AUTHOR_NAME="%s" ;' % user
-        env += 'export GIT_COMMITTER_NAME="%s" ;' % user
-        env += 'export GIT_AUTHOR_EMAIL= ;'
-        env += 'export GIT_COMMITTER_EMAIL= ;'
-
-    env += 'export GIT_AUTHOR_DATE="%s" ;' % date
-    env += 'export GIT_COMMITTER_DATE="%s" ;' % date
-    return env
-
-#------------------------------------------------------------------------------
-
-state = ''
-opt_nrepack = 0
-verbose = False
-
-try:
-    opts, args = getopt.getopt(sys.argv[1:], 's:t:n:v', ['gitstate=', 'tempdir=', 'nrepack=', 'verbose'])
-    for o, a in opts:
-        if o in ('-s', '--gitstate'):
-            state = a
-            state = os.path.abspath(state)
-        if o in ('-n', '--nrepack'):
-            opt_nrepack = int(a)
-        if o in ('-v', '--verbose'):
-            verbose = True
-    if len(args) != 1:
-        raise Exception('params')
-except:
-    usage()
-    sys.exit(1)
-
-hgprj = args[0]
-os.chdir(hgprj)
-
-if state:
-    if os.path.exists(state):
-        if verbose:
-            print 'State does exist, reading'
-        f = open(state, 'r')
-        hgvers = pickle.load(f)
-    else:
-        print 'State does not exist, first run'
-
-sock = os.popen('hg tip --template "{rev}"')
-tip = sock.read()
-if sock.close():
-    sys.exit(1)
-if verbose:
-    print 'tip is', tip
-
-# Calculate the branches
-if verbose:
-    print 'analysing the branches...'
-hgchildren["0"] = ()
-hgparents["0"] = (None, None)
-hgbranch["0"] = "master"
-for cset in range(1, int(tip) + 1):
-    hgchildren[str(cset)] = ()
-    prnts = os.popen('hg log -r %d --template "{parents}"' % cset).read().strip().split(' ')
-    prnts = map(lambda x: x[:x.find(':')], prnts)
-    if prnts[0] != '':
-        parent = prnts[0].strip()
-    else:
-        parent = str(cset - 1)
-    hgchildren[parent] += ( str(cset), )
-    if len(prnts) > 1:
-        mparent = prnts[1].strip()
-        hgchildren[mparent] += ( str(cset), )
-    else:
-        mparent = None
-
-    hgparents[str(cset)] = (parent, mparent)
-
-    if mparent:
-        # For merge changesets, take either one, preferably the 'master' branch
-        if hgbranch[mparent] == 'master':
-            hgbranch[str(cset)] = 'master'
-        else:
-            hgbranch[str(cset)] = hgbranch[parent]
-    else:
-        # Normal changesets
-        # For first children, take the parent branch, for the others create a new branch
-        if hgchildren[parent][0] == str(cset):
-            hgbranch[str(cset)] = hgbranch[parent]
-        else:
-            hgbranch[str(cset)] = "branch-" + str(cset)
-
-if not hgvers.has_key("0"):
-    print 'creating repository'
-    os.system('git init')
-
-# loop through every hg changeset
-for cset in range(int(tip) + 1):
-
-    # incremental, already seen
-    if hgvers.has_key(str(cset)):
-        continue
-    hgnewcsets += 1
-
-    # get info
-    log_data = os.popen('hg log -r %d --template "{tags}\n{date|date}\n{author}\n"' % cset).readlines()
-    tag = log_data[0].strip()
-    date = log_data[1].strip()
-    user = log_data[2].strip()
-    parent = hgparents[str(cset)][0]
-    mparent = hgparents[str(cset)][1]
-
-    #get comment
-    (fdcomment, filecomment) = tempfile.mkstemp()
-    csetcomment = os.popen('hg log -r %d --template "{desc}"' % cset).read().strip()
-    os.write(fdcomment, csetcomment)
-    os.close(fdcomment)
-
-    print '-----------------------------------------'
-    print 'cset:', cset
-    print 'branch:', hgbranch[str(cset)]
-    print 'user:', user
-    print 'date:', date
-    print 'comment:', csetcomment
-    if parent:
-	print 'parent:', parent
-    if mparent:
-        print 'mparent:', mparent
-    if tag:
-        print 'tag:', tag
-    print '-----------------------------------------'
-
-    # checkout the parent if necessary
-    if cset != 0:
-        if hgbranch[str(cset)] == "branch-" + str(cset):
-            print 'creating new branch', hgbranch[str(cset)]
-            os.system('git checkout -b %s %s' % (hgbranch[str(cset)], hgvers[parent]))
-        else:
-            print 'checking out branch', hgbranch[str(cset)]
-            os.system('git checkout %s' % hgbranch[str(cset)])
-
-    # merge
-    if mparent:
-        if hgbranch[parent] == hgbranch[str(cset)]:
-            otherbranch = hgbranch[mparent]
-        else:
-            otherbranch = hgbranch[parent]
-        print 'merging', otherbranch, 'into', hgbranch[str(cset)]
-        os.system(getgitenv(user, date) + 'git merge --no-commit -s ours "" %s %s' % (hgbranch[str(cset)], otherbranch))
-
-    # remove everything except .git and .hg directories
-    os.system('find . \( -path "./.hg" -o -path "./.git" \) -prune -o ! -name "." -print | xargs rm -rf')
-
-    # repopulate with checkouted files
-    os.system('hg update -C %d' % cset)
-
-    # add new files
-    os.system('git ls-files -x .hg --others | git update-index --add --stdin')
-    # delete removed files
-    os.system('git ls-files -x .hg --deleted | git update-index --remove --stdin')
-
-    # commit
-    os.system(getgitenv(user, date) + 'git commit --allow-empty --allow-empty-message -a -F %s' % filecomment)
-    os.unlink(filecomment)
-
-    # tag
-    if tag and tag != 'tip':
-        os.system(getgitenv(user, date) + 'git tag %s' % tag)
-
-    # delete branch if not used anymore...
-    if mparent and len(hgchildren[str(cset)]):
-        print "Deleting unused branch:", otherbranch
-        os.system('git branch -d %s' % otherbranch)
-
-    # retrieve and record the version
-    vvv = os.popen('git show --quiet --pretty=format:%H').read()
-    print 'record', cset, '->', vvv
-    hgvers[str(cset)] = vvv
-
-if hgnewcsets >= opt_nrepack and opt_nrepack != -1:
-    os.system('git repack -a -d')
-
-# write the state for incrementals
-if state:
-    if verbose:
-        print 'Writing state'
-    f = open(state, 'w')
-    pickle.dump(hgvers, f)
-
-# vim: et ts=8 sw=4 sts=4
diff --git a/contrib/hg-to-git/hg-to-git.txt b/contrib/hg-to-git/hg-to-git.txt
deleted file mode 100644
index 91f8fe6..0000000
--- a/contrib/hg-to-git/hg-to-git.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-hg-to-git.py is able to convert a Mercurial repository into a git one,
-and preserves the branches in the process (unlike tailor)
-
-hg-to-git.py can probably be greatly improved (it's a rather crude
-combination of shell and python) but it does already work quite well for
-me. Features:
-	- supports incremental conversion
-	  (for keeping a git repo in sync with a hg one)
-        - supports hg branches
-        - converts hg tags
-
-Note that the git repository will be created 'in place' (at the same
-location as the source hg repo). You will have to manually remove the
-'.hg' directory after the conversion.
-
-Also note that the incremental conversion uses 'simple' hg changesets
-identifiers (ordinals, as opposed to SHA-1 ids), and since these ids
-are not stable across different repositories the hg-to-git.py state file
-is forever tied to one hg repository.
-
-Stelian Pop <stelian@popies.net>
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 07/17] contrib: remove 'stats'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (4 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 05/17] contrib: remove 'hg-to-git' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 08/17] contrib: remove 'convert-objects' Felipe Contreras
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No real activity since 2012 (or ever), no tests, no documentation.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/stats/git-common-hash |  26 ------
 contrib/stats/mailmap.pl      |  70 --------------
 contrib/stats/packinfo.pl     | 212 ------------------------------------------
 3 files changed, 308 deletions(-)
 delete mode 100755 contrib/stats/git-common-hash
 delete mode 100755 contrib/stats/mailmap.pl
 delete mode 100755 contrib/stats/packinfo.pl

diff --git a/contrib/stats/git-common-hash b/contrib/stats/git-common-hash
deleted file mode 100755
index e27fd08..0000000
--- a/contrib/stats/git-common-hash
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-# This script displays the distribution of longest common hash prefixes.
-# This can be used to determine the minimum prefix length to use
-# for object names to be unique.
-
-git rev-list --objects --all | sort | perl -lne '
-  substr($_, 40) = "";
-  # uncomment next line for a distribution of bits instead of hex chars
-  # $_ = unpack("B*",pack("H*",$_));
-  if (defined $p) {
-    ($p ^ $_) =~ /^(\0*)/;
-    $common = length $1;
-    if (defined $pcommon) {
-      $count[$pcommon > $common ? $pcommon : $common]++;
-    } else {
-      $count[$common]++; # first item
-    }
-  }
-  $p = $_;
-  $pcommon = $common;
-  END {
-    $count[$common]++; # last item
-    print "$_: $count[$_]" for 0..$#count;
-  }
-'
diff --git a/contrib/stats/mailmap.pl b/contrib/stats/mailmap.pl
deleted file mode 100755
index 9513f5e..0000000
--- a/contrib/stats/mailmap.pl
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/perl
-
-use warnings 'all';
-use strict;
-use Getopt::Long;
-
-my $match_emails;
-my $match_names;
-my $order_by = 'count';
-Getopt::Long::Configure(qw(bundling));
-GetOptions(
-	'emails|e!' => \$match_emails,
-	'names|n!'  => \$match_names,
-	'count|c'   => sub { $order_by = 'count' },
-	'time|t'    => sub { $order_by = 'stamp' },
-) or exit 1;
-$match_emails = 1 unless $match_names;
-
-my $email = {};
-my $name = {};
-
-open(my $fh, '-|', "git log --format='%at <%aE> %aN'");
-while(<$fh>) {
-	my ($t, $e, $n) = /(\S+) <(\S+)> (.*)/;
-	mark($email, $e, $n, $t);
-	mark($name, $n, $e, $t);
-}
-close($fh);
-
-if ($match_emails) {
-	foreach my $e (dups($email)) {
-		foreach my $n (vals($email->{$e})) {
-			show($n, $e, $email->{$e}->{$n});
-		}
-		print "\n";
-	}
-}
-if ($match_names) {
-	foreach my $n (dups($name)) {
-		foreach my $e (vals($name->{$n})) {
-			show($n, $e, $name->{$n}->{$e});
-		}
-		print "\n";
-	}
-}
-exit 0;
-
-sub mark {
-	my ($h, $k, $v, $t) = @_;
-	my $e = $h->{$k}->{$v} ||= { count => 0, stamp => 0 };
-	$e->{count}++;
-	$e->{stamp} = $t unless $t < $e->{stamp};
-}
-
-sub dups {
-	my $h = shift;
-	return grep { keys($h->{$_}) > 1 } keys($h);
-}
-
-sub vals {
-	my $h = shift;
-	return sort {
-		$h->{$b}->{$order_by} <=> $h->{$a}->{$order_by}
-	} keys($h);
-}
-
-sub show {
-	my ($n, $e, $h) = @_;
-	print "$n <$e> ($h->{$order_by})\n";
-}
diff --git a/contrib/stats/packinfo.pl b/contrib/stats/packinfo.pl
deleted file mode 100755
index be188c0..0000000
--- a/contrib/stats/packinfo.pl
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/perl
-#
-# This tool will print vaguely pretty information about a pack.  It
-# expects the output of "git verify-pack -v" as input on stdin.
-#
-# $ git verify-pack -v | packinfo.pl
-#
-# This prints some full-pack statistics; currently "all sizes", "all
-# path sizes", "tree sizes", "tree path sizes", and "depths".
-#
-# * "all sizes" stats are across every object size in the file;
-#   full sizes for base objects, and delta size for deltas.
-# * "all path sizes" stats are across all object's "path sizes".
-#   A path size is the sum of the size of the delta chain, including the
-#   base object.  In other words, it's how many bytes need be read to
-#   reassemble the file from deltas.
-# * "tree sizes" are object sizes grouped into delta trees.
-# * "tree path sizes" are path sizes grouped into delta trees.
-# * "depths" should be obvious.
-#
-# When run as:
-#
-# $ git verify-pack -v | packinfo.pl -tree
-#
-# the trees of objects are output along with the stats.  This looks
-# like:
-#
-#   0 commit 031321c6...      803      803
-#
-#   0   blob 03156f21...     1767     1767
-#   1    blob f52a9d7f...       10     1777
-#   2     blob a8cc5739...       51     1828
-#   3      blob 660e90b1...       15     1843
-#   4       blob 0cb8e3bb...       33     1876
-#   2     blob e48607f0...      311     2088
-#      size: count 6 total 2187 min 10 max 1767 mean 364.50 median 51 std_dev 635.85
-# path size: count 6 total 11179 min 1767 max 2088 mean 1863.17 median 1843 std_dev 107.26
-#
-# The first number after the sha1 is the object size, the second
-# number is the path size.  The statistics are across all objects in
-# the previous delta tree.  Obviously they are omitted for trees of
-# one object.
-#
-# When run as:
-#
-# $ git verify-pack -v | packinfo.pl -tree -filenames
-#
-# it adds filenames to the tree.  Getting this information is slow:
-#
-#   0   blob 03156f21...     1767     1767 Documentation/git-lost-found.txt @ tags/v1.2.0~142
-#   1    blob f52a9d7f...       10     1777 Documentation/git-lost-found.txt @ tags/v1.5.0-rc1~74
-#   2     blob a8cc5739...       51     1828 Documentation/git-lost+found.txt @ tags/v0.99.9h^0
-#   3      blob 660e90b1...       15     1843 Documentation/git-lost+found.txt @ master~3222^2~2
-#   4       blob 0cb8e3bb...       33     1876 Documentation/git-lost+found.txt @ master~3222^2~3
-#   2     blob e48607f0...      311     2088 Documentation/git-lost-found.txt @ tags/v1.5.2-rc3~4
-#      size: count 6 total 2187 min 10 max 1767 mean 364.50 median 51 std_dev 635.85
-# path size: count 6 total 11179 min 1767 max 2088 mean 1863.17 median 1843 std_dev 107.26
-#
-# When run as:
-#
-# $ git verify-pack -v | packinfo.pl -dump
-#
-# it prints out "sha1 size pathsize depth" for each sha1 in lexical
-# order.
-#
-# 000079a2eaef17b7eae70e1f0f635557ea67b644 30 472 7
-# 00013cafe6980411aa6fdd940784917b5ff50f0a 44 1542 4
-# 000182eacf99cde27d5916aa415921924b82972c 499 499 0
-# ...
-#
-# This is handy for comparing two packs.  Adding "-filenames" will add
-# filenames, as per "-tree -filenames" above.
-
-use strict;
-use Getopt::Long;
-
-my $filenames = 0;
-my $tree = 0;
-my $dump = 0;
-GetOptions("tree" => \$tree,
-           "filenames" => \$filenames,
-           "dump" => \$dump);
-
-my %parents;
-my %children;
-my %sizes;
-my @roots;
-my %paths;
-my %types;
-my @commits;
-my %names;
-my %depths;
-my @depths;
-
-while (<STDIN>) {
-    my ($sha1, $type, $size, $space, $offset, $depth, $parent) = split(/\s+/, $_);
-    next unless ($sha1 =~ /^[0-9a-f]{40}$/);
-    $depths{$sha1} = $depth || 0;
-    push(@depths, $depth || 0);
-    push(@commits, $sha1) if ($type eq 'commit');
-    push(@roots, $sha1) unless $parent;
-    $parents{$sha1} = $parent;
-    $types{$sha1} = $type;
-    push(@{$children{$parent}}, $sha1);
-    $sizes{$sha1} = $size;
-}
-
-if ($filenames && ($tree || $dump)) {
-    open(NAMES, "git name-rev --all|");
-    while (<NAMES>) {
-        if (/^(\S+)\s+(.*)$/) {
-            my ($sha1, $name) = ($1, $2);
-            $names{$sha1} = $name;
-        }
-    }
-    close NAMES;
-
-    for my $commit (@commits) {
-        my $name = $names{$commit};
-        open(TREE, "git ls-tree -t -r $commit|");
-        print STDERR "Plumbing tree $name\n";
-        while (<TREE>) {
-            if (/^(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
-                my ($mode, $type, $sha1, $path) = ($1, $2, $3, $4);
-                $paths{$sha1} = "$path @ $name";
-            }
-        }
-        close TREE;
-    }
-}
-
-sub stats {
-    my @data = sort {$a <=> $b} @_;
-    my $min = $data[0];
-    my $max = $data[$#data];
-    my $total = 0;
-    my $count = scalar @data;
-    for my $datum (@data) {
-        $total += $datum;
-    }
-    my $mean = $total / $count;
-    my $median = $data[int(@data / 2)];
-    my $diff_sum = 0;
-    for my $datum (@data) {
-        $diff_sum += ($datum - $mean)**2;
-    }
-    my $std_dev = sqrt($diff_sum / $count);
-    return ($count, $total, $min, $max, $mean, $median, $std_dev);
-}
-
-sub print_stats {
-    my $name = shift;
-    my ($count, $total, $min, $max, $mean, $median, $std_dev) = stats(@_);
-    printf("%s: count %s total %s min %s max %s mean %.2f median %s std_dev %.2f\n",
-           $name, $count, $total, $min, $max, $mean, $median, $std_dev);
-}
-
-my @sizes;
-my @path_sizes;
-my @all_sizes;
-my @all_path_sizes;
-my %path_sizes;
-
-sub dig {
-    my ($sha1, $depth, $path_size) = @_;
-    $path_size += $sizes{$sha1};
-    push(@sizes, $sizes{$sha1});
-    push(@all_sizes, $sizes{$sha1});
-    push(@path_sizes, $path_size);
-    push(@all_path_sizes, $path_size);
-    $path_sizes{$sha1} = $path_size;
-    if ($tree) {
-        printf("%3d%s %6s %s %8d %8d %s\n",
-               $depth, (" " x $depth), $types{$sha1},
-               $sha1, $sizes{$sha1}, $path_size, $paths{$sha1});
-    }
-    for my $child (@{$children{$sha1}}) {
-        dig($child, $depth + 1, $path_size);
-    }
-}
-
-my @tree_sizes;
-my @tree_path_sizes;
-
-for my $root (@roots) {
-    undef @sizes;
-    undef @path_sizes;
-    dig($root, 0, 0);
-    my ($aa, $sz_total) = stats(@sizes);
-    my ($bb, $psz_total) = stats(@path_sizes);
-    push(@tree_sizes, $sz_total);
-    push(@tree_path_sizes, $psz_total);
-    if ($tree) {
-        if (@sizes > 1) {
-            print_stats("     size", @sizes);
-            print_stats("path size", @path_sizes);
-        }
-        print "\n";
-    }
-}
-
-if ($dump) {
-    for my $sha1 (sort keys %sizes) {
-        print "$sha1 $sizes{$sha1} $path_sizes{$sha1} $depths{$sha1} $paths{$sha1}\n";
-    }
-} else {
-    print_stats("      all sizes", @all_sizes);
-    print_stats(" all path sizes", @all_path_sizes);
-    print_stats("     tree sizes", @tree_sizes);
-    print_stats("tree path sizes", @tree_path_sizes);
-    print_stats("         depths", @depths);
-}
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 08/17] contrib: remove 'convert-objects'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (5 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 07/17] contrib: remove 'stats' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 09/17] contrib: remove 'git-shell-commands' Felipe Contreras
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No activity since 2010, no tests, no documentation.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/convert-objects/convert-objects.c       | 329 ------------------------
 contrib/convert-objects/git-convert-objects.txt |  29 ---
 2 files changed, 358 deletions(-)
 delete mode 100644 contrib/convert-objects/convert-objects.c
 delete mode 100644 contrib/convert-objects/git-convert-objects.txt

diff --git a/contrib/convert-objects/convert-objects.c b/contrib/convert-objects/convert-objects.c
deleted file mode 100644
index f3b57bf..0000000
--- a/contrib/convert-objects/convert-objects.c
+++ /dev/null
@@ -1,329 +0,0 @@
-#include "cache.h"
-#include "blob.h"
-#include "commit.h"
-#include "tree.h"
-
-struct entry {
-	unsigned char old_sha1[20];
-	unsigned char new_sha1[20];
-	int converted;
-};
-
-#define MAXOBJECTS (1000000)
-
-static struct entry *convert[MAXOBJECTS];
-static int nr_convert;
-
-static struct entry * convert_entry(unsigned char *sha1);
-
-static struct entry *insert_new(unsigned char *sha1, int pos)
-{
-	struct entry *new = xcalloc(1, sizeof(struct entry));
-	hashcpy(new->old_sha1, sha1);
-	memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
-	convert[pos] = new;
-	nr_convert++;
-	if (nr_convert == MAXOBJECTS)
-		die("you're kidding me - hit maximum object limit");
-	return new;
-}
-
-static struct entry *lookup_entry(unsigned char *sha1)
-{
-	int low = 0, high = nr_convert;
-
-	while (low < high) {
-		int next = (low + high) / 2;
-		struct entry *n = convert[next];
-		int cmp = hashcmp(sha1, n->old_sha1);
-		if (!cmp)
-			return n;
-		if (cmp < 0) {
-			high = next;
-			continue;
-		}
-		low = next+1;
-	}
-	return insert_new(sha1, low);
-}
-
-static void convert_binary_sha1(void *buffer)
-{
-	struct entry *entry = convert_entry(buffer);
-	hashcpy(buffer, entry->new_sha1);
-}
-
-static void convert_ascii_sha1(void *buffer)
-{
-	unsigned char sha1[20];
-	struct entry *entry;
-
-	if (get_sha1_hex(buffer, sha1))
-		die("expected sha1, got '%s'", (char *) buffer);
-	entry = convert_entry(sha1);
-	memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
-}
-
-static unsigned int convert_mode(unsigned int mode)
-{
-	unsigned int newmode;
-
-	newmode = mode & S_IFMT;
-	if (S_ISREG(mode))
-		newmode |= (mode & 0100) ? 0755 : 0644;
-	return newmode;
-}
-
-static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
-{
-	char *new = xmalloc(size);
-	unsigned long newlen = 0;
-	unsigned long used;
-
-	used = 0;
-	while (size) {
-		int len = 21 + strlen(buffer);
-		char *path = strchr(buffer, ' ');
-		unsigned char *sha1;
-		unsigned int mode;
-		char *slash, *origpath;
-
-		if (!path || strtoul_ui(buffer, 8, &mode))
-			die("bad tree conversion");
-		mode = convert_mode(mode);
-		path++;
-		if (memcmp(path, base, baselen))
-			break;
-		origpath = path;
-		path += baselen;
-		slash = strchr(path, '/');
-		if (!slash) {
-			newlen += sprintf(new + newlen, "%o %s", mode, path);
-			new[newlen++] = '\0';
-			hashcpy((unsigned char *)new + newlen, (unsigned char *) buffer + len - 20);
-			newlen += 20;
-
-			used += len;
-			size -= len;
-			buffer = (char *) buffer + len;
-			continue;
-		}
-
-		newlen += sprintf(new + newlen, "%o %.*s", S_IFDIR, (int)(slash - path), path);
-		new[newlen++] = 0;
-		sha1 = (unsigned char *)(new + newlen);
-		newlen += 20;
-
-		len = write_subdirectory(buffer, size, origpath, slash-origpath+1, sha1);
-
-		used += len;
-		size -= len;
-		buffer = (char *) buffer + len;
-	}
-
-	write_sha1_file(new, newlen, tree_type, result_sha1);
-	free(new);
-	return used;
-}
-
-static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
-	void *orig_buffer = buffer;
-	unsigned long orig_size = size;
-
-	while (size) {
-		size_t len = 1+strlen(buffer);
-
-		convert_binary_sha1((char *) buffer + len);
-
-		len += 20;
-		if (len > size)
-			die("corrupt tree object");
-		size -= len;
-		buffer = (char *) buffer + len;
-	}
-
-	write_subdirectory(orig_buffer, orig_size, "", 0, result_sha1);
-}
-
-static unsigned long parse_oldstyle_date(const char *buf)
-{
-	char c, *p;
-	char buffer[100];
-	struct tm tm;
-	const char *formats[] = {
-		"%c",
-		"%a %b %d %T",
-		"%Z",
-		"%Y",
-		" %Y",
-		NULL
-	};
-	/* We only ever did two timezones in the bad old format .. */
-	const char *timezones[] = {
-		"PDT", "PST", "CEST", NULL
-	};
-	const char **fmt = formats;
-
-	p = buffer;
-	while (isspace(c = *buf))
-		buf++;
-	while ((c = *buf++) != '\n')
-		*p++ = c;
-	*p++ = 0;
-	buf = buffer;
-	memset(&tm, 0, sizeof(tm));
-	do {
-		const char *next = strptime(buf, *fmt, &tm);
-		if (next) {
-			if (!*next)
-				return mktime(&tm);
-			buf = next;
-		} else {
-			const char **p = timezones;
-			while (isspace(*buf))
-				buf++;
-			while (*p) {
-				if (!memcmp(buf, *p, strlen(*p))) {
-					buf += strlen(*p);
-					break;
-				}
-				p++;
-			}
-		}
-		fmt++;
-	} while (*buf && *fmt);
-	printf("left: %s\n", buf);
-	return mktime(&tm);
-}
-
-static int convert_date_line(char *dst, void **buf, unsigned long *sp)
-{
-	unsigned long size = *sp;
-	char *line = *buf;
-	char *next = strchr(line, '\n');
-	char *date = strchr(line, '>');
-	int len;
-
-	if (!next || !date)
-		die("missing or bad author/committer line %s", line);
-	next++; date += 2;
-
-	*buf = next;
-	*sp = size - (next - line);
-
-	len = date - line;
-	memcpy(dst, line, len);
-	dst += len;
-
-	/* Is it already in new format? */
-	if (isdigit(*date)) {
-		int datelen = next - date;
-		memcpy(dst, date, datelen);
-		return len + datelen;
-	}
-
-	/*
-	 * Hacky hacky: one of the sparse old-style commits does not have
-	 * any date at all, but we can fake it by using the committer date.
-	 */
-	if (*date == '\n' && strchr(next, '>'))
-		date = strchr(next, '>')+2;
-
-	return len + sprintf(dst, "%lu -0700\n", parse_oldstyle_date(date));
-}
-
-static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
-	char *new = xmalloc(size + 100);
-	unsigned long newlen = 0;
-
-	/* "tree <sha1>\n" */
-	memcpy(new + newlen, buffer, 46);
-	newlen += 46;
-	buffer = (char *) buffer + 46;
-	size -= 46;
-
-	/* "parent <sha1>\n" */
-	while (!memcmp(buffer, "parent ", 7)) {
-		memcpy(new + newlen, buffer, 48);
-		newlen += 48;
-		buffer = (char *) buffer + 48;
-		size -= 48;
-	}
-
-	/* "author xyz <xyz> date" */
-	newlen += convert_date_line(new + newlen, &buffer, &size);
-	/* "committer xyz <xyz> date" */
-	newlen += convert_date_line(new + newlen, &buffer, &size);
-
-	/* Rest */
-	memcpy(new + newlen, buffer, size);
-	newlen += size;
-
-	write_sha1_file(new, newlen, commit_type, result_sha1);
-	free(new);
-}
-
-static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
-	void *orig_buffer = buffer;
-	unsigned long orig_size = size;
-
-	if (memcmp(buffer, "tree ", 5))
-		die("Bad commit '%s'", (char *) buffer);
-	convert_ascii_sha1((char *) buffer + 5);
-	buffer = (char *) buffer + 46;    /* "tree " + "hex sha1" + "\n" */
-	while (!memcmp(buffer, "parent ", 7)) {
-		convert_ascii_sha1((char *) buffer + 7);
-		buffer = (char *) buffer + 48;
-	}
-	convert_date(orig_buffer, orig_size, result_sha1);
-}
-
-static struct entry * convert_entry(unsigned char *sha1)
-{
-	struct entry *entry = lookup_entry(sha1);
-	enum object_type type;
-	void *buffer, *data;
-	unsigned long size;
-
-	if (entry->converted)
-		return entry;
-	data = read_sha1_file(sha1, &type, &size);
-	if (!data)
-		die("unable to read object %s", sha1_to_hex(sha1));
-
-	buffer = xmalloc(size);
-	memcpy(buffer, data, size);
-
-	if (type == OBJ_BLOB) {
-		write_sha1_file(buffer, size, blob_type, entry->new_sha1);
-	} else if (type == OBJ_TREE)
-		convert_tree(buffer, size, entry->new_sha1);
-	else if (type == OBJ_COMMIT)
-		convert_commit(buffer, size, entry->new_sha1);
-	else
-		die("unknown object type %d in %s", type, sha1_to_hex(sha1));
-	entry->converted = 1;
-	free(buffer);
-	free(data);
-	return entry;
-}
-
-int main(int argc, char **argv)
-{
-	unsigned char sha1[20];
-	struct entry *entry;
-
-	setup_git_directory();
-
-	if (argc != 2)
-		usage("git-convert-objects <sha1>");
-	if (get_sha1(argv[1], sha1))
-		die("Not a valid object name %s", argv[1]);
-
-	entry = convert_entry(sha1);
-	printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
-	return 0;
-}
diff --git a/contrib/convert-objects/git-convert-objects.txt b/contrib/convert-objects/git-convert-objects.txt
deleted file mode 100644
index 0565d83..0000000
--- a/contrib/convert-objects/git-convert-objects.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-git-convert-objects(1)
-======================
-
-NAME
-----
-git-convert-objects - Converts old-style git repository
-
-
-SYNOPSIS
---------
-[verse]
-'git-convert-objects'
-
-DESCRIPTION
------------
-Converts old-style git repository to the latest format
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org>
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 09/17] contrib: remove 'git-shell-commands'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (6 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 08/17] contrib: remove 'convert-objects' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 10/17] contrib: reomve 'thunderbird-patch-inline' Felipe Contreras
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No activity, no tests.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/git-shell-commands/README | 18 ------------------
 contrib/git-shell-commands/help   | 18 ------------------
 contrib/git-shell-commands/list   | 10 ----------
 3 files changed, 46 deletions(-)
 delete mode 100644 contrib/git-shell-commands/README
 delete mode 100755 contrib/git-shell-commands/help
 delete mode 100755 contrib/git-shell-commands/list

diff --git a/contrib/git-shell-commands/README b/contrib/git-shell-commands/README
deleted file mode 100644
index 438463b..0000000
--- a/contrib/git-shell-commands/README
+++ /dev/null
@@ -1,18 +0,0 @@
-Sample programs callable through git-shell.  Place a directory named
-'git-shell-commands' in the home directory of a user whose shell is
-git-shell.  Then anyone logging in as that user will be able to run
-executables in the 'git-shell-commands' directory.
-
-Provided commands:
-
-help: Prints out the names of available commands.  When run
-interactively, git-shell will automatically run 'help' on startup,
-provided it exists.
-
-list: Displays any bare repository whose name ends with ".git" under
-user's home directory.  No other git repositories are visible,
-although they might be clonable through git-shell.  'list' is designed
-to minimize the number of calls to git that must be made in finding
-available repositories; if your setup has additional repositories that
-should be user-discoverable, you may wish to modify 'list'
-accordingly.
diff --git a/contrib/git-shell-commands/help b/contrib/git-shell-commands/help
deleted file mode 100755
index 535770c..0000000
--- a/contrib/git-shell-commands/help
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-if tty -s
-then
-	echo "Run 'help' for help, or 'exit' to leave.  Available commands:"
-else
-	echo "Run 'help' for help.  Available commands:"
-fi
-
-cd "$(dirname "$0")"
-
-for cmd in *
-do
-	case "$cmd" in
-	help) ;;
-	*) [ -f "$cmd" ] && [ -x "$cmd" ] && echo "$cmd" ;;
-	esac
-done
diff --git a/contrib/git-shell-commands/list b/contrib/git-shell-commands/list
deleted file mode 100755
index 6f89938..0000000
--- a/contrib/git-shell-commands/list
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-print_if_bare_repo='
-	if "$(git --git-dir="$1" rev-parse --is-bare-repository)" = true
-	then
-		printf "%s\n" "${1#./}"
-	fi
-'
-
-find -type d -name "*.git" -exec sh -c "$print_if_bare_repo" -- \{} \; -prune 2>/dev/null
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 10/17] contrib: reomve 'thunderbird-patch-inline'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (7 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 09/17] contrib: remove 'git-shell-commands' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 11/17] contrib: remove 'workdir' Felipe Contreras
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No activity, no tests.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/thunderbird-patch-inline/README  | 20 ------------
 contrib/thunderbird-patch-inline/appp.sh | 55 --------------------------------
 2 files changed, 75 deletions(-)
 delete mode 100644 contrib/thunderbird-patch-inline/README
 delete mode 100755 contrib/thunderbird-patch-inline/appp.sh

diff --git a/contrib/thunderbird-patch-inline/README b/contrib/thunderbird-patch-inline/README
deleted file mode 100644
index 000147b..0000000
--- a/contrib/thunderbird-patch-inline/README
+++ /dev/null
@@ -1,20 +0,0 @@
-appp.sh is a script that is supposed to be used together with ExternalEditor
-for Mozilla Thunderbird. It will let you include patches inline in e-mails
-in an easy way.
-
-Usage:
-- Generate the patch with git format-patch.
-- Start writing a new e-mail in Thunderbird.
-- Press the external editor button (or Ctrl-E) to run appp.sh
-- Select the previously generated patch file.
-- Finish editing the e-mail.
-
-Any text that is entered into the message editor before appp.sh is called
-will be moved to the section between the --- and the diffstat.
-
-All S-O-B:s and Cc:s in the patch will be added to the CC list.
-
-To set it up, just install External Editor and tell it to use appp.sh as the
-editor.
-
-Zenity is a required dependency.
diff --git a/contrib/thunderbird-patch-inline/appp.sh b/contrib/thunderbird-patch-inline/appp.sh
deleted file mode 100755
index 8dc73ec..0000000
--- a/contrib/thunderbird-patch-inline/appp.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-# Copyright 2008 Lukas Sandström <luksan@gmail.com>
-#
-# AppendPatch - A script to be used together with ExternalEditor
-# for Mozilla Thunderbird to properly include patches inline in e-mails.
-
-# ExternalEditor can be downloaded at http://globs.org/articles.php?lng=en&pg=2
-
-CONFFILE=~/.appprc
-
-SEP="-=-=-=-=-=-=-=-=-=# Don't remove this line #=-=-=-=-=-=-=-=-=-"
-if [ -e "$CONFFILE" ] ; then
-	LAST_DIR=$(grep -m 1 "^LAST_DIR=" "${CONFFILE}"|sed -e 's/^LAST_DIR=//')
-	cd "${LAST_DIR}"
-else
-	cd > /dev/null
-fi
-
-PATCH=$(zenity --file-selection)
-
-if [ "$?" != "0" ] ; then
-	#zenity --error --text "No patchfile given."
-	exit 1
-fi
-
-cd - > /dev/null
-
-SUBJECT=$(sed -n -e '/^Subject: /p' "${PATCH}")
-HEADERS=$(sed -e '/^'"${SEP}"'$/,$d' $1)
-BODY=$(sed -e "1,/${SEP}/d" $1)
-CMT_MSG=$(sed -e '1,/^$/d' -e '/^---$/,$d' "${PATCH}")
-DIFF=$(sed -e '1,/^---$/d' "${PATCH}")
-
-CCS=`echo -e "$CMT_MSG\n$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \
-	-e 's/^Signed-off-by: \(.*\)/\1,/gp'`
-
-echo "$SUBJECT" > $1
-echo "Cc: $CCS" >> $1
-echo "$HEADERS" | sed -e '/^Subject: /d' -e '/^Cc: /d' >> $1
-echo "$SEP" >> $1
-
-echo "$CMT_MSG" >> $1
-echo "---" >> $1
-if [ "x${BODY}x" != "xx" ] ; then
-	echo >> $1
-	echo "$BODY" >> $1
-	echo >> $1
-fi
-echo "$DIFF" >> $1
-
-LAST_DIR=$(dirname "${PATCH}")
-
-grep -v "^LAST_DIR=" "${CONFFILE}" > "${CONFFILE}_"
-echo "LAST_DIR=${LAST_DIR}" >> "${CONFFILE}_"
-mv "${CONFFILE}_" "${CONFFILE}"
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 11/17] contrib: remove 'workdir'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (8 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 10/17] contrib: reomve 'thunderbird-patch-inline' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 12/17] contrib: remove 'svn-fe' Felipe Contreras
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No activity since 2010, no documentation, no tests.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/workdir/git-new-workdir | 82 -----------------------------------------
 1 file changed, 82 deletions(-)
 delete mode 100755 contrib/workdir/git-new-workdir

diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir
deleted file mode 100755
index 75e8b25..0000000
--- a/contrib/workdir/git-new-workdir
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/bin/sh
-
-usage () {
-	echo "usage:" $@
-	exit 127
-}
-
-die () {
-	echo $@
-	exit 128
-}
-
-if test $# -lt 2 || test $# -gt 3
-then
-	usage "$0 <repository> <new_workdir> [<branch>]"
-fi
-
-orig_git=$1
-new_workdir=$2
-branch=$3
-
-# want to make sure that what is pointed to has a .git directory ...
-git_dir=$(cd "$orig_git" 2>/dev/null &&
-  git rev-parse --git-dir 2>/dev/null) ||
-  die "Not a git repository: \"$orig_git\""
-
-case "$git_dir" in
-.git)
-	git_dir="$orig_git/.git"
-	;;
-.)
-	git_dir=$orig_git
-	;;
-esac
-
-# don't link to a configured bare repository
-isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
-if test ztrue = z$isbare
-then
-	die "\"$git_dir\" has core.bare set to true," \
-		" remove from \"$git_dir/config\" to use $0"
-fi
-
-# don't link to a workdir
-if test -h "$git_dir/config"
-then
-	die "\"$orig_git\" is a working directory only, please specify" \
-		"a complete repository."
-fi
-
-# don't recreate a workdir over an existing repository
-if test -e "$new_workdir"
-then
-	die "destination directory '$new_workdir' already exists."
-fi
-
-# make sure the links use full paths
-git_dir=$(cd "$git_dir"; pwd)
-
-# create the workdir
-mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!"
-
-# create the links to the original repo.  explicitly exclude index, HEAD and
-# logs/HEAD from the list since they are purely related to the current working
-# directory, and should not be shared.
-for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
-do
-	case $x in
-	*/*)
-		mkdir -p "$(dirname "$new_workdir/.git/$x")"
-		;;
-	esac
-	ln -s "$git_dir/$x" "$new_workdir/.git/$x"
-done
-
-# now setup the workdir
-cd "$new_workdir"
-# copy the HEAD from the original repository as a default branch
-cp "$git_dir/HEAD" .git/HEAD
-# checkout the branch (either the same as HEAD from the original repository, or
-# the one that was asked for)
-git checkout -f $branch
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 12/17] contrib: remove 'svn-fe'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (9 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 11/17] contrib: remove 'workdir' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 13/17] contrib: remove 'rerere-train' Felipe Contreras
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras, Jonathan Nieder

No activity since 2012, no tests.

Cc: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/svn-fe/.gitignore      |  4 ---
 contrib/svn-fe/Makefile        | 63 -------------------------------------
 contrib/svn-fe/svn-fe.c        | 18 -----------
 contrib/svn-fe/svn-fe.txt      | 71 ------------------------------------------
 contrib/svn-fe/svnrdump_sim.py | 57 ---------------------------------
 5 files changed, 213 deletions(-)
 delete mode 100644 contrib/svn-fe/.gitignore
 delete mode 100644 contrib/svn-fe/Makefile
 delete mode 100644 contrib/svn-fe/svn-fe.c
 delete mode 100644 contrib/svn-fe/svn-fe.txt
 delete mode 100755 contrib/svn-fe/svnrdump_sim.py

diff --git a/contrib/svn-fe/.gitignore b/contrib/svn-fe/.gitignore
deleted file mode 100644
index 02a7791..0000000
--- a/contrib/svn-fe/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-/*.xml
-/*.1
-/*.html
-/svn-fe
diff --git a/contrib/svn-fe/Makefile b/contrib/svn-fe/Makefile
deleted file mode 100644
index 360d8da..0000000
--- a/contrib/svn-fe/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
-all:: svn-fe$X
-
-CC = gcc
-RM = rm -f
-MV = mv
-
-CFLAGS = -g -O2 -Wall
-LDFLAGS =
-ALL_CFLAGS = $(CFLAGS)
-ALL_LDFLAGS = $(LDFLAGS)
-EXTLIBS =
-
-GIT_LIB = ../../libgit.a
-VCSSVN_LIB = ../../vcs-svn/lib.a
-LIBS = $(VCSSVN_LIB) $(GIT_LIB) $(EXTLIBS)
-
-QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
-QUIET_SUBDIR1 =
-
-ifneq ($(findstring $(MAKEFLAGS),w),w)
-PRINT_DIR = --no-print-directory
-else # "make -w"
-NO_SUBDIR = :
-endif
-
-ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifndef V
-	QUIET_CC      = @echo '   ' CC $@;
-	QUIET_LINK    = @echo '   ' LINK $@;
-	QUIET_SUBDIR0 = +@subdir=
-	QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
-	                $(MAKE) $(PRINT_DIR) -C $$subdir
-endif
-endif
-
-svn-fe$X: svn-fe.o $(VCSSVN_LIB) $(GIT_LIB)
-	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ svn-fe.o \
-		$(ALL_LDFLAGS) $(LIBS)
-
-svn-fe.o: svn-fe.c ../../vcs-svn/svndump.h
-	$(QUIET_CC)$(CC) -I../../vcs-svn -o $*.o -c $(ALL_CFLAGS) $<
-
-svn-fe.html: svn-fe.txt
-	$(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
-		MAN_TXT=../contrib/svn-fe/svn-fe.txt \
-		../contrib/svn-fe/$@
-
-svn-fe.1: svn-fe.txt
-	$(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
-		MAN_TXT=../contrib/svn-fe/svn-fe.txt \
-		../contrib/svn-fe/$@
-	$(MV) ../../Documentation/svn-fe.1 .
-
-../../vcs-svn/lib.a: FORCE
-	$(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) vcs-svn/lib.a
-
-../../libgit.a: FORCE
-	$(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) libgit.a
-
-clean:
-	$(RM) svn-fe$X svn-fe.o svn-fe.html svn-fe.xml svn-fe.1
-
-.PHONY: all clean FORCE
diff --git a/contrib/svn-fe/svn-fe.c b/contrib/svn-fe/svn-fe.c
deleted file mode 100644
index f363505..0000000
--- a/contrib/svn-fe/svn-fe.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * This file is in the public domain.
- * You may freely use, modify, distribute, and relicense it.
- */
-
-#include <stdlib.h>
-#include "svndump.h"
-
-int main(int argc, char **argv)
-{
-	if (svndump_init(NULL))
-		return 1;
-	svndump_read((argc > 1) ? argv[1] : NULL, "refs/heads/master",
-			"refs/notes/svn/revs");
-	svndump_deinit();
-	svndump_reset();
-	return 0;
-}
diff --git a/contrib/svn-fe/svn-fe.txt b/contrib/svn-fe/svn-fe.txt
deleted file mode 100644
index a3425f4..0000000
--- a/contrib/svn-fe/svn-fe.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-svn-fe(1)
-=========
-
-NAME
-----
-svn-fe - convert an SVN "dumpfile" to a fast-import stream
-
-SYNOPSIS
---------
-[verse]
-mkfifo backchannel &&
-svnadmin dump --deltas REPO |
-	svn-fe [url] 3<backchannel |
-	git fast-import --cat-blob-fd=3 3>backchannel
-
-DESCRIPTION
------------
-
-Converts a Subversion dumpfile into input suitable for
-git-fast-import(1) and similar importers. REPO is a path to a
-Subversion repository mirrored on the local disk. Remote Subversion
-repositories can be mirrored on local disk using the `svnsync`
-command.
-
-Note: this tool is very young.  The details of its commandline
-interface may change in backward incompatible ways.
-
-INPUT FORMAT
-------------
-Subversion's repository dump format is documented in full in
-`notes/dump-load-format.txt` from the Subversion source tree.
-Files in this format can be generated using the 'svnadmin dump' or
-'svk admin dump' command.
-
-OUTPUT FORMAT
--------------
-The fast-import format is documented by the git-fast-import(1)
-manual page.
-
-NOTES
------
-Subversion dumps do not record a separate author and committer for
-each revision, nor do they record a separate display name and email
-address for each author.  Like git-svn(1), 'svn-fe' will use the name
-
----------
-user <user@UUID>
----------
-
-as committer, where 'user' is the value of the `svn:author` property
-and 'UUID' the repository's identifier.
-
-To support incremental imports, 'svn-fe' puts a `git-svn-id` line at
-the end of each commit log message if passed a URL on the command
-line.  This line has the form `git-svn-id: URL@REVNO UUID`.
-
-The resulting repository will generally require further processing
-to put each project in its own repository and to separate the history
-of each branch.  The 'git filter-branch --subdirectory-filter' command
-may be useful for this purpose.
-
-BUGS
-----
-Empty directories and unknown properties are silently discarded.
-
-The exit status does not reflect whether an error was detected.
-
-SEE ALSO
---------
-git-svn(1), svn2git(1), svk(1), git-filter-branch(1), git-fast-import(1),
-https://svn.apache.org/repos/asf/subversion/trunk/notes/dump-load-format.txt
diff --git a/contrib/svn-fe/svnrdump_sim.py b/contrib/svn-fe/svnrdump_sim.py
deleted file mode 100755
index 4e78a1c..0000000
--- a/contrib/svn-fe/svnrdump_sim.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/python
-"""
-Simulates svnrdump by replaying an existing dump from a file, taking care
-of the specified revision range.
-To simulate incremental imports the environment variable SVNRMAX can be set
-to the highest revision that should be available.
-"""
-import sys, os
-
-if sys.hexversion < 0x02040000:
-        # The limiter is the ValueError() calls. This may be too conservative
-        sys.stderr.write("svnrdump-sim.py: requires Python 2.4 or later.\n")
-        sys.exit(1)
-
-def getrevlimit():
-        var = 'SVNRMAX'
-        if var in os.environ:
-                return os.environ[var]
-        return None
-
-def writedump(url, lower, upper):
-        if url.startswith('sim://'):
-                filename = url[6:]
-                if filename[-1] == '/': filename = filename[:-1] #remove terminating slash
-        else:
-                raise ValueError('sim:// url required')
-        f = open(filename, 'r');
-        state = 'header'
-        wroterev = False
-        while(True):
-                l = f.readline()
-                if l == '': break
-                if state == 'header' and l.startswith('Revision-number: '):
-                        state = 'prefix'
-                if state == 'prefix' and l == 'Revision-number: %s\n' % lower:
-                        state = 'selection'
-                if not upper == 'HEAD' and state == 'selection' and l == 'Revision-number: %s\n' % upper:
-                        break;
-
-                if state == 'header' or state == 'selection':
-                        if state == 'selection': wroterev = True
-                        sys.stdout.write(l)
-        return wroterev
-
-if __name__ == "__main__":
-        if not (len(sys.argv) in (3, 4, 5)):
-                print("usage: %s dump URL -rLOWER:UPPER")
-                sys.exit(1)
-        if not sys.argv[1] == 'dump': raise NotImplementedError('only "dump" is suppported.')
-        url = sys.argv[2]
-        r = ('0', 'HEAD')
-        if len(sys.argv) == 4 and sys.argv[3][0:2] == '-r':
-                r = sys.argv[3][2:].lstrip().split(':')
-        if not getrevlimit() is None: r[1] = getrevlimit()
-        if writedump(url, r[0], r[1]): ret = 0
-        else: ret = 1
-        sys.exit(ret)
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 13/17] contrib: remove 'rerere-train'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (10 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 12/17] contrib: remove 'svn-fe' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 14/17] contrib: remove 'remotes2config' Felipe Contreras
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No activity, no nothing.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/rerere-train.sh | 52 -------------------------------------------------
 1 file changed, 52 deletions(-)
 delete mode 100755 contrib/rerere-train.sh

diff --git a/contrib/rerere-train.sh b/contrib/rerere-train.sh
deleted file mode 100755
index 36b6fee..0000000
--- a/contrib/rerere-train.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/sh
-# Copyright (c) 2008, Nanako Shiraishi
-# Prime rerere database from existing merge commits
-
-me=rerere-train
-USAGE="$me rev-list-args"
-
-SUBDIRECTORY_OK=Yes
-OPTIONS_SPEC=
-. $(git --exec-path)/git-sh-setup
-require_work_tree
-cd_to_toplevel
-
-# Remember original branch
-branch=$(git symbolic-ref -q HEAD) ||
-original_HEAD=$(git rev-parse --verify HEAD) || {
-	echo >&2 "Not on any branch and no commit yet?"
-	exit 1
-}
-
-mkdir -p "$GIT_DIR/rr-cache" || exit
-
-git rev-list --parents "$@" |
-while read commit parent1 other_parents
-do
-	if test -z "$other_parents"
-	then
-		# Skip non-merges
-		continue
-	fi
-	git checkout -q "$parent1^0"
-	if git merge $other_parents >/dev/null 2>&1
-	then
-		# Cleanly merges
-		continue
-	fi
-	if test -s "$GIT_DIR/MERGE_RR"
-	then
-		git show -s --pretty=format:"Learning from %h %s" "$commit"
-		git rerere
-		git checkout -q $commit -- .
-		git rerere
-	fi
-	git reset -q --hard
-done
-
-if test -z "$branch"
-then
-	git checkout "$original_HEAD"
-else
-	git checkout "${branch#refs/heads/}"
-fi
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 14/17] contrib: remove 'remotes2config'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (11 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 13/17] contrib: remove 'rerere-train' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 15/17] contrib: remove 'persistent-https' Felipe Contreras
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No activity since 2007. No documentation, no tests.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remotes2config.sh | 33 ---------------------------------
 1 file changed, 33 deletions(-)
 delete mode 100755 contrib/remotes2config.sh

diff --git a/contrib/remotes2config.sh b/contrib/remotes2config.sh
deleted file mode 100755
index 1cda19f..0000000
--- a/contrib/remotes2config.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-# Use this tool to rewrite your .git/remotes/ files into the config.
-
-. git-sh-setup
-
-if [ -d "$GIT_DIR"/remotes ]; then
-	echo "Rewriting $GIT_DIR/remotes" >&2
-	error=0
-	# rewrite into config
-	{
-		cd "$GIT_DIR"/remotes
-		ls | while read f; do
-			name=$(printf "$f" | tr -c "A-Za-z0-9-" ".")
-			sed -n \
-			-e "s/^URL:[ 	]*\(.*\)$/remote.$name.url \1 ./p" \
-			-e "s/^Pull:[ 	]*\(.*\)$/remote.$name.fetch \1 ^$ /p" \
-			-e "s/^Push:[ 	]*\(.*\)$/remote.$name.push \1 ^$ /p" \
-			< "$f"
-		done
-		echo done
-	} | while read key value regex; do
-		case $key in
-		done)
-			if [ $error = 0 ]; then
-				mv "$GIT_DIR"/remotes "$GIT_DIR"/remotes.old
-			fi ;;
-		*)
-			echo "git config $key "$value" $regex"
-			git config $key "$value" $regex || error=1 ;;
-		esac
-	done
-fi
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 15/17] contrib: remove 'persistent-https'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (12 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 14/17] contrib: remove 'remotes2config' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 16/17] contrib: remove 'git-resurrect' Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 17/17] contrib: remove 'contacts' Felipe Contreras
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras, Colby Ranger

No activity. No tests.

No chance of ever moving into the core because it uses Go.

Cc: Colby Ranger <cranger@google.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/persistent-https/LICENSE   | 202 -------------------------------------
 contrib/persistent-https/Makefile  |  38 -------
 contrib/persistent-https/README    |  62 ------------
 contrib/persistent-https/client.go | 189 ----------------------------------
 contrib/persistent-https/main.go   |  82 ---------------
 contrib/persistent-https/proxy.go  | 190 ----------------------------------
 contrib/persistent-https/socket.go |  97 ------------------
 7 files changed, 860 deletions(-)
 delete mode 100644 contrib/persistent-https/LICENSE
 delete mode 100644 contrib/persistent-https/Makefile
 delete mode 100644 contrib/persistent-https/README
 delete mode 100644 contrib/persistent-https/client.go
 delete mode 100644 contrib/persistent-https/main.go
 delete mode 100644 contrib/persistent-https/proxy.go
 delete mode 100644 contrib/persistent-https/socket.go

diff --git a/contrib/persistent-https/LICENSE b/contrib/persistent-https/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/contrib/persistent-https/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/contrib/persistent-https/Makefile b/contrib/persistent-https/Makefile
deleted file mode 100644
index 92baa3b..0000000
--- a/contrib/persistent-https/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-BUILD_LABEL=$(shell date +"%s")
-TAR_OUT=$(shell go env GOOS)_$(shell go env GOARCH).tar.gz
-
-all: git-remote-persistent-https git-remote-persistent-https--proxy \
-	git-remote-persistent-http
-
-git-remote-persistent-https--proxy: git-remote-persistent-https
-	ln -f -s git-remote-persistent-https git-remote-persistent-https--proxy
-
-git-remote-persistent-http: git-remote-persistent-https
-	ln -f -s git-remote-persistent-https git-remote-persistent-http
-
-git-remote-persistent-https:
-	go build -o git-remote-persistent-https \
-		-ldflags "-X main._BUILD_EMBED_LABEL $(BUILD_LABEL)"
-
-clean:
-	rm -f git-remote-persistent-http* *.tar.gz
-
-tar: clean all
-	@chmod 555 git-remote-persistent-https
-	@tar -czf $(TAR_OUT) git-remote-persistent-http* README LICENSE
-	@echo
-	@echo "Created $(TAR_OUT)"
diff --git a/contrib/persistent-https/README b/contrib/persistent-https/README
deleted file mode 100644
index f784dd2..0000000
--- a/contrib/persistent-https/README
+++ /dev/null
@@ -1,62 +0,0 @@
-git-remote-persistent-https
-
-The git-remote-persistent-https binary speeds up SSL operations
-by running a daemon job (git-remote-persistent-https--proxy) that
-keeps a connection open to a server.
-
-
-PRE-BUILT BINARIES
-
-Darwin amd64:
-https://commondatastorage.googleapis.com/git-remote-persistent-https/darwin_amd64.tar.gz
-
-Linux amd64:
-https://commondatastorage.googleapis.com/git-remote-persistent-https/linux_amd64.tar.gz
-
-
-INSTALLING
-
-Move all of the git-remote-persistent-http* binaries to a directory
-in PATH.
-
-
-USAGE
-
-HTTPS requests can be delegated to the proxy by using the
-"persistent-https" scheme, e.g.
-
-git clone persistent-https://kernel.googlesource.com/pub/scm/git/git
-
-Likewise, .gitconfig can be updated as follows to rewrite https urls
-to use persistent-https:
-
-[url "persistent-https"]
-	insteadof = https
-[url "persistent-http"]
-	insteadof = http
-
-
-#####################################################################
-# BUILDING FROM SOURCE
-#####################################################################
-
-LOCATION
-
-The source is available in the contrib/persistent-https directory of
-the Git source repository. The Git source repository is available at
-git://git.kernel.org/pub/scm/git/git.git/
-https://kernel.googlesource.com/pub/scm/git/git
-
-
-PREREQUISITES
-
-The code is written in Go (http://golang.org/) and the Go compiler is
-required. Currently, the compiler must be built and installed from tip
-of source, in order to include a fix in the reverse http proxy:
-http://code.google.com/p/go/source/detail?r=a615b796570a2cd8591884767a7d67ede74f6648
-
-
-BUILDING
-
-Run "make" to build the binaries. See the section on
-INSTALLING above.
diff --git a/contrib/persistent-https/client.go b/contrib/persistent-https/client.go
deleted file mode 100644
index 71125b5..0000000
--- a/contrib/persistent-https/client.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"bufio"
-	"errors"
-	"fmt"
-	"net"
-	"net/url"
-	"os"
-	"os/exec"
-	"strings"
-	"syscall"
-	"time"
-)
-
-type Client struct {
-	ProxyBin string
-	Args     []string
-
-	insecure bool
-}
-
-func (c *Client) Run() error {
-	if err := c.resolveArgs(); err != nil {
-		return fmt.Errorf("resolveArgs() got error: %v", err)
-	}
-
-	// Connect to the proxy.
-	uconn, hconn, addr, err := c.connect()
-	if err != nil {
-		return fmt.Errorf("connect() got error: %v", err)
-	}
-	// Keep the unix socket connection open for the duration of the request.
-	defer uconn.Close()
-	// Keep a connection to the HTTP server open, so no other user can
-	// bind on the same address so long as the process is running.
-	defer hconn.Close()
-
-	// Start the git-remote-http subprocess.
-	cargs := []string{"-c", fmt.Sprintf("http.proxy=%v", addr), "remote-http"}
-	cargs = append(cargs, c.Args...)
-	cmd := exec.Command("git", cargs...)
-
-	for _, v := range os.Environ() {
-		if !strings.HasPrefix(v, "GIT_PERSISTENT_HTTPS_SECURE=") {
-			cmd.Env = append(cmd.Env, v)
-		}
-	}
-	// Set the GIT_PERSISTENT_HTTPS_SECURE environment variable when
-	// the proxy is using a SSL connection.  This allows credential helpers
-	// to identify secure proxy connections, despite being passed an HTTP
-	// scheme.
-	if !c.insecure {
-		cmd.Env = append(cmd.Env, "GIT_PERSISTENT_HTTPS_SECURE=1")
-	}
-
-	cmd.Stdin = os.Stdin
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	if err := cmd.Run(); err != nil {
-		if eerr, ok := err.(*exec.ExitError); ok {
-			if stat, ok := eerr.ProcessState.Sys().(syscall.WaitStatus); ok && stat.ExitStatus() != 0 {
-				os.Exit(stat.ExitStatus())
-			}
-		}
-		return fmt.Errorf("git-remote-http subprocess got error: %v", err)
-	}
-	return nil
-}
-
-func (c *Client) connect() (uconn net.Conn, hconn net.Conn, addr string, err error) {
-	uconn, err = DefaultSocket.Dial()
-	if err != nil {
-		if e, ok := err.(*net.OpError); ok && (os.IsNotExist(e.Err) || e.Err == syscall.ECONNREFUSED) {
-			if err = c.startProxy(); err == nil {
-				uconn, err = DefaultSocket.Dial()
-			}
-		}
-		if err != nil {
-			return
-		}
-	}
-
-	if addr, err = c.readAddr(uconn); err != nil {
-		return
-	}
-
-	// Open a tcp connection to the proxy.
-	if hconn, err = net.Dial("tcp", addr); err != nil {
-		return
-	}
-
-	// Verify the address hasn't changed ownership.
-	var addr2 string
-	if addr2, err = c.readAddr(uconn); err != nil {
-		return
-	} else if addr != addr2 {
-		err = fmt.Errorf("address changed after connect. got %q, want %q", addr2, addr)
-		return
-	}
-	return
-}
-
-func (c *Client) readAddr(conn net.Conn) (string, error) {
-	conn.SetDeadline(time.Now().Add(5 * time.Second))
-	data := make([]byte, 100)
-	n, err := conn.Read(data)
-	if err != nil {
-		return "", fmt.Errorf("error reading unix socket: %v", err)
-	} else if n == 0 {
-		return "", errors.New("empty data response")
-	}
-	conn.Write([]byte{1}) // Ack
-
-	var addr string
-	if addrs := strings.Split(string(data[:n]), "\n"); len(addrs) != 2 {
-		return "", fmt.Errorf("got %q, wanted 2 addresses", data[:n])
-	} else if c.insecure {
-		addr = addrs[1]
-	} else {
-		addr = addrs[0]
-	}
-	return addr, nil
-}
-
-func (c *Client) startProxy() error {
-	cmd := exec.Command(c.ProxyBin)
-	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
-	stdout, err := cmd.StdoutPipe()
-	if err != nil {
-		return err
-	}
-	defer stdout.Close()
-	if err := cmd.Start(); err != nil {
-		return err
-	}
-	result := make(chan error)
-	go func() {
-		bytes, _, err := bufio.NewReader(stdout).ReadLine()
-		if line := string(bytes); err == nil && line != "OK" {
-			err = fmt.Errorf("proxy returned %q, want \"OK\"", line)
-		}
-		result <- err
-	}()
-	select {
-	case err := <-result:
-		return err
-	case <-time.After(5 * time.Second):
-		return errors.New("timeout waiting for proxy to start")
-	}
-	panic("not reachable")
-}
-
-func (c *Client) resolveArgs() error {
-	if nargs := len(c.Args); nargs == 0 {
-		return errors.New("remote needed")
-	} else if nargs > 2 {
-		return fmt.Errorf("want at most 2 args, got %v", c.Args)
-	}
-
-	// Rewrite the url scheme to be http.
-	idx := len(c.Args) - 1
-	rawurl := c.Args[idx]
-	rurl, err := url.Parse(rawurl)
-	if err != nil {
-		return fmt.Errorf("invalid remote: %v", err)
-	}
-	c.insecure = rurl.Scheme == "persistent-http"
-	rurl.Scheme = "http"
-	c.Args[idx] = rurl.String()
-	if idx != 0 && c.Args[0] == rawurl {
-		c.Args[0] = c.Args[idx]
-	}
-	return nil
-}
diff --git a/contrib/persistent-https/main.go b/contrib/persistent-https/main.go
deleted file mode 100644
index fd1b107..0000000
--- a/contrib/persistent-https/main.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// The git-remote-persistent-https binary speeds up SSL operations by running
-// a daemon job that keeps a connection open to a Git server. This ensures the
-// git-remote-persistent-https--proxy is running and delegating execution
-// to the git-remote-http binary with the http_proxy set to the daemon job.
-// A unix socket is used to authenticate the proxy and discover the
-// HTTP address. Note, both the client and proxy are included in the same
-// binary.
-package main
-
-import (
-	"flag"
-	"fmt"
-	"log"
-	"os"
-	"strings"
-	"time"
-)
-
-var (
-	forceProxy = flag.Bool("proxy", false, "Whether to start the binary in proxy mode")
-	proxyBin   = flag.String("proxy_bin", "git-remote-persistent-https--proxy", "Path to the proxy binary")
-	printLabel = flag.Bool("print_label", false, "Prints the build label for the binary")
-
-	// Variable that should be defined through the -X linker flag.
-	_BUILD_EMBED_LABEL string
-)
-
-const (
-	defaultMaxIdleDuration    = 24 * time.Hour
-	defaultPollUpdateInterval = 15 * time.Minute
-)
-
-func main() {
-	flag.Parse()
-	if *printLabel {
-		// Short circuit execution to print the build label
-		fmt.Println(buildLabel())
-		return
-	}
-
-	var err error
-	if *forceProxy || strings.HasSuffix(os.Args[0], "--proxy") {
-		log.SetPrefix("git-remote-persistent-https--proxy: ")
-		proxy := &Proxy{
-			BuildLabel:         buildLabel(),
-			MaxIdleDuration:    defaultMaxIdleDuration,
-			PollUpdateInterval: defaultPollUpdateInterval,
-		}
-		err = proxy.Run()
-	} else {
-		log.SetPrefix("git-remote-persistent-https: ")
-		client := &Client{
-			ProxyBin: *proxyBin,
-			Args:     flag.Args(),
-		}
-		err = client.Run()
-	}
-	if err != nil {
-		log.Fatalln(err)
-	}
-}
-
-func buildLabel() string {
-	if _BUILD_EMBED_LABEL == "" {
-		log.Println(`unlabeled build; build with "make" to label`)
-	}
-	return _BUILD_EMBED_LABEL
-}
diff --git a/contrib/persistent-https/proxy.go b/contrib/persistent-https/proxy.go
deleted file mode 100644
index bb0cdba..0000000
--- a/contrib/persistent-https/proxy.go
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"fmt"
-	"log"
-	"net"
-	"net/http"
-	"net/http/httputil"
-	"os"
-	"os/exec"
-	"os/signal"
-	"sync"
-	"syscall"
-	"time"
-)
-
-type Proxy struct {
-	BuildLabel         string
-	MaxIdleDuration    time.Duration
-	PollUpdateInterval time.Duration
-
-	ul        net.Listener
-	httpAddr  string
-	httpsAddr string
-}
-
-func (p *Proxy) Run() error {
-	hl, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		return fmt.Errorf("http listen failed: %v", err)
-	}
-	defer hl.Close()
-
-	hsl, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		return fmt.Errorf("https listen failed: %v", err)
-	}
-	defer hsl.Close()
-
-	p.ul, err = DefaultSocket.Listen()
-	if err != nil {
-		c, derr := DefaultSocket.Dial()
-		if derr == nil {
-			c.Close()
-			fmt.Println("OK\nA proxy is already running... exiting")
-			return nil
-		} else if e, ok := derr.(*net.OpError); ok && e.Err == syscall.ECONNREFUSED {
-			// Nothing is listening on the socket, unlink it and try again.
-			syscall.Unlink(DefaultSocket.Path())
-			p.ul, err = DefaultSocket.Listen()
-		}
-		if err != nil {
-			return fmt.Errorf("unix listen failed on %v: %v", DefaultSocket.Path(), err)
-		}
-	}
-	defer p.ul.Close()
-	go p.closeOnSignal()
-	go p.closeOnUpdate()
-
-	p.httpAddr = hl.Addr().String()
-	p.httpsAddr = hsl.Addr().String()
-	fmt.Printf("OK\nListening on unix socket=%v http=%v https=%v\n",
-		p.ul.Addr(), p.httpAddr, p.httpsAddr)
-
-	result := make(chan error, 2)
-	go p.serveUnix(result)
-	go func() {
-		result <- http.Serve(hl, &httputil.ReverseProxy{
-			FlushInterval: 500 * time.Millisecond,
-			Director:      func(r *http.Request) {},
-		})
-	}()
-	go func() {
-		result <- http.Serve(hsl, &httputil.ReverseProxy{
-			FlushInterval: 500 * time.Millisecond,
-			Director: func(r *http.Request) {
-				r.URL.Scheme = "https"
-			},
-		})
-	}()
-	return <-result
-}
-
-type socketContext struct {
-	sync.WaitGroup
-	mutex sync.Mutex
-	last  time.Time
-}
-
-func (sc *socketContext) Done() {
-	sc.mutex.Lock()
-	defer sc.mutex.Unlock()
-	sc.last = time.Now()
-	sc.WaitGroup.Done()
-}
-
-func (p *Proxy) serveUnix(result chan<- error) {
-	sockCtx := &socketContext{}
-	go p.closeOnIdle(sockCtx)
-
-	var err error
-	for {
-		var uconn net.Conn
-		uconn, err = p.ul.Accept()
-		if err != nil {
-			err = fmt.Errorf("accept failed: %v", err)
-			break
-		}
-		sockCtx.Add(1)
-		go p.handleUnixConn(sockCtx, uconn)
-	}
-	sockCtx.Wait()
-	result <- err
-}
-
-func (p *Proxy) handleUnixConn(sockCtx *socketContext, uconn net.Conn) {
-	defer sockCtx.Done()
-	defer uconn.Close()
-	data := []byte(fmt.Sprintf("%v\n%v", p.httpsAddr, p.httpAddr))
-	uconn.SetDeadline(time.Now().Add(5 * time.Second))
-	for i := 0; i < 2; i++ {
-		if n, err := uconn.Write(data); err != nil {
-			log.Printf("error sending http addresses: %+v\n", err)
-			return
-		} else if n != len(data) {
-			log.Printf("sent %d data bytes, wanted %d\n", n, len(data))
-			return
-		}
-		if _, err := uconn.Read([]byte{0, 0, 0, 0}); err != nil {
-			log.Printf("error waiting for Ack: %+v\n", err)
-			return
-		}
-	}
-	// Wait without a deadline for the client to finish via EOF
-	uconn.SetDeadline(time.Time{})
-	uconn.Read([]byte{0, 0, 0, 0})
-}
-
-func (p *Proxy) closeOnIdle(sockCtx *socketContext) {
-	for d := p.MaxIdleDuration; d > 0; {
-		time.Sleep(d)
-		sockCtx.Wait()
-		sockCtx.mutex.Lock()
-		if d = sockCtx.last.Add(p.MaxIdleDuration).Sub(time.Now()); d <= 0 {
-			log.Println("graceful shutdown from idle timeout")
-			p.ul.Close()
-		}
-		sockCtx.mutex.Unlock()
-	}
-}
-
-func (p *Proxy) closeOnUpdate() {
-	for {
-		time.Sleep(p.PollUpdateInterval)
-		if out, err := exec.Command(os.Args[0], "--print_label").Output(); err != nil {
-			log.Printf("error polling for updated binary: %v\n", err)
-		} else if s := string(out[:len(out)-1]); p.BuildLabel != s {
-			log.Printf("graceful shutdown from updated binary: %q --> %q\n", p.BuildLabel, s)
-			p.ul.Close()
-			break
-		}
-	}
-}
-
-func (p *Proxy) closeOnSignal() {
-	ch := make(chan os.Signal, 10)
-	signal.Notify(ch, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM), os.Signal(syscall.SIGHUP))
-	sig := <-ch
-	p.ul.Close()
-	switch sig {
-	case os.Signal(syscall.SIGHUP):
-		log.Printf("graceful shutdown from signal: %v\n", sig)
-	default:
-		log.Fatalf("exiting from signal: %v\n", sig)
-	}
-}
diff --git a/contrib/persistent-https/socket.go b/contrib/persistent-https/socket.go
deleted file mode 100644
index 193b911..0000000
--- a/contrib/persistent-https/socket.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"fmt"
-	"log"
-	"net"
-	"os"
-	"path/filepath"
-	"syscall"
-)
-
-// A Socket is a wrapper around a Unix socket that verifies directory
-// permissions.
-type Socket struct {
-	Dir string
-}
-
-func defaultDir() string {
-	sockPath := ".git-credential-cache"
-	if home := os.Getenv("HOME"); home != "" {
-		return filepath.Join(home, sockPath)
-	}
-	log.Printf("socket: cannot find HOME path. using relative directory %q for socket", sockPath)
-	return sockPath
-}
-
-// DefaultSocket is a Socket in the $HOME/.git-credential-cache directory.
-var DefaultSocket = Socket{Dir: defaultDir()}
-
-// Listen announces the local network address of the unix socket. The
-// permissions on the socket directory are verified before attempting
-// the actual listen.
-func (s Socket) Listen() (net.Listener, error) {
-	network, addr := "unix", s.Path()
-	if err := s.mkdir(); err != nil {
-		return nil, &net.OpError{Op: "listen", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
-	}
-	return net.Listen(network, addr)
-}
-
-// Dial connects to the unix socket. The permissions on the socket directory
-// are verified before attempting the actual dial.
-func (s Socket) Dial() (net.Conn, error) {
-	network, addr := "unix", s.Path()
-	if err := s.checkPermissions(); err != nil {
-		return nil, &net.OpError{Op: "dial", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
-	}
-	return net.Dial(network, addr)
-}
-
-// Path returns the fully specified file name of the unix socket.
-func (s Socket) Path() string {
-	return filepath.Join(s.Dir, "persistent-https-proxy-socket")
-}
-
-func (s Socket) mkdir() error {
-	if err := s.checkPermissions(); err == nil {
-		return nil
-	} else if !os.IsNotExist(err) {
-		return err
-	}
-	if err := os.MkdirAll(s.Dir, 0700); err != nil {
-		return err
-	}
-	return s.checkPermissions()
-}
-
-func (s Socket) checkPermissions() error {
-	fi, err := os.Stat(s.Dir)
-	if err != nil {
-		return err
-	}
-	if !fi.IsDir() {
-		return fmt.Errorf("socket: got file, want directory for %q", s.Dir)
-	}
-	if fi.Mode().Perm() != 0700 {
-		return fmt.Errorf("socket: got perm %o, want 700 for %q", fi.Mode().Perm(), s.Dir)
-	}
-	if st := fi.Sys().(*syscall.Stat_t); int(st.Uid) != os.Getuid() {
-		return fmt.Errorf("socket: got uid %d, want %d for %q", st.Uid, os.Getuid(), s.Dir)
-	}
-	return nil
-}
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 16/17] contrib: remove 'git-resurrect'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (13 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 15/17] contrib: remove 'persistent-https' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  2014-05-09 19:11 ` [PATCH v2 17/17] contrib: remove 'contacts' Felipe Contreras
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras

No activity, no documentation, no tests, no chance of ever graduating.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/git-resurrect.sh | 182 -----------------------------------------------
 1 file changed, 182 deletions(-)
 delete mode 100755 contrib/git-resurrect.sh

diff --git a/contrib/git-resurrect.sh b/contrib/git-resurrect.sh
deleted file mode 100755
index d7e97bb..0000000
--- a/contrib/git-resurrect.sh
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/bin/sh
-
-USAGE="[-a] [-r] [-m] [-t] [-n] [-b <newname>] <name>"
-LONG_USAGE="git-resurrect attempts to find traces of a branch tip
-called <name>, and tries to resurrect it.  Currently, the reflog is
-searched for checkout messages, and with -r also merge messages.  With
--m and -t, the history of all refs is scanned for Merge <name> into
-other/Merge <other> into <name> (respectively) commit subjects, which
-is rather slow but allows you to resurrect other people's topic
-branches."
-
-OPTIONS_KEEPDASHDASH=
-OPTIONS_STUCKLONG=
-OPTIONS_SPEC="\
-git resurrect $USAGE
---
-b,branch=            save branch as <newname> instead of <name>
-a,all                same as -l -r -m -t
-k,keep-going         full rev-list scan (instead of first match)
-l,reflog             scan reflog for checkouts (enabled by default)
-r,reflog-merges      scan for merges recorded in reflog
-m,merges             scan for merges into other branches (slow)
-t,merge-targets      scan for merges of other branches into <name>
-n,dry-run            don't recreate the branch"
-
-. git-sh-setup
-
-search_reflog () {
-        sed -ne 's~^\([^ ]*\) .*\tcheckout: moving from '"$1"' .*~\1~p' \
-                < "$GIT_DIR"/logs/HEAD
-}
-
-search_reflog_merges () {
-	git rev-parse $(
-		sed -ne 's~^[^ ]* \([^ ]*\) .*\tmerge '"$1"':.*~\1^2~p' \
-			< "$GIT_DIR"/logs/HEAD
-	)
-}
-
-_x40="[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]"
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
-
-search_merges () {
-        git rev-list --all --grep="Merge branch '$1'" \
-                --pretty=tformat:"%P %s" |
-        sed -ne "/^$_x40 \($_x40\) Merge .*/ {s//\1/p;$early_exit}"
-}
-
-search_merge_targets () {
-	git rev-list --all --grep="Merge branch '[^']*' into $branch\$" \
-		--pretty=tformat:"%H %s" --all |
-	sed -ne "/^\($_x40\) Merge .*/ {s//\1/p;$early_exit} "
-}
-
-dry_run=
-early_exit=q
-scan_reflog=t
-scan_reflog_merges=
-scan_merges=
-scan_merge_targets=
-new_name=
-
-while test "$#" != 0; do
-	case "$1" in
-	    -b|--branch)
-		shift
-		new_name="$1"
-		;;
-	    -n|--dry-run)
-		dry_run=t
-		;;
-	    --no-dry-run)
-		dry_run=
-		;;
-	    -k|--keep-going)
-		early_exit=
-		;;
-	    --no-keep-going)
-		early_exit=q
-		;;
-	    -m|--merges)
-		scan_merges=t
-		;;
-	    --no-merges)
-		scan_merges=
-		;;
-	    -l|--reflog)
-		scan_reflog=t
-		;;
-	    --no-reflog)
-		scan_reflog=
-		;;
-	    -r|--reflog_merges)
-		scan_reflog_merges=t
-		;;
-	    --no-reflog_merges)
-		scan_reflog_merges=
-		;;
-	    -t|--merge-targets)
-		scan_merge_targets=t
-		;;
-	    --no-merge-targets)
-		scan_merge_targets=
-		;;
-	    -a|--all)
-		scan_reflog=t
-		scan_reflog_merges=t
-		scan_merges=t
-		scan_merge_targets=t
-		;;
-	    --)
-		shift
-		break
-		;;
-	    *)
-		usage
-		;;
-	esac
-	shift
-done
-
-test "$#" = 1 || usage
-
-all_strategies="$scan_reflog$scan_reflog_merges$scan_merges$scan_merge_targets"
-if test -z "$all_strategies"; then
-	die "must enable at least one of -lrmt"
-fi
-
-branch="$1"
-test -z "$new_name" && new_name="$branch"
-
-if test ! -z "$scan_reflog"; then
-	if test -r "$GIT_DIR"/logs/HEAD; then
-		candidates="$(search_reflog $branch)"
-	else
-		die 'reflog scanning requested, but' \
-			'$GIT_DIR/logs/HEAD not readable'
-	fi
-fi
-if test ! -z "$scan_reflog_merges"; then
-	if test -r "$GIT_DIR"/logs/HEAD; then
-		candidates="$candidates $(search_reflog_merges $branch)"
-	else
-		die 'reflog scanning requested, but' \
-			'$GIT_DIR/logs/HEAD not readable'
-	fi
-fi
-if test ! -z "$scan_merges"; then
-	candidates="$candidates $(search_merges $branch)"
-fi
-if test ! -z "$scan_merge_targets"; then
-	candidates="$candidates $(search_merge_targets $branch)"
-fi
-
-candidates="$(git rev-parse $candidates | sort -u)"
-
-if test -z "$candidates"; then
-	hint=
-	test "z$all_strategies" != "ztttt" \
-		&& hint=" (maybe try again with -a)"
-	die "no candidates for $branch found$hint"
-fi
-
-echo "** Candidates for $branch **"
-for cmt in $candidates; do
-	git --no-pager log --pretty=tformat:"%ct:%h [%cr] %s" --abbrev-commit -1 $cmt
-done \
-| sort -n | cut -d: -f2-
-
-newest="$(git rev-list -1 $candidates)"
-if test ! -z "$dry_run"; then
-	printf "** Most recent: "
-	git --no-pager log -1 --pretty=tformat:"%h %s" $newest
-elif ! git rev-parse --verify --quiet $new_name >/dev/null; then
-	printf "** Restoring $new_name to "
-	git --no-pager log -1 --pretty=tformat:"%h %s" $newest
-	git branch $new_name $newest
-else
-	printf "Most recent: "
-	git --no-pager log -1 --pretty=tformat:"%h %s" $newest
-	echo "** $new_name already exists, doing nothing"
-fi
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 17/17] contrib: remove 'contacts'
  2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
                   ` (14 preceding siblings ...)
  2014-05-09 19:11 ` [PATCH v2 16/17] contrib: remove 'git-resurrect' Felipe Contreras
@ 2014-05-09 19:11 ` Felipe Contreras
  15 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 19:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Felipe Contreras, Eric Sunshine

There are better out-of-tree tools, and this tool is not planned to move
into the core anyway.

No tests either.

Cc: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/contacts/git-contacts     | 203 --------------------------------------
 contrib/contacts/git-contacts.txt |  94 ------------------
 2 files changed, 297 deletions(-)
 delete mode 100755 contrib/contacts/git-contacts
 delete mode 100644 contrib/contacts/git-contacts.txt

diff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts
deleted file mode 100755
index dbe2abf..0000000
--- a/contrib/contacts/git-contacts
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/perl
-
-# List people who might be interested in a patch.  Useful as the argument to
-# git-send-email --cc-cmd option, and in other situations.
-#
-# Usage: git contacts <file | rev-list option> ...
-
-use strict;
-use warnings;
-use IPC::Open2;
-
-my $since = '5-years-ago';
-my $min_percent = 10;
-my $labels_rx = qr/Signed-off-by|Reviewed-by|Acked-by|Cc/i;
-my %seen;
-
-sub format_contact {
-	my ($name, $email) = @_;
-	return "$name <$email>";
-}
-
-sub parse_commit {
-	my ($commit, $data) = @_;
-	my $contacts = $commit->{contacts};
-	my $inbody = 0;
-	for (split(/^/m, $data)) {
-		if (not $inbody) {
-			if (/^author ([^<>]+) <(\S+)> .+$/) {
-				$contacts->{format_contact($1, $2)} = 1;
-			} elsif (/^$/) {
-				$inbody = 1;
-			}
-		} elsif (/^$labels_rx:\s+([^<>]+)\s+<(\S+?)>$/o) {
-			$contacts->{format_contact($1, $2)} = 1;
-		}
-	}
-}
-
-sub import_commits {
-	my ($commits) = @_;
-	return unless %$commits;
-	my $pid = open2 my $reader, my $writer, qw(git cat-file --batch);
-	for my $id (keys(%$commits)) {
-		print $writer "$id\n";
-		my $line = <$reader>;
-		if ($line =~ /^([0-9a-f]{40}) commit (\d+)/) {
-			my ($cid, $len) = ($1, $2);
-			die "expected $id but got $cid\n" unless $id eq $cid;
-			my $data;
-			# cat-file emits newline after data, so read len+1
-			read $reader, $data, $len + 1;
-			parse_commit($commits->{$id}, $data);
-		}
-	}
-	close $reader;
-	close $writer;
-	waitpid($pid, 0);
-	die "git-cat-file error: $?\n" if $?;
-}
-
-sub get_blame {
-	my ($commits, $source, $from, $ranges) = @_;
-	return unless @$ranges;
-	open my $f, '-|',
-		qw(git blame --porcelain -C),
-		map({"-L$_->[0],+$_->[1]"} @$ranges),
-		'--since', $since, "$from^", '--', $source or die;
-	while (<$f>) {
-		if (/^([0-9a-f]{40}) \d+ \d+ \d+$/) {
-			my $id = $1;
-			$commits->{$id} = { id => $id, contacts => {} }
-				unless $seen{$id};
-			$seen{$id} = 1;
-		}
-	}
-	close $f;
-}
-
-sub blame_sources {
-	my ($sources, $commits) = @_;
-	for my $s (keys %$sources) {
-		for my $id (keys %{$sources->{$s}}) {
-			get_blame($commits, $s, $id, $sources->{$s}{$id});
-		}
-	}
-}
-
-sub scan_patches {
-	my ($sources, $id, $f) = @_;
-	my $source;
-	while (<$f>) {
-		if (/^From ([0-9a-f]{40}) Mon Sep 17 00:00:00 2001$/) {
-			$id = $1;
-			$seen{$id} = 1;
-		}
-		next unless $id;
-		if (m{^--- (?:a/(.+)|/dev/null)$}) {
-			$source = $1;
-		} elsif (/^@@ -(\d+)(?:,(\d+))?/ && $source) {
-			my $len = defined($2) ? $2 : 1;
-			push @{$sources->{$source}{$id}}, [$1, $len] if $len;
-		}
-	}
-}
-
-sub scan_patch_file {
-	my ($commits, $file) = @_;
-	open my $f, '<', $file or die "read failure: $file: $!\n";
-	scan_patches($commits, undef, $f);
-	close $f;
-}
-
-sub parse_rev_args {
-	my @args = @_;
-	open my $f, '-|',
-		qw(git rev-parse --revs-only --default HEAD --symbolic), @args
-		or die;
-	my @revs;
-	while (<$f>) {
-		chomp;
-		push @revs, $_;
-	}
-	close $f;
-	return @revs if scalar(@revs) != 1;
-	return "^$revs[0]", 'HEAD' unless $revs[0] =~ /^-/;
-	return $revs[0], 'HEAD';
-}
-
-sub scan_rev_args {
-	my ($commits, $args) = @_;
-	my @revs = parse_rev_args(@$args);
-	open my $f, '-|', qw(git rev-list --reverse), @revs or die;
-	while (<$f>) {
-		chomp;
-		my $id = $_;
-		$seen{$id} = 1;
-		open my $g, '-|', qw(git show -C --oneline), $id or die;
-		scan_patches($commits, $id, $g);
-		close $g;
-	}
-	close $f;
-}
-
-sub mailmap_contacts {
-	my ($contacts) = @_;
-	my %mapped;
-	my $pid = open2 my $reader, my $writer, qw(git check-mailmap --stdin);
-	for my $contact (keys(%$contacts)) {
-		print $writer "$contact\n";
-		my $canonical = <$reader>;
-		chomp $canonical;
-		$mapped{$canonical} += $contacts->{$contact};
-	}
-	close $reader;
-	close $writer;
-	waitpid($pid, 0);
-	die "git-check-mailmap error: $?\n" if $?;
-	return \%mapped;
-}
-
-if (!@ARGV) {
-	die "No input revisions or patch files\n";
-}
-
-my (@files, @rev_args);
-for (@ARGV) {
-	if (-e) {
-		push @files, $_;
-	} else {
-		push @rev_args, $_;
-	}
-}
-
-my %sources;
-for (@files) {
-	scan_patch_file(\%sources, $_);
-}
-if (@rev_args) {
-	scan_rev_args(\%sources, \@rev_args)
-}
-
-my $toplevel = `git rev-parse --show-toplevel`;
-chomp $toplevel;
-chdir($toplevel) or die "chdir failure: $toplevel: $!\n";
-
-my %commits;
-blame_sources(\%sources, \%commits);
-import_commits(\%commits);
-
-my $contacts = {};
-for my $commit (values %commits) {
-	for my $contact (keys %{$commit->{contacts}}) {
-		$contacts->{$contact}++;
-	}
-}
-$contacts = mailmap_contacts($contacts);
-
-my $ncommits = scalar(keys %commits);
-for my $contact (keys %$contacts) {
-	my $percent = $contacts->{$contact} * 100 / $ncommits;
-	next if $percent < $min_percent;
-	print "$contact\n";
-}
diff --git a/contrib/contacts/git-contacts.txt b/contrib/contacts/git-contacts.txt
deleted file mode 100644
index dd914d1..0000000
--- a/contrib/contacts/git-contacts.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-git-contacts(1)
-===============
-
-NAME
-----
-git-contacts - List people who might be interested in a set of changes
-
-
-SYNOPSIS
---------
-[verse]
-'git contacts' (<patch>|<range>|<rev>)...
-
-
-DESCRIPTION
------------
-
-Given a set of changes, specified as patch files or revisions, determine people
-who might be interested in those changes.  This is done by consulting the
-history of each patch or revision hunk to find people mentioned by commits
-which touched the lines of files under consideration.
-
-Input consists of one or more patch files or revision arguments.  A revision
-argument can be a range or a single `<rev>` which is interpreted as
-`<rev>..HEAD`, thus the same revision arguments are accepted as for
-linkgit:git-format-patch[1]. Patch files and revision arguments can be combined
-in the same invocation.
-
-This command can be useful for determining the list of people with whom to
-discuss proposed changes, or for finding the list of recipients to Cc: when
-submitting a patch series via `git send-email`. For the latter case, `git
-contacts` can be used as the argument to `git send-email`'s `--cc-cmd` option.
-
-
-DISCUSSION
-----------
-
-`git blame` is invoked for each hunk in a patch file or revision.  For each
-commit mentioned by `git blame`, the commit message is consulted for people who
-authored, reviewed, signed, acknowledged, or were Cc:'d.  Once the list of
-participants is known, each person's relevance is computed by considering how
-many commits mentioned that person compared with the total number of commits
-under consideration.  The final output consists only of participants who exceed
-a minimum threshold of participation.
-
-
-OUTPUT
-------
-
-For each person of interest, a single line is output, terminated by a newline.
-If the person's name is known, ``Name $$<user@host>$$'' is printed; otherwise
-only ``$$<user@host>$$'' is printed.
-
-
-EXAMPLES
---------
-
-* Consult patch files:
-+
-------------
-$ git contacts feature/*.patch
-------------
-
-* Revision range:
-+
-------------
-$ git contacts R1..R2
-------------
-
-* From a single revision to `HEAD`:
-+
-------------
-$ git contacts origin
-------------
-
-* Helper for `git send-email`:
-+
-------------
-$ git send-email --cc-cmd='git contacts' feature/*.patch
-------------
-
-
-LIMITATIONS
------------
-
-Several conditions controlling a person's significance are currently
-hard-coded, such as minimum participation level (10%), blame date-limiting (5
-years), and `-C` level for detecting moved and copied lines (a single `-C`). In
-the future, these conditions may become configurable.
-
-
-GIT
----
-Part of the linkgit:git[1] suite
-- 
1.9.2+fc1.28.g12374c0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 04/17] contrib: remove 'diffall'
  2014-05-09 19:11 ` [PATCH v2 04/17] contrib: remove 'diffall' Felipe Contreras
@ 2014-05-09 19:27   ` Tim Henigan
  0 siblings, 0 replies; 42+ messages in thread
From: Tim Henigan @ 2014-05-09 19:27 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Git Mailing List, Junio C Hamano

On Fri, May 9, 2014 at 12:11 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> There is no more need for this tool since the --dir-dirr option was
> introduced.

s/--dir-dirr/--dir-diff/

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-09 19:11 ` [PATCH v2 01/17] contrib: remove outdated README Felipe Contreras
@ 2014-05-09 19:58   ` Junio C Hamano
  2014-05-09 21:54     ` Felipe Contreras
  0 siblings, 1 reply; 42+ messages in thread
From: Junio C Hamano @ 2014-05-09 19:58 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

Felipe Contreras <felipe.contreras@gmail.com> writes:

> There is no guideline as for what should be part of contrib.
>
> Some tools are actively maintained, others consist of a single commit.
> Some tools have active user-base, some aren't used by anyone. Some tools
> are on the path towards the core, others will never get there. Some
> tools are already out-of-tree and simply mirrored, others probably
> wouldn't survive out-of-tree. Some tools are production-ready, others
> don't even run. Some tools have tests, most don't.
>
> Junio has explained that he wrote this a long time ago, when Git was a
> different beast, now this no longer applies.
>
> The only way to find out if a tool belongs in contrib or not is to as
> Junio.
>
> Cc: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> ---

This is wrong.

The reason I suggested splitting remote-hg out of my tree does not
have anything to do with "removal of disused and inactive" described
in the document.  As written elsewhere, it was a response to

    http://thread.gmane.org/gmane.comp.version-control.git/248063/focus=248457

where you said

    I don't want to do anything for a "contrib" tool.

and in response I suggested that you have an option to make it a
standalone third-party project (and the other option being to stay
in contrib/ but then you have to work well with others just like
other contributors).  With the promotion to the core has already
been ruled out as not an ideal direction in the thread that begins
at this one:

    http://thread.gmane.org/gmane.comp.version-control.git/247660/focus=248167

that is one of the only two alternatives I can offer.  Given that
the Git ecosystem has matured enough to let third-party tools
flourish on their own merit, if you do not want to work on a thing
in contrib/, that is now a more viable option than it used to be.

For tools that are happy to be in contrib/ and are still in use by
users, none of the above would apply.  And what the text says is
still perfectly valid.  There is nothing outdated in it.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-09 19:58   ` Junio C Hamano
@ 2014-05-09 21:54     ` Felipe Contreras
  2014-05-13 18:10       ` Martin Langhoff
  0 siblings, 1 reply; 42+ messages in thread
From: Felipe Contreras @ 2014-05-09 21:54 UTC (permalink / raw)
  To: Junio C Hamano, Felipe Contreras; +Cc: git

Junio C Hamano wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
> 
> > There is no guideline as for what should be part of contrib.
> >
> > Some tools are actively maintained, others consist of a single commit.
> > Some tools have active user-base, some aren't used by anyone. Some tools
> > are on the path towards the core, others will never get there. Some
> > tools are already out-of-tree and simply mirrored, others probably
> > wouldn't survive out-of-tree. Some tools are production-ready, others
> > don't even run. Some tools have tests, most don't.
> >
> > Junio has explained that he wrote this a long time ago, when Git was a
> > different beast, now this no longer applies.
> >
> > The only way to find out if a tool belongs in contrib or not is to as
> > Junio.
> >
> > Cc: Junio C Hamano <gitster@pobox.com>
> > Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
> > ---
> 
> This is wrong.
> 
> The reason I suggested splitting remote-hg out of my tree does not

This particular patch has nothing to do with remote-hg.

> have anything to do with "removal of disused and inactive" described
> in the document.  As written elsewhere, it was a response to
> 
>     http://thread.gmane.org/gmane.comp.version-control.git/248063/focus=248457
> 
> where you said
> 
>     I don't want to do anything for a "contrib" tool.

You are once more twisting the sequence of events.

*First* you blocked any progres towards graduation 2014-05-06, even
though I told you what John Keeping argued wasn't going to happen.

  http://thread.gmane.org/gmane.comp.version-control.git/247660/focus=248242

*After* that I decided not touch git-remote-hg/bzr on your tree any more
2014-05-08.

  http://thread.gmane.org/gmane.comp.version-control.git/248063/focus=248457

Do not attempt to construe the consequence as the cause. You caused it.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-09 21:54     ` Felipe Contreras
@ 2014-05-13 18:10       ` Martin Langhoff
  2014-05-13 18:27         ` Junio C Hamano
  0 siblings, 1 reply; 42+ messages in thread
From: Martin Langhoff @ 2014-05-13 18:10 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Junio C Hamano, Git Mailing List

On Fri, May 9, 2014 at 5:54 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> You are once more twisting the sequence of events.

Found this gem looking for background to the proposed removal to code of mine.

Felipe, if you are wanting to have a war of words with Junio, go have
it, with him. I don't know (nor care) who's right, I'll just buy
popcorn.

If you are going to bother every maintainer under contrib over a
problem they have nothing to do with, you'll make an enemy of the
whole group. I think you're doing fantastic on that track.

Right now, you're acting as a remarkable troll.




m
-- 
 martin.langhoff@gmail.com
 -  ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 ~ http://docs.moodle.org/en/User:Martin_Langhoff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-13 18:10       ` Martin Langhoff
@ 2014-05-13 18:27         ` Junio C Hamano
  2014-05-13 18:54           ` Felipe Contreras
  0 siblings, 1 reply; 42+ messages in thread
From: Junio C Hamano @ 2014-05-13 18:27 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: Felipe Contreras, Git Mailing List

Martin Langhoff <martin.langhoff@gmail.com> writes:

> On Fri, May 9, 2014 at 5:54 PM, Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>> You are once more twisting the sequence of events.
>
> Found this gem looking for background to the proposed removal to code of mine.
>
> Felipe, if you are wanting to have a war of words with Junio, go have
> it, with him.

Please don't feed the troll.  I was happy to be done with it.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-13 18:27         ` Junio C Hamano
@ 2014-05-13 18:54           ` Felipe Contreras
  2014-05-13 21:05             ` Junio C Hamano
  0 siblings, 1 reply; 42+ messages in thread
From: Felipe Contreras @ 2014-05-13 18:54 UTC (permalink / raw)
  To: Junio C Hamano, Martin Langhoff; +Cc: Felipe Contreras, Git Mailing List

Junio C Hamano wrote:
> Martin Langhoff <martin.langhoff@gmail.com> writes:
> 
> > On Fri, May 9, 2014 at 5:54 PM, Felipe Contreras
> > <felipe.contreras@gmail.com> wrote:
> >> You are once more twisting the sequence of events.
> >
> > Found this gem looking for background to the proposed removal to code of mine.
> >
> > Felipe, if you are wanting to have a war of words with Junio, go have
> > it, with him.
> 
> Please don't feed the troll.  I was happy to be done with it.

I was going to let this comment go (as I let the endless stream of
ad hominem attacks go), but this just one ridiculous.

I've contributed 400 patches, changed 12700 lines, sent 4200 mails on
the list. Then I'm not happy with a decision you made, and I ask you
*one* question to clarify your rationale, and I'm still waiting for an
answer.

I think after this insane amount of work I'm entitled to an answer for
this *one* question.

Instead you passive aggressively label me as a troll?

This is really disquieting.

Junio, do you honestly think I am a troll? Have at least the decency of
telling it to me.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-13 18:54           ` Felipe Contreras
@ 2014-05-13 21:05             ` Junio C Hamano
  2014-05-13 21:35               ` Martin Langhoff
  2014-05-13 22:52               ` Felipe Contreras
  0 siblings, 2 replies; 42+ messages in thread
From: Junio C Hamano @ 2014-05-13 21:05 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Martin Langhoff, Git Mailing List

Felipe Contreras <felipe.contreras@gmail.com> writes:

> Junio, do you honestly think I am a troll?

You certainly are acting like one, aren't you?

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-13 21:05             ` Junio C Hamano
@ 2014-05-13 21:35               ` Martin Langhoff
  2014-05-13 22:29                 ` Felipe Contreras
  2014-05-13 22:52               ` Felipe Contreras
  1 sibling, 1 reply; 42+ messages in thread
From: Martin Langhoff @ 2014-05-13 21:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Felipe Contreras, Git Mailing List

Felipe,

someone can contribute positively, and also be very destructive.

Your positive contributions, nobody will deny.

However, you have to tame the other part to be good company.

I have had patches and contributions rejected in the past, sometimes
rudely. Same has happened to many others, if you contribute long
enough, it is pretty much guaranteed that it will happen to you.
Maintainer is wrong, or you are wrong, or someone is just having a bad
day.

But these are NOT good reasons to make a big scene. It is reasonable
to be upset, it is reasonable to think that Junio is wrong or unfair;
walk away, take some time off, cool down your own mind, give others
time to cool down as well.

cheers,



m

On Tue, May 13, 2014 at 5:05 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
>> Junio, do you honestly think I am a troll?
>
> You certainly are acting like one, aren't you?
>



-- 
 martin.langhoff@gmail.com
 -  ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 ~ http://docs.moodle.org/en/User:Martin_Langhoff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-13 21:35               ` Martin Langhoff
@ 2014-05-13 22:29                 ` Felipe Contreras
  2014-05-14 12:51                   ` Philippe Vaucher
  0 siblings, 1 reply; 42+ messages in thread
From: Felipe Contreras @ 2014-05-13 22:29 UTC (permalink / raw)
  To: Martin Langhoff, Junio C Hamano; +Cc: Felipe Contreras, Git Mailing List

Martin Langhoff wrote:

> I have had patches and contributions rejected in the past, sometimes
> rudely. Same has happened to many others, if you contribute long
> enough, it is pretty much guaranteed that it will happen to you.
> Maintainer is wrong, or you are wrong, or someone is just having a bad
> day.

This is not about a couple of patches I worked in a weekend being
rejected. This is about the work I've been doing since the past two
years almost like a full-time job dropped to the floor with no
explanation at all. I started with the expectation that they were going
to move to the core, because Junio said so, then he changed his mind and
didn't want to explain his reasoning.

It's not just a bad day.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-13 21:05             ` Junio C Hamano
  2014-05-13 21:35               ` Martin Langhoff
@ 2014-05-13 22:52               ` Felipe Contreras
  1 sibling, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-13 22:52 UTC (permalink / raw)
  To: Junio C Hamano, Felipe Contreras; +Cc: Martin Langhoff, Git Mailing List

Junio C Hamano wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
> 
> > Junio, do you honestly think I am a troll?
> 
> You certainly are acting like one, aren't you?

I'm deeply offended by the fact that would think that I'm purposely
intent on provoking people, or disrupting more important discussions.

I understand how my style of communication can upset people, mainly
because people are not used to frankness. But I thought you of all
people would see how much effort I've put into so many areas of Git, and
therefore that my primary objective is to improve Git, not offend
people. That you would understand that me offending people is a
side-effect of me trying to improve Git, not that I improve Git just so
I can offend people.

I understand why you would choose not to reply to some mails that might
be too flammable, or unimportant, or difficult. But in this case, the
culmination of countless hours of work, what I had in mind since the
beginning; that the tools graduate into the core, was finally there, and
you took it away. And then you didn't give an explanation, and then you
ignored me.

I thought you would understand that most of the code that arrived to the
mailing list had different versions behind, experiments, discussion in
different channels, tests, and that was the reason why most of the code
I submitted to remote-hg and remote-bzr simply worked, and it was
simple. And why when other people did the same, the results were not so
satisfactory.

But no, apparently you didn't value my work at all. Maybe you thought
each line I sent took me the time it takes to write a tweet, maybe you
thought because it's in Python even kids in primary school could write
it.

In fact it's worth so little to you that it's not even worth the time to
respond *one* question, not even in consideration of all these years of
effort.

And then you have the nerve to call me a troll on top of that?

I'm done with you. Consider the bridge burned.

Good bye.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-13 22:29                 ` Felipe Contreras
@ 2014-05-14 12:51                   ` Philippe Vaucher
  2014-05-14 19:35                     ` Felipe Contreras
  0 siblings, 1 reply; 42+ messages in thread
From: Philippe Vaucher @ 2014-05-14 12:51 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Martin Langhoff, Junio C Hamano, Git Mailing List

>> I have had patches and contributions rejected in the past, sometimes
>> rudely. Same has happened to many others, if you contribute long
>> enough, it is pretty much guaranteed that it will happen to you.
>> Maintainer is wrong, or you are wrong, or someone is just having a bad
>> day.
>
> This is not about a couple of patches I worked in a weekend being
> rejected. This is about the work I've been doing since the past two
> years almost like a full-time job dropped to the floor with no
> explanation at all. I started with the expectation that they were going
> to move to the core, because Junio said so, then he changed his mind and
> didn't want to explain his reasoning.
>
> It's not just a bad day.

Here are two posts where Junio and Michael Haggerty explain the
reasoning to you:

- http://article.gmane.org/gmane.comp.version-control.git/248727
- http://article.gmane.org/gmane.comp.version-control.git/248693

Basically, in your case it boils down to your social manners. Despite
the (good) work you did, many people think the community and git as a
whole as more to loose by having to deal with your theatrics,
especially since you try to take everyone hostage of your situations.
No amount of "arguing" (calling it "ad hominem" etc) will change
anything at this point, you have to accept that your social actions
have a big part of responsibility in this.

IMHO, you should change your behavior into a more respectful one and
give people some time to discover you changed, otherwise it is
innevitable that you'll just get banned/ignored by mostly everyone.

We spent way too much energy dealing with these silly issues, please
find a way to deal with it that doesn't annoy everyone and doens't
affect the friendlyness of the mailing list.

Philippe

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 12:51                   ` Philippe Vaucher
@ 2014-05-14 19:35                     ` Felipe Contreras
  2014-05-14 19:55                       ` Martin Langhoff
                                         ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-14 19:35 UTC (permalink / raw)
  To: Philippe Vaucher, Felipe Contreras
  Cc: Martin Langhoff, Junio C Hamano, Git Mailing List

Philippe Vaucher wrote:
> >> I have had patches and contributions rejected in the past, sometimes
> >> rudely. Same has happened to many others, if you contribute long
> >> enough, it is pretty much guaranteed that it will happen to you.
> >> Maintainer is wrong, or you are wrong, or someone is just having a bad
> >> day.
> >
> > This is not about a couple of patches I worked in a weekend being
> > rejected. This is about the work I've been doing since the past two
> > years almost like a full-time job dropped to the floor with no
> > explanation at all. I started with the expectation that they were going
> > to move to the core, because Junio said so, then he changed his mind and
> > didn't want to explain his reasoning.
> >
> > It's not just a bad day.
> 
> Here are two posts where Junio and Michael Haggerty explain the
> reasoning to you:
> 
> - http://article.gmane.org/gmane.comp.version-control.git/248727
> - http://article.gmane.org/gmane.comp.version-control.git/248693
> 
> Basically, in your case it boils down to your social manners.

You are not paying attention at all.

Junio did *not* use my social manners as a reason to block the
graduation, nor the quality of the code, he used a *TECHNICAL* reason.

Prior to his decision there were no complaints about my "manners" since
I returned. It was his *TECHNICAL* decision that triggered this.

Junio never explained his *TECHNICAL* reason, and Michael Haggerty
simply said "there are good technical arguments for and against
moving git-remote-hg out of contrib", that was all his explanation for
the *TECHNICAL* reason.

You, and other people, are using the behavior I displayed *AFTER* Junio
made his *TECHNICAL* decision as the cause for his decision not to
graduate. That's a wrong direction fallacy.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 19:35                     ` Felipe Contreras
@ 2014-05-14 19:55                       ` Martin Langhoff
  2014-05-14 20:26                       ` Jeff King
  2014-05-14 20:59                       ` Junio C Hamano
  2 siblings, 0 replies; 42+ messages in thread
From: Martin Langhoff @ 2014-05-14 19:55 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Philippe Vaucher, Junio C Hamano, Git Mailing List

On Wed, May 14, 2014 at 3:35 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> You are not paying attention at all.

Junio may have been trying to be polite and not tell you directly that
attitude was a factor. Whatever. He is the maintainer. Of all the
folks in this list, he gets to call the shots when the criteria aren't
100% clear.

Quite a few voices here have been heard, all telling you that you are
wrong. Even if you might be right about some aspects, you are wrong.

Time to let go.

good bye,



m
-- 
 martin.langhoff@gmail.com
 -  ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 ~ http://docs.moodle.org/en/User:Martin_Langhoff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 19:35                     ` Felipe Contreras
  2014-05-14 19:55                       ` Martin Langhoff
@ 2014-05-14 20:26                       ` Jeff King
  2014-05-14 21:26                         ` Felipe Contreras
  2014-05-14 20:59                       ` Junio C Hamano
  2 siblings, 1 reply; 42+ messages in thread
From: Jeff King @ 2014-05-14 20:26 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Philippe Vaucher, Martin Langhoff, Junio C Hamano, Git Mailing List

On Wed, May 14, 2014 at 02:35:08PM -0500, Felipe Contreras wrote:

> Prior to his decision there were no complaints about my "manners" since
> I returned. It was his *TECHNICAL* decision that triggered this.

There have been several complaints about your behavior since you
returned[1,2,3,4], in addition to the times I and others have simply
left threads because they did not feel that arguing with you was
productive (a thing that several people, myself included, told you in
the past that they would do).

I have not paid all that close attention to this remote-hg contrib
argument. Maybe you are 100% right and Junio is wrong and lying and
cannot back up his decision, but somehow needs to cover it up through
rhetoric. But that does not at all match my past experiences with
Junio's behavior.  And given my past experiences with you, and your
behavior in response to the discussion, I find it likely that either
mis-communication or your stubbornness is a likely factor. And also
given those experiences, I've avoided wading into the thread myself or
spending too much time thinking about it.

I can understand that it hurts to be called a troll. I really do believe
you are trying your best to improve git. But I hope you also understand
that in terms of the time and emotional drains on other participants,
from our perspective interacting with you is quite similar to
interacting with a troll.

Your continued arguing on this topic does not seem like it is going
anywhere, and I believe is wasting time and hurting the atmosphere of
the list. Please stop. You have had many chances to interact with people
on the list[5], and now you are seeing the consequences of your
behaviors: people have little tolerance for you and will stop paying
attention.

-Peff

[1] http://article.gmane.org/gmane.comp.version-control.git/247108

[2] http://article.gmane.org/gmane.comp.version-control.git/247121

[4] http://article.gmane.org/gmane.comp.version-control.git/247168

[3] http://article.gmane.org/gmane.comp.version-control.git/248000

[5] Even though you were previously asked to leave, I believe people
    on the list gave interacting with you a fair shot in the past month
    or two. And we somehow still ended up at the same place.  That's
    just my perception, of course. I'd invite anybody watching to form
    their own opinions.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 19:35                     ` Felipe Contreras
  2014-05-14 19:55                       ` Martin Langhoff
  2014-05-14 20:26                       ` Jeff King
@ 2014-05-14 20:59                       ` Junio C Hamano
  2014-05-14 23:28                         ` Felipe Contreras
  2 siblings, 1 reply; 42+ messages in thread
From: Junio C Hamano @ 2014-05-14 20:59 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Philippe Vaucher, Martin Langhoff, Git Mailing List

Felipe Contreras <felipe.contreras@gmail.com> writes:

> Philippe Vaucher wrote:
>> >> I have had patches and contributions rejected in the past, sometimes
>> >> rudely. Same has happened to many others, if you contribute long
>> >> enough, it is pretty much guaranteed that it will happen to you.
>> >> Maintainer is wrong, or you are wrong, or someone is just having a bad
>> >> day.
>> >
>> > This is not about a couple of patches I worked in a weekend being
>> > rejected. This is about the work I've been doing since the past two
>> > years almost like a full-time job dropped to the floor with no
>> > explanation at all. I started with the expectation that they were going
>> > to move to the core, because Junio said so, then he changed his mind and
>> > didn't want to explain his reasoning.
>> >
>> > It's not just a bad day.
>> 
>> Here are two posts where Junio and Michael Haggerty explain the
>> reasoning to you:
>> 
>> - http://article.gmane.org/gmane.comp.version-control.git/248727
>> - http://article.gmane.org/gmane.comp.version-control.git/248693
>> 
>> Basically, in your case it boils down to your social manners.
>
> You are not paying attention at all.
>
> Junio did *not* use my social manners as a reason to block the
> graduation, nor the quality of the code, he used a *TECHNICAL* reason.
>
> Prior to his decision there were no complaints about my "manners" since
> I returned. It was his *TECHNICAL* decision that triggered this.
>
> Junio never explained his *TECHNICAL* reason, and Michael Haggerty
> simply said "there are good technical arguments for and against
> moving git-remote-hg out of contrib", that was all his explanation for
> the *TECHNICAL* reason.
>
> You, and other people, are using the behavior I displayed *AFTER* Junio
> made his *TECHNICAL* decision as the cause for his decision not to
> graduate. That's a wrong direction fallacy.

I am not interested in distinction between technical and social that
much.  The points that were raised in the thread started by John
Keeping, and some of the points that came to my mind while on that
thread, even though I may not have mentioned in *that* thread, that
affected the way *I* thought about the issue are these (not
exhaustive):

 - We may be painted in a hard place if remote-hg or remote-bzr take
   us to a position where the Git as a whole is blocked while it is
   incompatible with the other side.

   Maintaining it as an independent project (aka Unbundling) would
   eliminate that risk, instead of having to handwave and say "that
   risk does not exist".

 - A remote-helper has to depend on both sides.  Keeping it in
   either contrib/ or in core, as opposed to unbundling, may make
   things easier for the remote-helper maintainer, because at least
   it would allow the helper to advance with Git in lock-step (but I
   never heard that you do not prefer unbundling for this reason).

 - In a longer term, a properly maintained remote-helpers should
   work with wide varieties of Git and the remote system versions
   anyway, so unbundling would be logically the more "correct" thing
   to do.

 - Unbundling would make it less easier to use the remote-helpers
   for people who are used to keep up with my tree and pick them up
   from contrib/, but that is a tiny minority these days.  Most
   people use what distros package, and the distros that already
   package contrib/ remote-helpers will switch their upstream to
   unbundled repositories in order not to regress their packages for
   their users.

 - On the other hand, unbundling will make it easier for the the
   end-users (both the ones who are fed distro packaged versions and
   the ones who build from the source _and_ who overcome the "less
   easier because now they have to pull from not just me but from
   the unbundled places" inconvenience) to keep up with the
   leading/bleeding edge, because the remote-helpers do not have to
   freeze at the same time other parts of Git are frozen before the
   release, and users and distros can pick improved remote-helpers
   up and even "mix and match", when they have some other reason
   that prevents them from updating Git itself.

 - Unbundling would also involve the risk of making them obscure,
   and the original reason why we added contrib/ area to host
   "having something is often better than having nothing" tools,
   even if some of them were of lessor quality, was exactly that.
   While building the momentum and the Git community, it was
   necessary to have a nursery.  That reasoning no longer applies
   these days, and we have seen examples of third-party independent
   products that can improve the users' Git life flourishing.

   "We have less need for a nursery" is not a reason to kick bundled
   things out that want to be bundled, but it tells us that we no
   longer have to be afraid of unbundled things dying in obscurity,
   if there are other reasons that tell us unbundling is better.

I may be missing some others, and I would be lying if I did not at
all think of the "net liability" issue Michael brought up, but the
above that does not include anything you labelled as "social
manners" was more or less enough to convince me to say

    ... and I am inclined to be persuaded that the users of
    remote-hg/bzr may better off if they are unbundled from my tree.

in

    http://thread.gmane.org/gmane.comp.version-control.git/247660/focus=248242

That is not to say that I disagree with Michael and social issues do
not matter.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 20:26                       ` Jeff King
@ 2014-05-14 21:26                         ` Felipe Contreras
  0 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-14 21:26 UTC (permalink / raw)
  To: Jeff King, Felipe Contreras
  Cc: Philippe Vaucher, Martin Langhoff, Junio C Hamano, Git Mailing List

Jeff King wrote:
> On Wed, May 14, 2014 at 02:35:08PM -0500, Felipe Contreras wrote:
> 
> > Prior to his decision there were no complaints about my "manners" since
> > I returned. It was his *TECHNICAL* decision that triggered this.
> 
> There have been several complaints about your behavior since you
> returned[1,2,3,4],

> [1] http://article.gmane.org/gmane.comp.version-control.git/247108

This is not a complaint, you are merely saying you are not interested in
discussing with me without mentioning any bad behavior at that time.

And this is not related to remote-hg/bzr.

> [2] http://article.gmane.org/gmane.comp.version-control.git/247121

This is a complaint without pointing out what are the specific instances
of bad behavior, present or past.

> [4] http://article.gmane.org/gmane.comp.version-control.git/247168

This is not a complaint about bad behavior. Unless you think making a
bet is bad behavior.

And this is unrelated to remote-hg/bzr.

> [3] http://article.gmane.org/gmane.comp.version-control.git/248000

This is a complaint about a factual statement, a prediction about the
future that turned out to be true. Unflattering factual predictions can
hardly be considered "bad behavior"

And this is unrelated to remote-hg/bzr.

> I have not paid all that close attention to this remote-hg contrib
> argument. Maybe you are 100% right and Junio is wrong and lying and
> cannot back up his decision, but somehow needs to cover it up through
> rhetoric. But that does not at all match my past experiences with
> Junio's behavior.

The fact that something hasn't happened in the past doesn't mean it's
not happening right now.

I am still waiting for Junio's answer to *one* question.

If your expectation about Junio is correct, it should be easy for him to
say "Felipe is wrong, here's where I explained in full my rationale
of the technical issues that triggered my decision to demote the remote
helpers, and as you can see, the importance of the decision is well
matched by the detail of my explanation". But he is not doing that, is
he?

It would be easy for him to do that, why isn't he doing so? You are
giving him a free pass.

> I can understand that it hurts to be called a troll. I really do believe
> you are trying your best to improve git. But I hope you also understand
> that in terms of the time and emotional drains on other participants,
> from our perspective interacting with you is quite similar to
> interacting with a troll.

Yes, I can understand that, and I would understand if Junio said I was
acting *like* a troll. But he unequivocally said I was a troll, even
when I asked for clarification.

Maybe that's acceptable to you. That's where I draw the line.

> Your continued arguing on this topic does not seem like it is going
> anywhere,

I'm not arguing on this topic any more. I gave up on Junio trying to
answer my *one* question. The remote helpers will not graduate because
Junio said so, and he didn't explain his reasoning. That's an
unfortunate fact.

All I'm trying now is to move foward, by:

 1) Add a warning about the new location of remote-helpers

 (Junio chose to argue instead)

 2) Remove the remote-helpers and replace them with warning stubs

 ("Somehow" the patches didn't reach the mailing list)

 3) Make sure everything is in place for users and packagers to use the
    new location (it can't never be as good as graduating to the core)
 
 (The fact that Junio is preventing 1) and 2) doesn't help)

Additionally:

 4) Correct any misconceptions in the lingering threads

> and I believe is wasting time and hurting the atmosphere of
> the list. Please stop.

Tell other people to stop. I am merely replying to misconstrued
conceptions. If other people stop, so would my replies.

I am not going to let the record about such an important decision be
tainted by these misconceptions.

> [5] Even though you were previously asked to leave, I believe people
>     on the list gave interacting with you a fair shot in the past month
>     or two. And we somehow still ended up at the same place.  That's
>     just my perception, of course. I'd invite anybody watching to form
>     their own opinions.

And that's entirely Junio's fault for making a haste decision, and
giving no rationale about it.

Given all the time I've spent on these tools, I wasn't willing to let my
work be threated like crap by Junio. I deserved an explanation, and if
he wasn't going to give one, I'd rather leave the project trying to get
one (even if that meant behaving in a way other people considered
"bad").

And BTW, I still think git-archimport and git-quiltimport should be
demoted from the core, and I think the contrib area should be cleaned
up, many of the tools removed, and others maintained out-of-tree. Do not
think I sent those patches to "troll".

Cheers.

P.S. While we disagree on many topics, I do appreciate the fact that you
are never condescending and try to be honest, and when it becomes
difficult to do that, you explain so and leave the discussing. Never
letting your ego get in the way of a clear record. Which is more than I
can say about Junio after this incident.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 20:59                       ` Junio C Hamano
@ 2014-05-14 23:28                         ` Felipe Contreras
  2014-05-14 23:50                           ` Martin Langhoff
  2014-05-15 22:56                           ` Junio C Hamano
  0 siblings, 2 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-14 23:28 UTC (permalink / raw)
  To: Junio C Hamano, Felipe Contreras
  Cc: Philippe Vaucher, Martin Langhoff, Git Mailing List

Junio C Hamano wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
> > Junio never explained his *TECHNICAL* reason, and Michael Haggerty
> > simply said "there are good technical arguments for and against
> > moving git-remote-hg out of contrib", that was all his explanation for
> > the *TECHNICAL* reason.

> I am not interested in distinction between technical and social that
> much.  The points that were raised in the thread started by John
> Keeping, and some of the points that came to my mind while on that
> thread, even though I may not have mentioned in *that* thread, that
> affected the way *I* thought about the issue are these (not
> exhaustive):

Let's be clear; the discussion in that thread was contrib vs. core. Most
of the points you mention below are not related to that.

== contrib vs. core ==

This is the only point relevant to contrib vs. core:

>  - We may be painted in a hard place if remote-hg or remote-bzr take
>    us to a position where the Git as a whole is blocked while it is
>    incompatible with the other side.

It will never happen. I already argued against it[1], multiple times.
Essentially making the tests optional removes any possibility of
blockage (pluse many more arguments).

This is the crux of the problem, because as far as I know, it's the only
suppsed argument against contrib vs. core. An argument very weak and
already refuted.

I repeatedly asked Junio to clarify his reasoning, because it can't
possibly be that this is the only reason, and that's the full rationale.

If this is it. Then it's very clear: core wins.

== bundle vs. unbundle ==

The rest of the arguments are *not* related to contrib vs. core. They
are a red herring, but I'll answer anyway.

>  - A remote-helper has to depend on both sides.  Keeping it in
>    either contrib/ or in core, as opposed to unbundling, may make
>    things easier for the remote-helper maintainer, because at least
>    it would allow the helper to advance with Git in lock-step (but I
>    never heard that you do not prefer unbundling for this reason).

I am the maintainer I told you that wasn't the way to go and I'm telling
you again.

>  - In a longer term, a properly maintained remote-helpers should
>    work with wide varieties of Git and the remote system versions
>    anyway, so unbundling would be logically the more "correct" thing
>    to do.

I already argued against this (and so did you[2]); the same argument
applies to git-p4, git-cvs, git-svn, git-archimport, etc.

We are not seeing efforts to unbundle those. Why? Because it would be
detrimental to our users, for many reasons, starting by the fact that
there's no good visibility of out-of-tree tools.

>  - Unbundling would make it less easier to use the remote-helpers
>    for people who are used to keep up with my tree and pick them up
>    from contrib/, but that is a tiny minority these days.  Most
>    people use what distros package, and the distros that already
>    package contrib/ remote-helpers will switch their upstream to
>    unbundled repositories in order not to regress their packages for
>    their users.

That is not true. Distributions mostly put everything in contrib/ into
/usr/share/git without much care about what does what. If something is
missing the users might notice, but the packages wouldn't. It would
require different packagers that care to create the new packages, if it
happens at all. The new packages might be created in a ppa, or some
other third-party place not very visible.

If proper packages manage to end up in the main distribution
repositories, it will take a long time, and in the meantime users will
be left with a bad taste in their mouth.

It will take even more time if these tools remain in contrib/ because
nobody will notice anything, until bugs start to pile up.

>  - On the other hand, unbundling will make it easier for the the
>    end-users (both the ones who are fed distro packaged versions and
>    the ones who build from the source _and_ who overcome the "less
>    easier because now they have to pull from not just me but from
>    the unbundled places" inconvenience) to keep up with the
>    leading/bleeding edge, because the remote-helpers do not have to
>    freeze at the same time other parts of Git are frozen before the
>    release, and users and distros can pick improved remote-helpers
>    up and even "mix and match", when they have some other reason
>    that prevents them from updating Git itself.

Users don't care much about being on the bleeding edge. They care that
their tools keep working and in the same way. For that it's more
important that the maintainers have as many eyes as possible no the
patches. And sending the patches on git@vger.kernel.org has certain
helped in that regard. You want to take that away from them.

Additionally, they care that the tools are easy to set up. Being able to
clone Mercurial repositories from an out-of-the-box version of Git is
much more important to them than being "on the bleeding edge".

Plus this also applies got git-p4, git-cvs, git-svn, etc. It's not a
good argument for them, and it's not a good argument for
git-remote-hg/bzr either.

>  - Unbundling would also involve the risk of making them obscure,
>    and the original reason why we added contrib/ area to host
>    "having something is often better than having nothing" tools,
>    even if some of them were of lessor quality, was exactly that.
>    While building the momentum and the Git community, it was
>    necessary to have a nursery.  That reasoning no longer applies
>    these days, and we have seen examples of third-party independent
>    products that can improve the users' Git life flourishing.

This is not true. The reasoning behind the contrib/ nursery was
*entirely* so that they could move into the core, just like you said
they would since day one [3]. If they are not going to be part of the
core, all the time in contrib was wasted.

If they had been an out-of-tree project, interest would slowly build up
to the point where separate packages get created and slowly build
popularity.

Instead what we would have is a big breakage in user expectations,
followed by uncertain period of time where the tools are not packaged.
And git-remote-hg/bzr would have to compete with other tools who have
had longer time in the free-market, and thus have more publicity in the
form of blog posts, etc. There's already multiple git-remote-hg and
git-remote-bzr, and it would be hard to explain which is which and why
you would want to use these particular ones. The only salient point
would be that they were once part of the git.git repository, but that
begs the question; why did they got dropped. And the fact that you
haven't been able to provide a good explanation doesn't help.

If on the other hand they become part of the core as was the intention
since day one, none of this would happen, and *everybody* would be happy.

>    "We have less need for a nursery" is not a reason to kick bundled
>    things out that want to be bundled, but it tells us that we no
>    longer have to be afraid of unbundled things dying in obscurity,
>    if there are other reasons that tell us unbundling is better.

Do we no longer have to be afraid of that? WHY? All the responses from
the contrib cleanup patches seem to suggest that pretty much *everyone*
is afraid the contrib tools would die in obscurity if unbundled.

> I may be missing some others, and I would be lying if I did not at
> all think of the "net liability" issue Michael brought up, but the
> above that does not include anything you labelled as "social
> manners" was more or less enough to convince me to say
> 
>     ... and I am inclined to be persuaded that the users of
>     remote-hg/bzr may better off if they are unbundled from my tree.
> 
> in
> 
>     http://thread.gmane.org/gmane.comp.version-control.git/247660/focus=248242

This is a huge distraction and a red herring. The issue discussed never
was bundle vs. unbundle, it was contrib vs. core. After answering the
original issue we could discuss contrib vs. unbundle, or core vs.
unbundle. But you tainted the discussion by deciding on the case bundle
vs. unbundle before it was even discussed, and with no explanation.

The jury is still out in the case core vs. unbundle, and if the best
arguments in favor of unbundle are the ones you just brought up, then
the case is pretty one-sided.

Either way the case is closed, because the judge already passed
veredict, even before there was a chance to bring any arguments.

== Conclusion ==

Do not be fooled. There was only one argument that blocked the
graduation to the core, it was a bad one, and it was refuted pretty
decisevely; remote-hg/bzr should move to the core.

If and when foreign scm tools such as git-p4, git-cvs, git-svn and
git-remote-hg/bzr should move out of the core and be unbundled is a
separate matter that hasn't been discussed yet. When such discussion
happens it should take more than the weak arguments Junio has put forth
in order to determine their faith. And when doing so there should be
measures in place to make sure the transition is as smooth as possible,
like a page that lists these tools, and documentation about the best
practices that these out-of-tree tools should follow (I already argued
for that).

The facts remain clear: Junio made a hasty decision with regards to
git-remote-hg/bzr, which he would *never* do with other tools in exactly
the same position: git-p4, git-svn, etc.

[1] http://article.gmane.org/gmane.comp.version-control.git/248685
[2] http://article.gmane.org/gmane.comp.version-control.git/248156
[3] http://article.gmane.org/gmane.comp.version-control.git/220277

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 23:50                           ` Martin Langhoff
@ 2014-05-14 23:48                             ` Felipe Contreras
  0 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-14 23:48 UTC (permalink / raw)
  To: Martin Langhoff, Felipe Contreras
  Cc: Junio C Hamano, Philippe Vaucher, Git Mailing List

Martin Langhoff wrote:
> On Wed, May 14, 2014 at 7:28 PM, Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> > Do we no longer have to be afraid of that? WHY? All the responses from
> > the contrib cleanup patches seem to suggest that pretty much *everyone*
> 
> The responses also been clear in that you are toxic.

You are replying to a mail about a *TECHNICAL* reason. Junio made a good
job of concentrating on the technical side.

If you are not willing or unable to concentrate on the technical side,
reply to something else, you are just tainting the discussion.

If you are willing to concede that Junio made a wrong technical
decision, I'd be willing to discuss about the social issues that
happened *after* that with you. But I doubt you are interested in doing
either one of those, so I don't don't see what's the point of you even
replying.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 23:28                         ` Felipe Contreras
@ 2014-05-14 23:50                           ` Martin Langhoff
  2014-05-14 23:48                             ` Felipe Contreras
  2014-05-15 22:56                           ` Junio C Hamano
  1 sibling, 1 reply; 42+ messages in thread
From: Martin Langhoff @ 2014-05-14 23:50 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Junio C Hamano, Philippe Vaucher, Git Mailing List

On Wed, May 14, 2014 at 7:28 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> Do we no longer have to be afraid of that? WHY? All the responses from
> the contrib cleanup patches seem to suggest that pretty much *everyone*

The responses also been clear in that you are toxic. You've hijacked
this mailing list on a personal crusade over a particular point over
which Junio has discretion.

We get it. You disagree with the maintainer. It is clear now. Learn to
live with it; or at least let everyone else be.

Can we call Hitler on this one and close these threads now?

You sent a nice email saying bridges are burned. We get the point.
It's over. Bridges burned. NO CARRIER.

Bye now.



m
-- 
 martin.langhoff@gmail.com
 -  ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 ~ http://docs.moodle.org/en/User:Martin_Langhoff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-14 23:28                         ` Felipe Contreras
  2014-05-14 23:50                           ` Martin Langhoff
@ 2014-05-15 22:56                           ` Junio C Hamano
  2014-05-16  8:08                             ` Felipe Contreras
  1 sibling, 1 reply; 42+ messages in thread
From: Junio C Hamano @ 2014-05-15 22:56 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Philippe Vaucher, Martin Langhoff, Git Mailing List

Felipe Contreras <felipe.contreras@gmail.com> writes:

> Junio C Hamano wrote:
>> Felipe Contreras <felipe.contreras@gmail.com> writes:
>> > Junio never explained his *TECHNICAL* reason, and Michael Haggerty
>> > simply said "there are good technical arguments for and against
>> > moving git-remote-hg out of contrib", that was all his explanation for
>> > the *TECHNICAL* reason.
>
>> I am not interested in distinction between technical and social that
>> much.  The points that were raised in the thread started by John
>> Keeping, and some of the points that came to my mind while on that
>> thread, even though I may not have mentioned in *that* thread, that
>> affected the way *I* thought about the issue are these (not
>> exhaustive):
>
> Let's be clear; the discussion in that thread was contrib vs. core. Most
> of the points you mention below are not related to that.
>
> == contrib vs. core ==
>
> This is the only point relevant to contrib vs. core:
> 
> >  - We may be painted in a hard place if remote-hg or remote-bzr take
> >    us to a position where the Git as a whole is blocked while it is
> >    incompatible with the other side.
>
> It will never happen. I already argued against it[1], multiple times.
> Essentially making the tests optional removes any possibility of
> blockage (pluse many more arguments).

I already said that your "It will never happen" is a handwaving, and
I already saw you "argued against it".  There is no point repeating
that exchange.  We both know, and bystanders with popcorns in their
hands also know, that we have different opinions.

You may have been interested in contrib/core in the thread, but that
does not prevent others from considering other aspects of the issue
and different and possibly better solutions, which was to unbundle.

I was very confident back in that thread that the remote Hg bridge
would not merely survive but would serve its users well as a
standalone project, and the level of confidence was actually a lot
higher than for a hypothetical case where other "already in-core"
bridges like git-svn/p4 are somehow forced to become standalone,
simply because of the difference in the depths of involvement of
respective area maintainers.  Without meaning any disrespect to Eric
or Pete, I think my prodding them (by forwarding issues and proposed
patches by others to them when I see them on the list) has been
helping the area maintainers who have other time and attention
obligations to help us, by drawing their attention and making their
workload smaller (they can only Ack and have me apply, instead of
maintaining a separate tree).  There is a greater risk for these
bridges to become unmaintained if we do not have them in my tree,
and that would only hurt our users.  In the ideal world, it may be
better if it weren't that way, but at the same time, new issues that
changing time brings to them seem to be handled more or less OK, so
we have to be content with the status quo.

But I did not see that particular risk at all for the remote Hg
bridge.  You have been very interested in maintaining it, and I
don't think I ever had to prod you to respond to an issue raised on
the list.  It is an apples-and-oranges comparison to bring up
git-svn/p4.

Besides, I want to see the "git-core has the best thing among
competing implementations for a specific niche subtask" perception
changed in the longer term so that it becomes natural for users to
say something like "For this particular task, there is no support in
what comes with core (or there is a tool that comes with core to
address similar issues but in a way different from what you want),
and the go-to tool these days for that kind of task is to use this
third-party plugin", because it is simply unrealistic to expect my
tree to forever be the be-all destination for everything.

Things like "git imerge" are helping us to go in that direction.  I
was hoping that the remote Hg bridge to be capable of becoming the
first demonstration to graduate out of contrib/ that shows the users
that is the case, not with just talk but with a specific example.

Anyway, the above is only within the discussion theme of John
Keeping's thread [*1*].  You seem to be adamant that you do not
consider other people's opinions that came in later threads you
started [*2*], and I do not think that is a sensible way to discuss
things.

After seeing these discussions, it tells me that the code is not fit
for the core (also [*3*]), and I think there no longer is any reason
for us to still talk only about contrib vs core.  As you already
said, you do not want to see them in contrib/, and as you already
saw, everybody other than you do not want to see them in core and
some of them do not want to even see them in contrib/ for that
matter.

I do not see that there is any direction other than out.


[Reference]

*1* http://thread.gmane.org/gmane.comp.version-control.git/247660/focus=248167
*2* http://thread.gmane.org/gmane.comp.version-control.git/248705
*3* http://thread.gmane.org/gmane.comp.version-control.git/248063/focus=248727

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-15 22:56                           ` Junio C Hamano
@ 2014-05-16  8:08                             ` Felipe Contreras
  2014-05-16  8:59                               ` William Giokas
  0 siblings, 1 reply; 42+ messages in thread
From: Felipe Contreras @ 2014-05-16  8:08 UTC (permalink / raw)
  To: Junio C Hamano, Felipe Contreras
  Cc: Philippe Vaucher, Martin Langhoff, Git Mailing List

Junio C Hamano wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:

> > == contrib vs. core ==
> >
> > This is the only point relevant to contrib vs. core:
> > 
> > >  - We may be painted in a hard place if remote-hg or remote-bzr take
> > >    us to a position where the Git as a whole is blocked while it is
> > >    incompatible with the other side.
> >
> > It will never happen. I already argued against it[1], multiple times.
> > Essentially making the tests optional removes any possibility of
> > blockage (pluse many more arguments).
> 
> I already said that your "It will never happen" is a handwaving, and
> I already saw you "argued against it".

This is a red herring. Ignore the fact that it will never happen (which
it won't), the next point remains a FACT, and you conveniently ignore
it.

ANSWER THIS:

> > Essentially making the tests optional removes any possibility of
> > blockage (pluse many more arguments).

If the tests are optional, it doesn't matter if such change you are
worried about happens or not (it won't).

That's all there is to it. You made a wrong call. The tools *can* move
into the core, and you said they couldn't.

> You may have been interested in contrib/core in the thread, but that
> does not prevent others from considering other aspects of the issue
> and different and possibly better solutions, which was to unbundle.

That is IRRELEVANT to the fact that the tools *could* move into the
core. You are using arguments (refuted) to demonstrate that the tools
*might be better served* by being unbundled, in order to explain why
they *could not* move into the core.

That's a red herring.

> I was very confident back in that thread that the remote Hg bridge
> would not merely survive but would serve its users well as a
> standalone project,

And you were wrong.

> There is a greater risk for these bridges to become unmaintained if we
> do not have them in my tree, and that would only hurt our users.

> But I did not see that particular risk at all for the remote Hg
> bridge.  You have been very interested in maintaining it, and I
> don't think I ever had to prod you to respond to an issue raised on
> the list.  It is an apples-and-oranges comparison to bring up
> git-svn/p4.

In other words; if I had done a poorer job of maintaining these tools,
they would have had a higher chance of moving into the core?

If that's the case I would gladly stop any maintenance on them. Just say
the word.

I worked extremely hard so they could become part of the core, if being
part of the core means I have to maintain them less, so be it.

> Besides, I want to see the "git-core has the best thing among
> competing implementations for a specific niche subtask" perception
> changed in the longer term so that it becomes natural for users to
> say something like "For this particular task, there is no support in
> what comes with core (or there is a tool that comes with core to
> address similar issues but in a way different from what you want),
> and the go-to tool these days for that kind of task is to use this
> third-party plugin",

Where are you saying that? Nowhere, that's where. Therefore every tool
you unbundle, you are throwing to the wolves.

> Things like "git imerge" are helping us to go in that direction.  I
> was hoping that the remote Hg bridge to be capable of becoming the
> first demonstration to graduate out of contrib/ that shows the users
> that is the case, not with just talk but with a specific example.

You told me you wanted them to move to the core, you even moved them to
the core.

Then after years of work you change your mind, AGAINST my explicit will
and with clear strong arguments AGAINST your apparently newly conceived
idea. And idea you didn't explain clearly, and which you didn't give any
chance of being refuted.

In other words; an idea which very well COULD BE WRONG, and which very
well could impact negatively many Git users.

But you cannot even ponder the notion that you could possibly be wrong.

> After seeing these discussions, it tells me that the code is not fit
> for the core (also [*3*]), and I think there no longer is any reason
> for us to still talk only about contrib vs core. As you already said,
> you do not want to see them in contrib/,

No, I want to see them in the core, and you said you did too. More
importantly the vast majority of our users would want to see them in the
core, therefore the discussion of contrib vs. core is pretty much
relevant, but you don't care about them, do you?

As I said, I will complain about this publicly _to our users_, which you
are disregarding completely with this poorly thought decision and the
subsequent ones.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-16  8:08                             ` Felipe Contreras
@ 2014-05-16  8:59                               ` William Giokas
  2014-05-16 10:21                                 ` Felipe Contreras
  0 siblings, 1 reply; 42+ messages in thread
From: William Giokas @ 2014-05-16  8:59 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Junio C Hamano, Philippe Vaucher, Martin Langhoff, Git Mailing List

[-- Attachment #1: Type: text/plain, Size: 2344 bytes --]

On Fri, May 16, 2014 at 03:08:51AM -0500, Felipe Contreras wrote:
> Junio C Hamano wrote:
> > Felipe Contreras <felipe.contreras@gmail.com> writes:
> 
> > > == contrib vs. core ==
> > >
> > > This is the only point relevant to contrib vs. core:
> > > 
> > > >  - We may be painted in a hard place if remote-hg or remote-bzr take
> > > >    us to a position where the Git as a whole is blocked while it is
> > > >    incompatible with the other side.
> > >
> > > It will never happen. I already argued against it[1], multiple times.
> > > Essentially making the tests optional removes any possibility of
> > > blockage (pluse many more arguments).
> > 
> > I already said that your "It will never happen" is a handwaving, and
> > I already saw you "argued against it".
> 
> This is a red herring. Ignore the fact that it will never happen (which
> it won't), the next point remains a FACT, and you conveniently ignore
> it.

It may not block git being released, but as we can see from the recent
patches that were needed to enable hg 3.0 support it can break and would
have to follow *both* mercurial and git upstreams, not just git's. After
thinking about this for a while, I would have to agree with Junio That
it's better if a bridge between to actively developed applications not
be coupled to one.

This does not mean that I think git-remote-hg is not of a quality to be
in the git.git tree, but it is simply a fact of development and
stability. If git's remote-helper stuff changes but mercurial doesn't,
we're fine because, having seen the speed of your fixes, we would have a
fix before the next release without a doubt. However, if mercurial
changes, like it just did, then git itself would need to make a release
to have it actually work with the newest release.

Having the tool out of tree allows the maintainer to fix things on both
ends and release independently so that both situations above can be
solved without any real hassle on git or mercurial's side.

This goes for bzr, too, but it looks to be changing less quickly.

tl;dr: This may not block a release, but it will make releases a lot
more dependent on outside forces.

Thanks,

-- 
William Giokas | KaiSforza | http://kaictl.net/
GnuPG Key: 0x73CD09CF
Fingerprint: F73F 50EF BBE2 9846 8306  E6B8 6902 06D8 73CD 09CF

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-16  8:59                               ` William Giokas
@ 2014-05-16 10:21                                 ` Felipe Contreras
  2014-05-16 11:25                                   ` William Giokas
  0 siblings, 1 reply; 42+ messages in thread
From: Felipe Contreras @ 2014-05-16 10:21 UTC (permalink / raw)
  To: William Giokas, Felipe Contreras
  Cc: Junio C Hamano, Philippe Vaucher, Martin Langhoff, Git Mailing List

William Giokas wrote:
> On Fri, May 16, 2014 at 03:08:51AM -0500, Felipe Contreras wrote:
> > This is a red herring. Ignore the fact that it will never happen (which
> > it won't), the next point remains a FACT, and you conveniently ignore
> > it.
> 
> It may not block git being released, but as we can see from the recent
> patches that were needed to enable hg 3.0 support it can break and would
> have to follow *both* mercurial and git upstreams, not just git's.

Indeed, it *can* happen, nobody has argued otherwise. The thing is how
*likely* is it that it will happen again.

As I said, in my experience developing this there has never been a
single instance where such a change was required for *newer* versions of
Mercurial.

>From what I can tell this is an exceptional situation.

And it makes sense that when it happened, it happened exactly in the
part where I wrote custom push() method. Mercurial has unstable API, but
in unstable API's are part that are more stable than others. Generally
the higher level the API is, the more stable it tends to be.

The Linux kernels makes an even weaker promise of API stability than
Mercurial does, but even then, the higher the API you use, the less
likelihood you have of breakage. I've seen this in practice many times.

And it does makes sense that for practical purses Mercurial would try to
avoid changes in the higher level API, which require changes in many
places, and not so much in lower level APIs, which might require a few
changes here and there.

The problem is that in order to replace the higher level API push(), I
had to use the lower level API, and that's where the breakage happened,
it was not unlikely. It is unlikely that another change in this
particular API will happen soon, but not extremely so.

As I already explained, this can be mitigated by contacting the
Mercurial developers and figure out if their high-level API can
accommodate the kind of functionality git-remote-hg needs. Maybe by
adding a new option, or maybe by adding another high-level helper
function.

Either way, I doubt Junio is qualified at all to discern between the
likelihood of future Mercurial API changes that would break
git-remote-hg. He has seen one, and he is wrongly assuming there are
more to come.

> After thinking about this for a while, I would have to agree with
> Junio That it's better if a bridge between to actively developed
> applications not be coupled to one.

How exactly would it be better?

If you concede that the Git release wouldn't be affected, then assuming
a hypothetical future where git-remote-hg is bundled, and we have a
Mercurial API breakage, we would have:

 Git < v2.5 fail, Git >= 2.5 get the fix

If we unbundle, we have:

 git-remote-hg < v0.5 fail, git-remote-hg >= v0.5 get the fix

What is the big difference?

I presume you would say that git-remote-hg v0.5 could be released
earlier than Git v2.5, so the users would get the fix faster. However,
that is not the case if the breakage is detected *before* the Mercurial
release happened, in which case both Git v2.4 and git-remote-hg v0.4
would already contain the fix, and it doesn't matter much which was
released first.

The problem is that I wasn't doing the continuous integration with the
development version of Mercurial, which I am now, so these kind of
exceptional issues would be detected earlier.

Moreover, it is likely that the distribution package for git-remote-hg
would not be maintained as rigorously as the Git package. It might not
even be part of the official packages (e.g. ppa or AUR). Therefore, even
if the git-remote-hg v0.4 happens earlier, it might reach the users
later.

Furthermore, we are talking about a single script that can be installed
by hand easily. The users can simply override their distribution's
script and install by hand the latest version, as many have been doing
already when they report errors and want the latest fix.

Even more. git-remote-hg will not have maintenance releases, if an
exceptional issue like this happens, it can be back-ported to Git v2.3.x,
Git v2.2.x, and so on.

It seems like a very feeble argument in favor of unbundling *at best*.

> This does not mean that I think git-remote-hg is not of a quality to be
> in the git.git tree, but it is simply a fact of development and
> stability. If git's remote-helper stuff changes but mercurial doesn't,
> we're fine because, having seen the speed of your fixes, we would have a
> fix before the next release without a doubt. However, if mercurial
> changes, like it just did, then git itself would need to make a release
> to have it actually work with the newest release.

That is not true. In this particular case, because I didn't build
against the development version of Mercurial, yes, but not for the
future.

If I had the tests I have in place now, we would have detected the
change earlier, and Git v1.9.2 would *already* contain the fix, and when
Mercurial v3.0 got released we wouldn't need to make a Git release in
response (same goes for unbundled git-remote-hg).

> Having the tool out of tree allows the maintainer to fix things on both
> ends and release independently so that both situations above can be
> solved without any real hassle on git or mercurial's side.

As I said; that won't happen. This was an exceptional situation for
different reasons.

If git-remote-hg was unbundled, and the correct tests in place, I would
have v0.2 already with the fix for hg 3.0, and when hg 3.0 got released
I wouldn't be forced to make another v0.2 release. Additionally, I would
not need to make the v0.2 release because of a fix for hg 3.0-dev as
merged.

In other words; the releases wouldn't be as tightly coupled as you make
them seem.

> This goes for bzr, too, but it looks to be changing less quickly.

More like not at all.

> tl;dr: This may not block a release, but it will make releases a lot
> more dependent on outside forces.

tl;dr: That won't happen. Even if it did, it would happen in the
unbundled release a well.

Also note that Junio never brought these points, and they were never
discussed.

I think if I had the tests for the Mercurial development version, the
fix for hg 3.0 would be already released in Git 1.9.2, and I find it
very likely that the graduation to the core would not have been tainted
by this extremely exceptional situation, and the graduation would
continue just fine for Git v2.1.

Sadly we would never know, because people are not good with thought
experiments, and they can't see what such a situation would look like,
and how a similar exceptional situation would look just like that. Not
to mention the fact that suck situation wouldn't happen at all.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-16 10:21                                 ` Felipe Contreras
@ 2014-05-16 11:25                                   ` William Giokas
  2014-05-16 12:20                                     ` Felipe Contreras
  0 siblings, 1 reply; 42+ messages in thread
From: William Giokas @ 2014-05-16 11:25 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Junio C Hamano, Philippe Vaucher, Martin Langhoff, Git Mailing List

[-- Attachment #1: Type: text/plain, Size: 704 bytes --]

On Fri, May 16, 2014 at 05:21:36AM -0500, Felipe Contreras wrote:
> How exactly would it be better?
> 
> If you concede that the Git release wouldn't be affected, then assuming
> a hypothetical future where git-remote-hg is bundled, and we have a
> Mercurial API breakage, we would have:
> 
>  Git < v2.5 fail, Git >= 2.5 get the fix
> 
> If we unbundle, we have:
> 
>  git-remote-hg < v0.5 fail, git-remote-hg >= v0.5 get the fix
> 
> What is the big difference?

It's a matter of scope and where the releases happen, that is all.

Thank you,
-- 
William Giokas | KaiSforza | http://kaictl.net/
GnuPG Key: 0x73CD09CF
Fingerprint: F73F 50EF BBE2 9846 8306  E6B8 6902 06D8 73CD 09CF

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 01/17] contrib: remove outdated README
  2014-05-16 11:25                                   ` William Giokas
@ 2014-05-16 12:20                                     ` Felipe Contreras
  0 siblings, 0 replies; 42+ messages in thread
From: Felipe Contreras @ 2014-05-16 12:20 UTC (permalink / raw)
  To: William Giokas, Felipe Contreras
  Cc: Junio C Hamano, Philippe Vaucher, Martin Langhoff, Git Mailing List

William Giokas wrote:
> On Fri, May 16, 2014 at 05:21:36AM -0500, Felipe Contreras wrote:
> > How exactly would it be better?
> > 
> > If you concede that the Git release wouldn't be affected, then assuming
> > a hypothetical future where git-remote-hg is bundled, and we have a
> > Mercurial API breakage, we would have:
> > 
> >  Git < v2.5 fail, Git >= 2.5 get the fix
> > 
> > If we unbundle, we have:
> > 
> >  git-remote-hg < v0.5 fail, git-remote-hg >= v0.5 get the fix
> > 
> > What is the big difference?
> 
> It's a matter of scope and where the releases happen, that is all.

Of course the core vs. out-of-tree question is a matter of where the
releases happen. The question here was: in which way is out-of-tree a
better place?

If it's a matter of scope, that is; should a foreign vcs interface tool
be bundled in the Git core? Then that question applies not only to
git-remote-hg/bzr, but also git-p4, git-cvs, git-svn, and others.

The answer to the first question seems to be; it's not at all clear (in
fact there doesn't seem to be any valid argument in favour of
out-of-tree). The answer to the second question is; we are not asking
that question right now (for the moment foreign vcs tools should remain
part of the Git core).

I started the graduation series by saying "there doesn't seem to be any
good reason not to", and Junio agreed. Now Junio doesn't agree, but it's
till the case there's no good reason not to.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2014-05-16 12:31 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-09 19:11 [PATCH v2 00/17] contrib: cleanup Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 01/17] contrib: remove outdated README Felipe Contreras
2014-05-09 19:58   ` Junio C Hamano
2014-05-09 21:54     ` Felipe Contreras
2014-05-13 18:10       ` Martin Langhoff
2014-05-13 18:27         ` Junio C Hamano
2014-05-13 18:54           ` Felipe Contreras
2014-05-13 21:05             ` Junio C Hamano
2014-05-13 21:35               ` Martin Langhoff
2014-05-13 22:29                 ` Felipe Contreras
2014-05-14 12:51                   ` Philippe Vaucher
2014-05-14 19:35                     ` Felipe Contreras
2014-05-14 19:55                       ` Martin Langhoff
2014-05-14 20:26                       ` Jeff King
2014-05-14 21:26                         ` Felipe Contreras
2014-05-14 20:59                       ` Junio C Hamano
2014-05-14 23:28                         ` Felipe Contreras
2014-05-14 23:50                           ` Martin Langhoff
2014-05-14 23:48                             ` Felipe Contreras
2014-05-15 22:56                           ` Junio C Hamano
2014-05-16  8:08                             ` Felipe Contreras
2014-05-16  8:59                               ` William Giokas
2014-05-16 10:21                                 ` Felipe Contreras
2014-05-16 11:25                                   ` William Giokas
2014-05-16 12:20                                     ` Felipe Contreras
2014-05-13 22:52               ` Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 02/17] contrib: remove 'vim' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 03/17] contrib: remove 'emacs' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 04/17] contrib: remove 'diffall' Felipe Contreras
2014-05-09 19:27   ` Tim Henigan
2014-05-09 19:11 ` [PATCH v2 05/17] contrib: remove 'hg-to-git' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 07/17] contrib: remove 'stats' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 08/17] contrib: remove 'convert-objects' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 09/17] contrib: remove 'git-shell-commands' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 10/17] contrib: reomve 'thunderbird-patch-inline' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 11/17] contrib: remove 'workdir' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 12/17] contrib: remove 'svn-fe' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 13/17] contrib: remove 'rerere-train' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 14/17] contrib: remove 'remotes2config' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 15/17] contrib: remove 'persistent-https' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 16/17] contrib: remove 'git-resurrect' Felipe Contreras
2014-05-09 19:11 ` [PATCH v2 17/17] contrib: remove 'contacts' Felipe Contreras

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).