Re: [PATCH] contrib/hooks: avoid requiring root access in usage instructions
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
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
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
Global Financial Loan.doc Description: MS-Word document
[PATCH] New git status format with --alternate
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
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
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
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
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
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
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.
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
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
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
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
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.
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
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
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
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.
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)
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)
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()
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
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()
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()
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
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
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
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