Re: git-p4: exception when cloning a perforce repository
On 18 Jan 2014, at 19:22, Pete Wyckoff p...@padd.com wrote: dam...@iwi.me wrote on Thu, 16 Jan 2014 17:02 +0100: On 16 Jan 2014, at 15:45, Pete Wyckoff p...@padd.com wrote: Oh cool, that helps a lot. P4 is just broken here, so we can get away with being a bit sloppy in git. I'll try just pretending empty symlinks are not in the repo. Hopefully you'll have a future commit in your p4 repo that brings back bn.h properly. Thanks ! I would love to use git instead of perforce if possible :) Still not sure about how I'll test this. I can test for you, no probleme with that. Any chance you can give this a go? I've a bigger patch in a longer series, but this should be the minimal fix. If it works, I'll ship it to Junio. Yeah it seems to work fine ! I’ve finally imported all 152620 changesets :) Thanks ! (git pull from this morning + patch) Thanks, -- Pete 8 From 8556ab04dd126184e26a380b7ed08998fd33debe Mon Sep 17 00:00:00 2001 From: Pete Wyckoff p...@padd.com Date: Thu, 16 Jan 2014 18:34:09 -0500 Subject: [PATCH] git p4: work around p4 bug that causes empty symlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Damien Gérard highlights an interesting problem. Some p4 repositories end up with symlinks that have an empty target. It is not possible to create this with current p4, but they do indeed exist. The effect in git p4 is that p4 print on the symlink returns an empty string, confusing the curret symlink-handling code. In p4, syncing to a change that includes such a bogus symlink creates errors: //depot/empty-symlink - updating /home/me/p4/empty-symlink rename: /home/me/p4/empty-symlink: No such file or directory and leaves no symlink. Replicate the p4 behavior by ignoring these bogus symlinks. If they are fixed in later revisions, the symlink will be replaced properly. Reported-by: Damien Gérard dam...@iwi.me Signed-off-by: Pete Wyckoff p...@padd.com --- git-p4.py | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/git-p4.py b/git-p4.py index 5ea8bb8..e798ecf 100755 --- a/git-p4.py +++ b/git-p4.py @@ -2075,7 +2075,14 @@ class P4Sync(Command, P4UserMap): # p4 print on a symlink sometimes contains target\n; # if it does, remove the newline data = ''.join(contents) -if data[-1] == '\n': +if not data: +# Some version of p4 allowed creating a symlink that pointed +# to nothing. This causes p4 errors when checking out such +# a change, and errors here too. Work around it by ignoring +# the bad symlink; hopefully a future change fixes it. +print \nIgnoring empty symlink in %s % file['depotFile'] +return +elif data[-1] == '\n': contents = [data[:-1]] else: contents = [data] -- 1.8.5.2.320.g99957e5 -- 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: git-p4: exception when cloning a perforce repository
On 18 Jan 2014, at 19:22, Pete Wyckoff p...@padd.com wrote: dam...@iwi.me wrote on Thu, 16 Jan 2014 17:02 +0100: On 16 Jan 2014, at 15:45, Pete Wyckoff p...@padd.com wrote: Oh cool, that helps a lot. P4 is just broken here, so we can get away with being a bit sloppy in git. I'll try just pretending empty symlinks are not in the repo. Hopefully you'll have a future commit in your p4 repo that brings back bn.h properly. Thanks ! I would love to use git instead of perforce if possible :) Still not sure about how I'll test this. I can test for you, no probleme with that. Any chance you can give this a go? I've a bigger patch in a longer series, but this should be the minimal fix. If it works, I'll ship it to Junio. Just for info, it works but it seems there are still some issues when a git repository is present within the perforce repo : error: Invalid path 'Tools/Doc/bin/yuidoc/.git/FETCH_HEAD' error: Invalid path 'Tools/Doc/bin/yuidoc/.git/HEAD' error: Invalid path 'Tools/Doc/bin/yuidoc/.git/ORIG_HEAD’ [...] Those files have been added then removed in another commit I’ve have to make git reset —hard ‘HEAD^’ git p4 sync to a clean staging area right after the clone. Thanks, -- Pete 8 From 8556ab04dd126184e26a380b7ed08998fd33debe Mon Sep 17 00:00:00 2001 From: Pete Wyckoff p...@padd.com Date: Thu, 16 Jan 2014 18:34:09 -0500 Subject: [PATCH] git p4: work around p4 bug that causes empty symlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Damien Gérard highlights an interesting problem. Some p4 repositories end up with symlinks that have an empty target. It is not possible to create this with current p4, but they do indeed exist. The effect in git p4 is that p4 print on the symlink returns an empty string, confusing the curret symlink-handling code. In p4, syncing to a change that includes such a bogus symlink creates errors: //depot/empty-symlink - updating /home/me/p4/empty-symlink rename: /home/me/p4/empty-symlink: No such file or directory and leaves no symlink. Replicate the p4 behavior by ignoring these bogus symlinks. If they are fixed in later revisions, the symlink will be replaced properly. Reported-by: Damien Gérard dam...@iwi.me Signed-off-by: Pete Wyckoff p...@padd.com --- git-p4.py | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/git-p4.py b/git-p4.py index 5ea8bb8..e798ecf 100755 --- a/git-p4.py +++ b/git-p4.py @@ -2075,7 +2075,14 @@ class P4Sync(Command, P4UserMap): # p4 print on a symlink sometimes contains target\n; # if it does, remove the newline data = ''.join(contents) -if data[-1] == '\n': +if not data: +# Some version of p4 allowed creating a symlink that pointed +# to nothing. This causes p4 errors when checking out such +# a change, and errors here too. Work around it by ignoring +# the bad symlink; hopefully a future change fixes it. +print \nIgnoring empty symlink in %s % file['depotFile'] +return +elif data[-1] == '\n': contents = [data[:-1]] else: contents = [data] -- 1.8.5.2.320.g99957e5 -- 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
GIT_WORK_TREE and GIT_DIR with git clone
Hi, I would like to have git clone respect GIT_DIR (and --git-dir) so I can clone multiple repos into the same working directory (I know there was another request for this[1]). The pattern here is big projects that are modularized into multiple git repositories, but supposed to be overlaid over a common directory structure. I would like to be able to tell my users that they can simply do: git clone --git-dir=_/git/module1/.git module1-url git clone --git-dir=_/git/module2/.git module2-url which will overlay the files from both modules into the current directory, which from git's perspective is the work-tree for both modules. [1] http://article.gmane.org/gmane.comp.version-control.git/170073/match=git_work_tree+git_dir+git+clone -- 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
Bug archive
Hey Guys, I am Abhishek, I am new here. For now I just have one question is there any centralize DB place where I can see Bugs reported on / about Git ? something like bugzilla of trac for Git-Scm ? -- Thanks Abhishek http://thezeroth.net -- 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 2/4] diff test: Add tests for combine-diff with orderfile
In the next patch combine-diff will have special code-path for taking orderfile into account. Prepare for making changes by introducing coverage tests for that case. Signed-off-by: Kirill Smelkov k...@mns.spb.ru --- t/t4056-diff-order.sh | 21 + 1 file changed, 21 insertions(+) diff --git a/t/t4056-diff-order.sh b/t/t4056-diff-order.sh index 9e2b29e..c0460bb 100755 --- a/t/t4056-diff-order.sh +++ b/t/t4056-diff-order.sh @@ -97,4 +97,25 @@ do ' done +test_expect_success 'setup for testing combine-diff order' ' + git checkout -b tmp HEAD~ + create_files 3 + git checkout master + git merge --no-commit -s ours tmp + create_files 5 +' + +test_expect_success combine-diff: no order (=tree object order) ' + git diff --name-only HEAD HEAD^ HEAD^2 actual + test_cmp expect_none actual +' + +for i in 1 2 +do + test_expect_success combine-diff: orderfile using option ($i) ' + git diff -Oorder_file_$i --name-only HEAD HEAD^ HEAD^2 actual + test_cmp expect_$i actual + ' +done + test_done -- 1.9.rc0.143.g6fd479e -- 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 3/4] combine-diff: Optimize combine_diff_path sets intersection
Currently, when generating combined diff, for a commit, we intersect diff paths from diff(parent_0,commit) to diff(parent_i,commit) comparing all paths pairs, i.e. doing it the quadratic way. That is correct, but could be optimized: Paths come from trees in sorted (= tree) order, and so does diff_tree() emits resulting paths in that order too. Now if we look at diffcore transformations, all of them, except diffcore_order, preserve resulting path ordering: - skip_stat_unmatch, grep, pickaxe, filter -- just skip elements - order stays preserved - break -- just breaks diff for a path, adding path dup after the path - order stays preserved - detect rename/copy-- resulting paths are emitted sorted (verified empirically) So only diffcore_order changes diff paths ordering. But diffcore_order meaning affects only presentation - i.e. only how to show the diff, so we could do all the internal computations without paths reordering, and order only resultant paths set. This is faster, since, if we know two paths sets are all ordered, their intersection could be done in linear time. This patch does just that. Timings for `git log --raw --no-abbrev --no-renames` without `-c` (git log) and with `-c` (git log -c) before and after the patch are as follows: linux.git v3.10..v3.11 log log -c before 1.9s20.4s after 1.9s16.6s navy.git(private repo) log log -c before 0.83s 15.6s after 0.83s2.1s P.S. I think linux.git case is sped up not so much as the second one, since in navy.git, there are more exotic (subtree, etc) merges. P.P.S. My tracing showed that the rest of the time (16.6s vs 1.9s) is usually spent in computing huge diffs from commit to second parent. Will try to deal with it, if I'll have time. P.P.P.S. For combine_diff_path, -len is not needed anymore - will remove it in the next noisy cleanup path, to maintain good signal/noise ratio here. Signed-off-by: Kirill Smelkov k...@mns.spb.ru --- combine-diff.c | 93 +- 1 file changed, 72 insertions(+), 21 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 3b92c448..98c2562 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -15,8 +15,8 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent) { struct diff_queue_struct *q = diff_queued_diff; - struct combine_diff_path *p; - int i; + struct combine_diff_path *p, *pprev, *ptmp; + int i, cmp; if (!n) { struct combine_diff_path *list = NULL, **tail = list; @@ -47,28 +47,43 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, return list; } - for (p = curr; p; p = p-next) { - int found = 0; - if (!p-len) + /* +* NOTE paths are coming sorted here (= in tree order) +*/ + + pprev = NULL; + p = curr; + i = 0; + + while (1) { + if (!p) + break; + + cmp = (i = q-nr) ? -1 + : strcmp(p-path, q-queue[i]-two-path); + if (cmp 0) { + if (pprev) + pprev-next = p-next; + ptmp = p; + p = p-next; + free(ptmp); + if (curr == ptmp) + curr = p; continue; - for (i = 0; i q-nr; i++) { - const char *path; - int len; + } - if (diff_unmodified_pair(q-queue[i])) - continue; - path = q-queue[i]-two-path; - len = strlen(path); - if (len == p-len !memcmp(path, p-path, len)) { - found = 1; - hashcpy(p-parent[n].sha1, q-queue[i]-one-sha1); - p-parent[n].mode = q-queue[i]-one-mode; - p-parent[n].status = q-queue[i]-status; - break; - } + if (cmp 0) { + i++; + continue; } - if (!found) - p-len = 0; + + hashcpy(p-parent[n].sha1, q-queue[i]-one-sha1); + p-parent[n].mode = q-queue[i]-one-mode; + p-parent[n].status = q-queue[i]-status; + + pprev = p; + p = p-next; + i++; } return curr; } @@ -1295,6 +1310,13 @@ static void handle_combined_callback(struct
[PATCH 1/4] diffcore-order: Export generic ordering interface
At present, diffcore_order() interface is to accept only queue of `struct diff_filepair`. In the next patches, we'll need to order `struct combine_diff_path` by path, so let's first rework diffcore-order to also provide generic low-level interface for ordering arbitrary objects, provided they have path accessors. The new interface is: - `struct obj_order`for describing objects to ordering routine, and - order_objects() for actually doing the ordering work. Signed-off-by: Kirill Smelkov k...@mns.spb.ru --- diffcore-order.c | 53 +++-- diffcore.h | 15 +++ 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/diffcore-order.c b/diffcore-order.c index fe7f1f4..327a93e 100644 --- a/diffcore-order.c +++ b/diffcore-order.c @@ -57,11 +57,7 @@ static void prepare_order(const char *orderfile) } } -struct pair_order { - struct diff_filepair *pair; - int orig_order; - int order; -}; + static int match_order(const char *path) { @@ -84,35 +80,56 @@ static int match_order(const char *path) return order_cnt; } -static int compare_pair_order(const void *a_, const void *b_) +static int compare_objs_order(const void *a_, const void *b_) { - struct pair_order const *a, *b; - a = (struct pair_order const *)a_; - b = (struct pair_order const *)b_; + struct obj_order const *a, *b; + a = (struct obj_order const *)a_; + b = (struct obj_order const *)b_; if (a-order != b-order) return a-order - b-order; return a-orig_order - b-orig_order; } + +void order_objects(const char *orderfile, obj_path_fn_t obj_path, + struct obj_order *objs, int nr) +{ + int i; + + if (!nr) + return; + + prepare_order(orderfile); + for (i = 0; i nr; i++) { + objs[i].orig_order = i; + objs[i].order = match_order(obj_path(objs[i].obj)); + } + qsort(objs, nr, sizeof(*objs), compare_objs_order); +} + + +static const char *pair_pathtwo(void *obj) +{ + struct diff_filepair *pair = (struct diff_filepair *)obj; + + return pair-two-path; +} + void diffcore_order(const char *orderfile) { struct diff_queue_struct *q = diff_queued_diff; - struct pair_order *o; + struct obj_order *o; int i; if (!q-nr) return; o = xmalloc(sizeof(*o) * q-nr); - prepare_order(orderfile); - for (i = 0; i q-nr; i++) { - o[i].pair = q-queue[i]; - o[i].orig_order = i; - o[i].order = match_order(o[i].pair-two-path); - } - qsort(o, q-nr, sizeof(*o), compare_pair_order); for (i = 0; i q-nr; i++) - q-queue[i] = o[i].pair; + o[i].obj = q-queue[i]; + order_objects(orderfile, pair_pathtwo, o, q-nr); + for (i = 0; i q-nr; i++) + q-queue[i] = o[i].obj; free(o); return; } diff --git a/diffcore.h b/diffcore.h index 1c16c85..1fd00fc 100644 --- a/diffcore.h +++ b/diffcore.h @@ -111,6 +111,21 @@ extern void diffcore_merge_broken(void); extern void diffcore_pickaxe(struct diff_options *); extern void diffcore_order(const char *orderfile); +/* low-level interface to diffcore_order */ +struct obj_order { + void *obj; /* setup by caller */ + + /* setup/used by order_objects() */ + int orig_order; + int order; +}; + +typedef const char *(*obj_path_fn_t)(void *obj); + +void order_objects(const char *orderfile, obj_path_fn_t obj_path, + struct obj_order *objs, int nr); + + #define DIFF_DEBUG 0 #if DIFF_DEBUG void diff_debug_filespec(struct diff_filespec *, int, const char *); -- 1.9.rc0.143.g6fd479e -- 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 0/4] `log -c` speedup
Hello up there, I'm using `git log --raw` to reconstruct file dates (readonly filesystem for git archives) and, as it turned out, for --raw to emit diffs for merges we need to explicitly activate combine-diff via -c. The combined-diff turned out to be slow, I'm trying to optimize it. Please apply. Thanks beforehand, Kirill Kirill Smelkov (4): diffcore-order: Export generic ordering interface diff test: Add tests for combine-diff with orderfile combine-diff: Optimize combine_diff_path sets intersection combine-diff: combine_diff_path.len is not needed anymore combine-diff.c| 121 +- diff-lib.c| 2 - diff.h| 1 - diffcore-order.c | 53 ++ diffcore.h| 15 +++ t/t4056-diff-order.sh | 21 + 6 files changed, 151 insertions(+), 62 deletions(-) -- 1.9.rc0.143.g6fd479e -- 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 4/4] combine-diff: combine_diff_path.len is not needed anymore
Brefore previous patch, -len was used to speedup name compares and also to mark removed paths via len=0. Now we do significantly less strcmp and also just remove paths from list and free right after we know a path will not be needed, so -len is not needed anymore. Signed-off-by: Kirill Smelkov k...@mns.spb.ru --- combine-diff.c | 30 +- diff-lib.c | 2 -- diff.h | 1 - 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 98c2562..07faa96 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -31,7 +31,6 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, p-path = (char *) (p-parent[num_parent]); memcpy(p-path, path, len); p-path[len] = 0; - p-len = len; p-next = NULL; memset(p-parent, 0, sizeof(p-parent[0]) * num_parent); @@ -1234,8 +1233,6 @@ void show_combined_diff(struct combine_diff_path *p, { struct diff_options *opt = rev-diffopt; - if (!p-len) - return; if (opt-output_format (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME | DIFF_FORMAT_NAME_STATUS)) @@ -1299,11 +1296,8 @@ static void handle_combined_callback(struct diff_options *opt, q.queue = xcalloc(num_paths, sizeof(struct diff_filepair *)); q.alloc = num_paths; q.nr = num_paths; - for (i = 0, p = paths; p; p = p-next) { - if (!p-len) - continue; + for (i = 0, p = paths; p; p = p-next) q.queue[i++] = combined_pair(p, num_parent); - } opt-format_callback(q, opt, opt-format_callback_data); for (i = 0; i num_paths; i++) free_combined_pair(q.queue[i]); @@ -1369,11 +1363,9 @@ void diff_tree_combined(const unsigned char *sha1, diff_flush(diffopts); } - /* find out surviving paths */ - for (num_paths = 0, p = paths; p; p = p-next) { - if (p-len) - num_paths++; - } + /* find out number of surviving paths */ + for (num_paths = 0, p = paths; p; p = p-next) + num_paths++; /* order paths according to diffcore_order */ if (opt-orderfile num_paths) { @@ -1398,10 +1390,8 @@ void diff_tree_combined(const unsigned char *sha1, if (opt-output_format (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME | DIFF_FORMAT_NAME_STATUS)) { - for (p = paths; p; p = p-next) { - if (p-len) - show_raw_diff(p, num_parent, rev); - } + for (p = paths; p; p = p-next) + show_raw_diff(p, num_parent, rev); needsep = 1; } else if (opt-output_format @@ -1414,11 +1404,9 @@ void diff_tree_combined(const unsigned char *sha1, if (needsep) printf(%s%c, diff_line_prefix(opt), opt-line_termination); - for (p = paths; p; p = p-next) { - if (p-len) - show_patch_diff(p, num_parent, dense, - 0, rev); - } + for (p = paths; p; p = p-next) + show_patch_diff(p, num_parent, dense, + 0, rev); } } diff --git a/diff-lib.c b/diff-lib.c index e6d33b3..938869d 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -121,7 +121,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option) dpath-path = (char *) (dpath-parent[5]); dpath-next = NULL; - dpath-len = path_len; memcpy(dpath-path, ce-name, path_len); dpath-path[path_len] = '\0'; hashclr(dpath-sha1); @@ -323,7 +322,6 @@ static int show_modified(struct rev_info *revs, p = xmalloc(combine_diff_path_size(2, pathlen)); p-path = (char *) p-parent[2]; p-next = NULL; - p-len = pathlen; memcpy(p-path, new-name, pathlen); p-path[pathlen] = 0; p-mode = mode; diff --git a/diff.h b/diff.h index 0e6898f..a24a767 100644 --- a/diff.h +++ b/diff.h @@ -198,7 +198,6 @@ extern int diff_root_tree_sha1(const unsigned char *new, const char *base, struct combine_diff_path { struct combine_diff_path *next; -
No local cloning for insteadOf URLs
Hi there, on Linux I'm using the config option url.[].insteadOf feature to clone certain (very big) submodules from a local mirror instead of from remote. The configuration is something like [url /home/sampleuser/mirrors/bigrepo.git] insteadOf = git@remotehost:bigrepo.git Cloning this repo with git clone git@remotehost:bigrepo.git works fine, it is cloning from my local repo instead of from the remote one. But: I was expecting the 'git clone' call to take into account that it is cloning a local repository and create hard links to the packs of my local mirror repository, but instead it copies the whole repo just as it was a remote repository. This should get fixed, this 'git clone' call should detect that it is cloning a local repository and create hard links to the *.pack files. When cloning the local mirror directly with git clone /home/sampleuser/mirrors/bigrepo.git 'git clone' automatically creates hard links to the local mirrors *.pack files. Cheers, Hannes -- 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: [msysGit] Consecutive git gc fails on Windows network share
(No top-posting, please see my comments below) On 2014-01-20 15.02, Jochen wrote: On 01/16/2014 10:55 AM, Jochen Haag wrote: Hello, we want to report the following issue, because it seems to be not an intended behaviour. Maybe someone can have a look at it at some point. It is not urgent for us. After upgrading from Git version 1.8.1.msysgit.1 to 1.8.5.2.msysgit.0 we observed that a consecutive git gc fails, in case the Git repo is located on a Windows network share. Operating system used is Windows 7 64 bit SP1. In case git gc fails temporary packs and index remain in .git/objects/pack/. Consecutive means, that git gc is called on an already packed repository (e.g. git gc is called more than once). This is the output given in case of error: U:\GitEnvgit gc Counting objects: 139, done. Delta compression using up to 8 threads. Compressing objects: 100% (71/71), done. Writing objects: 100% (139/139), done. Total 139 (delta 65), reused 139 (delta 65) fatal: renaming '.git/objects/pack/.tmp-7920-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack' failed: Permission denied error: failed to run repack And here the output with GIT_TRACE = 1: U:\GitEnvgit gc trace: built-in: git 'gc' trace: run_command: 'pack-refs' '--all' '--prune' trace: built-in: git 'pack-refs' '--all' '--prune' trace: run_command: 'reflog' 'expire' '--all' trace: built-in: git 'reflog' 'expire' '--all' trace: run_command: 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: built-in: git 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: run_command: 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-7612-pack' trace: built-in: git 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-7612-pack' Counting objects: 139, done. Delta compression using up to 8 threads. Compressing objects: 100% (71/71), done. Writing objects: 100% (139/139), done. Total 139 (delta 65), reused 139 (delta 65) fatal: renaming '.git/objects/pack/.tmp-7612-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack' failed: Permission denied error: failed to run repack After running git gc twice, this is what is left in .git/objects/pack/: U:\GitEnv\.git\objects\packls -al total 53676 drwxr-xr-x1 hgj2fe Administ0 Jan 16 10:43 . drwxr-xr-x1 hgj2fe Administ0 Jan 14 12:52 .. -r--r--r--1 hgj2fe Administ 4964 Jan 16 10:43 .tmp-7612-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.idx -r--r--r--1 hgj2fe Administ 18315618 Jan 16 10:43 .tmp-7612-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack -r--r--r--1 hgj2fe Administ 4964 Jan 16 10:40 .tmp-7920-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.idx -r--r--r--1 hgj2fe Administ 18315618 Jan 16 10:40 .tmp-7920-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack -r--r--r--1 hgj2fe Administ 4964 Jan 14 12:52 pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.idx -r--r--r--1 hgj2fe Administ 18315618 Jan 14 12:52 pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack In case we remove the read-only flag of the pack and index manually before running git gc again, no problem occurs: U:\GitEnv\.git\objects\packgit gc trace: built-in: git 'gc' trace: run_command: 'pack-refs' '--all' '--prune' trace: built-in: git 'pack-refs' '--all' '--prune' trace: run_command: 'reflog' 'expire' '--all' trace: built-in: git 'reflog' 'expire' '--all' trace: run_command: 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: built-in: git 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: run_command: 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' 'U:/GitEnv/.git/objects/pack/.tmp-3736-pack' trace: built-in: git 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' 'U:/GitEnv/.git/objects/pack/.tmp-3736-pack' Counting objects: 139, done. Delta compression using up to 8 threads. Compressing objects: 100% (71/71), done. Writing objects: 100% (139/139), done. Total 139 (delta 65), reused 139 (delta 65) trace: run_command: 'prune-packed' trace: built-in: git 'prune-packed' trace: run_command: 'update-server-info' trace: built-in: git 'update-server-info' trace: run_command: 'prune' '--expire' '2.weeks.ago' trace: built-in: git 'prune' '--expire' '2.weeks.ago' trace: run_command: 'rerere' 'gc' trace: built-in: git 'rerere' 'gc' The problem might be related to this commit: https://github.com/msysgit/git/commit/a1bbc6c0176f1fa2d4aa571cc0183a1f0ff9b285 Best regards, Jochen
git-remote-hg
Hi, I am using git-remote-hg to access to projects on bitbucket. I can clone the master branch fine and push to it. I also see hg branches as remotes/origin/branches/«branch». However, if I create a local branch branches/x and want to push it to remotes/origin/branches/x, it gets pushed to the remote master (aka default) branch. What is the recommended way of working with multiple branches when interacting with a remote hg repository? Best, C. P.S. The remote helper also prints many lines like: error: Object 4a83cec050af8749b3eacc9da9b216350bb86c07 already has a mark -- 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: Bug archive
Hi, On Mon, Jan 20, 2014 at 5:11 PM, Abhishek Patil abhis...@thezeroth.net wrote: Hey Guys, I am Abhishek, I am new here. For now I just have one question is there any centralize DB place where I can see Bugs reported on / about Git ? something like bugzilla of trac for Git-Scm ? Please have a look at this thread: http://thread.gmane.org/gmane.comp.version-control.git/237890/ Best, Christian. -- 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
problematic git log submodule-dir/
Hi all. i've noticed that 'git log submodule-dir' and 'git log submodule-dir/' return different results (module's head changes vs. nothing). is it a bug? looks like a trailing slash is a problem for git-log. tested on git-1.8.5.3-2.fc20.x86_64. BR, Paweł. -- gpg key fingerprint = 60B4 9886 AD53 EB3E 88BB 1EB5 C52E D01B 683B 9411 -- 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: Bug archive
Thanks Christian, Best, Abhishek On Mon, Jan 20, 2014 at 06:35:43PM +0100, Christian Couder wrote: Hi, On Mon, Jan 20, 2014 at 5:11 PM, Abhishek Patil abhis...@thezeroth.net wrote: Hey Guys, I am Abhishek, I am new here. For now I just have one question is there any centralize DB place where I can see Bugs reported on / about Git ? something like bugzilla of trac for Git-Scm ? Please have a look at this thread: http://thread.gmane.org/gmane.comp.version-control.git/237890/ Best, Christian. -- 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/RFC] Makefile: Fix compilation of windows resource file
If the git version number consists of less than three period separated numbers, then the windows resource file compilation issues a syntax error: $ touch git.rc $ make V=1 git.res GIT_VERSION = 1.9.rc0 windres -O coff \ -DMAJOR=1 -DMINOR=9 -DPATCH=rc0 \ -DGIT_VERSION=\\\1.9.rc0\\\ git.rc -o git.res C:\msysgit\msysgit\mingw\bin\windres.exe: git.rc:2: syntax error make: *** [git.res] Error 1 $ [Note that -DPATCH=rc0] In order to fix the syntax error, we replace any rcX with zero and include some additional 'zero' padding to the version number list. Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk --- Hi Junio, This patch is marked RFC because, as I was just about to send this email, I realized it wouldn't always work: $ touch git.rc $ make V=1 GIT_VERSION=1.9.dirty git.res windres -O coff \ -DMAJOR=1 -DMINOR=9 -DPATCH=dirty \ -DGIT_VERSION=\\\1.9.dirty\\\ git.rc -o git.res C:\msysgit\msysgit\mingw\bin\windres.exe: git.rc:2: syntax error make: *** [git.res] Error 1 $ :-D I suspect it would be easier to change GIT-VERSION-GEN to also set, say, GIT_VERSION_MAJOR, GIT_VERSION_MINOR and GIT_VERSION_PATCH ... ATB, Ramsay Jones Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b4af1e2..308baaa 100644 --- a/Makefile +++ b/Makefile @@ -1773,7 +1773,7 @@ $(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES git.res: git.rc GIT-VERSION-FILE $(QUIET_RC)$(RC) \ - $(join -DMAJOR= -DMINOR= -DPATCH=, $(wordlist 1,3,$(subst -, ,$(subst ., ,$(GIT_VERSION) \ + $(join -DMAJOR= -DMINOR= -DPATCH=, $(wordlist 1,3,$(patsubst rc%,0,$(subst -, ,$(subst ., ,$(GIT_VERSION))) 0 0))) \ -DGIT_VERSION=\\\$(GIT_VERSION)\\\ $ -o $@ ifndef NO_PERL -- 1.8.5 -- 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 0/2] performance regression in mark_edges_uninteresting
This series fixes a rev-list performance regression in fbd4a70 (list-objects: mark more commits as edges in mark_edges_uninteresting, 2013-08-16). That commit is a little tricky because it actually _knows_ it's trading off CPU for a better packfile, but I think we're performing the tradeoff in too many places. See the second commit for details. [1/2]: t/perf: time rev-list with UNINTERESTING commits [2/2]: list-objects: only look at cmdline trees with edge_hint Here's t/perf/p0001 output that shows the problem: 0001.5: rev-list --objects $commit --not --all fbd4a703^ fbd4a703 HEAD 0.04(0.04+0.00) 0.28(0.27+0.00) +600.0% 0.04(0.04+0.00) +0.0% -Peff PS If you are wondering about the output format above, I had to munge it manually to avoid giant 115-character lines. We should maybe teach the perf suite an alternate output format. :) -- 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 1/2] t/perf: time rev-list with UNINTERESTING commits
We time a straight rev-list --all and its --object counterpart, both going all the way to the root. However, we do not time a partial history walk. This patch adds an extreme case: a walk over a very small slice of history, but with a very large set of UNINTERESTING tips. This is similar to the connectivity check run by git on a small fetch, or the walk done by any pre-receive hooks that want to check incoming commits. This test reveals a performance regression in git v1.8.4.2, caused by fbd4a70 (list-objects: mark more commits as edges in mark_edges_uninteresting, 2013-08-16): Test fbd4a703^ fbd4a703 -- 0001.1: rev-list --all 0.69(0.67+0.02) 0.69(0.68+0.01) +0.0% 0001.2: rev-list --all --objects 3.47(3.44+0.02) 3.48(3.44+0.03) +0.3% 0001.4: rev-list $commit --not --all 0.04(0.04+0.00) 0.04(0.04+0.00) +0.0% 0001.5: rev-list --objects $commit --not --all 0.04(0.03+0.00) 0.27(0.24+0.02) +575.0% Signed-off-by: Jeff King p...@peff.net --- Sorry for the long lines in the commit message. I'm open to suggestions on reformatting. t/perf/p0001-rev-list.sh | 17 + 1 file changed, 17 insertions(+) diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh index 4f71a63..b7258a7 100755 --- a/t/perf/p0001-rev-list.sh +++ b/t/perf/p0001-rev-list.sh @@ -14,4 +14,21 @@ test_perf 'rev-list --all --objects' ' git rev-list --all --objects /dev/null ' +test_expect_success 'create new unreferenced commit' ' + git checkout --detach HEAD + echo content file + git add file + git commit -m detached + commit=$(git rev-parse --verify HEAD) + git checkout - +' + +test_perf 'rev-list $commit --not --all' ' + git rev-list $commit --not --all /dev/null +' + +test_perf 'rev-list --objects $commit --not --all' ' + git rev-list --objects $commit --not --all /dev/null +' + test_done -- 1.8.5.2.500.g8060133 -- 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 2/2] list-objects: only look at cmdline trees with edge_hint
When rev-list is given a command-line like: git rev-list --objects $commit --not --all the most accurate answer is the difference between the set of objects reachable from $commit and the set reachable from all of the existing refs. However, we have not historically provided that answer, because it is very expensive to calculate. We would have to open every tree of every commit in the entire history. Instead, we find the accurate set difference of the reachable commits, and then mark the trees at the boundaries as uninteresting. This misses objects which appear in the trees of both the interesting commits and deep within the uninteresting history. Commit fbd4a70 (list-objects: mark more commits as edges in mark_edges_uninteresting, 2013-08-16) noticed that we miss those objects during pack-objects, and added code to examine the trees of all of the --not refs given on the command-line. Note that this is still not the complete set difference, because we look only at the tips of the command-line arguments, not all of their reachable commits. But it increases the set of boundary objects we consider, which is especially important for shallow fetches. So we are trading extra CPU time for a larger set of boundary objects, which can improve the resulting pack size for a --thin pack. This tradeoff probably makes sense in the context of pack-objects, where we have set revs-edge_hint to have the traversal feed us the set of boundary objects. For a regular rev-list, though, it is probably not a good tradeoff. It is true that it makes our list slightly closer to a true set difference, but it is a rare case where this is important. And because we do not have revs-edge_hint set, we do nothing useful with the larger set of boundary objects. This patch therefore ties the extra tree examination to the revs-edge_hint flag; it is the presence of that flag that makes the tradeoff worthwhile. Here is output from the p0001-rev-list showing the improvement in performance: Test HEAD^ HEAD - 0001.1: rev-list --all 0.69(0.65+0.02) 0.69(0.66+0.02) +0.0% 0001.2: rev-list --all --objects 3.22(3.19+0.03) 3.23(3.20+0.03) +0.3% 0001.4: rev-list $commit --not --all 0.04(0.04+0.00) 0.04(0.04+0.00) +0.0% 0001.5: rev-list --objects $commit --not --all 0.27(0.26+0.01) 0.04(0.04+0.00) -85.2% Signed-off-by: Jeff King p...@peff.net --- list-objects.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/list-objects.c b/list-objects.c index 6cbedf0..43ce1d9 100644 --- a/list-objects.c +++ b/list-objects.c @@ -162,15 +162,17 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge) } mark_edge_parents_uninteresting(commit, revs, show_edge); } - for (i = 0; i revs-cmdline.nr; i++) { - struct object *obj = revs-cmdline.rev[i].item; - struct commit *commit = (struct commit *)obj; - if (obj-type != OBJ_COMMIT || !(obj-flags UNINTERESTING)) - continue; - mark_tree_uninteresting(commit-tree); - if (revs-edge_hint !(obj-flags SHOWN)) { - obj-flags |= SHOWN; - show_edge(commit); + if (revs-edge_hint) { + for (i = 0; i revs-cmdline.nr; i++) { + struct object *obj = revs-cmdline.rev[i].item; + struct commit *commit = (struct commit *)obj; + if (obj-type != OBJ_COMMIT || !(obj-flags UNINTERESTING)) + continue; + mark_tree_uninteresting(commit-tree); + if (revs-edge_hint !(obj-flags SHOWN)) { + obj-flags |= SHOWN; + show_edge(commit); + } } } } -- 1.8.5.2.500.g8060133 -- 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/WIP v2 00/14] inotify support
Duy Nguyen pclo...@gmail.com writes: I think a clever way to handle this would be to add a new command: Wait:: This command serves synchronization. Git creates a file of its choice in $GIT_DIR/watch (say, `.git/watch/wait.random`). Then it sends wait path. The watcher MUST block until it has processed all change notifications up to and including path. So wait.random inotify event functions as a barrier. Nice. I forgot to specify a return for wait. Not sure you need one, though correctly handling the timeout (that you apply for all select()) may be somewhat tricky without it. Ok, that's probably a confused sum of rambles. Let me know if you can make any sense of it. Thank you for your input. Now I'm back to the white board (or paper). Don't go too far ;-) Thanks a lot for doing this! It's good that you picked it up, and I think your design strikes a good balance in the complexity of the protocol and the daemon's state. -- Thomas Rast t...@thomasrast.ch -- 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: [msysGit] Consecutive git gc fails on Windows network share
On 20.01.2014 18:16, Torsten Bögershausen wrote: (No top-posting, please see my comments below) On 2014-01-20 15.02, Jochen wrote: On 01/16/2014 10:55 AM, Jochen Haag wrote: Hello, we want to report the following issue, because it seems to be not an intended behaviour. Maybe someone can have a look at it at some point. It is not urgent for us. After upgrading from Git version 1.8.1.msysgit.1 to 1.8.5.2.msysgit.0 we observed that a consecutive git gc fails, in case the Git repo is located on a Windows network share. Operating system used is Windows 7 64 bit SP1. In case git gc fails temporary packs and index remain in .git/objects/pack/. Consecutive means, that git gc is called on an already packed repository (e.g. git gc is called more than once). This is the output given in case of error: U:\GitEnvgit gc Counting objects: 139, done. Delta compression using up to 8 threads. Compressing objects: 100% (71/71), done. Writing objects: 100% (139/139), done. Total 139 (delta 65), reused 139 (delta 65) fatal: renaming '.git/objects/pack/.tmp-7920-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack' failed: Permission denied error: failed to run repack And here the output with GIT_TRACE = 1: U:\GitEnvgit gc trace: built-in: git 'gc' trace: run_command: 'pack-refs' '--all' '--prune' trace: built-in: git 'pack-refs' '--all' '--prune' trace: run_command: 'reflog' 'expire' '--all' trace: built-in: git 'reflog' 'expire' '--all' trace: run_command: 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: built-in: git 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: run_command: 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-7612-pack' trace: built-in: git 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-7612-pack' Counting objects: 139, done. Delta compression using up to 8 threads. Compressing objects: 100% (71/71), done. Writing objects: 100% (139/139), done. Total 139 (delta 65), reused 139 (delta 65) fatal: renaming '.git/objects/pack/.tmp-7612-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack' failed: Permission denied error: failed to run repack After running git gc twice, this is what is left in .git/objects/pack/: U:\GitEnv\.git\objects\packls -al total 53676 drwxr-xr-x1 hgj2fe Administ0 Jan 16 10:43 . drwxr-xr-x1 hgj2fe Administ0 Jan 14 12:52 .. -r--r--r--1 hgj2fe Administ 4964 Jan 16 10:43 .tmp-7612-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.idx -r--r--r--1 hgj2fe Administ 18315618 Jan 16 10:43 .tmp-7612-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack -r--r--r--1 hgj2fe Administ 4964 Jan 16 10:40 .tmp-7920-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.idx -r--r--r--1 hgj2fe Administ 18315618 Jan 16 10:40 .tmp-7920-pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack -r--r--r--1 hgj2fe Administ 4964 Jan 14 12:52 pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.idx -r--r--r--1 hgj2fe Administ 18315618 Jan 14 12:52 pack-ad9d069e7c27ce19cc5b6cde82b4a38bedbf5884.pack In case we remove the read-only flag of the pack and index manually before running git gc again, no problem occurs: U:\GitEnv\.git\objects\packgit gc trace: built-in: git 'gc' trace: run_command: 'pack-refs' '--all' '--prune' trace: built-in: git 'pack-refs' '--all' '--prune' trace: run_command: 'reflog' 'expire' '--all' trace: built-in: git 'reflog' 'expire' '--all' trace: run_command: 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: built-in: git 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago' trace: run_command: 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' 'U:/GitEnv/.git/objects/pack/.tmp-3736-pack' trace: built-in: git 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' 'U:/GitEnv/.git/objects/pack/.tmp-3736-pack' Counting objects: 139, done. Delta compression using up to 8 threads. Compressing objects: 100% (71/71), done. Writing objects: 100% (139/139), done. Total 139 (delta 65), reused 139 (delta 65) trace: run_command: 'prune-packed' trace: built-in: git 'prune-packed' trace: run_command: 'update-server-info' trace: built-in: git 'update-server-info' trace: run_command: 'prune' '--expire' '2.weeks.ago' trace: built-in: git 'prune' '--expire' '2.weeks.ago' trace: run_command: 'rerere' 'gc' trace: built-in: git 'rerere' 'gc' The problem might be related to this commit:
Re: [PATCH 1/2] t/perf: time rev-list with UNINTERESTING commits
On Mon, Jan 20, 2014 at 04:31:01PM -0500, Jeff King wrote: diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh index 4f71a63..b7258a7 100755 --- a/t/perf/p0001-rev-list.sh +++ b/t/perf/p0001-rev-list.sh @@ -14,4 +14,21 @@ test_perf 'rev-list --all --objects' ' git rev-list --all --objects /dev/null ' +test_expect_success 'create new unreferenced commit' ' + git checkout --detach HEAD + echo content file + git add file + git commit -m detached + commit=$(git rev-parse --verify HEAD) + git checkout - +' This is bad to be touching the repo and assuming it is non-bare. For some reason I assumed that the perf suite made a copy of the repo, but it doesn't. If you point to a bare repo via GIT_PERF_REPO, this part of the test fails. It's actually enough to demonstrate the problem without changing the tree at all. So this produces the same numbers, and works everywhere: diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh index b7258a7..16359d5 100755 --- a/t/perf/p0001-rev-list.sh +++ b/t/perf/p0001-rev-list.sh @@ -15,12 +15,7 @@ test_perf 'rev-list --all --objects' ' ' test_expect_success 'create new unreferenced commit' ' - git checkout --detach HEAD - echo content file - git add file - git commit -m detached - commit=$(git rev-parse --verify HEAD) - git checkout - + commit=$(git commit-tree HEAD^{tree} -p HEAD) ' test_perf 'rev-list $commit --not --all' ' It still modifies the test repo, but at least in a fairly innocuous way. -Peff -- 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 0/2] performance regression in mark_edges_uninteresting
On Mon, Jan 20, 2014 at 04:28:45PM -0500, Jeff King wrote: [1/2]: t/perf: time rev-list with UNINTERESTING commits [2/2]: list-objects: only look at cmdline trees with edge_hint Here's t/perf/p0001 output that shows the problem: 0001.5: rev-list --objects $commit --not --all fbd4a703^ fbd4a703 HEAD 0.04(0.04+0.00) 0.28(0.27+0.00) +600.0% 0.04(0.04+0.00) +0.0% Those numbers are on git.git. Obviously 600% is a lot, but 24ms is not. However, the cost is a factor of the tree size times the number of refs. For the homebrew.git repository stored at GitHub, which has ~28,000 refs (mostly pointing at pull-request tips in refs/pull), the numbers are much more dramatic: fbd4a703^ fbd4a703 HEAD 0.50(0.46+0.02) 8.23(8.17+0.06) +1546.0% 0.50(0.48+0.01) +0.0% -Peff -- 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 1/2] t/perf: time rev-list with UNINTERESTING commits
Jeff King p...@peff.net writes: On Mon, Jan 20, 2014 at 04:31:01PM -0500, Jeff King wrote: diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh index 4f71a63..b7258a7 100755 --- a/t/perf/p0001-rev-list.sh +++ b/t/perf/p0001-rev-list.sh @@ -14,4 +14,21 @@ test_perf 'rev-list --all --objects' ' git rev-list --all --objects /dev/null ' +test_expect_success 'create new unreferenced commit' ' +git checkout --detach HEAD +echo content file +git add file +git commit -m detached +commit=$(git rev-parse --verify HEAD) +git checkout - +' This is bad to be touching the repo and assuming it is non-bare. For some reason I assumed that the perf suite made a copy of the repo, but it doesn't. If you point to a bare repo via GIT_PERF_REPO, this part of the test fails. It does make a copy, but with cp -Rl. I haven't actually ever tried what happens if you point it at a bare though. It *should* fail because it tries to cd $repo/.git, but if that was itself bare... -- Thomas Rast t...@thomasrast.ch -- 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 1/2] t/perf: time rev-list with UNINTERESTING commits
On Mon, Jan 20, 2014 at 11:32:12PM +0100, Thomas Rast wrote: This is bad to be touching the repo and assuming it is non-bare. For some reason I assumed that the perf suite made a copy of the repo, but it doesn't. If you point to a bare repo via GIT_PERF_REPO, this part of the test fails. It does make a copy, but with cp -Rl. I haven't actually ever tried what happens if you point it at a bare though. It *should* fail because it tries to cd $repo/.git, but if that was itself bare... Oh, hmph. I checked my linux repo, which I had used as GIT_PERF_REPO, and noticed that it had the test commit in its reflog. But I forgot that is because I did the test manually there right before writing up the t/perf script! So yes, it copies, and it's totally fine to be modifying the repo. Bare repos seem to work just fine for me. It looks like we use `git rev-parse --git-dir` to get the source, and then copy that to `.git` in the temporary directory. So that works fine either way, and we do have a directory available as the working dir. But of course the config from the bare repo says `core.bare = true`, so some commands will bail. We could perhaps just set GIT_WORK_TREE in the perf scripts, which I believe would override the bare setting in the .git/config. And then we know the repos will be consistently non-bare. Whether we do that or not, I think the update I posted is preferable, as it reproduces the problem in a much simpler manner. -Peff -- 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: [msysGit] Consecutive git gc fails on Windows network share
Hi Torsten, On Mon, 20 Jan 2014, Torsten Bögershausen wrote: (No top-posting, please see my comments below) already very good! For extra brownie points, just edit the quoted part to reflect the abridged version needed to understand the context. On 2014-01-20 15.02, Jochen wrote: On 01/16/2014 10:55 AM, Jochen Haag wrote: The rename command replaces a mv -f command of the original shell script. Obviously the -f option can also override a read-only file but rename can not on a network share. I allowed me to a) reconstruct the original mail, Please note that together with an exceedingly flakey internet connection, not only having to scroll through the mail (most of which was actually not relevant to your reply) and having to delete most parts again ate up my complete Git time budget for today. Just something you might want to keep in mind. b) add +++ at the places where you added the stat() and chmod(), c) and to send the question is this a good implementation ? to upstream git. I think your implementation makes sense. As I said in my other reply, I think that the problem would be addressed more generally in compat/mingw.c. It is to be doubted highly that upstream wants to handle cases such as rename() cannot overwrite read-only files on Windows everywhere they call rename() because the platforms upstream cares about do not have that problem. So we probably need just the same _wchmod we have in mingw_unlink also in mingw_rename. Ciao, Johannes
Re: [msysGit] Consecutive git gc fails on Windows network share
On Tue, Jan 21, 2014 at 12:25 AM, Johannes Schindelin johannes.schinde...@gmx.de wrote: On Mon, 20 Jan 2014, Torsten Bögershausen wrote: b) add +++ at the places where you added the stat() and chmod(), c) and to send the question is this a good implementation ? to upstream git. I think your implementation makes sense. As I said in my other reply, I think that the problem would be addressed more generally in compat/mingw.c. It is to be doubted highly that upstream wants to handle cases such as rename() cannot overwrite read-only files on Windows everywhere they call rename() because the platforms upstream cares about do not have that problem. I'm not so sure. A quick test shows me that this is not the case for NTFS. Since this is over a network-share, the problem is probably server-side, and can affect other systems as well. So a work-around might be appropriate for all systems, no? -- 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 2/2] list-objects: only look at cmdline trees with edge_hint
On Tue, Jan 21, 2014 at 4:32 AM, Jeff King p...@peff.net wrote: This patch therefore ties the extra tree examination to the revs-edge_hint flag; it is the presence of that flag that makes the tradeoff worthwhile. Here is output from the p0001-rev-list showing the improvement in performance: Test HEAD^ HEAD - 0001.1: rev-list --all 0.69(0.65+0.02) 0.69(0.66+0.02) +0.0% 0001.2: rev-list --all --objects 3.22(3.19+0.03) 3.23(3.20+0.03) +0.3% 0001.4: rev-list $commit --not --all 0.04(0.04+0.00) 0.04(0.04+0.00) +0.0% 0001.5: rev-list --objects $commit --not --all 0.27(0.26+0.01) 0.04(0.04+0.00) -85.2% You must have so much fun (or headache, depending on your view) with the variety of repos on github :) diff --git a/list-objects.c b/list-objects.c index 6cbedf0..43ce1d9 100644 --- a/list-objects.c +++ b/list-objects.c @@ -162,15 +162,17 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge) } mark_edge_parents_uninteresting(commit, revs, show_edge); } - for (i = 0; i revs-cmdline.nr; i++) { - struct object *obj = revs-cmdline.rev[i].item; - struct commit *commit = (struct commit *)obj; - if (obj-type != OBJ_COMMIT || !(obj-flags UNINTERESTING)) - continue; - mark_tree_uninteresting(commit-tree); - if (revs-edge_hint !(obj-flags SHOWN)) { - obj-flags |= SHOWN; - show_edge(commit); + if (revs-edge_hint) { + for (i = 0; i revs-cmdline.nr; i++) { + struct object *obj = revs-cmdline.rev[i].item; + struct commit *commit = (struct commit *)obj; + if (obj-type != OBJ_COMMIT || !(obj-flags UNINTERESTING)) + continue; + mark_tree_uninteresting(commit-tree); + if (revs-edge_hint !(obj-flags SHOWN)) { Not really important, but perhaps remove revs-edge_hint here because it's already checked? + obj-flags |= SHOWN; + show_edge(commit); + } } } } -- 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: [PATCH 2/2] list-objects: only look at cmdline trees with edge_hint
On Tue, Jan 21, 2014 at 06:57:08AM +0700, Duy Nguyen wrote: You must have so much fun (or headache, depending on your view) with the variety of repos on github :) It's fun on days like these when the solution is fairly straightforward. :) + if (revs-edge_hint) { + for (i = 0; i revs-cmdline.nr; i++) { + struct object *obj = revs-cmdline.rev[i].item; + struct commit *commit = (struct commit *)obj; + if (obj-type != OBJ_COMMIT || !(obj-flags UNINTERESTING)) + continue; + mark_tree_uninteresting(commit-tree); + if (revs-edge_hint !(obj-flags SHOWN)) { Not really important, but perhaps remove revs-edge_hint here because it's already checked? Yes, I think that is a good idea. Thanks. Re-roll coming in a moment. -Peff -- 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 0/2] performance regression in mark_edges_uninteresting
On Mon, Jan 20, 2014 at 04:28:45PM -0500, Jeff King wrote: This series fixes a rev-list performance regression in fbd4a70 (list-objects: mark more commits as edges in mark_edges_uninteresting, 2013-08-16). That commit is a little tricky because it actually _knows_ it's trading off CPU for a better packfile, but I think we're performing the tradeoff in too many places. See the second commit for details. [1/2]: t/perf: time rev-list with UNINTERESTING commits [2/2]: list-objects: only look at cmdline trees with edge_hint Here's t/perf/p0001 output that shows the problem: 0001.5: rev-list --objects $commit --not --all fbd4a703^ fbd4a703 HEAD 0.04(0.04+0.00) 0.28(0.27+0.00) +600.0% 0.04(0.04+0.00) +0.0% Here's v2 that addresses the minor comments on the list (simpler test in the first patch, and dropping the now-redundant revs-edge_hint check in the second patch). -Peff -- 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 1/2] t/perf: time rev-list with UNINTERESTING commits
We time a straight rev-list --all and its --object counterpart, both going all the way to the root. However, we do not time a partial history walk. This patch adds an extreme case: a walk over a very small slice of history, but with a very large set of UNINTERESTING tips. This is similar to the connectivity check run by git on a small fetch, or the walk done by any pre-receive hooks that want to check incoming commits. This test reveals a performance regression in git v1.8.4.2, caused by fbd4a70 (list-objects: mark more commits as edges in mark_edges_uninteresting, 2013-08-16): Test fbd4a703^ fbd4a703 -- 0001.1: rev-list --all 0.69(0.67+0.02) 0.69(0.68+0.01) +0.0% 0001.2: rev-list --all --objects 3.47(3.44+0.02) 3.48(3.44+0.03) +0.3% 0001.4: rev-list $commit --not --all 0.04(0.04+0.00) 0.04(0.04+0.00) +0.0% 0001.5: rev-list --objects $commit --not --all 0.04(0.03+0.00) 0.27(0.24+0.02) +575.0% Signed-off-by: Jeff King p...@peff.net --- t/perf/p0001-rev-list.sh | 12 1 file changed, 12 insertions(+) diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh index 4f71a63..16359d5 100755 --- a/t/perf/p0001-rev-list.sh +++ b/t/perf/p0001-rev-list.sh @@ -14,4 +14,16 @@ test_perf 'rev-list --all --objects' ' git rev-list --all --objects /dev/null ' +test_expect_success 'create new unreferenced commit' ' + commit=$(git commit-tree HEAD^{tree} -p HEAD) +' + +test_perf 'rev-list $commit --not --all' ' + git rev-list $commit --not --all /dev/null +' + +test_perf 'rev-list --objects $commit --not --all' ' + git rev-list --objects $commit --not --all /dev/null +' + test_done -- 1.8.5.2.500.g8060133 -- 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 2/2] list-objects: only look at cmdline trees with edge_hint
When rev-list is given a command-line like: git rev-list --objects $commit --not --all the most accurate answer is the difference between the set of objects reachable from $commit and the set reachable from all of the existing refs. However, we have not historically provided that answer, because it is very expensive to calculate. We would have to open every tree of every commit in the entire history. Instead, we find the accurate set difference of the reachable commits, and then mark the trees at the boundaries as uninteresting. This misses objects which appear in the trees of both the interesting commits and deep within the uninteresting history. Commit fbd4a70 (list-objects: mark more commits as edges in mark_edges_uninteresting, 2013-08-16) noticed that we miss those objects during pack-objects, and added code to examine the trees of all of the --not refs given on the command-line. Note that this is still not the complete set difference, because we look only at the tips of the command-line arguments, not all of their reachable commits. But it increases the set of boundary objects we consider, which is especially important for shallow fetches. So we are trading extra CPU time for a larger set of boundary objects, which can improve the resulting pack size for a --thin pack. This tradeoff probably makes sense in the context of pack-objects, where we have set revs-edge_hint to have the traversal feed us the set of boundary objects. For a regular rev-list, though, it is probably not a good tradeoff. It is true that it makes our list slightly closer to a true set difference, but it is a rare case where this is important. And because we do not have revs-edge_hint set, we do nothing useful with the larger set of boundary objects. This patch therefore ties the extra tree examination to the revs-edge_hint flag; it is the presence of that flag that makes the tradeoff worthwhile. Here is output from the p0001-rev-list showing the improvement in performance: Test HEAD^ HEAD - 0001.1: rev-list --all 0.69(0.65+0.02) 0.69(0.66+0.02) +0.0% 0001.2: rev-list --all --objects 3.22(3.19+0.03) 3.23(3.20+0.03) +0.3% 0001.4: rev-list $commit --not --all 0.04(0.04+0.00) 0.04(0.04+0.00) +0.0% 0001.5: rev-list --objects $commit --not --all 0.27(0.26+0.01) 0.04(0.04+0.00) -85.2% Signed-off-by: Jeff King p...@peff.net --- list-objects.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/list-objects.c b/list-objects.c index 6cbedf0..206816f 100644 --- a/list-objects.c +++ b/list-objects.c @@ -162,15 +162,17 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge) } mark_edge_parents_uninteresting(commit, revs, show_edge); } - for (i = 0; i revs-cmdline.nr; i++) { - struct object *obj = revs-cmdline.rev[i].item; - struct commit *commit = (struct commit *)obj; - if (obj-type != OBJ_COMMIT || !(obj-flags UNINTERESTING)) - continue; - mark_tree_uninteresting(commit-tree); - if (revs-edge_hint !(obj-flags SHOWN)) { - obj-flags |= SHOWN; - show_edge(commit); + if (revs-edge_hint) { + for (i = 0; i revs-cmdline.nr; i++) { + struct object *obj = revs-cmdline.rev[i].item; + struct commit *commit = (struct commit *)obj; + if (obj-type != OBJ_COMMIT || !(obj-flags UNINTERESTING)) + continue; + mark_tree_uninteresting(commit-tree); + if (!(obj-flags SHOWN)) { + obj-flags |= SHOWN; + show_edge(commit); + } } } } -- 1.8.5.2.500.g8060133 -- 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: Diagnosing stray/stale .keep files -- explore what is in a pack?
On Wed, Jan 15, 2014 at 06:50:33PM -0500, Martin Langhoff wrote: On Wed, Jan 15, 2014 at 12:49 PM, Junio C Hamano gits...@pobox.com wrote: As long as we can reliably determine that it is safe to do so without risking races, automatically cleaning .lock files is a good thing to do. If the .lock file is a day old, it seems to me that it should be safe to call it stale. Probably. The way our lease system works, nobody should be holding a ref lock for more than a few milliseconds. That being said, we do lock other things, like the index. Generally I think the index lock should be quick, too. And similar for config file rewrites, and shallow files. And rerere files, it looks like. My, git grep commit_lock_file turns up a lot of hits. :) So I think all of the existing uses are fine, and I suppose that most new cases should be fine, too, because git processes tend not to last a long time. You asked earlier if I had a script for cleaning locks. No code worth sharing, but I'll give an outline of what we do at GitHub. We basically do: find -name *.lock -mmin +60 | xargs rm I.e., we give only an hour. For keep files, we give a day (since things like hooks may run for a while under the lock, though a day is probably excessive). And we check that it begins with ^receive-pack. As far as I know, neither of these has ever caused any problems. Of course, any problems might not be immediately obvious. Can anyone take the lock if there is already a lock file? Git never takes an existing lock. It expects you to clean it up yourself. For the keep files, I already drafted a script that looks inside the keep file, if it reads 'receive-pack [pid] [host]' it checks whether the hostname matches, and if so whether the pid matches a running process. Only if the host matches and the pid is dead we call it stale. That sounds reasonable. Seems fairly conservative to me. Are there scenarios where we think this can misfire? I cannot think of any. -Peff -- 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 0/2] Propagating flags carefully from the command line
On Wed, Jan 15, 2014 at 03:59:42PM -0800, Junio C Hamano wrote: So this is my second try. The second one now gets rid of the call to mark_blob_uninteresting() as Peff suggested, because the first patch makes the function very well aware that it only should mark the objects that are reachable from the object, and by definition blobs do not reach anything. Junio C Hamano (2): revision: mark contents of an uninteresting tree uninteresting revision: propagate flag bits from tags to pointees Sorry for a slow review, but I just read through your earlier comments and this series. I agree there was definitely a bug in what we were discussing earlier, and this looks like the right way to fix it. The end result splits the flag-setting responsibility much more sensibly. Thanks. -Peff -- 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 2/3] setup_pager: set MORE=R
On Thu, Jan 16, 2014 at 11:26:50PM -0800, Kyle J. McKay wrote: --- a/pager.c +++ b/pager.c @@ -87,6 +87,10 @@ void setup_pager(void) argv_array_push(env, LESS=FRSX); if (!getenv(LV)) argv_array_push(env, LV=-c); +#ifdef PAGER_MORE_UNDERSTANDS_R +if (!getenv(MORE)) +argv_array_push(env, MORE=R); +#endif How about adding a leading - to both the LESS and MORE settings? Since you're in there patching... :) I do not have any problem with that, but would very much prefer it as a separate patch, in case there are any fallouts. And while the less man page does not have that wording, it does show this: LESS=-options; export LESS and this: LESS=-Dn9.1$-Ds4.1 Ugh. Having just read the LESS discussion, it makes me wonder if the strchr(getenv(LESS), 'R') check I add elsewhere in the series is sufficient. I suspect in practice it is good enough, but I would not be surprised if there is a way to fool it with a sufficiently complex LESS variable. Maybe we should just assume it is enough, and people with crazy LESS settings can set color.pager as appropriate? -- 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 2/3] setup_pager: set MORE=R
On Fri, Jan 17, 2014 at 11:17:01AM -0800, Junio C Hamano wrote: +#ifdef PAGER_MORE_UNDERSTANDS_R + if (!getenv(MORE)) + argv_array_push(env, MORE=R); +#endif pager_process.env = argv_array_detach(env, NULL); if (start_command(pager_process)) Let me repeat from $gmane/240110: - Can we generalize this a bit so that a builder can pass a list of var=val pairs and demote the existing LESS=FRSX to just a canned setting of such a mechanism? As we need to maintain this set these environments when unset here and also in git-sh-setup.sh, I think it is about time to do that clean-up. Duplicating two settings was borderline OK, but seeing the third added fairly soon after the second was added tells me that the clean-up must come before adding the third. Wow, I somehow _completely_ missed that thread. When I looked at the code with LV, I assumed it was just something that had happened long ago and I had forgotten about. I didn't even bother reading git log. Yeah, I agree that git-sh-setup should be consistent with what the C porcelains do. However, adding build-time variables like: PAGER_ENV = LESS=-FRSX LV=-c does complicate the point of my series, which was to add more intimate logic about how we handle LESS. With the current code, I can know that an unset LESS variable means we will set R ourselves and turn on color. We can get around that with something like: int pager_can_handle_color(void) { const char *pager = get_pager(); if (!strcmp(pager, less)) { const char *x = getenv(LESS); if (!x) { const char *e; for (e = pager_env; *e; e++) if ((x = skip_prefix(e, LESS=))) break; } return !x || strchr(x, 'R'); } [...] } but we are still hard-coding a lot of intelligence about less here. I wonder if the abstraction provided by the Makefile variable is really worthwhile. Anybody adding a new line to it would also want to tweak pager_can_handle_color to add similar logic. Taking a step back for a moment, we are getting two things out of such a Makefile variable: 1. An easy way for packager to add intelligence about common pagers on their system. 2. DRY between git-sh-setup and the C code. I do like (1), but I do not know if we want to try to encode the can handle color logic into a Makefile variable. What would it look like? For (2), an alternate method would be to simply provide git pager as C code, which spawns the appropriate pager as the C code would. Then git-sh-setup can easily build around that. -Peff -- 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 2/3] setup_pager: set MORE=R
On Fri, Jan 17, 2014 at 03:42:32PM -0800, Junio C Hamano wrote: Junio C Hamano gits...@pobox.com writes: Perhaps we can start it like this. Then pager.c can iterate over the PAGER_ENV string, parse out LESS=, LV=, etc., and do its thing. We would also need to muck with git-sh-setup.sh but that file is already preprocessed in the Makefile, so we should be able to do something similar to # @@BROKEN_PATH_FIX@@ there. And here is such an attempt. There may be some missing dependencies that need to be covered with a mechanism like GIT-BUILD-OPTIONS, though. Perhaps instead of just dumping it into a macro, we could actually parse it at compile time into C code, and store the result as a header file. Then that header file becomes the proper dependency, and this run-time error: + while (*pager_env) { + struct strbuf buf = STRBUF_INIT; + const char *cp = strchrnul(pager_env, '='); + + if (!*cp) + die(malformed build-time PAGER_ENV); would become a compile-time error. We could do the same for the shell code, too. I'm thinking something like: diff --git a/Makefile b/Makefile index b4af1e2..3a8d15e 100644 --- a/Makefile +++ b/Makefile @@ -2182,6 +2182,16 @@ GIT-LDFLAGS: FORCE echo $$FLAGS GIT-LDFLAGS; \ fi +GIT-PAGER-ENV: + @PAGER_ENV='$(PAGER_ENV)'; \ + if test x$$PAGER_ENV != x`cat GIT-PAGER-ENV 2/dev/null`; then \ + echo $$PAGER_ENV GIT-PAGER-ENV; \ + fi + +pager-env.h: GIT-PAGER-ENV mkcarray + $(SHELL_PATH) mkcarray pager_env $ $@+ + mv $@+ $@ + # We need to apply sq twice, once to protect from the shell # that runs GIT-BUILD-OPTIONS, and then again to protect it # and the first level quoting from the shell that runs echo. diff --git a/mkcarray b/mkcarray index e69de29..5962440 100644 --- a/mkcarray +++ b/mkcarray @@ -0,0 +1,21 @@ +name=$1; shift +guard=$(echo $name | tr a-z A-Z) + +cat -EOF +#ifndef ${guard}_H +#define ${guard}_H + +static const char *${name} = { +EOF + +for i in $(cat); do + # XXX c-quote the values? + printf '\t%s,\n' $i +done + +cat EOF + NULL +}; + +#endif /* ${guard}_H */ +EOF -- 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