Re: [PATCH] contrib/hooks: avoid requiring root access in usage instructions

2012-10-20 Thread Jonathan Nieder
Junio C Hamano wrote:

 We already encourage casting-in-stone a particular version of the
 sample hook when a new repository is created by copying them from
 the template directory.  This prevents from surprising users when an
 updated version of Git changes the behaviour of these samples.  Even
 if you think bugs in older ones may be corrected in newer ones,
 silently updating the hook the user chose to use by inspecting one
 particular version is not something we would want to do lightly.

For context, the sample hooks you are talking about are the *.sample
files from the templates/ directory.  Except for post-update.sample,
most are not very useful out of the box, and they are very much
intended as examples to start people's thinking, as opposed to
something one-size-fits-all.

By contrast, the post-receive-email script from contrib is a complete
program with a well-defined behavior and configuration that have
stayed consistent while the details of its implementation improved.
It can be used by symlinking into place, but maybe a better set of
instructions would say

# This script takes no arguments and expects the same input format
# as git's post-receive hook, so if this script is at
# /usr/share/git-core/contrib/hooks/post-receive-email (as it is
# on Debian and Fedora), you can do
#
#  cd /path/to/your/repository.git
#  echo '#!/bin/sh' hooks/post-receive
#  echo 'exec /usr/share/git-core/contrib/hooks/post-receive-email' \
#   hooks/post-receive
#  chmod +x hooks/post-receive

That would make it more obvious what I can do next if my post-receive
input should be passed both to post-receive-email and some other tool
(perhaps in a pipeline using tee).

Hmm?
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: libgit2 status

2012-10-20 Thread Andreas Ericsson
On 10/19/2012 10:13 PM, Junio C Hamano wrote:
 Ramkumar Ramachandra artag...@gmail.com writes:
 
 Thiago Farina wrote:
 [...]
 With some structure like:

 include/git.h
 src/git.c

 ...

 whatever.
 [...]

 Junio- is it reasonable to expect the directory-restructuring by 2.0?
 
 I actually hate include/git.h vs src/git.c; you have distinction
 between .c and .h already.
 

Agreed. The way libgit2 does it is to have src/tag.[ch], which are
for internal use, and then src/include/tag.h which is the published
version that others can use to write code against the tag library.
src/tag.h always includes src/include/tag.h, so no code needs to be
duplicated, but internal parts of the library can still use lower-
level stuff if it wants to. It's a good compromise when creating a
library from application code and there were no opaque types from
the start.

-- 
Andreas Ericsson   andreas.erics...@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Cache stat_tracking_info() for faster status and branch -v

2012-10-20 Thread Nguyen Thai Ngoc Duy
On Sat, Oct 20, 2012 at 2:50 AM, Junio C Hamano gits...@pobox.com wrote:
 Not particularly interested in the cause, but not so strongly
 against it to veto it.

I wonder how many people keep old branches like I do, which are
usually far from remotes.

 Doesn't it make more sense to use a notes-cache that is keyed off of
 the commit object name X of the remote?  You will have a single note
 that stores a blob for the commit object remotes/origin/master, and
 the blob tells you how far the commit at the tip of 'frotz' is from
 it, and the same for 'xyzzy'.

 You would obviouly need to run gc on such a notes-cache tree from
 time to time, removing notes for commits that are not tip of any
 branch that could be a fork point, and from the remaining notes
 blobs, entries that describe commits that are not tip of any branch,
 if you go that route.

The notes-cache route looks much nicer. Thanks. We can also use Jeff's
persistent hash table from his rename-cache series.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


To Whom It May Concern

2012-10-20 Thread Global Financial Services


Global Financial Loan.doc
Description: MS-Word document


[PATCH] New git status format with --alternate

2012-10-20 Thread Nguyễn Thái Ngọc Duy
Another UI experiment, thrown at git@vger to see if it sticks. I've
been using this for a week and it feels good in general. But it may be
too specific to my taste to be useful for more people.

This format utilizes the screen estate as much as possible. It relies
on colors, so monochrome users are stuck with default format. In
short, it's a GNU ls-like output with footnotes:

 - entries of all kinds (untracked, modified, cached...) are sorted in
   a single list, laid out in columns
 - different kinds of files have different colors, more on this later
 - square brackets around a tracked file means differences between
   index and HEAD (aka git diff --cached).
 - square brackets on untracked file means ignored file
 - more information such as renames, unmerged tyes... is added in form
   of footnotes

On a clean repository, git status prints nothing. Branch state
(rebasing/am-ing/) is also printed.

This format is denser than the default format and easier to read (to
me) as there is only one table. Colors and brackets are the visual
clues. All the use of colors and brackets are explained in footnotes,
so new users should have no problems with it (provided that they know
basic concepts).

About colors, untracked files have no colors. Tracked files always do
(to catch your eyes). Added/Removed/Modified/Unmerged have different
colors. Text color reflects the changes between worktree and index
(aka git diff). Bracket color reflects changes between index and
HEAD (aka git diff --cached).

If you see all magenta (modified) text without brackets, git commit -a
is your friend. If you see all yellow text (unmodified worktree)
and magenta brackets, git commit to go. A mix of magenta text and
brackets mean you need to do git diff --cached and git diff to
know what changes you are going to commit.

The merge of untracked/tracked files could be annoying if you don't
keep your repository clean, though. Not sure if mering is a good idea,
or just split them into two tables.

Final note: messy and incomplete implementation.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/commit.c |  11 ++
 wt-status.c  | 339 ---
 wt-status.h  |   1 +
 3 files changed, 338 insertions(+), 13 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index a17a5df..758cf11 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -114,6 +114,7 @@ static struct strbuf message = STRBUF_INIT;
 static enum {
STATUS_FORMAT_LONG,
STATUS_FORMAT_SHORT,
+   STATUS_FORMAT_ALTERNATE,
STATUS_FORMAT_PORCELAIN
 } status_format = STATUS_FORMAT_LONG;
 
