Git development
 help / color / mirror / Atom feed
* Comments on "Understanding Version Control" by Eric S. Raymond
From: Jakub Narebski @ 2009-02-02 18:48 UTC (permalink / raw)
  To: git; +Cc: Eric S. Raymond

Some time ago I have found "Understanding Version-Control Systems"
(http://www.catb.org/esr/writings/version-control/version-control.html)
paper (in draft version) by Eric S. Raymond, via Joel Spolsky
recommendation in 'Podcast #37' entry in Stackoverflow Blog
(http://blog.stackoverflow.com/2009/01/podcast-37/).

This is a very nice _survey paper_, currently in development, so we
now have time for comments, corrections and suggestions.  It is
currently on hiatus (it seems that last changes are from the Jan 2008,
slightly more than a year ago), but it is not abandoned.  ESR plans to
get back to it after Wesnoth and gpsd do their upcoming releases.

In my opinion the most important issue is concentrating on "container
identity" instead of on the underlying issue of renames in version
control, which includes intelligent, rename-aware merge; talk about
issues and not about possible solution.  I will concentrate on this
issue for now, and leave for example issue of workflows, and of VCS
history for possible later posts (it is long enough as is).


Below you can find my comments; quoted fragments of "Understanding
Version Control' essay are prefixed with 'UVC> '.  'TODO' refers to
http://www.catb.org/esr/writings/version-control/TODO.html

Please do participate in this discussion, especially if you have
something to say with respect to rename detection versus rename
tracking issue.  Thanks in advance.

----------------------------------------------------------------------
http://www.catb.org/esr/writings/version-control/version-control.html

(Independent comment)

[...]
UVC> This leads to an awkward case called a cross-merge which tends to
UVC> confuse history-aware merging tools.

First, please remember that history-unaware merging tools, such as CVS
merge operation (unless you manually specified points in history) have
trouble with much simpler case of repeated merging into the same
branch.

Second, I think that currently DVCS can deal with criss-cross merges
correctly; for example git with its recursive merge strategy, or so
called MarkMerge from revctrl.org [TODO: probably needs survey how
other modern merging DVCS, such as Mercurial, Bazaar or Monotone, deal
with criss-cross merges].

......................................................................

UVC> == Container identity ==
UVC> 
UVC> In a VCS with container identity, files and directories have a
UVC> stable internal identity, initialized when the file is added to
UVC> the repository. This identity follows them through renames and
UVC> moves. This means that filenames and directories are versioned,
UVC> so that it is possible (for example) for the VCS to notice while
UVC> doing a merge between branches that two files with different
UVC> names are descendants of the same file and do a smarter merge of
UVC> their contents.

This whole subsection confuses in my opinion the goal (rename-aware
merge) with means (container identity).  It should concentrate on
intelligent merging after renames or moves, not on the possible ways
to do this.  It should list what is expected of modern VCS to do,
_then_ enumerate possible ways to do this.

But the most important thing is that "container identity" is a wrong
idea to have: wholesame rename (or copy) of a file is just special
case of more generic code movement and copying.

UVC> 
UVC> Container identity can be implemented by giving each file in the
UVC> repository a 'true name' analogous to a Unix inode,
UVC> Alternatively, it can be implemented implicitly by keeping all
UVC> records of renames in history and chasing through them each time
UVC> the VCS needs to check what file X was called in revision Y.

If I understand correctly 'file-ids' is the way original Arch (and its
descendant) did this, and how Bazaar deal with file and directory
renames, while 'tracking renames' is what Mercurial doea (a bit
incompletly).

But there is _another_ way to have rename-aware merge, and it is how
Git does it.  Git uses heuristic similarity based _rename detection_
to find how to do a merge in presence of renames.  This works quite
well _in practice_ (but it makes it harder to _test_ this solution).


Those three ways of dealing with renames have the following advantages
and disadvantages:

1. Need to use VCS to do file and directory renames and copies.

   Both 'file-ids' and 'rename tracking' have this limitation.

   This means that you cannot use your favorite filemanager, or IDE
   if it doesn't have support for your VCS, or patches to move and
   copy files.  This might be migitated a bit by doing rename
   detection at commit time (Mercurial has this ability wia
   hg-addremove, but it is not automatic), but that means freezing
   current algorithm results; with rename detection you can always
   take advantage of improved rename detection.

2. Ability to improve and correct errors in rename information.

   Both 'file-ids' and 'rename tracking' make it hard to correct
   errors in rename info, for example if you incorrectly marked file
   as copy or rename, or forgot to mark it as copy or rename.  If
   'file-ids' info is stored separately from history, it is less of an
   issue, but I don't see how you can correct errorneous rename
   information in 'rename tracking' solution short of rewriting
   history.

   In the case of 'rename detection' solution Git uses it is
   non-issue, as no rename information is stored.

3. Dealing with independently (in separate branches) added files.
   (this issue can be found in "Test suite" section of TODO).

   Most 'file-ids' solution have the problem if you add the same file
   independently on different branches (e.g. adding file via patch).
   First, one of histories must vanish; second, you have to repeat
   resolution if file-id conflict for every repeated merge.

   From TODO 'rename tracking' solution used in Mercurial doesn't have
   this problem, and of course Git's 'rename detection' doesn't have
   it either.

   Note that there are different versions of this issue: same name
   and same contents, different name same contents (rename without
   ancestor), and same name different contents.  The last case is of
   issue with automatic file-ids if they are dependent on file name;
   first case is of issue with automatic file-ids if they depend on
   branch/comitter/time, i.e. if file-ids differ on different
   branches.  Note: same contents here migh mean _almost_ the same
   contents.

4. Creating new files in renamed directories.
   
   Usually called support for directory renames; the problem is if one
   side (on one branch) renames some directory, and other side (other
   branch) creates new files in the old-name directory.

   For 'file-ids' solution this means that there have to be 'file-ids'
   ('inodes') also for directories; Bazaar has this feature.  For
   'rename tracking' solution this means that rename information for
   directories has to be stored somewhere; from what I understand
   Mercurial with its filename-hashed storage and per-file stored
   rename information doesn't have this feature.  For both 'file-id'
   and 'rename tracking' ('rename info') solutions this I think
   usually mean that you have to do directory renames using VCS
   tools.

   Whle on first glance it might seem that 'rename detection' solution
   (like the one used in Git) cannot deal with this problem it is not
   true.  VCS employing similarity based rename detection can detect
   wholesame directory rename based on pattern of file renames, and
   can put new file in new-name of directory.  Moreover it should be
   able to deal quite sanely with more complicated cases like
   splitting or merging of directories.  _However_ Git currently does
   not support this case (but see the note below), although there were
   some preliminary patches adding 'wholesame directory rename
   detection', so it is not purely theoretical.

   Note: usually you cannot simply move file to new directory without
   any other changes, so automatic creating new file (from the point
   of view of branch we merge into) in new-name directory instead of
   old-name directory might be not a good idea without stopping for
   manual merge conflict resolution, as it would result in semantic
   conflict.
   
5. Misdetection of file renames, and remembering manual corrections.
   (this problem concerns only 'rename detection' solution).

   Of course 'rename detection' algorithm is not perfect.  It can find
   rename when there isn't any if many files consist mainly from
   identical boilerplate (e.g. copyright, license, etc.).  It can fail
   to detect rename if files differ too much (usually then files
   cannot be merged automatically anyway then), or if files are too
   small (like usually in simple test cases used).  In the presence of
   multiple file renames and copies it can assign move or copy source
   to the wrong file.

   Closely related to this issue is a problem of remembering manual
   corrections to rename detection algorithm, and manual hints (like
   inn 'rename tracking' solution).  Both were discussed on git
   mailing list, the former under the name of having git-rerere2,
   remembering (and reusing) of recorded resolutions of tree-level
   conflicted merge, but there were (if I remember correctly) no
   conclusion and no patches.
   
6. Performance bottlenecks in managing renames during merge

   I don't know if it is a problem for 'file-id' solution (Bazaar), or
   for 'rename tracking' solution (Mercurial), but with 'rename
   detection' (Git) if there were a lot of reorganization of directory
   hierarchy between merge points then merge can take a lot of time.


UVC> 
UVC> Absence of container identity has the symptom that file
UVC> rename/move operations have to be modeled as a file add followed
UVC> by a delete, with the deleted file's history magically copied
UVC> during the add. 

I don't know if this paragraph was meant to be about another issue
with renames in VCS, namely dealing with renames and copise during
history browsing (which includes both log of changes, and tracking
line-wise file history aka. annotate/blame/praise).


1. Rename-aware changelog (commit logs).

1.1. Showing renames in "<scm> log", i.e. in whole project history.

     The only complication with rename detection here is choosing a
     level of rename and copy detection, as it might be CPU
     intensive.  In Git those are 'detect renames', 'detect copies as
     well as renames' and 'find copies harder'. That can, of course,
     be configured.

1.2. Following renames in "<scm> log <filename>", i.e. in single file
     history.

     Currently Git does not support it very well.  There is '--follow'
     option for git-log, but it is more of a hack to have something
     similar to what for example Subversion provides, than a full
     solution.  It works for simple histories, and might fail for more
     complicated ones; it is not however fundamental limitation.  On
     can always use "git log -- <old name> <new name>"...

     On the other hand single file history should be for developers
     second-class citizen in VCS supporting changesets; full history
     is _more_ than sum of single-file histories.


2. Rename-aware line-wise file history (which means annotating file
   with history of each line, something like "cvs annotate").

   Note that line-wise file history cannot deal with _deletions_;
   it is a known limitation of this tool.

2.1. Following wholesame file renames and copying.

     The issue is not stopping at file rename when tracking where
     given line came from... and of course representing this
     information in blame/annotate output.  git-blame supports this,
     and I think other VCS (Bazaar, Mercurial) also does.
     [TODO: check this]

2.2. Following code movement and copying.

     You can request that git-blame detect moving lines in the file
     (e.g. moving around code), and detect lines copied from other
     files (code moved across files).  I think it is (together with
     ability to ignore changes in whitespace in blame/annotate)
     currently (?) feature unique to Git; it also shows that idea of
     "container identities" is limited and narrow-minded, and that one
     should think of file renames as of special case of code
     movement. 
     [TODO: perhaps sreenshot of "git gui blame" or equivalent?]
     [TODO: some stats about file renames and other code movement]

UVC> 
UVC> Usually VCSes that lack container identity also create parent
UVC> directories on the fly whenever a file is added or checked out, and
UVC> you cannot actually have an empty directory in a repository.
 
In my opinion this is an fundamentally unrelated issue.  The question
if directories are created and deleted on demand is behavioral issue;
note that _not_ having directories deleted on the fly result in higher
probability of file/directory conflict.

Git is a bit peculiar in this case: empty directories _can_ be
represented in repository, currently cannot be represented in (flat)
staging area aka. index although it shouldn't be too hard to add, and
are removed on the fly which again shouldn't be too hard to change.

Note that you can track empty directories in Git (even if VCS adds
them and removes them on the fly) by trick of having for example empty
'.gitignore' file in it.


UVC> == Snapshots vs. changesets ==
UVC> 
UVC> There are two ways to model the history of a line of
UVC> development. One is as a series of snapshots of an evolving tree
UVC> of files. The other is as a series of changesets transforming
UVC> that tree from a root state (usually empty) to a tip state.

Git is snapshot-based (although packed format uses [binary] delta
compression).  Mercurial is changeset-based.  Bazaar uses different
representation altogether, I think[1] (used to use weave); wiki
says that it is snapshot-oriented, but it has file-ids.

[1] http://bazaar-vcs.org/BazaarFormats is a bit lacking in details

[...]
UVC> Changeset-based systems have some further distinctions based on
UVC> what kinds of data a changeset carries. At minimum, a changeset
UVC> is a group of deltas to individual files, but there are
UVC> variations in what kind of file-tree operations are represented
UVC> in changesets.  

I think most famous _example_ here is Darcs, with _idea_ of other
operations than simple text delta, like "rename this variable to that
name" example in documentation, but I don't know if it was actually
went beyound hand-waving.

Note that patch commutation algebra of Darcs (most pure-changeset VCS
there, in my opinion) might look like a neat idea, but please remember
than Darcs had (and perhaps has still) exponential bad performance of
merging in some cases.

UVC> 
UVC> Changesets which include an explicit representation of
UVC> file/directory moves and renames make it easy to implement
UVC> container identity. (Container identity could also be implemented
UVC> as a separate sequence of transaction records running parallel to
UVC> a snapshot-sequence representation, but I know of no VCS that
UVC> actually does this.) 

[TODO: check how Bazaar actually does this, as it is example of VCS
with 'file-ids', also for directories; check where Mercurial stores
'rename tracking' information].

[...]
UVC> Snapshot and changesets are not perfectly dual
UVC> representations. It took a long time for VCS designers to notice
UVC> this; the broken symmetry was at the core of a well-known
UVC> argument between the designers of Arch and Subversion in 2003,
UVC> and did not begin to become widely understood until after Martin
UVC> Pool's 2004 essay "Integrals and Derivatives"[2]. Pool, a
UVC> co-author of bzr, correctly noted that attempts to stick with the
UVC> more intuitive sequence-of-snapshots representation have several
UVC> troubling consequences, including making container identity and
UVC> past merges between branches more difficult to track. 
UVC> 
UVC> [2] http://sourcefrog.net/weblog/software/vc/derivatives.html

Below there is excerpt from OLD "Integrals and Derivatives" essay
(I hope I have choosen relevant part of this essay).

ID> Working in terms of changesets, or at least having the option to
ID> do so allows more powerful operation. 
ID>
ID> For example, consider repeated merges among a related set of
ID> trees. Arch and Darcs [which work primarily in the changeset
ID> domain] handle this well, because they can easily remember which
ID> changesets have already come across. Subversion and CVS tend to
ID> handle it poorly, because merely tracking which version from the
ID> other tree has merged doesn't really capture the right
ID> information.

This is, as we now know, _wrong_.  Subversion and CVS handle this
poorly not because they are snapshot based (CVS most certainly is not:
it is file-level delta based), but because they do not store merge
information (which revisions were merged to form a merge commit,
i.e. all parents of a merge commit): they lack merge tracking.
Therefore it is not possible to find common ancestors (merge bases),
because there is no enough information.  _Not_ because being
snapshot-based.

Additionally it is now I think universally acknowledged that three-way
merge (with a bit extra to deal with possibly multiple merge-bases,
e.g. in presence of criss-cross merge) is superior merge algorithm; it
is certainly superior to "reapply patches skipping already present"
algorithm that quoted example seems to imply that Arch and Darcs use
(which is available in modern DVCS as well, either as some patch
management / patch queue extensions, or as git-rebase, Mercurial's
transplant extension, or Bazaar graft extension).


[...]

UVC> = What, if anything, have we learned from history? =
UVC> 
UVC> There's a folk saying that "It's not what you don't know that
UVC> hurts you, it's what you think you know that ain't so." In
UVC> examining the pattern of development of VCSes, it seems to me
UVC> that the this sub-field of computer science has been less
UVC> hampered than most by difficulties in finding appropriate
UVC> techniques, but more hampered than most by wrong assumptions that
UVC> hung on far longer than they should have. 
UVC> 
UVC> First wrong assumption: Conflict resolution by merging is
UVC> intractably difficult, so we'll have to settle for locking. It
UVC> took at least fifteen and arguably twenty years for VCS designers
UVC> to get shut of that one. But it's historical now. 

I'm not sure if it has place here, i.e. if it was wrong assumption or
just lack of thought, but I would emphasize that commit-before-merge 
is much, much better than merge-before-commit (or update-before-commit, 
as it is _implicit_ merge that might need to be performed) workflow.

One of more important tasks of VCS is to not lose your changes; the
merge-before-commit does not fill this tack completely, in my opinion,
especially nowadays with networked large-group collarboration.

?merge strategies

UVC> 
UVC> Second wrong assumption: Change history representation as a
UVC> snapshot sequence is perfectly dual to the representation as
UVC> change/add/delete/rename sequences.. This folk theorem is well
UVC> expressed in the 2004 essay "On Arch and Subversion"[3]. It is
UVC> appealing, widely held, and dead wrong.
UVC> 
UVC> File renames break the apparent symmetry. The failure of
UVC> snapshot-based models to correctly address this has caused
UVC> endless design failures, subtle bugs, and user misery. 

It is not true.  Example of snapshot-based Git, which with its rename
detection deals very well in practice with file renames contradict
this theory.  Bazaar which is supposedly snapshot-based, yet support
"container identities" ('file-ids') contradict this further.

The symmetry might be broken _only_ if there are other operators in
changesets than simple delta.  But one has to remember that if
representation is not equivalent to snapshot-based in the sense that
you can do a (3-way) merge based on endpoints (branches to be merged
and common ancestors aka. merge bases) _only_, and one has to take
_whole_ history into account when merging, then there is high
probability of cases where merge performance suffers badly.  Please do
not say that performance doesn't matter, because it does; if operation
takes minutes (or more) rather than seconds, then this would affect
workflow used, as people try to avoid unpleasant operations...

UVC> 
UVC> Practically speaking, failure to address this broken symmetry
UVC> goes a long way towards explaining why CVS became such a
UVC> disaster. But the damage didn't end there, which is why I'm
UVC> courting controversy by pointing out that it underlies a debate
UVC> about third-generation designs that is still live today. Should
UVC> VCSes be purely content-addressable filesystems (the Mercurial
UVC> and git approach) or should they have container identity (as in
UVC> Arch, monotone, and bzr)? 
UVC> 
UVC> That debate is not over, but at least VCS designers are grappling
UVC> with it now. 

CVS was disaster no because of (supposedly) broken symmetry between
snapshots (snapshot-based operations) and changesets; it was disaster
because its per-file versioning roots were very visible in: non-atomic
commits, no support for changesets, heavyweight (bad performance)
branching and tagging, complete lack of support for renaming files.

I agree that the issue of content-addressed filesystem versus
container identities (file-ids) is importnat one, but I would say that
neither one won over the other...

UVC> 
UVC> I have a guess about the third wrong assumption. I think it goes
UVC> something like this: The correct choice of abstractions,
UVC> operations, and containers in a VCS is the one that makes the
UVC> cleverest sorts of data-shuffling possible. I suspect that, as
UVC> our algorithms get better, we're going to find that the best
UVC> choices are not the most theoretically clever ones but rather the
UVC> ones that are easiest for human beings to intuitively model.

Here I think Git model wins hands down: DAG (Direct Acyclic Graph) of
commits (Monotone had it first), clear relation between objects:
commit object contain metadata (like authorship and commit message),
link to zero (root / initial commit), one (usual case), or two or more
(merges) parent commits, and link to snapshot of a state of project at
given version...  Having branches and tags (and remote-tracking
branches) to exist outside DAG of commits, in a separate namespaces;
not that disaster of conventions for imitation of branches and tags in
Subversion.  Having current branch to be just pointer to one of
branches.

Having delta compression "under the hood" in the packfiles allow to
combine efficiency of deltas for repository size and network transfer,
while retaining very clear model of snapshot-based VCS.

UVC> 
UVC> This is why, even though I find constructions like today's
UVC> elaborate merge theory[4] fascinating to think about. I'm not
UVC> sure it is actually going anywhere useful. Naive merge algorithms
UVC> with poor behavior at edge cases may actually be preferable to
UVC> more sophisticated ones that handle edge cases well but that
UVC> humans have trouble anticipating effectively.

Nowadays even Bram Cohen of Codeville merge agrees[citation needed]
that 3-way merge, which works in most cases but if fails is easy to
understood, is better than advanced merge strategies which can merge
automatically a few more cases, but if fail it is difficult to resolve
conflicts; note that fail include wrongly resolved merge (merge
strategy gives no conflicts, but merge resolution is wrong).

UVC> 
UVC> An even more interesting question is this: what are the fourth,
UVC> and nth wrong assumptions --- the ones we haven't noticed we're
UVC> making yet? 
UVC> 
UVC> [3] http://www.reverberate.org/computers/ArchAndSVN.html
UVC> [4] http://revctrl.org/CategoryMergeAlgorithm

Well, Linus probably would say that concentrating on special case of
file and directory renames instead of more generic code movement is a
wrong idea.

But what do YOU think?

-- 
Jakub Narebski
Poland

^ permalink raw reply

* [PATCH v2 2/2] Test functionality of new config variable "diff.primer"
From: Keith Cascio @ 2009-02-02 18:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <1233598855-1088-2-git-send-email-keith@cs.ucla.edu>

Test functionality of new config variable "diff.primer"

Signed-off-by: Keith Cascio <keith@cs.ucla.edu>
---
 t/t4035-diff-primer.sh |  129 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 129 insertions(+), 0 deletions(-)
 create mode 100755 t/t4035-diff-primer.sh

diff --git a/t/t4035-diff-primer.sh b/t/t4035-diff-primer.sh
new file mode 100755
index 0000000..c33911c
--- /dev/null
+++ b/t/t4035-diff-primer.sh
@@ -0,0 +1,129 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Keith G. Cascio
+#
+# based on t4015-diff-whitespace.sh by Johannes E. Schindelin
+#
+
+test_description='Ensure diff engine honors config variable "diff.primer".
+
+'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/diff-lib.sh
+
+tr 'Q' '\015' << EOF > x
+whitespace at beginning
+whitespace change
+whitespace in the middle
+whitespace at end
+unchanged line
+CR at endQ
+EOF
+
+git add x
+git commit -m '1.0' >/dev/null 2>&1
+
+tr '_' ' ' << EOF > x
+	whitespace at beginning
+whitespace 	 change
+white space in the middle
+whitespace at end__
+unchanged line
+CR at end
+EOF
+
+test_expect_success 'ensure diff.primer born empty' '
+[ -z $(git config --get diff.primer) ]
+'
+
+tr 'Q_' '\015 ' << EOF > expect_noprimer
+diff --git a/x b/x
+index d99af23..8b32fb5 100644
+--- a/x
++++ b/x
+@@ -1,6 +1,6 @@
+-whitespace at beginning
+-whitespace change
+-whitespace in the middle
+-whitespace at end
++	whitespace at beginning
++whitespace 	 change
++white space in the middle
++whitespace at end__
+ unchanged line
+-CR at endQ
++CR at end
+EOF
+git diff > out
+test_expect_success 'test git-diff with empty value of diff.primer' 'test_cmp expect_noprimer out'
+
+git config diff.primer '-w'
+
+test_expect_success 'ensure diff.primer value set' '
+[ $(git config --get diff.primer) = "-w" ]
+'
+
+git diff --no-primer > out
+test_expect_success 'test git-diff --no-primer' 'test_cmp expect_noprimer out'
+git diff-files -p > out
+test_expect_success 'ensure diff-files unaffected by diff.primer' 'test_cmp expect_noprimer out'
+git diff-index -p HEAD > out
+test_expect_success 'ensure diff-index unaffected by diff.primer' 'test_cmp expect_noprimer out'
+
+cat << EOF > expect_primer
+diff --git a/x b/x
+index d99af23..8b32fb5 100644
+EOF
+git diff > out
+test_expect_success 'test git-diff with diff.primer = -w' 'test_cmp expect_primer out'
+git diff-files -p --primer > out
+test_expect_success 'ensure diff-files honors --primer' 'test_cmp expect_primer out'
+git diff-index -p --primer HEAD > out
+test_expect_success 'ensure diff-index honors --primer' 'test_cmp expect_primer out'
+
+git add x
+git commit -m 'whitespace changes' >/dev/null 2>&1
+
+git config diff.primer '-w --color'
+
+tr 'Q_' '\015 ' << EOF > expect
+Subject: [PATCH] whitespace changes
+
+---
+ x |   10 +++++-----
+ 1 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/x b/x
+index d99af23..8b32fb5 100644
+--- a/x
++++ b/x
+@@ -1,6 +1,6 @@
+-whitespace at beginning
+-whitespace change
+-whitespace in the middle
+-whitespace at end
++	whitespace at beginning
++whitespace 	 change
++white space in the middle
++whitespace at end__
+ unchanged line
+-CR at endQ
++CR at end
+--_
+EOF
+
+git format-patch --stdout HEAD^..HEAD 2>&1 | sed -re '1,3d;$d' | sed -re '$d' > out
+test_expect_success 'ensure format-patch unaffected by diff.primer' 'test_cmp expect out'
+
+git add x
+git commit -m '2.0' >/dev/null 2>&1
+
+git config diff.primer '-w'
+
+git diff-tree -p -r          HEAD^ HEAD > out
+test_expect_success 'ensure diff-tree unaffected by diff.primer' 'test_cmp expect_noprimer out'
+git diff-tree -p -r --primer HEAD^ HEAD > out
+test_expect_success 'ensure diff-tree honors --primer' 'test_cmp expect_primer out'
+
+test_done
+
-- 
1.6.1

^ permalink raw reply related

* Re: [PATCH] Force gitk as the forground process when it starts up on  Mac OS X
From: Sverre Rabbelier @ 2009-02-02 19:07 UTC (permalink / raw)
  To: Gisle Aas; +Cc: git
In-Reply-To: <b48ea8a00902020536t1baea7fbw4fbf27f235024639@mail.gmail.com>

Heya,

On Mon, Feb 2, 2009 at 14:36, Gisle Aas <gisle@aas.no> wrote:
> It annoys me that gitk always start out in the background on Mac OS X. Hence this patch
> --Gisle
>
>
> From 272c7f9b6a2bcdf48e4141b9dc5af445fa69a27b Mon Sep 17 00:00:00 2001
> From: Gisle Aas <gisle@aas.no>
> Date: Mon, 2 Feb 2009 14:27:20 +0100
> Subject: [PATCH] Force gitk as the forground process when it starts up
> on Mac OS X
>
> This patch makes gitk start in the foreground this for those that have the
> tclCarbonProcess package installed.  Unfortunately that package is not
> shipped by default from Apple, but it's part of ActiveTcl.
>
> Signed-off-by: Gisle Aas <gisle@aas.no>

There, fixed that for ya :).

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply

* git maintenance bug tracker sooner better than later
From: jidanni @ 2009-02-02 19:07 UTC (permalink / raw)
  To: git

I predict that git maintenance will have to adopt a bug tracker.

Just like many other packages that relied on just sending bugs and
patches to a mailing list, in the end ended up adding a bug tracker.

^ permalink raw reply

* Re: [PATCH] bash: offer to show (un)staged changes
From: Tuncer Ayaz @ 2009-02-02 19:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <4ac8254d0902011650g714c5a7cya3c5111a74b8d8ea@mail.gmail.com>

On Mon, Feb 2, 2009 at 1:50 AM, Tuncer Ayaz <tuncer.ayaz@gmail.com> wrote:
> On Mon, Feb 2, 2009 at 12:43 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Tuncer Ayaz <tuncer.ayaz@gmail.com> writes:
>>
>>> On Mon, Jan 19, 2009 at 6:29 PM, Shawn O. Pearce <spearce@spearce.org> wrote:
>>>> Junio C Hamano <gitster@pobox.com> wrote:
>>>>> Thomas Rast <trast@student.ethz.ch> writes:
>>>>>
>>>>> > +           if test ! -z "$GIT_PS1_EXPENSIVE"; then
>>>>> > +                   git update-index --refresh >/dev/null 2>&1 || w="*"
>>>>>
>>>>> This makes the feature unavailable for people who care about the stat
>>>>> dirtiness and explicitly set diff.autorefreshindex to false, doesn't it?
>>>>
>>>> Yup, and I'm one of those people who sets autorefresindex to false
>>>> in my ~/.gitconfig, usually before I even have user.{name,email} set.
>>>>
>>>> I do like the idea of what Thomas is trying to do here, but its
>>>> so bloody expensive to compute dirty state on every prompt in
>>>> some repositories that I'd shoot myself.  E.g. WebKit is huge,
>>>
>>> I've been thinking about this and wondered
>>> whether implementing "status --mini" or
>>> "status --short" which prints "+?*" in wt-status.c
>>> could be made fast enough.
>>>
>>> Should we try to implement and profile this
>>> or do we know it will be slow beforehand?
>>
>> I think I've seen a patch to do something like that, soon after Shawn
>> announced his repo tool.
>
> The best I could find is your patch from October 25th 2008
> which implements:
>       $ ./git-shortstatus
>       M     Makefile
>       R100  COPYING -> RENAMING
>           M builtin-commit.c
>           M builtin-revert.c
>           M builtin.h
>           M git.c
>           M wt-status.c
>           M wt-status.h
>
> Is this what you meant?

I am confident that this is the patch Junio referred to
and as time permits I will give it a try.

^ permalink raw reply

* [PATCH git-gui v2 0/2] Teach git-gui to use --primer.
From: Keith Cascio @ 2009-02-02 19:31 UTC (permalink / raw)
  To: Shawn O Pearce; +Cc: git

The next two patches teach git-gui to take advantage of the new diff.primer
feature from my other patch.  This enhancement includes menu-driven white
space ignore settings.  To see this patch in action: apply the diff.primer
patch to git.git, apply this patch to git-gui.git, fire up git-gui, modify a
file, then right-click on the diff panel and look for the new "White Space"
sub-menu.

Keith Cascio (2):
 Teach git-gui to use --primer.
 Hooks for new config variable "diff.primer".

 git-gui.sh     |   51 ++++++++++++++++++++++++++++++++++++++++++
 lib/diff.tcl   |    9 ++++++-
 lib/option.tcl |   57 +++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 110 insertions(+), 7 deletions(-)

^ permalink raw reply

* [PATCH git-gui v2 1/2] Teach git-gui to use --primer.
From: Keith Cascio @ 2009-02-02 19:32 UTC (permalink / raw)
  To: Shawn O Pearce; +Cc: git
In-Reply-To: <1233603121-1430-1-git-send-email-keith@cs.ucla.edu>

Teach git-gui to use --primer.
Also teach it to check diff's exit code instead of relying on piped
output, which could be altered as a consequence of primer options.

Signed-off-by: Keith Cascio <keith@cs.ucla.edu>
---
 lib/diff.tcl |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/diff.tcl b/lib/diff.tcl
index bbbf15c..0e1e4a3 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -276,6 +276,8 @@ proc start_show_diff {cont_info {add_opts {}}} {
 	}
 
 	lappend cmd -p
+	lappend cmd --exit-code
+	lappend cmd --primer
 	lappend cmd --no-color
 	if {$repo_config(gui.diffcontext) >= 1} {
 		lappend cmd "-U$repo_config(gui.diffcontext)"
@@ -310,6 +312,7 @@ proc read_diff {fd cont_info} {
 	global ui_diff diff_active
 	global is_3way_diff is_conflict_diff current_diff_header
 	global current_diff_queue
+	global errorCode
 
 	$ui_diff conf -state normal
 	while {[gets $fd line] >= 0} {
@@ -397,7 +400,9 @@ proc read_diff {fd cont_info} {
 	$ui_diff conf -state disabled
 
 	if {[eof $fd]} {
-		close $fd
+		fconfigure $fd -blocking 1
+		catch { close $fd } err
+		set diff_exit_status $errorCode
 
 		if {$current_diff_queue ne {}} {
 			advance_diff_queue $cont_info
@@ -413,7 +418,7 @@ proc read_diff {fd cont_info} {
 		}
 		ui_ready
 
-		if {[$ui_diff index end] eq {2.0}} {
+		if {$diff_exit_status eq "NONE"} {
 			handle_empty_diff
 		}
 		set callback [lindex $cont_info 1]
-- 
1.6.1

^ permalink raw reply related

* Re: duplicate sign-off-by error
From: Boyd Stephen Smith Jr. @ 2009-02-02 20:04 UTC (permalink / raw)
  To: Sharib Khan; +Cc: git
In-Reply-To: <79FCCC4F-9C66-470E-AC32-8F3AE3C81EE9@columbia.edu>

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

On Monday 02 February 2009 11:22:36 Sharib Khan wrote:
> I m getting a Duplicate Sign-off by error when trying to commit to 
the
> repository.
> I am using git 1.5.6 on solaris
>
> what is this error related to and how can it be resolved.

It's looking for lines in the commit message like:
Signed-off-by: Joe Hacker <jhacker@uni.edu>

and seeing duplication.  Remove the duplication and try again.

If you can't see the duplication, please try to put together a series 
operations we can preform to reproduce your error.
-- 
Boyd Stephen Smith Jr.                     ,= ,-_-. =. 
bss@iguanasuicide.net                     ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' 
http://iguanasuicide.net/                      \_/     


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* [PATCH git-gui v2 2/2] Hooks for new config variable "diff.primer".
From: Keith Cascio @ 2009-02-02 19:32 UTC (permalink / raw)
  To: Shawn O Pearce; +Cc: git
In-Reply-To: <1233603121-1430-2-git-send-email-keith@cs.ucla.edu>

Hooks for new config variable "diff.primer".
Add three checkboxes to both sides of options panel (local/global).  Add a
sub-menu named "White Space" to diff-panel right-click context menu, with
three checkboxes.

Signed-off-by: Keith Cascio <keith@cs.ucla.edu>
---
 git-gui.sh     |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/option.tcl |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/git-gui.sh b/git-gui.sh
index e018e07..5d93351 100755
--- a/git-gui.sh
+++ b/git-gui.sh
@@ -3075,10 +3075,43 @@ $ui_diff tag conf d>>>>>>> \
 
 $ui_diff tag raise sel
 
+proc mirror_diff_state {} {
+	global  diff__ignore_space_at_eol diff__ignore_space_change diff__ignore_all_space
+
+	set key  "diff.primer"
+	set ddo [git config --get $key]
+	set diff__ignore_space_at_eol [expr {[string match "*--ignore-space-at-eol*" $ddo] ? "true" : "false"}]
+	set diff__ignore_space_change [expr {[string match "*--ignore-space-change*" $ddo] ? "true" : "false"}]
+	set diff__ignore_all_space    [expr {[string match "*--ignore-all-space*"    $ddo] ? "true" : "false"}]
+}
+
+proc adjust_command_line { flag value str } {
+	if {$value eq "true"} {
+	  if { ! [string match "*$flag*" $str ] } {
+	    set              str [concat $str $flag] }
+	} else { regsub       -- $flag   $str "" str }
+	return                           $str
+}
+
+proc record_diff_state {} {
+	global  diff__ignore_space_at_eol diff__ignore_space_change diff__ignore_all_space
+
+	set key  "diff.primer"
+	set ddo [git config --get $key]
+	set ddo [adjust_command_line --ignore-space-at-eol $diff__ignore_space_at_eol $ddo]
+	set ddo [adjust_command_line --ignore-space-change $diff__ignore_space_change $ddo]
+	set ddo [adjust_command_line --ignore-all-space    $diff__ignore_all_space    $ddo]
+
+	git config $key $ddo
+	reshow_diff
+}
+
 # -- Diff Body Context Menu
 #
 
 proc create_common_diff_popup {ctxm} {
+	global  diff__ignore_space_at_eol diff__ignore_space_change diff__ignore_all_space
+
 	$ctxm add command \
 		-label [mc "Show Less Context"] \
 		-command show_less_context
@@ -3087,6 +3120,24 @@ proc create_common_diff_popup {ctxm} {
 		-label [mc "Show More Context"] \
 		-command show_more_context
 	lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+	mirror_diff_state
+	set whitespacemenu $ctxm.ws
+	menu $whitespacemenu -postcommand mirror_diff_state
+	$ctxm add cascade \
+		-label [mc "White Space"] \
+		-menu $whitespacemenu
+	$whitespacemenu add checkbutton \
+		-label [mc "--ignore-space-at-eol"] \
+		-variable diff__ignore_space_at_eol -onvalue "true" -offvalue "false" \
+		-command record_diff_state
+	$whitespacemenu add checkbutton \
+		-label [mc "--ignore-space-change"] \
+		-variable diff__ignore_space_change -onvalue "true" -offvalue "false" \
+		-command record_diff_state
+	$whitespacemenu add checkbutton \
+		-label [mc "--ignore-all-space"   ] \
+		-variable diff__ignore_all_space    -onvalue "true" -offvalue "false" \
+		-command record_diff_state
 	$ctxm add separator
 	$ctxm add command \
 		-label [mc Refresh] \
diff --git a/lib/option.tcl b/lib/option.tcl
index 1d55b49..fbdf4e8 100644
--- a/lib/option.tcl
+++ b/lib/option.tcl
@@ -28,6 +28,7 @@ proc save_config {} {
 	global repo_config global_config system_config
 	global repo_config_new global_config_new
 	global ui_comm_spell
+	global ddo diff_primer_global diff_primer_repo pseudovariables
 
 	foreach option $font_descs {
 		set name [lindex $option 0]
@@ -46,17 +47,40 @@ proc save_config {} {
 		unset global_config_new(gui.$font^^size)
 	}
 
+	foreach name [get_diff_primer] {
+		set diff_option [string range $name 8 [string length $name]]
+		set ifound      [lsearch     $diff_primer_global $diff_option]
+		if {$global_config_new($name) eq "true"} {
+		  if {$ifound <  0} { lappend diff_primer_global $diff_option }
+		} else {
+		  if {$ifound >= 0} { set     diff_primer_global [lreplace $diff_primer_global $ifound $ifound]}
+		}
+		set ifound      [lsearch     $diff_primer_repo   $diff_option]
+		if {  $repo_config_new($name) eq "true"} {
+		  if {$ifound <  0} { lappend diff_primer_repo   $diff_option }
+		} else {
+		  if {$ifound >= 0} { set     diff_primer_repo   [lreplace $diff_primer_repo   $ifound $ifound]}
+		}
+	}
+	array unset default_config gui.diff--ignore-*
+	set    default_config($ddo) ""
+	set global_config_new($ddo) [join    $diff_primer_global]
+	set   repo_config_new($ddo) [join    $diff_primer_repo  ]
+
 	foreach name [array names default_config] {
 		set value $global_config_new($name)
-		if {$value ne $global_config($name)} {
-			if {$value eq $system_config($name)} {
+		set value_global [expr {[info exists global_config($name)] ? $global_config($name) : ""}]
+		set value_system [expr {[info exists system_config($name)] ? $system_config($name) : ""}]
+		set value_repo   [expr {[info exists   repo_config($name)] ?   $repo_config($name) : ""}]
+		if {$value ne $value_global} {
+			if {$value eq $value_system} {
 				catch {git config --global --unset $name}
 			} else {
 				regsub -all "\[{}\]" $value {"} value
 				git config --global $name $value
 			}
 			set global_config($name) $value
-			if {$value eq $repo_config($name)} {
+			if {$value eq $value_repo} {
 				catch {git config --unset $name}
 				set repo_config($name) $value
 			}
@@ -65,8 +89,10 @@ proc save_config {} {
 
 	foreach name [array names default_config] {
 		set value $repo_config_new($name)
-		if {$value ne $repo_config($name)} {
-			if {$value eq $global_config($name)} {
+		set value_global [expr {[info exists global_config($name)] ? $global_config($name) : ""}]
+		set value_repo   [expr {[info exists   repo_config($name)] ?   $repo_config($name) : ""}]
+		if {$value ne $value_repo} {
+			if {$value eq $value_global} {
 				catch {git config --unset $name}
 			} else {
 				regsub -all "\[{}\]" $value {"} value
@@ -88,10 +114,23 @@ proc save_config {} {
 	}
 }
 
+proc get_diff_primer {} {
+	global repo_config global_config
+	global ddo diff_primer_global diff_primer_repo pseudovariables
+
+	set ddo "diff.primer"
+	set diff_primer_global [expr {[info exists global_config($ddo)] ? [split $global_config($ddo)] : [list]}]
+	set diff_primer_repo   [expr {[info exists   repo_config($ddo)] ? [split   $repo_config($ddo)] : [list]}]
+	set pseudovariables [list "gui.diff--ignore-space-at-eol" "gui.diff--ignore-space-change" "gui.diff--ignore-all-space"]
+
+	return $pseudovariables
+}
+
 proc do_options {} {
 	global repo_config global_config font_descs
 	global repo_config_new global_config_new
 	global ui_comm_spell
+	global ddo diff_primer_global diff_primer_repo pseudovariables
 
 	array unset repo_config_new
 	array unset global_config_new
@@ -108,6 +147,11 @@ proc do_options {} {
 	foreach name [array names global_config] {
 		set global_config_new($name) $global_config($name)
 	}
+	foreach name [get_diff_primer] {
+		set diff_option [string range $name 8 [string length $name]]
+		set global_config_new($name) [expr {[lsearch $diff_primer_global $diff_option] < 0 ? "false" : "true"}]
+		set   repo_config_new($name) [expr {[lsearch $diff_primer_repo   $diff_option] < 0 ? "false" : "true"}]
+	}
 
 	set w .options_editor
 	toplevel $w
@@ -150,6 +194,9 @@ proc do_options {} {
 		{i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}
 		{i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}}
 		{i-1..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
+		{b gui.diff--ignore-space-at-eol {mc "Diff Ignore Trailing White Space"            }}
+		{b gui.diff--ignore-space-change {mc "Diff Ignore Changes In Amount Of White Space"}}
+		{b gui.diff--ignore-all-space    {mc "Diff Ignore All White Space"                 }}
 		{i-0..99 gui.commitmsgwidth {mc "Commit Message Text Width"}}
 		{t gui.newbranchtemplate {mc "New Branch Name Template"}}
 		{c gui.encoding {mc "Default File Contents Encoding"}}
-- 
1.6.1

^ permalink raw reply related

* [JGIT PATCH] Fix AbstractTreeIterator path comparion betwen 'a' and 'a/b'
From: Tor Arne Vestbø @ 2009-02-02 20:13 UTC (permalink / raw)
  To: git; +Cc: Shawn O. Pearce, Robin Rosenberg

The occurance of a '/' as the next character in the longer path
does not neccecarily mean the two paths are equal, for example
when the longer path has more components following the '/'.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../jgit/treewalk/AbstractTreeIteratorTest.java    |   93 ++++++++++++++++++++
 .../jgit/treewalk/AbstractTreeIterator.java        |    4 +-
 2 files changed, 95 insertions(+), 2 deletions(-)
 create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/AbstractTreeIteratorTest.java

diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/AbstractTreeIteratorTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/AbstractTreeIteratorTest.java
new file mode 100644
index 0000000..4c74094
--- /dev/null
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/AbstractTreeIteratorTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.treewalk;
+
+import java.io.IOException;
+
+import org.spearce.jgit.errors.IncorrectObjectTypeException;
+import org.spearce.jgit.lib.FileMode;
+import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.lib.RepositoryTestCase;
+
+
+public class AbstractTreeIteratorTest extends RepositoryTestCase {
+
+
+	public class FakeTreeIterator extends WorkingTreeIterator {
+		public FakeTreeIterator(String path, FileMode fileMode) {
+			super(path);
+			mode = fileMode.getBits();
+			pathLen -= 1; // Get rid of extra '/'
+		}
+
+		@Override
+		public AbstractTreeIterator createSubtreeIterator(Repository repo)
+				throws IncorrectObjectTypeException, IOException {
+			return null;
+		}
+
+	}
+
+	public void testPathCompare() throws Exception {
+
+		assertTrue(new FakeTreeIterator("a", FileMode.TREE).pathCompare(
+				new FakeTreeIterator("a/b", FileMode.REGULAR_FILE)) < 0);
+
+		assertTrue(new FakeTreeIterator("a", FileMode.TREE).pathCompare(
+				new FakeTreeIterator("a//", FileMode.TREE)) == 0);
+
+		assertTrue(new FakeTreeIterator("a/b", FileMode.REGULAR_FILE).pathCompare(
+				new FakeTreeIterator("a", FileMode.TREE)) > 0);
+
+		assertTrue(new FakeTreeIterator("a//", FileMode.TREE).pathCompare(
+				new FakeTreeIterator("a", FileMode.TREE)) == 0);
+
+		assertTrue(new FakeTreeIterator("a", FileMode.REGULAR_FILE).pathCompare(
+				new FakeTreeIterator("a", FileMode.TREE)) < 0);
+
+		assertTrue(new FakeTreeIterator("a", FileMode.TREE).pathCompare(
+				new FakeTreeIterator("a", FileMode.REGULAR_FILE)) > 0);
+
+		assertTrue(new FakeTreeIterator("a", FileMode.REGULAR_FILE).pathCompare(
+				new FakeTreeIterator("a", FileMode.REGULAR_FILE)) == 0);
+
+		assertTrue(new FakeTreeIterator("a", FileMode.TREE).pathCompare(
+				new FakeTreeIterator("a", FileMode.TREE)) == 0);
+	}
+
+}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java
index 2ff3b99..7dd3f38 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java
@@ -289,9 +289,9 @@ int pathCompare(final AbstractTreeIterator p, final int pMode) {
 		}
 
 		if (cPos < aLen)
-			return (a[cPos] & 0xff) - lastPathChar(pMode);
+			return ((a[cPos] & 0xff) - lastPathChar(pMode)) + (aLen - cPos - 1);
 		if (cPos < bLen)
-			return lastPathChar(mode) - (b[cPos] & 0xff);
+			return (lastPathChar(mode) - (b[cPos] & 0xff)) - (bLen - cPos - 1);
 		return lastPathChar(mode) - lastPathChar(pMode);
 	}
 
-- 
1.6.1.2.309.g2ea3

^ permalink raw reply related

* Re: duplicate sign-off-by error
From: Sharib Khan @ 2009-02-02 20:16 UTC (permalink / raw)
  To: Boyd Stephen Smith Jr.; +Cc: git
In-Reply-To: <200902021405.00562.bss@iguanasuicide.net>


On Feb 2, 2009, at 3:04 PM, Boyd Stephen Smith Jr. wrote:

> On Monday 02 February 2009 11:22:36 Sharib Khan wrote:
>> I m getting a Duplicate Sign-off by error when trying to commit to
> the
>> repository.
>> I am using git 1.5.6 on solaris
>>
>> what is this error related to and how can it be resolved.
>
> It's looking for lines in the commit message like:
> Signed-off-by: Joe Hacker <jhacker@uni.edu>
>
but where are the commit messages stored - which file where i can find  
this
is it the COMMIT_EDITMSG file ?


> and seeing duplication.  Remove the duplication and try again.
>
> If you can't see the duplication, please try to put together a series
> operations we can preform to reproduce your error.

series of operations is

1. change to the file
2. save the file
3. git commit -a -m "change message"

at which pt, i get the duplication error

is this something related to solaris or git crashing - the commit had  
worked earlier ?

thanks

sk


>
> -- 
> Boyd Stephen Smith Jr.                     ,= ,-_-. =.
> bss@iguanasuicide.net                     ((_/)o o(\_))
> ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-'
> http://iguanasuicide.net/                      \_/
>

^ permalink raw reply

* Re: Comments on "Understanding Version Control" by Eric S. Raymond
From: Theodore Tso @ 2009-02-02 20:24 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, Eric S. Raymond
In-Reply-To: <200902021948.54700.jnareb@gmail.com>

On Mon, Feb 02, 2009 at 07:48:53PM +0100, Jakub Narebski wrote:
> In my opinion the most important issue is concentrating on "container
> identity" instead of on the underlying issue of renames in version
> control, which includes intelligent, rename-aware merge; talk about
> issues and not about possible solution.  I will concentrate on this
> issue for now, and leave for example issue of workflows, and of VCS
> history for possible later posts (it is long enough as is).

This was discussed in no small amount of detail on the mailing list
uvc-reviewers, which used to be hosted here:

	http://thyrsus.com/mailman/listinfo/uvc-reviewers

Unfortunately, it looks like Eric has taken down his mailman instance
on thyrsus.com.  I have personal archives of the list, and the list
used to be have public archives, so I don't feel any hesitation
sharing it with interested parties.

> Below you can find my comments; quoted fragments of "Understanding
> Version Control' essay are prefixed with 'UVC> '.  'TODO' refers to
> http://www.catb.org/esr/writings/version-control/TODO.html
> 
> Please do participate in this discussion, especially if you have
> something to say with respect to rename detection versus rename
> tracking issue.  Thanks in advance.

Heh.  A lot of this has been said already.  I think one of the reasons
why Eric kept things short in his paper, and did *not* say a lot about
whether or not container identity tracking was fundamentally needed or
not was because we didn't come to any real consensus on the
uvc-reviewers mailing list.  I believe it is extremely difficult to do
so given that it's very hard to avoid the slippery slope of advocating
for one SCM system versus another.

I'll include some of my writings on the subject from the uvc-reviewers
mailing list so folks can see where some of this discussion went last
time...  (All of this dates from January, 2008, when Eric was last
aggressively updating the paper in question.)  BTW, when I referred to
SCM's being a horrible hack and "guessing" and "fit only to be used by
amateurs" if they didn't record function-level identity tracking,
there were those who were seriously arguing that any SCM (i.e., like
git) that didn't track container identity was fundamentally a "hack".
Yes, there are people who seriously take that view, some of which were
very bitter that their DSCM didn't win the market/popularity wars, and
so their pet projects overtaken by SCM's such as git, describing
$THEIR_PET_SCM_WITH_PROVABLY_CORRECT_SEMANTICS as Betamax, and git as
VHS.  The argument that without rename-tracking, if git was used to
development an software for Air Traffic Control application, airplanes
could be dropping out of the sky was also made by these advocates, no
kidding.  (So was the argument that using a DSCM that didn't do
container identity tracking might be considered Programming
Malpractice.)

So be careful about wanting to reopen this discussion; if the some of
the wrong people join in, you may be very sorry!   :-)

   	     	       	       	    	       	    	 - Ted


> Here then are some types of identity  
> tracking one might imagine:
> 
>    * File identity tracking: tracks the identity of a file through  
> renames and moves.
>    * Simple file content tracking: tracks the identity of content  
> using adds and deletes within a single file.  (Note, there is a  
> question that could be asked here about the resolution of the  
> tracking.  Most current systems that track do so on a line-by-line  
> basis, but one could imagine tracking bytes.  I wont say any more  
> about this in this email.)
>    * Movement of content within a file: tracks the identity of  
> content within a file when lines are moved.
>    * Movement of content between files: tracks the identity of  
> content when lines are moved between files.

One obvious one which isn't in this list is "Directory Identity
Tracking", that is when you move a directory, new files which are
created in one branch at the original directory location will be moved
when you merge with another branch where the directory has been moved.

In private conversations with Tom Lord, he tells me that he had also
played with the concept of "Function/variable (more generally,
programming structure identifier) identity tracking".  That is,
suppose you had an editor like Eclipse which has as a primitive,
"Rename Java identifier (class/method function/variable)", and this
information was passed into the SCM so it could be tracked.  Then in
one branch, a Java identifier could be renamed, and then in another
branch, the use of that same Java identifier could be added in 20
different places --- and since the SCM knows, at a deep semantic
level, that a rename had taken place in Branch A, when it is merged
with Branch B, it could DTRT and change the newly added uses of the
renamed identifier to its new name.

And like with Directory Identity Tracking, it's not hard to come up
with scenarios where without this level of tracking, something
horribly wrong could take place as a result of the SCM not tracking
function identities and using them when doing merges.  At the very
least, the program would fail to compile, and if the example involved
an Air Traffic Control system and multiple function renames taking
place, you could even come up with a contrived horror scenario where
planes would be falling out of the sky --- that is, if you ignore
regression testing, and simple coding practices that would prevent
something like this from happening.

Of course, the flip argument by people who are trying to promote their
brand-spanking new SCM that did function identity tracking (FIT) is
critical since SCM's are all about ACCOUNTING, and without FIT,
systems that try to merges are just GUESSING, and *obviously* a system
which did FIT is far superior to a SCM that didn't; in fact, a SCM
that didn't do FIT is just a Horrible Hack Done By Amateurs.
Furthermore, using an SCM without this feature would (according to
promotors of this hypothetical new SCM), be Programming Malpractice.

And if this sounds silly, I'm just repeating the exact same arguments
that proponents of systems like arch, Bk, et.al, which store the user
intention information of file and directory renames, have recently
advanced against git since it doesn't store this sort of information.
(It may reconstruct rename information in a lazy fashion when it is
needed, but it doesn't store it.)  But if file and directory renames
is a type of user intention which MUST be stored in order for an SCM
not to be a hack, why not function, variable, and class renames?  That
too would be another type of user intention.

	 	     	    	     	  - Ted

---------------------------

> The second could be called "location".  Which file should this patch  
> be applied to?  Which lines within a file should this hunk be applied  
> to?  I argue in [2] that Darcs does strictly better at the task of  
> location than do SVN or GNU diff3.  (I think that SCCS, BK and CDV do  
> as well, but I don't understand them well enough to be sure.)  I  
> argue that Darcs does strictly better in the sense that its answers  
> to the location question are often better and never worse, and that  
> it does so *not* by having a more sophisticated heuristic or by  
> getting lucky more often, but by a simple, provably-correct algorithm  
> which uses valuable information that other algorithms overlook.

How are you defining "provably correct"?  In order to show
correctness, you need to define what correctness means.  

One approach is that you force the user to tell you --- and if you are
in the middle of applying a series of 500 patches, you throw up the
Annoying GUI Dialog Box which stops the application of patches dead in
its tracks, and force the user to confirm whether this is a rename, or
a delete followed by an add of remarkably similar content.  Or, if
patch removes all the files from one directory, and created them all
in another directory, that what was the user intention was a directory
rename, and the SCM records it as such.  Here, you are *assuming* that
what the user tells you is correct, and that's part of the lemma you
use for proving correctness.  If the user, who is seriously annoyed at
the popup boxes, says, "Yeah, yeah, yeah", and dismisses the dialog
box without changing the defaults (which were selected via a
hueristics and which were wrong), well, it's not the SCM's fault since
the user told it what it wanted, and the user was wrong.  GIGO.

In your case, you're saying that Darcs is using "valuable information"
that other algorithms overlook.  OK, so the Darcs people were more
clever about designing a hueristic which tries to approximate user
intention, and having designed the hueristic which uses said "valuable
information" you can prove whether or not Darcs' algorithm correctly
implemented said hueristic.

But at the end of the day, it's still a hueristic, and the use of
words "provably correct" is just a semantic trick.  Even svn's lack of
directory rename support could be considered "provably correct", if
the definition of "correct" is an algorithm which determinically
creates new files in their original location, even if all other files
in that directory were deleted and new files with the same name and
same content were created somewhere else.  It's still an algorithm,
and you can prove whether or not it meets its design specs, but to the
extent that it is less likely to approximate user intenions, people
would say that svn might be less useful in such cases than some other
SCM.

> Let's be careful not to lump these three things together, say "All  
> merging involves guessing.", and thus overlook the interesting fact  
> that some merge algorithms involve strictly more guessing than do  
> others.

Part of the problem is that words like "guessing" and claims of some
algorithm being "provably correct" are basically marketing words.
They are generally used to denigrate one SCM, and promote someone's
favorite SCM as being **better**.

Fundamentally, the goal of merging is to Do The Right Thing --- from a
semantic point of view, which means that the user's intentions is
what's important at the end of the day.  The question then is whether
you record the user's intentions, or try to determine it in from a
hueristics point of view.

The people who claim that recording the user's intentions is superior
will claim that you can never know for sure what the user meant, so
you have to ask him or her to provide that information.  In some cases
that's relatively easy; you require the user to use commands like "bk
mv" and "bk cp" and "bk rm" which not only performs the function, but
also records the user's intention.  Unfortunately, if you are applying
a patch, and the patch file hasn't been enhanced to carry this kind of
information, you have to use hueristics and then somehow get the user
to confirm them --- hence the use of the Annoying Popup Dialog Box.

In other cases, you can't determine it easily, such as the "rename a
Java method function" case, unless you have a specialized editor which
has this as a primitive, or, alternatively, even more Annoying Dialog
Boxes that pop up as you try to commit a change.  Once you have
recorded this information, using it in the merge is relatively easy
--- or if not easy, at least relatively easy to specify and then show
whether or not the information was used correctly.

What then tends to happen is that people whose SCM does one kind of
user intention recording (such as file renaming) will use this as a
huge club to say their system is better than another system, and that
a system which doesn't record this information is "Guessing".  They
will also say that their system is "Provably Correct".  So both of
these words are really Red Meat Marketing words, which get used when
people try to say that Their SCM Is Superior.

On the flip side, the people who don't do any recording of this
information will point out that trying to record the information is
hard, especially when changesets go through a lossy medium, such as
patch files which are e-mailed around, which doesn't record this kind
of user intention.  This may or may not applicable for a particular
project, but for some projects, it is extremely important, especially
for those where e-mail is the primary communication channel and how
patches get reviewed and passed around.

The other point which people on "we don't record user intentions; we
just record content" tend to use is that you can always add more
hueristics later, but in practice, if you didn't record the user
intention when you made the commit, it's almost impossible to add it
later.  So for example, suppose git, which doesn't have function
rename support today, has a new merge engine added later which works
specifically for Java files that correctly intuits and deals with
method function renames.  (Maybe some crazy Java programming
methodology does this all the time, so people get motivated to write
such a thing.)  A SCM which works on recorded user intentions will
need to add that support, in a way which doesn't break backwards
compatibility of their distributed repository, *OR* accept the fact
that for function renaming, it will have to use hueristics that are
run at merge time.

So this seems to be fundamentally a tradeoff.  The two *objective*
things that can be said is how many user intentions are recorded at
commit time (file rename?  directory rename?  function/variable
rename?), and what sort of information is used at merge time via
hueristics to determine user intention.  And if you want to call those
hueristics an "algorithm" because it sounds more mathy and provable,
sure, whatever.  The fact is, the algorithm is still an approximation
on trying to determine user intent, with the goal of making the merge
do the right thing from a Semantic Point of View.

				* * *

>From a project point of view, how often you actually *do* merges is an
interesting one.  If merges requiring complicated user intention
tracking is necessary don't happen very often, maybe focusing on
this issue to the extent that SCM geeks tend to do isn't very
productive.  In my opinion, the overall usability of the system is
*far* more important.  In the OSS world, every project is competing
for programmers, and if the tool is easier to use, the more likely it
will be that you can get people to contribute to your project.  Even
if they aren't bright enough to work on the core algorithms for your
project, they could at least improve the documentation.  That was what
drove my decision to switch to Mercurial back in 2005.  Last year, I
moved my projects to git because of various features that worked well
with my development workflow and which generally improved programmer
productivity.  Whether or not file or directory renames were being
tracked in the SCM had *no* bearing on my decision to switch, because
merges happen rarely, and I have an extensive regression test suite
which I run after almost every commit, and *definitely* after every
merge.  So if a merge doesn't do the right thing, that's OK; I'll fix
it up, and use "git commit --amend" correct the merge commit.

And yet, people seem to focus on recording of user intention because
it reflects some holy grail of Perfection and Correctness.  And maybe,
because it is easily measurable, whereas usability and improving
programmer productivty are inherently more subjective measures.
What's very sad are the people who are feel profoundly hurt that they
spent a huge amount of their life working on SCM Correctness, only to
find that people chose other SCM's based on other metrics and other
issues other than the one that they felt was most important.
Unfortunately there's not a lot that can be done about that.

		      	       	      - Ted

^ permalink raw reply

* Re: duplicate sign-off-by error
From: Boyd Stephen Smith Jr. @ 2009-02-02 20:28 UTC (permalink / raw)
  To: Sharib Khan; +Cc: git
In-Reply-To: <597340B9-A11E-4C69-8389-326D3777D9BA@columbia.edu>

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

On Monday 02 February 2009 14:16:30 you wrote:
> On Feb 2, 2009, at 3:04 PM, Boyd Stephen Smith Jr. wrote:
> > On Monday 02 February 2009 11:22:36 Sharib Khan wrote:
> >> I m getting a Duplicate Sign-off by error when trying to 
commit to
> > the
> >> repository.
> >> I am using git 1.5.6 on solaris
> > It's looking for lines in the commit message like:
> > Signed-off-by: Joe Hacker <jhacker@uni.edu>
> but where are the commit messages stored - which file where i can 
find
> this
> is it the COMMIT_EDITMSG file ?

Usually.

> > If you can't see the duplication, please try to put together a 
series
> > operations we can preform to reproduce your error.
>
> series of operations is
>
> 1. change to the file
> 2. save the file
> 3. git commit -a -m "change message"

This is *not* what I asked for.  I asked for a series of operations 
*we* can perform to *reproduce* your error.  If I do this here, it 
works (no error).  The best way to give what I asked for is to 
start the series of operations with "git init" in an empty 
directory, but that's not the only way.

What if you just "git commit -a" as step 3?
What is "the file"?

> is this something related to solaris or git crashing - the commit 
had
> worked earlier ?

Possibly.  I can't look into it that much until I can reproduce it 
here.
-- 
Boyd Stephen Smith Jr.                     ,= ,-_-. =. 
bss@iguanasuicide.net                     ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' 
http://iguanasuicide.net/                      \_/     

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: Comments on "Understanding Version Control" by Eric S. Raymond
From: Eric S. Raymond @ 2009-02-02 20:35 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Jakub Narebski, git
In-Reply-To: <20090202202424.GG14762@mit.edu>

Theodore Tso <tytso@MIT.EDU>:
> Unfortunately, it looks like Eric has taken down his mailman instance
> on thyrsus.com.  I have personal archives of the list, and the list
> used to be have public archives, so I don't feel any hesitation
> sharing it with interested parties.

Oops!  I think it got lost during a system upgrade.  I should be able 
to restore it and the archives, now you've reminded me.

The paper isn't dead, by the way, I've just been buried in other stuff 
the last year or so.  It's been on my mind lately to resume work on it.
-- 
		<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>

^ permalink raw reply

* [PATCH v2 0/2] Introduce config variable "diff.primer"
From: Keith Cascio @ 2009-02-02 20:45 UTC (permalink / raw)
  To: git list
In-Reply-To: <1233598855-1088-3-git-send-email-keith@cs.ucla.edu>

Seems like the summary email for this patch refuses to deliver through the list.  
I can send it to anyone individually if you are interested.

                                          -- Keith

^ permalink raw reply

* Best CI Server for Git?
From: Tim Visher @ 2009-02-02 20:58 UTC (permalink / raw)
  To: git

Hello Everyone,

I'm setting up a CI environment for my team and I'm wondering what CI
Server works best with Git.  I'm actively considering Hudson and
Cruise Control and I'm leaning towards Hudson because of a demo I saw
Andrew Glover do at my local JUG.  It looks like it's not really
'officially' supported in either tool…

Thoughts?

-- 

In Christ,

Timmy V.

http://burningones.com/
http://five.sentenc.es/ - Spend less time on e-mail

^ permalink raw reply

* [PATCH v2 0/2] Introduce config variable "diff.primer"
From: Keith Cascio @ 2009-02-02 21:03 UTC (permalink / raw)
  To: git list
In-Reply-To: <1233598855-1088-2-git-send-email-keith@cs.ucla.edu>

The next two patches introduce a means by which to specify non-default options 
porcelain diff automatically obeys.  This version v2 fixes the problem with v1 
(violation of plumbing guarantee) by switching to opt_in rather than opt_out 
semantics.  v2 also corrects code style to mimic established convention.

At least one list poster expressed interest in implementing complimentary
functionality, i.e. "primer.*":
http://article.gmane.org/gmane.comp.version-control.git/107158
"primer.diff" compliments "diff.primer", the two styles in no way exclude each
other, and therefore "primer.*" is a good opportunity for future work.

Keith Cascio (2):
 Introduce config variable "diff.primer"
 Test functionality of new config variable "diff.primer"

 Documentation/config.txt       |   14 ++++
 Documentation/diff-options.txt |   10 +++
 builtin-diff.c                 |    2 +
 diff.c                         |   77 +++++++++++++++++++++---
 diff.h                         |   14 ++++-
 gitk-git/gitk                  |   16 +++---
 t/t4035-diff-primer.sh         |  129 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 242 insertions(+), 20 deletions(-)

^ permalink raw reply

* Git+Ant status?
From: Tim Visher @ 2009-02-02 21:12 UTC (permalink / raw)
  To: git

What's the status of git's integration with automated build tools such
as Ant or Maven?  Is anyone doing something like this for projects
that they're working on?

-- 

In Christ,

Timmy V.

http://burningones.com/
http://five.sentenc.es/ - Spend less time on e-mail

^ permalink raw reply

* webgit highlightes mem adresses as git versions
From: Toralf Förster @ 2009-02-02 21:04 UTC (permalink / raw)
  To: git

As seen here 
http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.27.y.git;a=commit;h=8ca2918f99b5861359de1805f27b08023c82abd2 
the strings [<c043d0f3>] and firends shouldn't be recognized as git hashes, 
isn't it ?

-- 
MfG/Sincerely

Toralf Förster
pgp finger print: 7B1A 07F4 EC82 0F90 D4C2 8936 872A E508 7DB6 9DA3

^ permalink raw reply

* [PATCH 0/4] add -p: Term::ReadKey and more
From: Thomas Rast @ 2009-02-02 21:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, Suraj Kurapati
In-Reply-To: <7vljspjk8n.fsf@gitster.siamese.dyndns.org>

I added some more patches. 3/4 is the previous version, with code
added to make / work (it just prompts for a regex) and a configuration
variable added for Junio:

Junio C Hamano wrote:
> I'd appreciate if you can allow this "single stroke" mode to be optionally
> turned off by the end user.

I decided to disable it by default since it is an inconsistency
between add -i and add -p for users of both, so if you want this
feature, make sure to enable interactive.readkey.  (I don't mind the
inconsistency as I never use 'add -i'.)

I also removed the stray %control_chars from back when my draft
versions used raw instead of cbreak mode, and consequently had to test
for Ctrl-C themselves.


Finally, the first two patches fix small problems I saw while looking
over the code, and 4/4 changes the color of error messages caused by
keyboard input to color.interactive.help, lest they drown in the hunk
that is automatically redisplayed.


Thomas Rast (4):
  add -p: change prompt separator for 'g'
  add -p: trap Ctrl-D in 'goto' mode
  add -p: prompt for single characters
  add -p: print errors in help colors

 Documentation/config.txt  |    6 ++++
 git-add--interactive.perl |   70 ++++++++++++++++++++++++++++++++++++--------
 2 files changed, 63 insertions(+), 13 deletions(-)

^ permalink raw reply

* [PATCH 1/4] add -p: change prompt separator for 'g'
From: Thomas Rast @ 2009-02-02 21:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, Suraj Kurapati
In-Reply-To: <7vljspjk8n.fsf@gitster.siamese.dyndns.org>

57886bc (git-add -i/-p: Change prompt separater from slash to comma,
2008-11-27) changed the prompt separator to ',', but forgot to adapt
the 'g' (goto) command.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-add--interactive.perl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 30ddab2..551b447 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -948,7 +948,7 @@ sub patch_update_file {
 			$other .= ',J';
 		}
 		if ($num > 1) {
-			$other .= '/g';
+			$other .= ',g';
 		}
 		for ($i = 0; $i < $num; $i++) {
 			if (!defined $hunk[$i]{USE}) {
-- 
1.6.1.2.513.g04677

^ permalink raw reply related

* [PATCH 2/4] add -p: trap Ctrl-D in 'goto' mode
From: Thomas Rast @ 2009-02-02 21:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, Suraj Kurapati
In-Reply-To: <7vljspjk8n.fsf@gitster.siamese.dyndns.org>

If the user hit Ctrl-D (EOF) while the script was in 'go to hunk?'
mode, it threw an undefined variable error.  Explicitly test for EOF
and have it re-enter the goto prompt loop.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-add--interactive.perl |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 551b447..3bf0cda 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -994,6 +994,9 @@ sub patch_update_file {
 					}
 					print "go to which hunk$extra? ";
 					$response = <STDIN>;
+					if (!defined $response) {
+						$response = '';
+					}
 					chomp $response;
 				}
 				if ($response !~ /^\s*\d+\s*$/) {
-- 
1.6.1.2.513.g04677

^ permalink raw reply related

* [PATCH 3/4] add -p: optionally prompt for single characters
From: Thomas Rast @ 2009-02-02 21:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, Suraj Kurapati
In-Reply-To: <7vljspjk8n.fsf@gitster.siamese.dyndns.org>

Use Term::ReadKey, if available and enabled with interactive.readkey,
to let the user answer add -p's prompts by pressing a single key.
We're not doing the same in the main 'add -i' interface because file
selection etc. may expect several characters.

Two commands take an argument: 'g' can easily cope since it'll just
offer a choice of chunks.  '/' now (unconditionally, even without
readkey) offers a chance to enter a regex if none was given.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/config.txt  |    6 ++++++
 git-add--interactive.perl |   45 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7fbf64d..cee64db 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1013,6 +1013,12 @@ instaweb.port::
 	The port number to bind the gitweb httpd to. See
 	linkgit:git-instaweb[1].
 
+interactive.readkey::
+	Attempt to use Term::ReadKey facilities to allow typing
+	one-letter input with a single key.  Currently only used by
+	the `\--patch` mode of linkgit:git-add[1].  Silently disabled
+	if Term::ReadKey is not available.
+
 log.date::
 	Set default date-time mode for the log command. Setting log.date
 	value is similar to using 'git-log'\'s --date option. The value is one of the
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 3bf0cda..3aa21db 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -33,6 +33,14 @@ my ($diff_new_color) =
 
 my $normal_color = $repo->get_color("", "reset");
 
+my $use_readkey = 0;
+if ($repo->config_bool("interactive.readkey")) {
+	eval {
+		use Term::ReadKey;
+		$use_readkey = 1;
+	};
+}
+
 sub colored {
 	my $color = shift;
 	my $string = join("", @_);
@@ -758,11 +766,32 @@ sub diff_applies {
 	return close $fh;
 }
 
+sub _restore_terminal_and_die {
+	ReadMode 'restore';
+	print "\n";
+	exit 1;
+}
+
+sub prompt_single_character {
+	if ($use_readkey) {
+		local $SIG{TERM} = \&_restore_terminal_and_die;
+		local $SIG{INT} = \&_restore_terminal_and_die;
+		ReadMode 'cbreak';
+		my $key = ReadKey 0;
+		ReadMode 'restore';
+		print "$key" if defined $key;
+		print "\n";
+		return $key;
+	} else {
+		return <STDIN>;
+	}
+}
+
 sub prompt_yesno {
 	my ($prompt) = @_;
 	while (1) {
 		print colored $prompt_color, $prompt;
-		my $line = <STDIN>;
+		my $line = prompt_single_character;
 		return 0 if $line =~ /^n/i;
 		return 1 if $line =~ /^y/i;
 	}
@@ -893,7 +922,7 @@ sub patch_update_file {
 			print @{$mode->{DISPLAY}};
 			print colored $prompt_color,
 				"Stage mode change [y/n/a/d/?]? ";
-			my $line = <STDIN>;
+			my $line = prompt_single_character;
 			if ($line =~ /^y/i) {
 				$mode->{USE} = 1;
 				last;
@@ -966,7 +995,7 @@ sub patch_update_file {
 			print;
 		}
 		print colored $prompt_color, "Stage this hunk [y,n,a,d,/$other,?]? ";
-		my $line = <STDIN>;
+		my $line = prompt_single_character;
 		if ($line) {
 			if ($line =~ /^y/i) {
 				$hunk[$ix]{USE} = 1;
@@ -1018,9 +1047,17 @@ sub patch_update_file {
 				next;
 			}
 			elsif ($line =~ m|^/(.*)|) {
+				my $regex = $1;
+				if ($1 eq "") {
+					print colored $prompt_color, "search for regex? ";
+					$regex = <STDIN>;
+					if (defined $regex) {
+						chomp $regex;
+					}
+				}
 				my $search_string;
 				eval {
-					$search_string = qr{$1}m;
+					$search_string = qr{$regex}m;
 				};
 				if ($@) {
 					my ($err,$exp) = ($@, $1);
-- 
1.6.1.2.513.g04677

^ permalink raw reply related

* [PATCH 4/4] add -p: print errors in help colors
From: Thomas Rast @ 2009-02-02 21:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, Suraj Kurapati
In-Reply-To: <7vljspjk8n.fsf@gitster.siamese.dyndns.org>

Print the error messages that go to STDERR in color.interactive.help.
While it's not really help text, the command help also pops up if an
unknown command was entered (which is an error), and it lets them
stand out nicely.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-add--interactive.perl |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 3aa21db..fe8f364 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -908,6 +908,10 @@ sub display_hunks {
 	return $i;
 }
 
+sub help_msg {
+	print STDERR colored $help_color, @_;
+}
+
 sub patch_update_file {
 	my ($ix, $num);
 	my $path = shift;
@@ -1029,11 +1033,11 @@ sub patch_update_file {
 					chomp $response;
 				}
 				if ($response !~ /^\s*\d+\s*$/) {
-					print STDERR "Invalid number: '$response'\n";
+					help_msg "Invalid number: '$response'\n";
 				} elsif (0 < $response && $response <= $num) {
 					$ix = $response - 1;
 				} else {
-					print STDERR "Sorry, only $num hunks available.\n";
+					help_msg "Sorry, only $num hunks available.\n";
 				}
 				next;
 			}
@@ -1062,7 +1066,7 @@ sub patch_update_file {
 				if ($@) {
 					my ($err,$exp) = ($@, $1);
 					$err =~ s/ at .*git-add--interactive line \d+, <STDIN> line \d+.*$//;
-					print STDERR "Malformed search regexp $exp: $err\n";
+					help_msg "Malformed search regexp $exp: $err\n";
 					next;
 				}
 				my $iy = $ix;
@@ -1072,7 +1076,7 @@ sub patch_update_file {
 					$iy++;
 					$iy = 0 if ($iy >= $num);
 					if ($ix == $iy) {
-						print STDERR "No hunk matches the given pattern\n";
+						help_msg "No hunk matches the given pattern\n";
 						last;
 					}
 				}
@@ -1084,7 +1088,7 @@ sub patch_update_file {
 					$ix--;
 				}
 				else {
-					print STDERR "No previous hunk\n";
+					help_msg "No previous hunk\n";
 				}
 				next;
 			}
@@ -1093,7 +1097,7 @@ sub patch_update_file {
 					$ix++;
 				}
 				else {
-					print STDERR "No next hunk\n";
+					help_msg "No next hunk\n";
 				}
 				next;
 			}
@@ -1106,13 +1110,13 @@ sub patch_update_file {
 					}
 				}
 				else {
-					print STDERR "No previous hunk\n";
+					help_msg "No previous hunk\n";
 				}
 				next;
 			}
 			elsif ($line =~ /^j/) {
 				if ($other !~ /j/) {
-					print STDERR "No next hunk\n";
+					help_msg "No next hunk\n";
 					next;
 				}
 			}
-- 
1.6.1.2.513.g04677

^ permalink raw reply related

* Re: Best CI Server for Git?
From: Jean-Baptiste Quenot @ 2009-02-02 21:59 UTC (permalink / raw)
  To: git
In-Reply-To: <c115fd3c0902021258i61a04f74u481ba66c645fe8f5@mail.gmail.com>

Hi there,

The URL looks weird but http://hudson.gotdns.com/ is the official Wiki
for Hudson, so the Git plugin hosted at
http://hudson.gotdns.com/wiki/display/HUDSON/Git+Plugin is officially
part of Hudson.

See for yourself the list of plugins in the source code browser:
http://fisheye4.atlassian.com/browse/hudson/trunk/hudson/plugins/

There is also the download section of the Hudson project:
https://hudson.dev.java.net/servlets/ProjectDocumentList?expandFolder=5818&folderID=0

Cheers,
-- 
Jean-Baptiste Quenot
http://jbq.caraldi.com/

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox