Re: [PATCH 2/2] dir: remove PATH_MAX limitation
On Sat, Jul 5, 2014 at 5:42 AM, Karsten Blees karsten.bl...@gmail.com wrote: 'git status' segfaults if a directory is longer than PATH_MAX, because processing .gitignore files in prep_exclude() writes past the end of a PATH_MAX-bounded buffer. Remove the limitation by using strbuf instead. Note: this fix just 'abuses' strbuf as string allocator, len is always 0. prep_exclude() can probably be simplified using more strbuf APIs. FYI I had a similar patch [1] that attempted to lazily strbuf_init() instead so that strbuf_ API could be used. [1] http://article.gmane.org/gmane.comp.version-control.git/248310 -- 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: t5150-request-pull.sh fails on newest master in Debian
On 5 July 2014 03:58, David Turner dtur...@twopensource.com wrote: On Sat, 2014-07-05 at 02:09 +0200, Øyvind A. Holm wrote: snip The test works. Seems as there's something fishy about the use of --prefix in this specific commit (v2.0.1-472-g6f92e5f). Ok, now I can reproduce on my linode box (haven't tried it locally yet). I'll try to get a fix up once I figure out what's up. Awesome. I've done some more ./configure --prefix testing, and this is the result: # --prefix is set to non-existing directory ./configure --prefix=/usr/local/varprg/git.master.v2.0.1-472-g6f92e5f # ./t5150-request-pull.sh fails. # --prefix is set to non-existing directory, use trailing slash ./configure --prefix=/usr/local/varprg/git.master.v2.0.1-472-g6f92e5f/ # ./t5150-request-pull.sh fails. # --prefix is set to existing directory ./configure --prefix=/usr/local/varprg/git.master.v2.0.1-442-g7fe6834 # ./t5150-request-pull.sh fails. # --prefix is set to existing directory ./configure --prefix=/usr/local # ./t5150-request-pull.sh succeeds. # --prefix is set to existing directory ./configure --prefix=/usr/local/varprg # ./t5150-request-pull.sh succeeds. # --prefix is set to non-existing directory ./configure --prefix=/usr/local/varprg/a-long-directory-name-which-does-not-exist # ./t5150-request-pull.sh succeeds. ./configure --prefix=/usr/local/varprg/git.master.a-long-directory-name-which-does-not-exist # ./t5150-request-pull.sh succeeds. So it's something with names like git.master.v2.0.1-472-g6f92e5f that ./configure --prefix is picky about. When testing this last night, I pushed the following branches to https://github.com/sunny256/git where I added all compiled files in various stages with git add -f .: t5150-fail.configure-without-prefix Succeeds. ./configure t5150-fail.configure-with-prefix Fails. ./configure --prefix=/usr/local/varprg/git.master.v2.0.1-472-g6f92e5f t5150-fail.configure-prefix-usr-local Succeeds. ./configure --prefix=/usr/local Maybe something will turn up by diffing those branches. I've got to leave for now, but will have a look at this later tonight. Cheers, Øyvind -- 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 fetch sha1
On Sat, Jul 5, 2014 at 6:05 AM, Allan Gardner allanegard...@gmail.com wrote: On Fri, Jul 4, 2014 at 10:41 PM, Shawn Pearce spea...@spearce.org wrote: On Fri, Jul 4, 2014 at 10:51 AM, Allan Gardner allanegard...@gmail.com wrote: Currently fetching a sha1 fails on git.kernel.org: $ git --version uname -a git version 1.9.4 Linux nixos 3.12.23 #1-NixOS SMP Thu Jan 1 00:00:01 UTC 1970 x86_64 GNU/Linux $ rm -rf test mkdir test cd test git init Initialized empty Git repository in ~/test/.git/ $ git fetch --depth 1 https://git.kernel.org/pub/scm/git/git.git 782735203c316041df120748e5e88c1787cdf4da error: no such remote ref 782735203c316041df120748e5e88c1787cdf4da I tried with head, same error. However, if I clone the full repository and then manually execute git upload-pack, it successfully fetches the commit: $ git fetch https://git.kernel.org/pub/scm/git/git.git master wait an hour $ git checkout -b sha1 782735203c316041df120748e5e88c1787cdf4da $ printf 0045want %s multi_ack_detailed\n000Ddeepen 1\n0009done\n 782735203c316041df120748e5e88c1787cdf4da input $ cat input | git upload-pack --stateless-rpc . output $ sed -z s/.*0008NAK\n// output output.pack $ git index-pack output.pack git verify-pack -v output.pack | grep commit f239687a5dbbd1bbb761d09edec582418c66c297 782735203c316041df120748e5e88c1787cdf4da commit 374 234 12 So theoretically this is supported server-side. Unfortunately kernel.org does not agree: No, it is not supported server side. Your test didn't even test what you think it tested. $ curl https://git.kernel.org/pub/scm/git/git.git/info/refs?service=git-upload-pack 2/dev/null | head -n 2 001e# service=git-upload-pack 009b6f92e5ff3cdc813de8ef5327fd4bad492fb7d6c9 HEADmulti_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed The capability you are asking about is allow-tip-sha1-in-want which does not appear in the server advertisement. So its not supported on this server. $ git upload-pack --advertise-refs --stateless-rpc . 00d16f92e5ff3cdc813de8ef5327fd4bad492fb7d6c9 HEADmulti_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/1.9.4 I did not ask about allow-tip-sha1-in-want, I think you did. You asked about passing a random SHA-1 to `git fetch`. The client will only send this SHA-1 to the server if an advertised ref exactly matches or the server advertised allow-tip-sha1-in-want. Otherwise, it errors out. and it is not enabled by default. It appears that the server must advertise no-done though, which indeed git.kernel.org does not. no-done is unrelated to passing a SHA-1 on the fetch line. The two concepts have nothing to do with each other. I seriously doubt anyone piggybacked additional features onto no-done years after it was introduced. So my next question is how git.kernel.org can set up the smart HTTP protocol without using --stateless-rpc; I guess I will have to ask them. Haha! Good luck with that. Current implementation requires --stateless-rpc to run smart HTTP. -- 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] refs.c: handle REFNAME_REFSPEC_PATTERN at end of page
When a ref crosses a memory page boundary, we restart the parsing at the beginning with the bytewise code. Pass the original flags to that code, rather than the current flags. Signed-off-by: David Turner dtur...@twitter.com --- refs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/refs.c b/refs.c index 20e2bf1..82e4842 100644 --- a/refs.c +++ b/refs.c @@ -153,6 +153,7 @@ int check_refname_format(const char *refname, int flags) const __m128i tilde_lb = _mm_set1_epi8('~' - 1); int component_count = 0; + int orig_flags = flags; if (refname[0] == 0 || refname[0] == '/') { /* entirely empty ref or initial ref component */ @@ -178,7 +179,7 @@ int check_refname_format(const char *refname, int flags) * End-of-page; fall back to slow method for * this entire ref. */ - return check_refname_format_bytewise(refname, flags); + return check_refname_format_bytewise(refname, orig_flags); tmp = _mm_loadu_si128((__m128i *)cp); tmp1 = _mm_loadu_si128((__m128i *)(cp + 1)); -- 2.0.0.390.gcb682f8 -- 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] t5000, t5003: simplify commit
Add the whole directory of test files at once using git add instead of calling git update-index on each of them and use git commit instead of the plumbing commands write-tree, update-ref and commit-tree to build the commit. This simplifies the code considerably. Signed-off-by: Rene Scharfe l@web.de --- t/t5000-tar-tree.sh| 12 t/t5003-archive-zip.sh | 12 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index 899c1c5..7b8babd 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -119,14 +119,10 @@ test_expect_success \ 'echo ignore me a/ignored echo ignored export-ignore .git/info/attributes' -test_expect_success \ -'add files to repository' \ -'find a -type f | xargs git update-index --add - find a -type l | xargs git update-index --add - treeid=$(git write-tree) - echo $treeid treeid - git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE=2005-05-27 22:00:00 \ - git commit-tree $treeid /dev/null)' +test_expect_success 'add files to repository' ' + git add a + GIT_COMMITTER_DATE=2005-05-27 22:00 git commit -m initial +' test_expect_success 'setup export-subst' ' echo substfile? export-subst .git/info/attributes diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh index 21a5c93..c929db5 100755 --- a/t/t5003-archive-zip.sh +++ b/t/t5003-archive-zip.sh @@ -61,14 +61,10 @@ test_expect_success \ 'echo ignore me a/ignored echo ignored export-ignore .git/info/attributes' -test_expect_success \ -'add files to repository' \ -'find a -type f | xargs git update-index --add - find a -type l | xargs git update-index --add - treeid=`git write-tree` - echo $treeid treeid - git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE=2005-05-27 22:00:00 \ - git commit-tree $treeid /dev/null)' +test_expect_success 'add files to repository' ' + git add a + GIT_COMMITTER_DATE=2005-05-27 22:00 git commit -m initial +' test_expect_success 'setup export-subst' ' echo substfile? export-subst .git/info/attributes -- 2.0.0 -- 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] Push fails with dumb http to SabreDAV
Background: I'm trying to host a git repository at my Box.com account, which offers DAV access using a server called SabreDAV. I ran into a few issues along the way. The first is that Box.com apparently doesn't like it if a directory has a dot in the name. No big deal, just use foo instead of foo.git for a bare repository. Next, it gives 404 errors when you try to GET a URL with an extraneous query string. Solution: use GIT_SMART_HTTP=0. Authentication is handled by libcurl automatically reading .netrc. I've gotten to the point where I can clone a repository, but pushing changes back to origin hangs followed by timeout. I don't know if this bug is in git or libcurl, but I think it's the former (as explained below). Problem (see also attachment): When you try to push changes to the remote, it hangs, followed by erroring out with code 52, which is CURLE_GOT_NOTHING. Further investigation shows that cURL successfully uses basic authentication to GET a few files before trying a PROPFIND request on the repository's root directory. The body of the request is in a separate XML file asking the server about the supportedlock property. The first time, cURL sends the request without authentication and receives back 401 Unauthorized. The second time it tries the same request using Basic authentication (this is the same pattern which worked on the earlier GET requests). It gets back a 100-Continue, but fails to upload the XML file like it did before (if you're following along on the typescript, the verbose cURL output should say * We are completely uploaded and fine). Instead it hangs for 60 seconds and errors out with Empty reply from server. I don't think this bug is in libcurl, since it successfully executes all the other commands. I will try to investigate further, but I think it has something to do with the multi-pass authentication. Attached is a typescript of the behavior (editorial comments are placed inside [[ ]], and all user info has been scrubbed). In case the attachment doesn't go through, I have also pasted the typescript to gist [1]. If anyone else wants to reproduce the bug, Box.com does offer a free account. [1] https://gist.githubusercontent.com/abbaad/d4a8ba1e36000eeb8e02/raw/dd5b10ae42b1936d8da33bd384c9affdb103f686/typescript.txt -- Abbaad Haider abb...@gmail.com $ git --version uname -a curl-config --version git version 2.0.1 Linux localhost 3.15.3-1-ARCH #1 SMP PREEMPT Tue Jul 1 07:32:45 CEST 2014 x86_64 GNU/Linux libcurl 7.37.0 $ mkdir foo; cd foo $ git --bare init Initialized empty Git repository in /home/user/foo/ $ git update-server-info $ cd .. $ sudo mount -t davfs https://dav.box.com/dav ./box $ cp -r foo box $ sudo umount box $ rm -r foo $ cat .netrc EOF machine dav.box.com login [[ redacted ]] password [[ redacted ]] EOF $ chmod 600 .netrc $ GIT_SMART_HTTP=0 git clone https://dav.box.com/dav/foo Cloning into 'foo'... warning: You appear to have cloned an empty repository. Checking connectivity... done. $ cd foo/.git/hooks $ mv post-update.sample post-update $ cd ../.. $ touch bar $ git add . $ git commit -a -m foo bar [master (root-commit) 2031b47] foo bar 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 bar $ GIT_SMART_HTTP=0 GIT_CURL_VERBOSE=1 GIT_TRACE=1 git push origin master trace: built-in: git 'push' 'origin' 'master' trace: run_command: 'git-remote-https' 'origin' 'https://dav.box.com/dav/foo' * Hostname was NOT found in DNS cache * Trying 74.112.185.70... * Connected to dav.box.com (74.112.185.70) port 443 (#0) * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: none * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * Server certificate: *subject: serialNumber=jde9iuVneOEaNkFotOvLFaWx0vb5-Qpv; C=US; ST=California; L=Los Altos; O=Box, Inc.; CN=*.box.com *start date: 2014-04-07 05:14:35 GMT *expire date: 2017-10-31 20:06:48 GMT *subjectAltName: dav.box.com matched *issuer: C=US; O=GeoTrust, Inc.; CN=GeoTrust SSL CA *SSL certificate verify ok. GET /dav/foo/info/refs HTTP/1.1 User-Agent: git/2.0.1 Host: dav.box.com Accept: */* Accept-Encoding: gzip Pragma: no-cache HTTP/1.1 401 Unauthorized * Server nginx is not blacklisted Server: nginx Date: Fri, 04 Jul 2014 23:34:18 GMT Content-Type: application/xml; charset=utf-8 Content-Length: 242 Connection: keep-alive Vary: Host WWW-Authenticate: Basic realm=dav.box.com * Ignoring the response-body * Connection #0 to host dav.box.com left intact * Issue another request to this URL: 'https://dav.box.com/dav/foo/info/refs' * Found bundle for host dav.box.com: 0x123ff40 * Re-using existing connection! (#0) with host dav.box.com * Connected to dav.box.com (74.112.185.70) port 443 (#0) * Server auth using Basic with user '[[ redacted ]]' GET /dav/foo/info/refs HTTP/1.1 Authorization: Basic [[ redacted ]] User-Agent: git/2.0.1 Host: dav.box.com Accept: */*
[PATCH] http-push.c: make CURLOPT_IOCTLDATA a usable pointer
Fixes a small bug affecting push to remotes which use some sort of multi-pass authentication. In particular the bug affected SabreDAV as configured by Box.com [1]. It must be a weird server configuration for the bug to have survived this long. Someone should write a test for it. [1] http://marc.info/?l=gitm=140460482604482 Signed-off-by: Abbaad Haider abb...@gmail.com --- http-push.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-push.c b/http-push.c index f2c56c8..bd42895 100644 --- a/http-push.c +++ b/http-push.c @@ -199,7 +199,7 @@ static void curl_setup_http(CURL *curl, const char *url, curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer); #ifndef NO_CURL_IOCTL curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer); - curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer); + curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer); #endif curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn); curl_easy_setopt(curl, CURLOPT_NOBODY, 0); -- 2.0.1 -- 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/3] cache-tree: Create/update cache-tree on checkout
On Tue, 2014-07-01 at 13:15 -0700, Junio C Hamano wrote: David Turner dtur...@twopensource.com writes: When git checkout checks out a branch, create or update the cache-tree so that subsequent operations are faster. Signed-off-by: David Turner dtur...@twitter.com --- builtin/checkout.c| 8 cache-tree.c | 5 +++-- t/t0090-cache-tree.sh | 15 ++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 07cf555..a023a86 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -553,6 +553,14 @@ static int merge_working_tree(const struct checkout_opts *opts, } } + if (!active_cache_tree) + active_cache_tree = cache_tree(); + + if (!cache_tree_fully_valid(active_cache_tree)) + cache_tree_update(active_cache_tree, + (const struct cache_entry * const *)active_cache, + active_nr, 0); + This looks much better than the previous round, but it still does allow verify_cache() to throw noises against unmerged entries in the cache, as WRITE_TREE_SILENT flag is not passed down, no? $ git checkout master^0 $ git am $this_message $ make $ edit builtin/checkout.c ;# make changes to the above lines $ ./git checkout -m master^0 x builtin/checkout.c: unmerged (972c8a7b28f16f88475268f9a714048c228e69db) x builtin/checkout.c: unmerged (f1dc56e55f7b2200412142b10517458ccfda2952) x builtin/checkout.c: unmerged (3b9753ba8c19e7dfe6e922f30eb85c83a92a4596) M builtin/checkout.c Warning: you are leaving 1 commit behind, not connected to any of your branches: 25fab54 cache-tree: Create/update cache-tree on checkout Switched to branch 'master' Passing WRITE_TREE_SILENT in the flags parameter will get rid of the conflict notice output from the above. The user is not interested in writing a brand new tree object at all in this case, so it feels wrong to actually let the call chain go down to update_one() and create new tree objects. Side note. And passing WRITE_TREE_DRY_RUN is not a good solution either, because a later write_cache_as_tree() will not create the necessary tree object once you stuff a tree object name in the cache-tree. What we want in this code path is a way to repair a sub cache_tree if it can be repaired without creating a new tree object and otherwise leave that part invalid. The existing cache-tree framework is not prepared to do that kind of thing. It wants to start from the bottom and percolate things up, computing levels nearer to the top-level only after it fully created the trees for deeper levels, because it is meant to be used only when we really want to write out trees. We may want to reuse update_one() but I am not convinced that doing an equivalent of write-tree when you switch branches is the right approach in the first place. You will eventually write it out as a tree, and having a relatively undamaged cache-tree will help you when you do so, but spending the cycles necessary to compute a fully populated cache-tree, only to let it degrade over time until you are ready to write it out as a tree, somehow sounds like asking for a duplicated work upfront. As I understand it, the cache-tree extension was originally designed to speed up writing the tree later. However, as Karsten Blees's work (and my own tests) have shown, it also speeds up git status. I use git status a lot while working, and I've talked to a few others who do the same. So I think it's worth spending extra time when switching branches to have a good working experience within that branch. In the new version of the patchset (which I'll post shortly), I've added an option WRITE_TREE_REPAIR, which does all of the work to compute a new tree object, but only adds it to the cache-tree if it already exists on-disk. This is a little wasteful for the reason that you note. So if you would like, I could add a config option to skip it. But I think it is a good default. Does this seem OK to you, assuming the implementation is good? -- 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 v4 4/4] cache-tree: Write updated cache-tree after commit
During the commit process, update the cache-tree. Write this updated cache-tree so that it's ready for subsequent commands. Add test code which demonstrates that git commit now writes the cache tree. Make all tests test the entire cache-tree, not just the root level. Signed-off-by: David Turner dtur...@twitter.com --- builtin/commit.c | 31 +++--- t/t0090-cache-tree.sh | 87 ++- 2 files changed, 91 insertions(+), 27 deletions(-) diff --git a/builtin/commit.c b/builtin/commit.c index 9cfef6c..5981755 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -342,6 +342,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, discard_cache(); read_cache_from(index_lock.filename); + if (update_main_cache_tree(WRITE_TREE_SILENT) = 0) + write_cache(fd, active_cache, active_nr); commit_style = COMMIT_NORMAL; return index_lock.filename; @@ -363,10 +365,18 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, fd = hold_locked_index(index_lock, 1); add_files_to_cache(also ? prefix : NULL, pathspec, 0); refresh_cache_or_die(refresh_flags); - update_main_cache_tree(WRITE_TREE_SILENT); - if (write_cache(fd, active_cache, active_nr) || - close_lock_file(index_lock)) - die(_(unable to write new_index file)); + if (active_cache_changed + || !cache_tree_fully_valid(active_cache_tree)) { + update_main_cache_tree(WRITE_TREE_SILENT); + active_cache_changed = 1; + } + if (active_cache_changed) { + if (write_cache(fd, active_cache, active_nr) || + close_lock_file(index_lock)) + die(_(unable to write new_index file)); + } else { + rollback_lock_file(index_lock); + } commit_style = COMMIT_NORMAL; return index_lock.filename; } @@ -383,14 +393,10 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, if (!only !pathspec.nr) { fd = hold_locked_index(index_lock, 1); refresh_cache_or_die(refresh_flags); - if (active_cache_changed) { - update_main_cache_tree(WRITE_TREE_SILENT); - if (write_cache(fd, active_cache, active_nr) || - commit_locked_index(index_lock)) - die(_(unable to write new_index file)); - } else { - rollback_lock_file(index_lock); - } + update_main_cache_tree(WRITE_TREE_SILENT); + if (write_cache(fd, active_cache, active_nr) || + commit_locked_index(index_lock)) + die(_(unable to write new_index file)); commit_style = COMMIT_AS_IS; return get_index_file(); } @@ -435,6 +441,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, fd = hold_locked_index(index_lock, 1); add_remove_files(partial); refresh_cache(REFRESH_QUIET); + update_main_cache_tree(WRITE_TREE_SILENT); if (write_cache(fd, active_cache, active_nr) || close_lock_file(index_lock)) die(_(unable to write new_index file)); diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh index 8437c5f..15f1484 100755 --- a/t/t0090-cache-tree.sh +++ b/t/t0090-cache-tree.sh @@ -7,8 +7,14 @@ cache-tree extension. . ./test-lib.sh +grep_nonmatch_ok () { +grep $@ +test $? = 2 return 1 +return 0 +} + cmp_cache_tree () { - test-dump-cache-tree actual + test-dump-cache-tree | grep_nonmatch_ok -v \#\(ref\) actual sed s/$_x40/SHA/ actual filtered test_cmp $1 filtered } @@ -16,15 +22,33 @@ cmp_cache_tree () { # We don't bother with actually checking the SHA1: # test-dump-cache-tree already verifies that all existing data is # correct. -test_shallow_cache_tree () { - printf SHA (%d entries, 0 subtrees)\n $(git ls-files|wc -l) expect +generate_expected_cache_tree () { + dir=$1${1:+/} + parent=$2 + # ls-files might have foo/bar, foo/bar/baz, and foo/bar/quux + # We want to count only foo because it's the only direct child + subtrees=$(git ls-files|grep /|cut -d / -f 1|uniq) + subtree_count=$(echo $subtrees|grep_nonmatch_ok -c .) + entries=$(git ls-files|wc -l) + printf SHA $dir (%d entries, %d subtrees)\n $entries $subtree_count + for subtree in $subtrees + do + cd $subtree + generate_expected_cache_tree
[PATCH v4 3/4] cache-tree: subdirectory tests
Add tests to confirm that invalidation of subdirectories nether over- nor under-invalidates. Signed-off-by: David Turner dtur...@twitter.com --- t/t0090-cache-tree.sh | 28 +--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh index 98fb1ab..8437c5f 100755 --- a/t/t0090-cache-tree.sh +++ b/t/t0090-cache-tree.sh @@ -21,10 +21,13 @@ test_shallow_cache_tree () { cmp_cache_tree expect } +# Test that the cache-tree for a given directory is invalid. +# If no directory is given, check that the root is invalid test_invalid_cache_tree () { - echo invalid (0 subtrees) expect - printf SHA #(ref) (%d entries, 0 subtrees)\n $(git ls-files|wc -l) expect - cmp_cache_tree expect + test-dump-cache-tree actual + sed -e s/$_x40/SHA/ -e s/[0-9]* subtrees//g actual filtered + expect=$(printf invalid $1 ()\n) + fgrep $expect filtered } test_no_cache_tree () { @@ -49,6 +52,25 @@ test_expect_success 'git-add invalidates cache-tree' ' test_invalid_cache_tree ' +test_expect_success 'git-add in subdir invalidates cache-tree' ' + test_when_finished git reset --hard; git read-tree HEAD + mkdir dirx + echo I changed this file dirx/foo + git add dirx/foo + test_invalid_cache_tree +' + +test_expect_success 'git-add in subdir does not invalidate sibling cache-tree' ' + git tag no-children + test_when_finished git reset --hard no-children; git read-tree HEAD + mkdir dir1 dir2 + test_commit dir1/a + test_commit dir2/b + echo I changed this file dir1/a + git add dir1/a + test_invalid_cache_tree dir1/ +' + test_expect_success 'update-index invalidates cache-tree' ' test_when_finished git reset --hard; git read-tree HEAD echo I changed this file foo -- 2.0.0.390.gcb682f8 -- 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 v4 1/4] cache-tree: Create/update cache-tree on checkout
When git checkout checks out a branch, create or update the cache-tree so that subsequent operations are faster. update_main_cache_tree learned a new flag, WRITE_TREE_REPAIR. When WRITE_TREE_REPAIR is set, portions of the cache-tree which do not correspond to existing tree objects are invalidated (and portions which do are marked as valid). No new tree objects are created. Signed-off-by: David Turner dtur...@twitter.com --- builtin/checkout.c| 8 cache-tree.c | 12 +++- cache-tree.h | 1 + t/t0090-cache-tree.sh | 19 --- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 07cf555..054214f 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -553,6 +553,14 @@ static int merge_working_tree(const struct checkout_opts *opts, } } + if (!active_cache_tree) + active_cache_tree = cache_tree(); + + if (!cache_tree_fully_valid(active_cache_tree)) + cache_tree_update(active_cache_tree, + (const struct cache_entry * const *)active_cache, + active_nr, WRITE_TREE_SILENT | WRITE_TREE_REPAIR); + if (write_cache(newfd, active_cache, active_nr) || commit_locked_index(lock_file)) die(_(unable to write new index file)); diff --git a/cache-tree.c b/cache-tree.c index 7fa524a..f951d7d 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -239,9 +239,12 @@ static int update_one(struct cache_tree *it, struct strbuf buffer; int missing_ok = flags WRITE_TREE_MISSING_OK; int dryrun = flags WRITE_TREE_DRY_RUN; + int repair = flags WRITE_TREE_REPAIR; int to_invalidate = 0; int i; + assert(!(dryrun repair)); + *skip_count = 0; if (0 = it-entry_count has_sha1_file(it-sha1)) @@ -374,7 +377,14 @@ static int update_one(struct cache_tree *it, #endif } - if (dryrun) + if (repair) { + unsigned char sha1[20]; + hash_sha1_file(buffer.buf, buffer.len, tree_type, sha1); + if (has_sha1_file(sha1)) + hashcpy(it-sha1, sha1); + else + to_invalidate = 1; + } else if (dryrun) hash_sha1_file(buffer.buf, buffer.len, tree_type, it-sha1); else if (write_sha1_file(buffer.buf, buffer.len, tree_type, it-sha1)) { strbuf_release(buffer); diff --git a/cache-tree.h b/cache-tree.h index f1923ad..666d18f 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -39,6 +39,7 @@ int update_main_cache_tree(int); #define WRITE_TREE_IGNORE_CACHE_TREE 2 #define WRITE_TREE_DRY_RUN 4 #define WRITE_TREE_SILENT 8 +#define WRITE_TREE_REPAIR 16 /* error return codes */ #define WRITE_TREE_UNREADABLE_INDEX (-1) diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh index 6c33e28..98fb1ab 100755 --- a/t/t0090-cache-tree.sh +++ b/t/t0090-cache-tree.sh @@ -44,14 +44,14 @@ test_expect_success 'read-tree HEAD establishes cache-tree' ' test_expect_success 'git-add invalidates cache-tree' ' test_when_finished git reset --hard; git read-tree HEAD - echo I changed this file foo + echo I changed this file foo git add foo test_invalid_cache_tree ' test_expect_success 'update-index invalidates cache-tree' ' test_when_finished git reset --hard; git read-tree HEAD - echo I changed this file foo + echo I changed this file foo git update-index --add foo test_invalid_cache_tree ' @@ -85,9 +85,22 @@ test_expect_success 'reset --hard without index gives cache-tree' ' test_shallow_cache_tree ' -test_expect_failure 'checkout gives cache-tree' ' +test_expect_success 'checkout gives cache-tree' ' + git tag current git checkout HEAD^ test_shallow_cache_tree ' +test_expect_success 'checkout -b gives cache-tree' ' + git checkout current + git checkout -b prev HEAD^ + test_shallow_cache_tree +' + +test_expect_success 'checkout -B gives cache-tree' ' + git checkout current + git checkout -B prev HEAD^ + test_shallow_cache_tree +' + test_done -- 2.0.0.390.gcb682f8 -- 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 v4 2/4] test-dump-cache-tree: invalid trees are not errors
Do not treat known-invalid trees as errors even when their count is incorrect. Because git already knows that these trees are invalid, nothing depends on the count field. Add a couple of comments. Signed-off-by: David Turner dtur...@twitter.com --- test-dump-cache-tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-dump-cache-tree.c b/test-dump-cache-tree.c index 47eab97..cbbbd8e 100644 --- a/test-dump-cache-tree.c +++ b/test-dump-cache-tree.c @@ -26,16 +26,16 @@ static int dump_cache_tree(struct cache_tree *it, return 0; if (it-entry_count 0) { + /* invalid */ dump_one(it, pfx, ); dump_one(ref, pfx, #(ref) ); - if (it-subtree_nr != ref-subtree_nr) - errs = 1; } else { dump_one(it, pfx, ); if (hashcmp(it-sha1, ref-sha1) || ref-entry_count != it-entry_count || ref-subtree_nr != it-subtree_nr) { + /* claims to be valid but is lying */ dump_one(ref, pfx, #(ref) ); errs = 1; } -- 2.0.0.390.gcb682f8 -- 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