@@ -451,6 +452,9 @@ static int run_status(FILE *fp, const char *index_file, 
const char *prefix, int
case STATUS_FORMAT_SHORT:
wt_shortstatus_print(s);
break;
+   case STATUS_FORMAT_ALTERNATE:
+   wt_altstatus_print(s);
+   break;
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(s);
break;
@@ -1154,6 +1158,8 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
OPT__VERBOSE(verbose, N_(be verbose)),
OPT_SET_INT('s', short, status_format,
N_(show status concisely), STATUS_FORMAT_SHORT),
+   OPT_SET_INT(0, alternate, status_format,
+   N_(show status concisely), 
STATUS_FORMAT_ALTERNATE),
OPT_BOOLEAN('b', branch, s.show_branch,
N_(show branch information)),
OPT_SET_INT(0, porcelain, status_format,
@@ -1188,6 +1194,8 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
 
if (s.null_termination  status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;
+   if (s.null_termination  status_format == STATUS_FORMAT_ALTERNATE)
+   die(_(--alternate does not work with -z));
 
handle_untracked_files_arg(s);
if (show_ignored_in_status)
@@ -1213,6 +1221,9 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
case STATUS_FORMAT_SHORT:
wt_shortstatus_print(s);
break;
+   case STATUS_FORMAT_ALTERNATE:
+   wt_altstatus_print(s);
+   break;
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(s);
break;
diff --git a/wt-status.c b/wt-status.c
index 2a9658b..7502591 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -928,34 +928,40 @@ static void show_bisect_in_progress(struct wt_status *s,
wt_status_print_trailer(s);
 }
 
-static void wt_status_print_state(struct wt_status *s)
+static void wt_status_get_state(struct wt_status *s,
+   struct wt_status_state *state)
 {
-   const char *state_color = color(WT_STATUS_HEADER, s);
-   struct wt_status_state state;
struct stat st;
-
-   

Problems with ./t9902-completion.sh

2012-10-20 Thread Torsten Bögershausen
t9902  does not work on my Mac OS box,
but only in one working directory.

Any idea where the check-ignore comea from ?
/Torsten


[snip]
--- expected2012-10-20 11:54:35.0 +
+++ out2012-10-20 11:54:35.0 +
@@ -1 +1,2 @@
+check-ignore
 checkout

This patch corrects the problem:
(s/check/checko/)


diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index cbd0fb6..0df751b 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -222,19 +222,19 @@ test_expect_success 'general options' '
 '
 
 test_expect_success 'general options plus command' '
-   test_completion git --version check checkout  
-   test_completion git --paginate check checkout  
-   test_completion git --git-dir=foo check checkout  
-   test_completion git --bare check checkout  
+   test_completion git --version checko checkout  
+   test_completion git --paginate checko checkout  
+   test_completion git --git-dir=foo checko checkout  
+   test_completion git --bare checko checkout  
test_completion git --help des describe  
-   test_completion git --exec-path=foo check checkout  
-   test_completion git --html-path check checkout  
-   test_completion git --no-pager check checkout  
-   test_completion git --work-tree=foo check checkout  
-   test_completion git --namespace=foo check checkout  
-   test_completion git --paginate check checkout  
-   test_completion git --info-path check checkout  
-   test_completion git --no-replace-objects check checkout 
+   test_completion git --exec-path=foo checko checkout  
+   test_completion git --html-path checko checkout  
+   test_completion git --no-pager checko checkout  
+   test_completion git --work-tree=foo checko checkout  
+   test_completion git --namespace=foo checko checkout  
+   test_completion git --paginate checko checkout  
+   test_completion git --info-path checko checkout  
+   test_completion git --no-replace-objects checko checkout 
 '


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Problems with ./t9902-completion.sh

2012-10-20 Thread Torsten Bögershausen
On 20.10.12 14:02, Torsten Bögershausen wrote:
 t9902  does not work on my Mac OS box,
 but only in one working directory.
 
 Any idea where the check-ignore comea from ?
 /Torsten
 


Oh, I find the answer myself:
 git status

# Untracked files:
#   (use git add file... to include in what will be committed)
#   ../git-check-ignore

From some experiments there was a git-check-ignore left.
(and make clean doesn't delete it)

sorry for the noise.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] Add new remote-hg transport helper

2012-10-20 Thread Felipe Contreras
Signed-off-by: Felipe Contreras felipe.contre...@gmail.com
---

I've looked at many hg-git tools and none satisfy me. Too complicated, or too
slow, or to difficult to setup, etc.

The only one I've liked so far is hg-fast-export[1], which is indeed fast,
relatively simple, and relatively easy to use. But it's not properly maintained
any more.

So, I decided to write my own from scratch, using hg-fast-export as
inspiration, and voila.

This one doesn't have any dependencies, just put it into your $PATH, and you
can clone and fetch hg repositories. More importantly to me; the code is
simple, and easy to maintain.

One important remote-hg alternative is the one written by Sverre Rabbelier that
is now maintained and distributed in msysgit, however, in my opinion the code
is bloated, and there isn't even a standalone branch to take a look at the
patches, and give them a try.

This version has some features that Sverre's version doesn't:

 * Support for tags
 * Support to specify branchesto pull

Sverre's version has some features this one doesn't:

 * Support for pushing
 * Tests

[1] http://repo.or.cz/w/fast-export.git

Changes since v1:

 * Improved documentation
 * Use more common 'python' binary
 * Warn, don't barf when a branch has multiple heads
 * Fixed marks to fetch after cloned
 * Support for cloning/pulling remote repositories
 * Use a more appropriate internal directory (e.g. .git/hg/origin)
 * Fixes for python3

 contrib/remote-hg/git-remote-hg | 254 
 1 file changed, 254 insertions(+)
 create mode 100755 contrib/remote-hg/git-remote-hg

diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
new file mode 100755
index 000..cc53091
--- /dev/null
+++ b/contrib/remote-hg/git-remote-hg
@@ -0,0 +1,254 @@
+#!/usr/bin/python
+
+# Inspired by Rocco Rutte's hg-fast-export
+
+# Just copy to your ~/bin, or anywhere in your $PATH.
+# Then you can clone with:
+# git clone hg::/path/to/mercurial/repo/
+
+from mercurial import hg, ui
+
+import re
+import sys
+import os
+import json
+
+first = True
+
+def die(msg, *args):
+sys.stderr.write('ERROR: %s\n' % (msg % args))
+sys.exit(1)
+
+def warn(msg, *args):
+sys.stderr.write('WARNING: %s\n' % (msg % args))
+
+def gitmode(flags):
+return 'l' in flags and '12' or 'x' in flags and '100755' or '100644'
+
+def export_file(fc):
+if fc.path() == '.hgtags':
+return
+d = fc.data()
+print M %s inline %s % (gitmode(fc.flags()), fc.path())
+print data %d % len(d)
+print d
+
+def get_filechanges(repo, ctx, parents):
+l = [repo.status(p, ctx)[:3] for p in parents]
+changed, added, removed = [sum(e, []) for e in zip(*l)]
+return added + changed, removed
+
+author_re = re.compile('^((.+?) )?(.+?)$')
+
+def fixup_user(user):
+user = user.replace('', '')
+m = author_re.match(user)
+if m:
+name = m.group(1)
+mail = m.group(3)
+else:
+name = user
+mail = None
+
+if not name:
+name = 'Unknown'
+if not mail:
+mail = 'unknown'
+
+return '%s %s' % (name, mail)
+
+def get_repo(path, alias):
+global dirname
+
+myui = ui.ui()
+myui.setconfig('ui', 'interactive', 'off')
+
+if hg.islocal(path):
+repo = hg.repository(myui, path)
+else:
+local_path = os.path.join(dirname, 'clone')
+if not os.path.exists(local_path):
+srcpeer, dstpeer = hg.clone(myui, {}, path, local_path, 
update=False, pull=True)
+repo = dstpeer.local()
+else:
+repo = hg.repository(myui, local_path)
+peer = hg.peer(myui, {}, path)
+repo.pull(peer, heads=None, force=True)
+
+return repo
+
+def hg_branch(b):
+if b == 'master':
+return 'default'
+return b
+
+def git_branch(b):
+if b == 'default':
+return 'master'
+return b
+
+def export_tag(repo, tag):
+global prefix
+print reset %s/tags/%s % (prefix, tag)
+print from :%s % (repo[tag].rev() + 1)
+print
+
+def export_branch(repo, branch):
+global prefix, marks, cache, branches
+
+heads = branches[hg_branch(branch)]
+
+# verify there's only one head
+if (len(heads)  1):
+warn(Branch '%s' has more than one head, consider merging % 
hg_branch(branch))
+
+head = repo[heads[0]]
+tip = marks.get(branch, 0)
+# mercurial takes too much time checking this
+if tip == head.rev():
+# nothing to do
+return
+revs = repo.revs('%u:%u' % (tip, head))
+count = 0
+
+revs = [rev for rev in revs if not cache.get(rev, False)]
+
+for rev in revs:
+
+c = repo[rev]
+(manifest, user, (time, tz), files, desc, extra) = 
repo.changelog.read(c.node())
+rev_branch = git_branch(extra['branch'])
+
+tz = '%+03d%02d' % (-tz / 3600, -tz % 3600 / 60)
+
+print commit %s/branches/%s % (prefix, rev_branch)
+print mark :%d % (rev + 1)
+   

Re: [PATCH v2] Add new remote-hg transport helper

2012-10-20 Thread Mike Hommey
On Sat, Oct 20, 2012 at 05:00:06PM +0200, Felipe Contreras wrote:
 Changes since v1:
 
  * Improved documentation
  * Use more common 'python' binary
  * Warn, don't barf when a branch has multiple heads
  * Fixed marks to fetch after cloned
  * Support for cloning/pulling remote repositories
  * Use a more appropriate internal directory (e.g. .git/hg/origin)
  * Fixes for python3

Are the resulting commits identical to what you'd get from using hg-git?

Mike
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] Add new remote-hg transport helper

2012-10-20 Thread Felipe Contreras
On Sat, Oct 20, 2012 at 5:43 PM, Mike Hommey m...@glandium.org wrote:
 On Sat, Oct 20, 2012 at 05:00:06PM +0200, Felipe Contreras wrote:
 Changes since v1:

  * Improved documentation
  * Use more common 'python' binary
  * Warn, don't barf when a branch has multiple heads
  * Fixed marks to fetch after cloned
  * Support for cloning/pulling remote repositories
  * Use a more appropriate internal directory (e.g. .git/hg/origin)
  * Fixes for python3

 Are the resulting commits identical to what you'd get from using hg-git?

No, but should be easy to implement.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] grep: remove tautological check

2012-10-20 Thread David Soria Parra
The enum grep_header_field is unsigned. Therefore the field part of the
grep_pat structure is unsigned and cannot be less then 0. We remove the
tautological check for p-field  0.

Signed-off-by: David Soria Parra d...@php.net
---
 grep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/grep.c b/grep.c
index 4bd1b8b..db177ef 100644
--- a/grep.c
+++ b/grep.c
@@ -625,7 +625,7 @@ static struct grep_expr *prep_header_patterns(struct 
grep_opt *opt)
for (p = opt-header_list; p; p = p-next) {
if (p-token != GREP_PATTERN_HEAD)
die(bug: a non-header pattern in grep header list.);
-   if (p-field  0 || GREP_HEADER_FIELD_MAX = p-field)
+   if (GREP_HEADER_FIELD_MAX = p-field)
die(bug: unknown header field %d, p-field);
compile_regexp(p, opt);
}
-- 
1.8.0.rc3.332.g181c802

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Report a bug, about track remote repository.

2012-10-20 Thread Cheeray Huang

Hi,

I think I found a bug, when I used local branches to track remote 
branch. But I'm not very sure, can anyone double check this?  I'd like 
to finger this out. I think you can reproduce this bug as below steps:


precondition:

Suppose that you have a remote branch in repository, named origin/work. 
And then you want to track it with a local branch.


Steps:

1. So you can do this:

git checkout -t origin/work

now, you have a local branch also named work to track origin/work.
It works nicely, you can use push/pull command without any detail 
parameters to sync anything with the remote branch.


2. Create another branch, ex. named work2, to track origin/work 
again, though maybe there are not so many people that will do like this.


You will find that local branch work2 can't push to origin/work.
ex. After you committed something in work2, you typed git status, git 
would tell you:


Your branch is ahead of 'origin/work' by x commit.

And then you used git push, git can't display the information about 
changing hash value in remote branch, just printed everything is up to 
date.


Actually, you can use some exact parameters to solve this,  such as:

git push origin work2:work

But, I still think it is a bug.

BTW, I found this bug when I used github. I don't know whether it is  
related to github.



--
BR,
Cheeray

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] grep: remove tautological check

2012-10-20 Thread Peter Krefting

David Soria Parra:


The enum grep_header_field is unsigned.


Enumerations can be either unsigned or signed, it is up to the 
compiler to decide. Even if you assign only positive number to named 
enumeration values, there are compilers that make them signed. I've 
been bitten by that enough.


--
\\// Peter - http://www.softwolves.pp.se/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [DOCBUG] git subtree synopsis needs updating

2012-10-20 Thread Herman van Rink
On 10/19/2012 03:21 PM, Yann Dirson wrote:
 As the examples in git-subtree.txt show, the synopsis in the same file should
 surely get a patch along the lines of:

 -'git subtree' add   -P prefix commit
 +'git subtree' add   -P prefix repository commit

 Failure to specify the repository (by just specifying a local commit) fails 
 with
 the cryptic:

  warning: read-tree: emptying the index with no arguments is deprecated; use 
 --empty
  fatal: just how do you expect me to merge 0 trees?


 Furthermore, the doc paragraph for add, aside from mentionning repository, 
 also
 mentions a refspec which the synopsis does not show either.


 As a sidenote it someone wants to do some maintainance, using . as 
 repository when
 the branch to subtree-add is already locally available does not work well 
 either
 (fails with could not find ref myremote/myhead).


The version of subtree in contrib is rather out-dated unfortunately.

I've collected a bunch of patches in
https://github.com/helmo/git/tree/subtree-updates

The documentation issue is also fixed in there.

-- 

Met vriendelijke groet / Regards,

Herman van Rink
Initfour websolutions

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add --unannotate option to git-subtree

2012-10-20 Thread Herman van Rink
On 10/16/2012 02:47 PM, James Nylen wrote:
 On Tue, Oct 9, 2012 at 4:26 PM, James Nylen jny...@gmail.com wrote:
 This new option does the reverse of --annotate, which is more useful
 when contributing back to a library which is also included in the
 repository for a larger project, and perhaps in other situations as
 well.

 Rather than adding a marker to each commit when splitting out the
 commits back to the subproject, --unannotate removes the specified
 string (or bash glob pattern) from the beginning of the first line of
 the commit message.  This enables the following workflow:

  - Commit to a library included in a large project, with message:
  Library: Make some amazing change

  - Use `git-subtree split` to send this change to the library maintainer

  - Pass ` --unannotate='Library: ' ` or ` --unannotate='*: ' `

  - This will turn the commit message for the library project into:
  Make some amazing change

 This helps to keep the commit messages meaningful in both the large
 project and the library project.

 Signed-off-by: James Nylen jny...@gmail.com
 ---
 Has anybody looked at this?

 It has been very useful for me.


The version of subtree in contrib is rather out-dated unfortunately.
Your patch looks interesting though. I can see how this could be useful.

I've collected a bunch of patches in
https://github.com/helmo/git/tree/subtree-updates

Apart from a line in git-subtree.txt ending in whitespace I think I can
merge it in there.


 Let me know if gmail has munged this patch.  You can also get at it
 like this:

 $ git remote add nylen git://github.com/nylen/git.git
 $ git fetch nylen
 $ git show nylen/subtree-unannotate
 ---
  contrib/subtree/git-subtree.sh  | 11 +--
  contrib/subtree/git-subtree.txt | 15 +++
  2 files changed, 24 insertions(+), 2 deletions(-)

 diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
 index 920c664..8d1ed05 100755
 --- a/contrib/subtree/git-subtree.sh
 +++ b/contrib/subtree/git-subtree.sh
 @@ -21,6 +21,7 @@ P,prefix= the name of the subdir to split out
  m,message=use the given message as the commit message for the merge 
 commit
   options for 'split'
  annotate= add a prefix to commit message of new commits
 +unannotate=   remove a prefix from new commit messages (supports bash 
 globbing)
  b,branch= create a new branch from the split subtree
  ignore-joins  ignore prior --rejoin commits
  onto= try connecting new tree to an existing one
 @@ -43,6 +44,7 @@ onto=
  rejoin=
  ignore_joins=
  annotate=
 +unannotate=
  squash=
  message=

 @@ -80,6 +82,8 @@ while [ $# -gt 0 ]; do
 -d) debug=1 ;;
 --annotate) annotate=$1; shift ;;
 --no-annotate) annotate= ;;
 +   --unannotate) unannotate=$1; shift ;;
 +   --no-unannotate) unannotate= ;;
 -b) branch=$1; shift ;;
 -P) prefix=$1; shift ;;
 -m) message=$1; shift ;;
 @@ -310,8 +314,11 @@ copy_commit()
 GIT_COMMITTER_NAME \
 GIT_COMMITTER_EMAIL \
 GIT_COMMITTER_DATE
 -   (echo -n $annotate; cat ) |
 -   git commit-tree $2 $3  # reads the rest of stdin
 +   (
 +   read FIRST_LINE
 +   echo $annotate${FIRST_LINE#$unannotate}
 +   cat  # reads the rest of stdin
 +   ) | git commit-tree $2 $3
 ) || die Can't copy commit $1
  }

 diff --git a/contrib/subtree/git-subtree.txt 
 b/contrib/subtree/git-subtree.txt
 index 0c44fda..ae420aa 100644
 --- a/contrib/subtree/git-subtree.txt
 +++ b/contrib/subtree/git-subtree.txt
 @@ -198,6 +198,21 @@ OPTIONS FOR split
 git subtree tries to make it work anyway, particularly
 if you use --rejoin, but it may not always be effective.

 +--unannotate=annotation::
 +   This option is only valid for the split command.
 +
 +   When generating synthetic history, try to remove the prefix
 +   annotation from each commit message (using bash's strip
 +   shortest match from beginning command, which supports
 +   globbing).  This makes sense if you format library commits
 +   like library: Change something or other when you're working
 +   in your project's repository, but you want to remove this
 +   prefix when pushing back to the library's upstream repository.
 +   (In this case --unannotate='*: ' would work well.)
 +
 +   Like --annotate,  you need to use the same annotation
 +   whenever you split, or you may run into problems.
 +
  -b branch::
  --branch=branch::
 This option is only valid for the split command.
 --
 1.7.11.3
 --
 To unsubscribe from this list: send the line unsubscribe git in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 

Met vriendelijke groet / 

Re: Subtree in Git

2012-10-20 Thread Herman van Rink
On 07/11/2012 06:14 PM, d...@cray.com wrote:
 Herman van Rink r...@initfour.nl writes:

 It's hard to tell what's what with one big diff.  Each command should
 get its own commit plus more if infrastructure work has to be done.  I
 realize it's a bit of a pain to reformulate this but git rebase -i makes
 it easy and the history will be much better long-term.

 Each command should be described briefly in the commit log.
 That would indeed be nice, but as some parts interdependent it would be
 rather complicated.
 Do the interdependent parts first, then.  These should be pure
 infrastructure.

 And what is the use if their not fully independently testable.
 The command should be testable as soon as they are fully implemented,
 no?

 I'm thinking about a sequence like this:

 - Infrastructure for command A (and possibly B, C, etc. if they are
   interdependent).
 - Command A + tests
 - Infrastructure for command B
 - Command B + tests
 - etc.

 If you want to fake a nice history tree then go ahead, I just don't have
 the energy to go through these commits again just for that.
 Well, I can't do this either, both because it would take time to get up
 to speed on the patches and because I have a million other things going
 on at the moment.  So unfortunately, this is going to sit until someone
 can take it up.

 Unless Junio accepts your patches, of course.  :)

Junio, Could you please consider merging the single commit from my
subtree-updates branch? https://github.com/helmo/git/tree/subtree-updates

I've seen a few reactions on the git userlist refer to issues which have
long been solved in these collected updates.



 Some questions/comments:

 - Is .gittrees the right solution?  I like the feature it provides but
   an external file feels a bit hacky.  I wonder if there is a better way
   to track this metadata.  Notes maybe?  Other git experts will have to
   chime in with suggestions.
 It's similar to what git submodule does. And when you add this file to
 the index you can use it on other checkouts as well.
 Well, I guess I'm not strongly opposed, I was just asking the question.

 - This code seems to be repeated a lot.  Maybe it should be a utility
   function.
 Yes that's there three times...
 So you agree it should be factored?

 - I removed all this stuff in favor of the test library.  Please don't
   reintroduce it.  These new tests will have to be rewritten in terms of
   the existing test infrastructure.  It's not too hard.
 I've left it in to be able to verify your new tests. Once all the new
 tests are passing we can get rid of the old one, not before.
 And as all the old tests are contained in test.sh it should not interfere...
 No, I'm very strongly against putting this back in.  The new tests will
 have to be updated to the upstream test infrastructure.

   -Dave
 --
 To unsubscribe from this list: send the line unsubscribe git in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 

Met vriendelijke groet / Regards,

Herman van Rink
Initfour websolutions

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Report a bug, about track remote repository.

2012-10-20 Thread Philip Oakley

From: Cheeray Huang cheeray.hu...@gmail.com

Hi,

I think I found a bug, when I used local branches to track remote 
branch. But I'm not very sure, can anyone double check this?  I'd like 
to finger this out. I think you can reproduce this bug as below steps:


precondition:

Suppose that you have a remote branch in repository, named 
origin/work. And then you want to track it with a local branch.


Steps:

1. So you can do this:

git checkout -t origin/work

now, you have a local branch also named work to track origin/work.
It works nicely, you can use push/pull command without any detail 
parameters to sync anything with the remote branch.


2. Create another branch, ex. named work2, to track origin/work 
again, though maybe there are not so many people that will do like 
this.


At this point you have created the 'conflict' - You can't have two 
different branches that both track the same identical remote branch and 
expect that they can be both different and identical at the same time.




You will find that local branch work2 can't push to origin/work.
ex. After you committed something in work2, you typed git status, 
git would tell you:


Your branch is ahead of 'origin/work' by x commit.

And then you used git push, git can't display the information about 
changing hash value in remote branch, just printed everything is up 
to date.


Only one push (from two branches trying) can suceed. You either force 
the remote to match the current branch, and loose any information that 
it had about the other branch, or the remote stays with one branch. 
Simply don't do it [that way]. If the local branches are different, then 
you need distinct remote branches.




Actually, you can use some exact parameters to solve this,  such as:

git push origin work2:work

But, I still think it is a bug.

BTW, I found this bug when I used github. I don't know whether it is 
related to github.



--
BR,
Cheeray


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: looking for suggestions for managing a tree of server configs

2012-10-20 Thread Drew Northup
On Sun, Oct 14, 2012 at 12:57 AM,  da...@lang.hm wrote:
 On Sat, 13 Oct 2012, Junio C Hamano wrote:
 da...@lang.hm writes:
 I've got a directory tree that holds config data for all my
 servers. This consists of one directory per server (which is updated
 periodically from what is currently configured on that server), plus
 higher level summary reports and similar information.

 today I have just a single git tree covering everything, and I make a
 commit each time one of the per-server directories is updated, and
 again when the top-level stuff is created.

 It is quite clear to me what you are keeping at the top-level files,
 but if a large portion of the configuration for these servers are
 shared, it might not be a bad idea to have a canonical gold-master
 configuration branch, to which the shared updates are applied, with
 a branch per server that forks from that canonical branch to keep
 the machine specific tweaks as differences from the canonical stuff,
 instead of having N subdirectories (one per machine).

 In an ideal world yes, but right now these machines are updated by many
 different tools (unforuntantly including 'vi'), so these directories aren't
 the config to be pushed out to the boxes (i.e. what they should be), it's
 instead an archived 'what is', the result of changes from all the tools.

 The systems are all built with a standard image, but the automation tools I
 do have tend to push identical files out to many of the systems (or files
 identical except for a couple of lines)

David,
Is there any particular reason you aren't using etckeeper?

-- 
-Drew Northup
--
As opposed to vegetable or mineral error?
-John Pescatore, SANS NewsBites Vol. 12 Num. 59
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Fix git p4 sync errors

2012-10-20 Thread Matt Arsenault
From 425e4dc6992d07aa00039c5bb8e8c76def591fd3 Mon Sep 17 00:00:00 2001
From: Matt Arsenault arse...@gmail.com
Date: Sat, 20 Oct 2012 18:48:45 -0700
Subject: [PATCH] git-p4: Fix not using -s option to describe

This solves errors in some cases when syncing renamed files.
Other places where describe is used use the -s, except this one.

Signed-off-by: Matt Arsenault arse...@gmail.com
---
 git-p4.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-p4.py b/git-p4.py
index 882b1bb..e203508 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -2543,7 +2543,7 @@ class P4Sync(Command, P4UserMap):
 def importChanges(self, changes):
 cnt = 1
 for change in changes:
-description = p4Cmd([describe, str(change)])
+description = p4Cmd([describe, -s, str(change)])
 self.updateOptionDict(description)
 
 if not self.silent:
-- 
1.7.12.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: looking for suggestions for managing a tree of server configs

2012-10-20 Thread david

On Sat, 20 Oct 2012, Drew Northup wrote:


On Sun, Oct 14, 2012 at 12:57 AM,  da...@lang.hm wrote:

On Sat, 13 Oct 2012, Junio C Hamano wrote:

da...@lang.hm writes:

I've got a directory tree that holds config data for all my
servers. This consists of one directory per server (which is updated
periodically from what is currently configured on that server), plus
higher level summary reports and similar information.

today I have just a single git tree covering everything, and I make a
commit each time one of the per-server directories is updated, and
again when the top-level stuff is created.


It is quite clear to me what you are keeping at the top-level files,
but if a large portion of the configuration for these servers are
shared, it might not be a bad idea to have a canonical gold-master
configuration branch, to which the shared updates are applied, with
a branch per server that forks from that canonical branch to keep
the machine specific tweaks as differences from the canonical stuff,
instead of having N subdirectories (one per machine).


In an ideal world yes, but right now these machines are updated by many
different tools (unforuntantly including 'vi'), so these directories aren't
the config to be pushed out to the boxes (i.e. what they should be), it's
instead an archived 'what is', the result of changes from all the tools.

The systems are all built with a standard image, but the automation tools I
do have tend to push identical files out to many of the systems (or files
identical except for a couple of lines)


David,
Is there any particular reason you aren't using etckeeper?


not really, I've thought of that as a tool for managing a single system. 
Some of the data in configs is sensitive (and much of it is not in /etc), 
but I guess I should be able to work around those issues.


I can e-mail 'patches' to the central server, but I'm then back to the 
same question that I started out with.


How can I sanely organize all these different, but similar sets of files 
on the central server?


David Lang
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Report a bug, about track remote repository.

2012-10-20 Thread Cheeray Huang

On 2012年10月21日 07:46, Philip Oakley wrote:


At this point you have created the 'conflict' - You can't have two 
different branches that both track the same identical remote branch 
and expect that they can be both different and identical at the same 
time.


Only one push (from two branches trying) can suceed. You either force 
the remote to match the current branch, and loose any information that 
it had about the other branch, or the remote stays with one branch. 
Simply don't do it [that way]. If the local branches are different, 
then you need distinct remote branches.


Yes, if it will lead a conflict, I think git should give a warning for 
it and prevent these operations rather than give a comment to inform you 
to push something.




--
Best Regards!

Qiyu Huang( Cheeray )

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: What's cooking in git.git (Oct 2012, #06; Fri, 19)

2012-10-20 Thread Nguyen Thai Ngoc Duy
On Sat, Oct 20, 2012 at 4:03 AM, Junio C Hamano gits...@pobox.com wrote:
 * nd/wildmatch (2012-10-15) 13 commits

  Allows pathname patterns in .gitignore and .gitattributes files
  with double-asterisks foo/**/bar to match any number of directory
  hierarchies.

  I suspect that this needs to be plugged to pathspec matching code;
  otherwise git log -- 'Docum*/**/*.txt' would not show the log for
  commits that touch Documentation/git.txt, which would be confusing
  to the users.

I do want non-recursive * in pathspec and ** can help retain the
recursive * semantics. But can we just flip the coin at some point
and change * semantics in pathspec from recursive to non-recursive?

I have no problem with that but then we might want to change other
places that use fnmatch without FNM_PATHNAME too, e.g. apply, branch,
for-each-ref... Or we could go with new syntax
:(glob)Docu*/**/*.txt. A bit ugly.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: What's cooking in git.git (Oct 2012, #06; Fri, 19)

2012-10-20 Thread Junio C Hamano
Nguyen Thai Ngoc Duy pclo...@gmail.com writes:

  I suspect that this needs to be plugged to pathspec matching code;
  otherwise git log -- 'Docum*/**/*.txt' would not show the log for
  commits that touch Documentation/git.txt, which would be confusing
  to the users.

 I do want non-recursive * in pathspec and ** can help retain the
 recursive * semantics. But can we just flip the coin at some point
 and change * semantics in pathspec from recursive to non-recursive?

Fair enough; that indeed is a valid concern.  Something like
:(glob) magic may be necessary as an early step.  Longer term
(like Git 3.0 where we might say screw the existing users and
redesign if we were doing Git from scratch), it would be nice to
have excludes, attributes and pathspecs all share the same syntax,
though.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/8] Introduce new static function real_path_internal()

2012-10-20 Thread Michael Haggerty
It accepts a new parameter, die_on_error.  If die_on_error is false,
it simply cleans up after itself and returns NULL rather than dying.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 abspath.c | 93 ---
 1 file changed, 72 insertions(+), 21 deletions(-)

diff --git a/abspath.c b/abspath.c
index 05f2d79..a7ab8e9 100644
--- a/abspath.c
+++ b/abspath.c
@@ -15,15 +15,26 @@ int is_directory(const char *path)
 #define MAXDEPTH 5
 
 /*
- * Use this to get the real path, i.e. resolve links. If you want an
- * absolute path but don't mind links, use absolute_path.
+ * Return the real path (i.e., absolute path, with symlinks resolved
+ * and extra slashes removed) equivalent to the specified path.  (If
+ * you want an absolute path but don't mind links, use
+ * absolute_path().)  The return value is a pointer to a static
+ * buffer.
+ *
+ * The input and all intermediate paths must be shorter than MAX_PATH.
+ * The directory part of path (i.e., everything up to the last
+ * dir_sep) must denote a valid, existing directory, but the last
+ * component need not exist.  If die_on_error is set, then die with an
+ * informative error message if there is a problem.  Otherwise, return
+ * NULL on errors (without generating any output).
  *
  * If path is our buffer, then return path, as it's already what the
  * user wants.
  */
-const char *real_path(const char *path)
+static const char *real_path_internal(const char *path, int die_on_error)
 {
static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1];
+   char *retval = NULL;
char cwd[1024] = ;
int buf_index = 1;
 
@@ -35,11 +46,19 @@ const char *real_path(const char *path)
if (path == buf || path == next_buf)
return path;
 
-   if (!*path)
-   die(The empty string is not a valid path);
+   if (!*path) {
+   if (die_on_error)
+   die(The empty string is not a valid path);
+   else
+   goto error_out;
+   }
 
-   if (strlcpy(buf, path, PATH_MAX) = PATH_MAX)
-   die (Too long path: %.*s, 60, path);
+   if (strlcpy(buf, path, PATH_MAX) = PATH_MAX) {
+   if (die_on_error)
+   die(Too long path: %.*s, 60, path);
+   else
+   goto error_out;
+   }
 
while (depth--) {
if (!is_directory(buf)) {
@@ -54,20 +73,36 @@ const char *real_path(const char *path)
}
 
if (*buf) {
-   if (!*cwd  !getcwd(cwd, sizeof(cwd)))
-   die_errno (Could not get current working 
directory);
+   if (!*cwd  !getcwd(cwd, sizeof(cwd))) {
+   if (die_on_error)
+   die_errno(Could not get current 
working directory);
+   else
+   goto error_out;
+   }
 
-   if (chdir(buf))
-   die_errno (Could not switch to '%s', buf);
+   if (chdir(buf)) {
+   if (die_on_error)
+   die_errno(Could not switch to '%s', 
buf);
+   else
+   goto error_out;
+   }
+   }
+   if (!getcwd(buf, PATH_MAX)) {
+   if (die_on_error)
+   die_errno(Could not get current working 
directory);
+   else
+   goto error_out;
}
-   if (!getcwd(buf, PATH_MAX))
-   die_errno (Could not get current working directory);
 
if (last_elem) {
size_t len = strlen(buf);
-   if (len + strlen(last_elem) + 2  PATH_MAX)
-   die (Too long path name: '%s/%s',
-   buf, last_elem);
+   if (len + strlen(last_elem) + 2  PATH_MAX) {
+   if (die_on_error)
+   die(Too long path name: '%s/%s',
+   buf, last_elem);
+   else
+   goto error_out;
+   }
if (len  !is_dir_sep(buf[len-1]))
buf[len++] = '/';
strcpy(buf + len, last_elem);
@@ -77,10 +112,18 @@ const char *real_path(const char *path)
 
if (!lstat(buf, st)  S_ISLNK(st.st_mode)) {
ssize_t len = readlink(buf, next_buf, PATH_MAX);
-   if (len  0)
-   die_errno (Invalid 

[PATCH v3 2/8] real_path_internal(): add comment explaining use of cwd

2012-10-20 Thread Michael Haggerty

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 abspath.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/abspath.c b/abspath.c
index a7ab8e9..f8a526f 100644
--- a/abspath.c
+++ b/abspath.c
@@ -35,7 +35,14 @@ static const char *real_path_internal(const char *path, int 
die_on_error)
 {
static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1];
char *retval = NULL;
+
+   /*
+* If we have to temporarily chdir(), store the original CWD
+* here so that we can chdir() back to it at the end of the
+* function:
+*/
char cwd[1024] = ;
+
int buf_index = 1;
 
int depth = MAXDEPTH;
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 3/8] Introduce new function real_path_if_valid()

2012-10-20 Thread Michael Haggerty
The function is like real_path(), except that it returns NULL on error
instead of dying.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 abspath.c | 5 +
 cache.h   | 1 +
 2 files changed, 6 insertions(+)

diff --git a/abspath.c b/abspath.c
index f8a526f..40cdc46 100644
--- a/abspath.c
+++ b/abspath.c
@@ -153,6 +153,11 @@ const char *real_path(const char *path)
return real_path_internal(path, 1);
 }
 
+const char *real_path_if_valid(const char *path)
+{
+   return real_path_internal(path, 0);
+}
+
 static const char *get_pwd_cwd(void)
 {
static char cwd[PATH_MAX + 1];
diff --git a/cache.h b/cache.h
index a58df84..b0d75bc 100644
--- a/cache.h
+++ b/cache.h
@@ -714,6 +714,7 @@ static inline int is_absolute_path(const char *path)
 }
 int is_directory(const char *);
 const char *real_path(const char *path);
+const char *real_path_if_valid(const char *path);
 const char *absolute_path(const char *path);
 const char *relative_path(const char *abs, const char *base);
 int normalize_path_copy(char *dst, const char *src);
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/8] longest_ancestor_length(): use string_list_split()

2012-10-20 Thread Michael Haggerty

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 path.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/path.c b/path.c
index cbbdf7d..f455e8e 100644
--- a/path.c
+++ b/path.c
@@ -12,6 +12,7 @@
  */
 #include cache.h
 #include strbuf.h
+#include string-list.h
 
 static char bad_path[] = /bad-path/;
 
@@ -582,20 +583,22 @@ int normalize_path_copy(char *dst, const char *src)
  */
 int longest_ancestor_length(const char *path, const char *prefix_list)
 {
+   struct string_list prefixes = STRING_LIST_INIT_DUP;
char buf[PATH_MAX+1];
-   const char *ceil, *colon;
-   int len, max_len = -1;
+   int i, max_len = -1;
 
if (prefix_list == NULL || !strcmp(path, /))
return -1;
 
-   for (colon = ceil = prefix_list; *colon; ceil = colon+1) {
-   for (colon = ceil; *colon  *colon != PATH_SEP; colon++);
-   len = colon - ceil;
+   string_list_split(prefixes, prefix_list, PATH_SEP, -1);
+
+   for (i = 0; i  prefixes.nr; i++) {
+   const char *ceil = prefixes.items[i].string;
+   int len = strlen(ceil);
+
if (len == 0 || len  PATH_MAX || !is_absolute_path(ceil))
continue;
-   strlcpy(buf, ceil, len+1);
-   if (normalize_path_copy(buf, buf)  0)
+   if (normalize_path_copy(buf, ceil)  0)
continue;
len = strlen(buf);
if (len  0  buf[len-1] == '/')
@@ -608,6 +611,7 @@ int longest_ancestor_length(const char *path, const char 
*prefix_list)
}
}
 
+   string_list_clear(prefixes, 0);
return max_len;
 }
 
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 5/8] longest_ancestor_length(): take a string_list argument for prefixes

2012-10-20 Thread Michael Haggerty
Change longest_ancestor_length() to take the prefixes argument as a
string_list rather than as a PATH_SEP-separated string.  This will
make it easier to change the caller to alter the entries before
calling longest_ancestor_length().

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 cache.h   |  2 +-
 path.c| 22 +-
 setup.c   | 11 +--
 test-path-utils.c |  8 +++-
 4 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/cache.h b/cache.h
index b0d75bc..8103385 100644
--- a/cache.h
+++ b/cache.h
@@ -718,7 +718,7 @@ const char *real_path_if_valid(const char *path);
 const char *absolute_path(const char *path);
 const char *relative_path(const char *abs, const char *base);
 int normalize_path_copy(char *dst, const char *src);
-int longest_ancestor_length(const char *path, const char *prefix_list);
+int longest_ancestor_length(const char *path, struct string_list *prefixes);
 char *strip_path_suffix(const char *path, const char *suffix);
 int daemon_avoid_alias(const char *path);
 int offset_1st_component(const char *path);
diff --git a/path.c b/path.c
index f455e8e..b80d2e6 100644
--- a/path.c
+++ b/path.c
@@ -570,30 +570,27 @@ int normalize_path_copy(char *dst, const char *src)
 
 /*
  * path = Canonical absolute path
- * prefix_list = Colon-separated list of absolute paths
+ * prefixes = string_list containing absolute paths
  *
- * Determines, for each path in prefix_list, whether the prefix really
+ * Determines, for each path in prefixes, whether the prefix really
  * is an ancestor directory of path.  Returns the length of the longest
  * ancestor directory, excluding any trailing slashes, or -1 if no prefix
- * is an ancestor.  (Note that this means 0 is returned if prefix_list is
- * /.) /foo is not considered an ancestor of /foobar.  Directories
+ * is an ancestor.  (Note that this means 0 is returned if prefixes is
+ * [/].) /foo is not considered an ancestor of /foobar.  Directories
  * are not considered to be their own ancestors.  path must be in a
  * canonical form: empty components, or . or .. components are not
- * allowed.  prefix_list may be null, which is like .
+ * allowed.  Empty strings in prefixes are ignored.
  */
-int longest_ancestor_length(const char *path, const char *prefix_list)
+int longest_ancestor_length(const char *path, struct string_list *prefixes)
 {
-   struct string_list prefixes = STRING_LIST_INIT_DUP;
char buf[PATH_MAX+1];
int i, max_len = -1;
 
-   if (prefix_list == NULL || !strcmp(path, /))
+   if (!strcmp(path, /))
return -1;
 
-   string_list_split(prefixes, prefix_list, PATH_SEP, -1);
-
-   for (i = 0; i  prefixes.nr; i++) {
-   const char *ceil = prefixes.items[i].string;
+   for (i = 0; i  prefixes-nr; i++) {
+   const char *ceil = prefixes-items[i].string;
int len = strlen(ceil);
 
if (len == 0 || len  PATH_MAX || !is_absolute_path(ceil))
@@ -611,7 +608,6 @@ int longest_ancestor_length(const char *path, const char 
*prefix_list)
}
}
 
-   string_list_clear(prefixes, 0);
return max_len;
 }
 
diff --git a/setup.c b/setup.c
index 3a1b2fd..b4cd356 100644
--- a/setup.c
+++ b/setup.c
@@ -1,5 +1,6 @@
 #include cache.h
 #include dir.h
+#include string-list.h
 
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
@@ -627,10 +628,11 @@ static dev_t get_device_or_die(const char *path, const 
char *prefix, int prefix_
 static const char *setup_git_directory_gently_1(int *nongit_ok)
 {
const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
+   struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
static char cwd[PATH_MAX+1];
const char *gitdirenv, *ret;
char *gitfile;
-   int len, offset, offset_parent, ceil_offset;
+   int len, offset, offset_parent, ceil_offset = -1;
dev_t current_device = 0;
int one_filesystem = 1;
 
@@ -655,7 +657,12 @@ static const char *setup_git_directory_gently_1(int 
*nongit_ok)
if (gitdirenv)
return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
 
-   ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
+   if (env_ceiling_dirs) {
+   string_list_split(ceiling_dirs, env_ceiling_dirs, PATH_SEP, 
-1);
+   ceil_offset = longest_ancestor_length(cwd, ceiling_dirs);
+   string_list_clear(ceiling_dirs, 0);
+   }
+
if (ceil_offset  0  has_dos_drive_prefix(cwd))
ceil_offset = 1;
 
diff --git a/test-path-utils.c b/test-path-utils.c
index 3bc20e9..acb0560 100644
--- a/test-path-utils.c
+++ b/test-path-utils.c
@@ -1,4 +1,5 @@
 #include cache.h
+#include string-list.h
 
 int main(int argc, char **argv)
 {
@@ -30,7 +31,12 @@ int main(int argc, char **argv)
}
 
if (argc == 4  !strcmp(argv[1], longest_ancestor_length)) 

[PATCH v3 6/8] longest_ancestor_length(): require prefix list entries to be normalized

2012-10-20 Thread Michael Haggerty
Move the responsibility for normalizing the prefixes passed to
longest_ancestor_length() to its caller.  In t0060, only test
longest_ancestor_lengths using normalized paths: remove empty entries
and non-absolute paths, strip trailing slashes from the paths, and
remove tests that thereby become redundant.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 path.c| 26 +++---
 setup.c   | 23 +++
 t/t0060-path-utils.sh | 41 +
 3 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/path.c b/path.c
index b80d2e6..d3d3f8b 100644
--- a/path.c
+++ b/path.c
@@ -570,20 +570,20 @@ int normalize_path_copy(char *dst, const char *src)
 
 /*
  * path = Canonical absolute path
- * prefixes = string_list containing absolute paths
+ * prefixes = string_list containing normalized, absolute paths without
+ * trailing slashes (except for the root directory, which is denoted by /).
  *
- * Determines, for each path in prefixes, whether the prefix really
+ * Determines, for each path in prefixes, whether the prefix
  * is an ancestor directory of path.  Returns the length of the longest
  * ancestor directory, excluding any trailing slashes, or -1 if no prefix
  * is an ancestor.  (Note that this means 0 is returned if prefixes is
  * [/].) /foo is not considered an ancestor of /foobar.  Directories
  * are not considered to be their own ancestors.  path must be in a
  * canonical form: empty components, or . or .. components are not
- * allowed.  Empty strings in prefixes are ignored.
+ * allowed.
  */
 int longest_ancestor_length(const char *path, struct string_list *prefixes)
 {
-   char buf[PATH_MAX+1];
int i, max_len = -1;
 
if (!strcmp(path, /))
@@ -593,19 +593,15 @@ int longest_ancestor_length(const char *path, struct 
string_list *prefixes)
const char *ceil = prefixes-items[i].string;
int len = strlen(ceil);
 
-   if (len == 0 || len  PATH_MAX || !is_absolute_path(ceil))
-   continue;
-   if (normalize_path_copy(buf, ceil)  0)
-   continue;
-   len = strlen(buf);
-   if (len  0  buf[len-1] == '/')
-   buf[--len] = '\0';
+   if (len == 1  ceil[0] == '/')
+   len = 0; /* root matches anything, with length 0 */
+   else if (!strncmp(path, ceil, len)  path[len] == '/')
+   ; /* match of length len */
+   else
+   continue; /* no match */
 
-   if (!strncmp(path, buf, len) 
-   path[len] == '/' 
-   len  max_len) {
+   if (len  max_len)
max_len = len;
-   }
}
 
return max_len;
diff --git a/setup.c b/setup.c
index b4cd356..df97ad3 100644
--- a/setup.c
+++ b/setup.c
@@ -622,6 +622,28 @@ static dev_t get_device_or_die(const char *path, const 
char *prefix, int prefix_
 }
 
 /*
+ * A string_list_each_func_t function that normalizes an entry from
+ * GIT_CEILING_DIRECTORIES or discards it if unusable.
+ */
+static int normalize_ceiling_entry(struct string_list_item *item, void *unused)
+{
+   const char *ceil = item-string;
+   int len = strlen(ceil);
+   char buf[PATH_MAX+1];
+
+   if (len == 0 || len  PATH_MAX || !is_absolute_path(ceil))
+   return 0;
+   if (normalize_path_copy(buf, ceil)  0)
+   return 0;
+   len = strlen(buf);
+   if (len  1  buf[len-1] == '/')
+   buf[--len] = '\0';
+   free(item-string);
+   item-string = xstrdup(buf);
+   return 1;
+}
+
+/*
  * We cannot decide in this function whether we are in the work tree or
  * not, since the config can only be read _after_ this function was called.
  */
@@ -659,6 +681,7 @@ static const char *setup_git_directory_gently_1(int 
*nongit_ok)
 
if (env_ceiling_dirs) {
string_list_split(ceiling_dirs, env_ceiling_dirs, PATH_SEP, 
-1);
+   filter_string_list(ceiling_dirs, 0, normalize_ceiling_entry, 
NULL);
ceil_offset = longest_ancestor_length(cwd, ceiling_dirs);
string_list_clear(ceiling_dirs, 0);
}
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 4ef2345..09a42a4 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -93,47 +93,32 @@ norm_path /d1/s1//../s2/../../d2 /d2 POSIX
 norm_path /d1/.../d2 /d1/.../d2 POSIX
 norm_path /d1/..././../d2 /d1/d2 POSIX
 
-ancestor /  -1
 ancestor / / -1
-ancestor /foo  -1
-ancestor /foo : -1
-ancestor /foo ::. -1
-ancestor /foo ::..:: -1
 ancestor /foo / 0
 ancestor /foo /fo -1
 ancestor /foo /foo -1
-ancestor /foo /foo/ -1
 ancestor /foo /bar -1
-ancestor /foo /bar/ -1
 ancestor /foo /foo/bar -1
-ancestor /foo /foo:/bar/ -1
-ancestor /foo /foo/:/bar/ -1
-ancestor /foo /foo::/bar/ -1

[PATCH v3 8/8] string_list_longest_prefix(): remove function

2012-10-20 Thread Michael Haggerty
This function was added in f103f95b11d087f07c0c48bf784cd9197e18f203 in
the erroneous expectation that it would be used in the
reimplementation of longest_ancestor_length().  But it turned out to
be easier to use a function specialized for comparing path prefixes
(i.e., one that knows about slashes and root paths) than to prepare
the paths in such a way that a generic string prefix comparison
function can be used.  So delete string_list_longest_prefix() and its
documentation and test cases.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 Documentation/technical/api-string-list.txt |  8 
 string-list.c   | 20 ---
 string-list.h   |  8 
 t/t0063-string-list.sh  | 30 -
 test-string-list.c  | 20 ---
 5 files changed, 86 deletions(-)

diff --git a/Documentation/technical/api-string-list.txt 
b/Documentation/technical/api-string-list.txt
index 94d7a2b..618400d 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -75,14 +75,6 @@ Functions
to be deleted.  Preserve the order of the items that are
retained.
 
-`string_list_longest_prefix`::
-
-   Return the longest string within a string_list that is a
-   prefix (in the sense of prefixcmp()) of the specified string,
-   or NULL if no such prefix exists.  This function does not
-   require the string_list to be sorted (it does a linear
-   search).
-
 `print_string_list`::
 
Dump a string_list to stdout, useful mainly for debugging purposes. It
diff --git a/string-list.c b/string-list.c
index c54b816..decfa74 100644
--- a/string-list.c
+++ b/string-list.c
@@ -136,26 +136,6 @@ void filter_string_list(struct string_list *list, int 
free_util,
list-nr = dst;
 }
 
-char *string_list_longest_prefix(const struct string_list *prefixes,
-const char *string)
-{
-   int i, max_len = -1;
-   char *retval = NULL;
-
-   for (i = 0; i  prefixes-nr; i++) {
-   char *prefix = prefixes-items[i].string;
-   if (!prefixcmp(string, prefix)) {
-   int len = strlen(prefix);
-   if (len  max_len) {
-   retval = prefix;
-   max_len = len;
-   }
-   }
-   }
-
-   return retval;
-}
-
 void string_list_clear(struct string_list *list, int free_util)
 {
if (list-items) {
diff --git a/string-list.h b/string-list.h
index 5efd07b..3a6a6dc 100644
--- a/string-list.h
+++ b/string-list.h
@@ -38,14 +38,6 @@ int for_each_string_list(struct string_list *list,
 void filter_string_list(struct string_list *list, int free_util,
string_list_each_func_t want, void *cb_data);
 
-/*
- * Return the longest string in prefixes that is a prefix (in the
- * sense of prefixcmp()) of string, or NULL if no such prefix exists.
- * This function does not require the string_list to be sorted (it
- * does a linear search).
- */
-char *string_list_longest_prefix(const struct string_list *prefixes, const 
char *string);
-
 
 /* Use these functions only on sorted lists: */
 int string_list_has_string(const struct string_list *list, const char *string);
diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh
index 41c8826..dbfc05e 100755
--- a/t/t0063-string-list.sh
+++ b/t/t0063-string-list.sh
@@ -17,14 +17,6 @@ test_split () {

 }
 
-test_longest_prefix () {
-   test $(test-string-list longest_prefix $1 $2) = $3
-}
-
-test_no_longest_prefix () {
-   test_must_fail test-string-list longest_prefix $1 $2
-}
-
 test_split foo:bar:baz : -1 EOF
 3
 [0]: foo
@@ -96,26 +88,4 @@ test_expect_success test remove_duplicates '
test a:b:c = $(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)
 '
 
-test_expect_success test longest_prefix '
-   test_no_longest_prefix - '' 
-   test_no_longest_prefix - x 
-   test_longest_prefix  x  
-   test_longest_prefix x x x 
-   test_longest_prefix  foo  
-   test_longest_prefix : foo  
-   test_longest_prefix f foo f 
-   test_longest_prefix foo foobar foo 
-   test_longest_prefix foo foo foo 
-   test_no_longest_prefix bar foo 
-   test_no_longest_prefix bar:bar foo 
-   test_no_longest_prefix foobar foo 
-   test_longest_prefix foo:bar foo foo 
-   test_longest_prefix foo:bar bar bar 
-   test_longest_prefix foo::bar foo foo 
-   test_longest_prefix foo:foobar foo foo 
-   test_longest_prefix foobar:foo foo foo 
-   test_longest_prefix foo: bar  
-   test_longest_prefix :foo bar 
-'
-
 test_done
diff --git a/test-string-list.c b/test-string-list.c
index 4693295..00ce6c9 100644
--- a/test-string-list.c
+++ b/test-string-list.c
@@ -97,26 +97,6 @@ int main(int argc, char