* Re: What's in git.git
From: Johannes Schindelin @ 2006-04-22 11:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, linux-kernel
In-Reply-To: <7vzmieo2j3.fsf@assigned-by-dhcp.cox.net>
Hi,
On Fri, 21 Apr 2006, Junio C Hamano wrote:
> - diff --stat: do not drop rename information.
>
> Johannes suggested "file => /dev/null" to show a deleted
> file as if a rename was done. While I think it makes some
> sense, I am afraid it diverges too much from the traditional
> diffstat output. I am undecided, somewhat negative, about
> the suggestion.
It was not so much a suggestion, but a misinterpretation of your patch. I
am also undecided and slightly negative about it.
> * The 'pu' branch, in addition, has these.
>
> - gitk: Fix geometry on rootless X (Johannes Schindelin)
I talked to Paul about this, and was not only slightly negative about it.
The suggestion was to either use native versions of Tk (which might or
might not fix it), or fix Tk.
Having spent already some time with this workaround, I am not willing to
invest more of it, though.
So, if people want to do something about this patch, go wild.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] Libify diff-files.
From: Junio C Hamano @ 2006-04-22 10:52 UTC (permalink / raw)
To: git; +Cc: torvalds, pasky
In-Reply-To: <7vbqutlxwq.fsf@assigned-by-dhcp.cox.net>
I noticed that there are two flags related to missing working
tree files in diff-files and diff-index. The former takes -q
to mean "do not report lossage of working tree files", and the
latter uses -m to mean "when not using --cached, pretend that
missing working tree files are actually present and match the
index".
Being able to pretend missing working tree files are unchanged
was originally done to help merging in a separate temporary
area, and it is useful, but I wish we used the same flag. I
started wondering if we can unify them to '-q', since '-m'
means "do not ignore merges" in diff-tree context (including
log and whatchanged).
NOTE. -q is different from specifying --diff-filter=ACMRTU;
while the former does not even feed the filepair to diffcore,
the latter tells the diffcore to filter deletion out in the
output phase. The distinction makes huge difference when the
rename/copy detection, especially without --find-copies-harder,
is involved.
Now, as far as I can tell, nobody uses "diff-files -q". Cogito
uses "diff-index -m" quite a bit, but I suspect large part of it
is remnant from the days it did a merge in a separate directory,
and/or a cut-and-paste error from neighbouring "diff-tree -m -r".
A cursory look suggests some could even be bugs. For example,
cg-patch has
diff-tree -m -r "$commitparent" "$commitid"
(where -m does not have any effect) which is immediately
followed by a
diff-index -m -r HEAD
where -m may or may not be intended.
^ permalink raw reply
* make update-index --chmod work with multiple files and --stdin
From: Alex Riesen @ 2006-04-22 20:46 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
I had a project where lots of files were "accidentally" marked +x, and
doing plain "git-update-index --chmod=-x" for each file was too slow.
Besides, it's somewhat inconsistent, that --chmod does work only for
one subsequent file.
---
Yes, windows again.
update-index.c | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
5c7b9c2d187f36ba8b5632d2125f2bd19abb3564
diff --git a/update-index.c b/update-index.c
index 1efac27..c3c2000 100644
--- a/update-index.c
+++ b/update-index.c
@@ -350,6 +350,7 @@ static int chmod_path(int flip, const ch
return -1;
}
active_cache_changed = 1;
+ report("chmod %cx '%s'", flip, path);
return 0;
}
@@ -478,6 +479,7 @@ int main(int argc, const char **argv)
int read_from_stdin = 0;
const char *prefix = setup_git_directory();
int prefix_length = prefix ? strlen(prefix) : 0;
+ char chmod_mode = 0;
git_config(git_default_config);
@@ -544,8 +546,7 @@ int main(int argc, const char **argv)
!strcmp(path, "--chmod=+x")) {
if (argc <= i+1)
die("git-update-index: %s <path>", path);
- if (chmod_path(path[8], argv[++i]))
- die("git-update-index: %s cannot chmod %s", path, argv[i]);
+ chmod_mode = path[8];
continue;
}
if (!strcmp(path, "--assume-unchanged")) {
@@ -594,6 +595,11 @@ int main(int argc, const char **argv)
die("unknown option %s", path);
}
update_one(path, prefix, prefix_length);
+ if ( chmod_mode ) {
+ if (chmod_path(chmod_mode, path))
+ die("git-update-index: cannot chmod %cx %s",
+ chmod_mode, path);
+ }
}
if (read_from_stdin) {
struct strbuf buf;
@@ -608,6 +614,12 @@ int main(int argc, const char **argv)
else
path_name = buf.buf;
update_one(path_name, prefix, prefix_length);
+ if ( chmod_mode ) {
+ const char *p = prefix_path(prefix, prefix_length, path_name);
+ if (chmod_path(chmod_mode, p))
+ die("git-update-index: cannot chmod %cx %s",
+ chmod_mode, p);
+ }
if (path_name != buf.buf)
free(path_name);
}
--
1.3.0.gc2941
^ permalink raw reply related
* [RFC] Loosening path argument check a little bit in revision.c
From: Junio C Hamano @ 2006-04-22 10:15 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
The argument parser revision.c::setup_revisions() insists on
path arguments that do not follow the double-dash marker to be
paths (either files or directories) that exist in the working
tree. As the fact that diff-files and update-index have
explicit options to ignore "missing" files reminds us,
traditionally we allowed a sparsely populated working tree, so
this check is not very user friendly.
This patch allows non-existing paths to be given without the
double-dash marker as long as they exist in the index, or they
are leading paths of blobs that exist in the index.
A misspelled tag v2.6.16 is not a very likely name to have only
in the index and not in the working tree, so this should not
break the case the original code wanted to fix ;-).
---
* I noticed a breakage in out test scripts while libifying
diff-files. The two-tree fast-forward merge test stuffs an
entry DF/DF in the index while having a working tree file DF,
and run "diff-files DF/DF" to make sure two-way read-tree
left the index dirty. The libified diff-files naturally uses
revision infrastructure to get its parameters, and the path
argument check causes the test to fail without this patch.
This is just an RFC. We can easily rewrite the particular
test to use the double-dash marker, but I suspect existing
porcelains share the same problem, expecting to be able to do
something like this:
$ names=`git diff-files --name-only`
$ git diff-index HEAD $names
Of course, the kosher way is to always use double-dash, like
this:
$ git diff-files -z --name-only |
xargs -0 git diff-index HEAD --
So I am not pushing this too strongly. Comments?
revision.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/revision.c b/revision.c
index 113dd5a..9f6dd24 100644
--- a/revision.c
+++ b/revision.c
@@ -504,6 +504,43 @@ void init_revisions(struct rev_info *rev
diff_setup(&revs->diffopt);
}
+static int check_path_arg(const char *path)
+{
+ struct stat st;
+ int tmp = lstat(path, &st);
+ if (!tmp)
+ return 0;
+ tmp = errno;
+ if (!active_cache)
+ read_cache();
+ if (active_cache) {
+ int namelen = strlen(path);
+ int pos = cache_name_pos(path, namelen);
+ if (pos < 0)
+ pos = -pos - 1;
+ if (pos < active_nr) {
+ struct cache_entry *ce = active_cache[pos];
+ if (ce_namelen(ce) == namelen &&
+ !memcmp(ce->name, path, namelen))
+ return 0;
+ }
+ /* Try it as a directory name - "foo/" */
+ while (++pos < active_nr) {
+ struct cache_entry *ce = active_cache[pos];
+ if (namelen < ce_namelen(ce) &&
+ !memcmp(ce->name, path, namelen)) {
+ /* prefix still matches */
+ if (ce->name[namelen] == '/')
+ return 0;
+ }
+ else
+ break; /* prefix does not match anymore */
+ }
+ }
+ errno = tmp;
+ return -1;
+}
+
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
@@ -752,16 +789,19 @@ int setup_revisions(int argc, const char
arg++;
}
if (get_sha1(arg, sha1) < 0) {
- struct stat st;
int j;
if (seen_dashdash || local_flags)
die("bad revision '%s'", arg);
- /* If we didn't have a "--", all filenames must exist */
+ /* If we didn't have a "--", all filenames must
+ * exist, either in the working tree or in the
+ * cache.
+ */
for (j = i; j < argc; j++) {
- if (lstat(argv[j], &st) < 0)
- die("'%s': %s", argv[j], strerror(errno));
+ if (check_path_arg(argv[j]))
+ die("'%s': %s", argv[j],
+ strerror(errno));
}
revs->prune_data = get_pathspec(revs->prefix, argv + i);
break;
^ permalink raw reply related
* Re: RFC: New diff-delta.c implementation
From: Nicolas Pitre @ 2006-04-22 3:19 UTC (permalink / raw)
To: Geert Bosch; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <602974A9-09A3-46E9-92D6-D30728923C11@adacore.com>
On Fri, 21 Apr 2006, Geert Bosch wrote:
> I wrote a new binary differencing algorithm that is both faster
> and generates smaller deltas than the current implementation.
> The format is compatible with that used by patch-delta, so
> it should be easy to integrate.
It looks really interesting.
It ignores the max_size argument but that is trivially fixed.
Then it triggers some assertions in the code when running the test
suite.
> Originally, I wrote this for the GDIFF format, see
> http://www.w3.org/TR/NOTE-gdiff-19970901.
> The adaptation for GIT format was relatively simple, but is not thoroughly
> tested.
Some trivial tests look fine but it fail on some others.
> The code is not derived from libxdiff, but uses the rabin_slide function
> written
> by David Mazieres (dm@uun.org). Also the tables are generated using his code.
> Finally, this was developed on Darwin, and not a Linux system, so some changes
> may be needed.
It does compile out of the box on Linux.
> Please feel free to play around with this code, and give feedback.
> Keep in mind this wasn't originally written for GIT, and C is not
> my native language, so don't mind my formatting etc.
I did reformat it a bit to be more inline with the rest of GIT's coding
style (and to help me read it). I'll look at fixing the issues I can
fix and post it back.
Nicolas
^ permalink raw reply
* Problem with Git in Cygwin on x86-64 platform
From: Tim O'Callaghan @ 2006-04-22 2:30 UTC (permalink / raw)
To: git
When running a 'make test' under cygwin on my 64bit machine, and got
the output below. The reason i cite the 64bit cygwin platform being a
difference is that i have run 'make test' on the exact same codebase
on a 32 bit machine. The only difference in compile environment is
that the cygwin install on the 64 bit machine is as of today, and the
32 bit machine was about three days ago.
----
*** t0000-basic.sh ***
* ok 1: .git/objects should be empty after git-init-db in an empty repo.
* ok 2: .git/objects should have 3 subdirectories.
* ok 3: git-update-index without --add should fail adding.
* ok 4: git-update-index with --add should succeed.
* ok 5: writing tree out with git-write-tree
* ok 6: validate object ID of a known tree.
* ok 7: git-update-index without --remove should fail removing.
* FAIL 8: git-update-index with --remove should be able to remove.
git-update-index --remove should-be-empty
* ok 9: git-write-tree should be able to write an empty tree.
* FAIL 10: validate object ID of a known tree.
test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904
* FAIL 11: adding various types of objects with git-update-index --add.
find path* ! -type d -print | xargs git-update-index --add
* ok 12: showing stage with git-ls-files --stage
* FAIL 13: validate git-ls-files output for a known tree.
diff current expected
* ok 14: writing tree out with git-write-tree.
* FAIL 15: validate object ID for a known tree.
test "$tree" = 087704a96baf1c2d1c869a8b084481e121c88b5b
* ok 16: showing tree with git-ls-tree
* FAIL 17: git-ls-tree output for a known tree.
diff current expected
* ok 18: showing tree with git-ls-tree -r
* FAIL 19: git-ls-tree -r output for a known tree.
diff current expected
* FAIL 20: git-read-tree followed by write-tree should be idempotent.
git-read-tree $tree &&
test -f .git/index &&
newtree=$(git-write-tree) &&
test "$newtree" = "$tree"
* FAIL 21: validate git-diff-files output for a know cache/work tree state.
git-diff-files >current && diff >/dev/null -b current expected
* FAIL 22: git-update-index --refresh should succeed.
git-update-index --refresh
* ok 23: no diff after checkout and git-update-index --refresh.
* failed 10 among 23 test(s)
-----
Any ideas on how to start tracking this one down?
Tim.
^ permalink raw reply
* Re: Problem with Git in Cygwin on x86-64 platform
From: Alex Riesen @ 2006-04-22 21:17 UTC (permalink / raw)
To: Tim O'Callaghan, git
In-Reply-To: <20060422023029.GC2444@Zangband>
Tim O'Callaghan, Sat, Apr 22, 2006 04:30:30 +0200:
> When running a 'make test' under cygwin on my 64bit machine, and got
> the output below. The reason i cite the 64bit cygwin platform being a
> difference is that i have run 'make test' on the exact same codebase
> on a 32 bit machine. The only difference in compile environment is
> that the cygwin install on the 64 bit machine is as of today, and the
> 32 bit machine was about three days ago.
>
> *** t0000-basic.sh ***
...
> * FAIL 8: git-update-index with --remove should be able to remove.
...
> Any ideas on how to start tracking this one down?
Start by going into git/t and running "./t0000-basic.sh -d -v"
^ permalink raw reply
* Re: make update-index --chmod work with multiple files and --stdin
From: Junio C Hamano @ 2006-04-23 0:54 UTC (permalink / raw)
To: Alex Riesen; +Cc: git
In-Reply-To: <20060422204642.GA7676@steel.home>
Alex Riesen <raa.lkml@gmail.com> writes:
> I had a project where lots of files were "accidentally" marked +x, and
> doing plain "git-update-index --chmod=-x" for each file was too slow.
> Besides, it's somewhat inconsistent, that --chmod does work only for
> one subsequent file.
If you are doing that on the command line, people may want to
have a way to mean "from here on do not do chmod, just do normal
update-index and nothing else" by resetting the chmod_mode thing
back to zero. Nothing major, and we do not do that to allow_add
and allow_remove either, but just a thought.
> + char chmod_mode = 0;
Perhaps "set_executable_bit"?
> + if ( chmod_mode ) {
Please lose ( extra ) whitespaces around parentheses.
> + if ( chmod_mode ) {
Likewise.
> + if (chmod_path(chmod_mode, p))
> + die("git-update-index: cannot chmod %cx %s",
> + chmod_mode, p);
> + }
Might make sense to die inside chmod_path() instead of repeating
the if () { die() } sequence twice? I dunno.
^ permalink raw reply
* Re: Problem with Git in Cygwin on x86-64 platform
From: Junio C Hamano @ 2006-04-23 0:57 UTC (permalink / raw)
To: Tim O'Callaghan; +Cc: git, Alex Riesen
In-Reply-To: <20060422211733.GB7676@steel.home>
Alex Riesen <raa.lkml@gmail.com> writes:
>> Any ideas on how to start tracking this one down?
>
> Start by going into git/t and running "./t0000-basic.sh -d -v"
I usually do "cd t && sh -x that-test -i -v".
^ permalink raw reply
* Re: RFC: New diff-delta.c implementation
From: Geert Bosch @ 2006-04-23 2:31 UTC (permalink / raw)
To: Davide Libenzi; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0604221333470.23166@alien.or.mcafeemobile.com>
On Sat, Apr 22, 2006 at 01:36:07PM -0700, Davide Libenzi wrote:
> Geert, I saw you're using a shift of 55 bits, that gives an degree of the
> root polynomial of 63, that is not prime. Where did you get the root
> polynomial, and why you did not chose 61 as degree of the root?
> Just curious ...
The polynomial was randomly created using code by David Mazieres, that
is part of LBFS. I chose a (irreducible) polynomial of degree 63 as
that was the same as LBFS did. As for my purposes it's best to have
a constant polynomial and I wanted to have all the code for
the computations in the same compilation unit for performance,
I decided to just have a little program print out the tables
and include it directly. The chosen polynomial was 0xb15e234bd3792f63.
Later on I haven't revisited this decision, although I agree that
it'd probably be a good idea to use a polynomial of prime degree,
even though we're not looking for cryptographically strong hashes here.
Below I include new tables for degree 61. The window size of 22 was
found by plotting graphs on a number of largish test cases (30-100MB)
and seeing how the size of the compressed output changed. It is
essential to do all comparisons using gzipped output. I've been
tempted a number of times to include new optimizations, only
to find out that the uncompressed size reduced, but final compressed
size grew. More smaller copies and literal data segments is generally
worse.
-Geert
#define RABIN_POLY 0x25bd5331c0d7096dULL
#define RABIN_DEGREE 61
#define RABIN_SHIFT 53
#define RABIN_WINDOW_SIZE 22
unsigned long long T[256] =
{ 0x0000000000000000ULL, 0x25bd5331c0d7096dULL, 0x4b7aa66381ae12daULL,
0x6ec7f55241791bb7ULL, 0x96f54cc7035c25b4ULL, 0xb3481ff6c38b2cd9ULL,
0xdd8feaa482f2376eULL, 0xf832b99542253e03ULL, 0x0857cabfc66f4205ULL,
0x2dea998e06b84b68ULL, 0x432d6cdc47c150dfULL, 0x66903fed871659b2ULL,
0x9ea28678c53367b1ULL, 0xbb1fd54905e46edcULL, 0xd5d8201b449d756bULL,
0xf065732a844a7c06ULL, 0x10af957f8cde840aULL, 0x3512c64e4c098d67ULL,
0x5bd5331c0d7096d0ULL, 0x7e68602dcda79fbdULL, 0x865ad9b88f82a1beULL,
0xa3e78a894f55a8d3ULL, 0xcd207fdb0e2cb364ULL, 0xe89d2ceacefbba09ULL,
0x18f85fc04ab1c60fULL, 0x3d450cf18a66cf62ULL, 0x5382f9a3cb1fd4d5ULL,
0x763faa920bc8ddb8ULL, 0x8e0d130749ede3bbULL, 0xabb04036893aead6ULL,
0xc577b564c843f161ULL, 0xe0cae6550894f80cULL, 0x04e279ced96a0179ULL,
0x215f2aff19bd0814ULL, 0x4f98dfad58c413a3ULL, 0x6a258c9c98131aceULL,
0x92173509da3624cdULL, 0xb7aa66381ae12da0ULL, 0xd96d936a5b983617ULL,
0xfcd0c05b9b4f3f7aULL, 0x0cb5b3711f05437cULL, 0x2908e040dfd24a11ULL,
0x47cf15129eab51a6ULL, 0x627246235e7c58cbULL, 0x9a40ffb61c5966c8ULL,
0xbffdac87dc8e6fa5ULL, 0xd13a59d59df77412ULL, 0xf4870ae45d207d7fULL,
0x144decb155b48573ULL, 0x31f0bf8095638c1eULL, 0x5f374ad2d41a97a9ULL,
0x7a8a19e314cd9ec4ULL, 0x82b8a07656e8a0c7ULL, 0xa705f347963fa9aaULL,
0xc9c20615d746b21dULL, 0xec7f55241791bb70ULL, 0x1c1a260e93dbc776ULL,
0x39a7753f530cce1bULL, 0x5760806d1275d5acULL, 0x72ddd35cd2a2dcc1ULL,
0x8aef6ac99087e2c2ULL, 0xaf5239f85050ebafULL, 0xc195ccaa1129f018ULL,
0xe4289f9bd1fef975ULL, 0x09c4f39db2d402f2ULL, 0x2c79a0ac72030b9fULL,
0x42be55fe337a1028ULL, 0x670306cff3ad1945ULL, 0x9f31bf5ab1882746ULL,
0xba8cec6b715f2e2bULL, 0xd44b19393026359cULL, 0xf1f64a08f0f13cf1ULL,
0x0193392274bb40f7ULL, 0x242e6a13b46c499aULL, 0x4ae99f41f515522dULL,
0x6f54cc7035c25b40ULL, 0x976675e577e76543ULL, 0xb2db26d4b7306c2eULL,
0xdc1cd386f6497799ULL, 0xf9a180b7369e7ef4ULL, 0x196b66e23e0a86f8ULL,
0x3cd635d3fedd8f95ULL, 0x5211c081bfa49422ULL, 0x77ac93b07f739d4fULL,
0x8f9e2a253d56a34cULL, 0xaa237914fd81aa21ULL, 0xc4e48c46bcf8b196ULL,
0xe159df777c2fb8fbULL, 0x113cac5df865c4fdULL, 0x3481ff6c38b2cd90ULL,
0x5a460a3e79cbd627ULL, 0x7ffb590fb91cdf4aULL, 0x87c9e09afb39e149ULL,
0xa274b3ab3beee824ULL, 0xccb346f97a97f393ULL, 0xe90e15c8ba40fafeULL,
0x0d268a536bbe038bULL, 0x289bd962ab690ae6ULL, 0x465c2c30ea101151ULL,
0x63e17f012ac7183cULL, 0x9bd3c69468e2263fULL, 0xbe6e95a5a8352f52ULL,
0xd0a960f7e94c34e5ULL, 0xf51433c6299b3d88ULL, 0x057140ecadd1418eULL,
0x20cc13dd6d0648e3ULL, 0x4e0be68f2c7f5354ULL, 0x6bb6b5beeca85a39ULL,
0x93840c2bae8d643aULL, 0xb6395f1a6e5a6d57ULL, 0xd8feaa482f2376e0ULL,
0xfd43f979eff47f8dULL, 0x1d891f2ce7608781ULL, 0x38344c1d27b78eecULL,
0x56f3b94f66ce955bULL, 0x734eea7ea6199c36ULL, 0x8b7c53ebe43ca235ULL,
0xaec100da24ebab58ULL, 0xc006f5886592b0efULL, 0xe5bba6b9a545b982ULL,
0x15ded593210fc584ULL, 0x306386a2e1d8cce9ULL, 0x5ea473f0a0a1d75eULL,
0x7b1920c16076de33ULL, 0x832b99542253e030ULL, 0xa696ca65e284e95dULL,
0xc8513f37a3fdf2eaULL, 0xedec6c06632afb87ULL, 0x1389e73b65a805e4ULL,
0x3634b40aa57f0c89ULL, 0x58f34158e406173eULL, 0x7d4e126924d11e53ULL,
0x857cabfc66f42050ULL, 0xa0c1f8cda623293dULL, 0xce060d9fe75a328aULL,
0xebbb5eae278d3be7ULL, 0x1bde2d84a3c747e1ULL, 0x3e637eb563104e8cULL,
0x50a48be72269553bULL, 0x7519d8d6e2be5c56ULL, 0x8d2b6143a09b6255ULL,
0xa8963272604c6b38ULL, 0xc651c7202135708fULL, 0xe3ec9411e1e279e2ULL,
0x03267244e97681eeULL, 0x269b217529a18883ULL, 0x485cd42768d89334ULL,
0x6de18716a80f9a59ULL, 0x95d33e83ea2aa45aULL, 0xb06e6db22afdad37ULL,
0xdea998e06b84b680ULL, 0xfb14cbd1ab53bfedULL, 0x0b71b8fb2f19c3ebULL,
0x2eccebcaefceca86ULL, 0x400b1e98aeb7d131ULL, 0x65b64da96e60d85cULL,
0x9d84f43c2c45e65fULL, 0xb839a70dec92ef32ULL, 0xd6fe525fadebf485ULL,
0xf343016e6d3cfde8ULL, 0x176b9ef5bcc2049dULL, 0x32d6cdc47c150df0ULL,
0x5c1138963d6c1647ULL, 0x79ac6ba7fdbb1f2aULL, 0x819ed232bf9e2129ULL,
0xa42381037f492844ULL, 0xcae474513e3033f3ULL, 0xef592760fee73a9eULL,
0x1f3c544a7aad4698ULL, 0x3a81077bba7a4ff5ULL, 0x5446f229fb035442ULL,
0x71fba1183bd45d2fULL, 0x89c9188d79f1632cULL, 0xac744bbcb9266a41ULL,
0xc2b3beeef85f71f6ULL, 0xe70eeddf3888789bULL, 0x07c40b8a301c8097ULL,
0x227958bbf0cb89faULL, 0x4cbeade9b1b2924dULL, 0x6903fed871659b20ULL,
0x9131474d3340a523ULL, 0xb48c147cf397ac4eULL, 0xda4be12eb2eeb7f9ULL,
0xfff6b21f7239be94ULL, 0x0f93c135f673c292ULL, 0x2a2e920436a4cbffULL,
0x44e9675677ddd048ULL, 0x61543467b70ad925ULL, 0x99668df2f52fe726ULL,
0xbcdbdec335f8ee4bULL, 0xd21c2b917481f5fcULL, 0xf7a178a0b456fc91ULL,
0x1a4d14a6d77c0716ULL, 0x3ff0479717ab0e7bULL, 0x5137b2c556d215ccULL,
0x748ae1f496051ca1ULL, 0x8cb85861d42022a2ULL, 0xa9050b5014f72bcfULL,
0xc7c2fe02558e3078ULL, 0xe27fad3395593915ULL, 0x121ade1911134513ULL,
0x37a78d28d1c44c7eULL, 0x5960787a90bd57c9ULL, 0x7cdd2b4b506a5ea4ULL,
0x84ef92de124f60a7ULL, 0xa152c1efd29869caULL, 0xcf9534bd93e1727dULL,
0xea28678c53367b10ULL, 0x0ae281d95ba2831cULL, 0x2f5fd2e89b758a71ULL,
0x419827bada0c91c6ULL, 0x6425748b1adb98abULL, 0x9c17cd1e58fea6a8ULL,
0xb9aa9e2f9829afc5ULL, 0xd76d6b7dd950b472ULL, 0xf2d0384c1987bd1fULL,
0x02b54b669dcdc119ULL, 0x270818575d1ac874ULL, 0x49cfed051c63d3c3ULL,
0x6c72be34dcb4daaeULL, 0x944007a19e91e4adULL, 0xb1fd54905e46edc0ULL,
0xdf3aa1c21f3ff677ULL, 0xfa87f2f3dfe8ff1aULL, 0x1eaf6d680e16066fULL,
0x3b123e59cec10f02ULL, 0x55d5cb0b8fb814b5ULL, 0x7068983a4f6f1dd8ULL,
0x885a21af0d4a23dbULL, 0xade7729ecd9d2ab6ULL, 0xc32087cc8ce43101ULL,
0xe69dd4fd4c33386cULL, 0x16f8a7d7c879446aULL, 0x3345f4e608ae4d07ULL,
0x5d8201b449d756b0ULL, 0x783f528589005fddULL, 0x800deb10cb2561deULL,
0xa5b0b8210bf268b3ULL, 0xcb774d734a8b7304ULL, 0xeeca1e428a5c7a69ULL,
0x0e00f81782c88265ULL, 0x2bbdab26421f8b08ULL, 0x457a5e74036690bfULL,
0x60c70d45c3b199d2ULL, 0x98f5b4d08194a7d1ULL, 0xbd48e7e14143aebcULL,
0xd38f12b3003ab50bULL, 0xf6324182c0edbc66ULL, 0x065732a844a7c060ULL,
0x23ea61998470c90dULL, 0x4d2d94cbc509d2baULL, 0x6890c7fa05dedbd7ULL,
0x90a27e6f47fbe5d4ULL, 0xb51f2d5e872cecb9ULL, 0xdbd8d80cc655f70eULL,
0xfe658b3d0682fe63ULL
};
unsigned long long U[256] =
{ 0x0000000000000000ULL, 0x067b86c43d6a6cb0ULL, 0x0cf70d887ad4d960ULL,
0x0a8c8b4c47beb5d0ULL, 0x19ee1b10f5a9b2c0ULL, 0x1f959dd4c8c3de70ULL,
0x151916988f7d6ba0ULL, 0x1362905cb2170710ULL, 0x166165102b846cedULL,
0x101ae3d416ee005dULL, 0x1a9668985150b58dULL, 0x1cedee5c6c3ad93dULL,
0x0f8f7e00de2dde2dULL, 0x09f4f8c4e347b29dULL, 0x03787388a4f9074dULL,
0x0503f54c99936bfdULL, 0x097f991197dfd0b7ULL, 0x0f041fd5aab5bc07ULL,
0x05889499ed0b09d7ULL, 0x03f3125dd0616567ULL, 0x1091820162766277ULL,
0x16ea04c55f1c0ec7ULL, 0x1c668f8918a2bb17ULL, 0x1a1d094d25c8d7a7ULL,
0x1f1efc01bc5bbc5aULL, 0x19657ac58131d0eaULL, 0x13e9f189c68f653aULL,
0x1592774dfbe5098aULL, 0x06f0e71149f20e9aULL, 0x008b61d57498622aULL,
0x0a07ea993326d7faULL, 0x0c7c6c5d0e4cbb4aULL, 0x12ff32232fbfa16eULL,
0x1484b4e712d5cddeULL, 0x1e083fab556b780eULL, 0x1873b96f680114beULL,
0x0b112933da1613aeULL, 0x0d6aaff7e77c7f1eULL, 0x07e624bba0c2caceULL,
0x019da27f9da8a67eULL, 0x049e5733043bcd83ULL, 0x02e5d1f73951a133ULL,
0x08695abb7eef14e3ULL, 0x0e12dc7f43857853ULL, 0x1d704c23f1927f43ULL,
0x1b0bcae7ccf813f3ULL, 0x118741ab8b46a623ULL, 0x17fcc76fb62cca93ULL,
0x1b80ab32b86071d9ULL, 0x1dfb2df6850a1d69ULL, 0x1777a6bac2b4a8b9ULL,
0x110c207effdec409ULL, 0x026eb0224dc9c319ULL, 0x041536e670a3afa9ULL,
0x0e99bdaa371d1a79ULL, 0x08e23b6e0a7776c9ULL, 0x0de1ce2293e41d34ULL,
0x0b9a48e6ae8e7184ULL, 0x0116c3aae930c454ULL, 0x076d456ed45aa8e4ULL,
0x140fd532664daff4ULL, 0x127453f65b27c344ULL, 0x18f8d8ba1c997694ULL,
0x1e835e7e21f31a24ULL, 0x004337779fa84bb1ULL, 0x0638b1b3a2c22701ULL,
0x0cb43affe57c92d1ULL, 0x0acfbc3bd816fe61ULL, 0x19ad2c676a01f971ULL,
0x1fd6aaa3576b95c1ULL, 0x155a21ef10d52011ULL, 0x1321a72b2dbf4ca1ULL,
0x16225267b42c275cULL, 0x1059d4a389464becULL, 0x1ad55fefcef8fe3cULL,
0x1caed92bf392928cULL, 0x0fcc49774185959cULL, 0x09b7cfb37ceff92cULL,
0x033b44ff3b514cfcULL, 0x0540c23b063b204cULL, 0x093cae6608779b06ULL,
0x0f4728a2351df7b6ULL, 0x05cba3ee72a34266ULL, 0x03b0252a4fc92ed6ULL,
0x10d2b576fdde29c6ULL, 0x16a933b2c0b44576ULL, 0x1c25b8fe870af0a6ULL,
0x1a5e3e3aba609c16ULL, 0x1f5dcb7623f3f7ebULL, 0x19264db21e999b5bULL,
0x13aac6fe59272e8bULL, 0x15d1403a644d423bULL, 0x06b3d066d65a452bULL,
0x00c856a2eb30299bULL, 0x0a44ddeeac8e9c4bULL, 0x0c3f5b2a91e4f0fbULL,
0x12bc0554b017eadfULL, 0x14c783908d7d866fULL, 0x1e4b08dccac333bfULL,
0x18308e18f7a95f0fULL, 0x0b521e4445be581fULL, 0x0d29988078d434afULL,
0x07a513cc3f6a817fULL, 0x01de95080200edcfULL, 0x04dd60449b938632ULL,
0x02a6e680a6f9ea82ULL, 0x082a6dcce1475f52ULL, 0x0e51eb08dc2d33e2ULL,
0x1d337b546e3a34f2ULL, 0x1b48fd9053505842ULL, 0x11c476dc14eeed92ULL,
0x17bff01829848122ULL, 0x1bc39c4527c83a68ULL, 0x1db81a811aa256d8ULL,
0x173491cd5d1ce308ULL, 0x114f170960768fb8ULL, 0x022d8755d26188a8ULL,
0x04560191ef0be418ULL, 0x0eda8adda8b551c8ULL, 0x08a10c1995df3d78ULL,
0x0da2f9550c4c5685ULL, 0x0bd97f9131263a35ULL, 0x0155f4dd76988fe5ULL,
0x072e72194bf2e355ULL, 0x144ce245f9e5e445ULL, 0x12376481c48f88f5ULL,
0x18bbefcd83313d25ULL, 0x1ec06909be5b5195ULL, 0x00866eef3f509762ULL,
0x06fde82b023afbd2ULL, 0x0c71636745844e02ULL, 0x0a0ae5a378ee22b2ULL,
0x196875ffcaf925a2ULL, 0x1f13f33bf7934912ULL, 0x159f7877b02dfcc2ULL,
0x13e4feb38d479072ULL, 0x16e70bff14d4fb8fULL, 0x109c8d3b29be973fULL,
0x1a1006776e0022efULL, 0x1c6b80b3536a4e5fULL, 0x0f0910efe17d494fULL,
0x0972962bdc1725ffULL, 0x03fe1d679ba9902fULL, 0x05859ba3a6c3fc9fULL,
0x09f9f7fea88f47d5ULL, 0x0f82713a95e52b65ULL, 0x050efa76d25b9eb5ULL,
0x03757cb2ef31f205ULL, 0x1017ecee5d26f515ULL, 0x166c6a2a604c99a5ULL,
0x1ce0e16627f22c75ULL, 0x1a9b67a21a9840c5ULL, 0x1f9892ee830b2b38ULL,
0x19e3142abe614788ULL, 0x136f9f66f9dff258ULL, 0x151419a2c4b59ee8ULL,
0x067689fe76a299f8ULL, 0x000d0f3a4bc8f548ULL, 0x0a8184760c764098ULL,
0x0cfa02b2311c2c28ULL, 0x12795ccc10ef360cULL, 0x1402da082d855abcULL,
0x1e8e51446a3bef6cULL, 0x18f5d780575183dcULL, 0x0b9747dce54684ccULL,
0x0decc118d82ce87cULL, 0x07604a549f925dacULL, 0x011bcc90a2f8311cULL,
0x041839dc3b6b5ae1ULL, 0x0263bf1806013651ULL, 0x08ef345441bf8381ULL,
0x0e94b2907cd5ef31ULL, 0x1df622cccec2e821ULL, 0x1b8da408f3a88491ULL,
0x11012f44b4163141ULL, 0x177aa980897c5df1ULL, 0x1b06c5dd8730e6bbULL,
0x1d7d4319ba5a8a0bULL, 0x17f1c855fde43fdbULL, 0x118a4e91c08e536bULL,
0x02e8decd7299547bULL, 0x049358094ff338cbULL, 0x0e1fd345084d8d1bULL,
0x086455813527e1abULL, 0x0d67a0cdacb48a56ULL, 0x0b1c260991dee6e6ULL,
0x0190ad45d6605336ULL, 0x07eb2b81eb0a3f86ULL, 0x1489bbdd591d3896ULL,
0x12f23d1964775426ULL, 0x187eb65523c9e1f6ULL, 0x1e0530911ea38d46ULL,
0x00c55998a0f8dcd3ULL, 0x06bedf5c9d92b063ULL, 0x0c325410da2c05b3ULL,
0x0a49d2d4e7466903ULL, 0x192b428855516e13ULL, 0x1f50c44c683b02a3ULL,
0x15dc4f002f85b773ULL, 0x13a7c9c412efdbc3ULL, 0x16a43c888b7cb03eULL,
0x10dfba4cb616dc8eULL, 0x1a533100f1a8695eULL, 0x1c28b7c4ccc205eeULL,
0x0f4a27987ed502feULL, 0x0931a15c43bf6e4eULL, 0x03bd2a100401db9eULL,
0x05c6acd4396bb72eULL, 0x09bac08937270c64ULL, 0x0fc1464d0a4d60d4ULL,
0x054dcd014df3d504ULL, 0x03364bc57099b9b4ULL, 0x1054db99c28ebea4ULL,
0x162f5d5dffe4d214ULL, 0x1ca3d611b85a67c4ULL, 0x1ad850d585300b74ULL,
0x1fdba5991ca36089ULL, 0x19a0235d21c90c39ULL, 0x132ca8116677b9e9ULL,
0x15572ed55b1dd559ULL, 0x0635be89e90ad249ULL, 0x004e384dd460bef9ULL,
0x0ac2b30193de0b29ULL, 0x0cb935c5aeb46799ULL, 0x123a6bbb8f477dbdULL,
0x1441ed7fb22d110dULL, 0x1ecd6633f593a4ddULL, 0x18b6e0f7c8f9c86dULL,
0x0bd470ab7aeecf7dULL, 0x0daff66f4784a3cdULL, 0x07237d23003a161dULL,
0x0158fbe73d507aadULL, 0x045b0eaba4c31150ULL, 0x0220886f99a97de0ULL,
0x08ac0323de17c830ULL, 0x0ed785e7e37da480ULL, 0x1db515bb516aa390ULL,
0x1bce937f6c00cf20ULL, 0x114218332bbe7af0ULL, 0x17399ef716d41640ULL,
0x1b45f2aa1898ad0aULL, 0x1d3e746e25f2c1baULL, 0x17b2ff22624c746aULL,
0x11c979e65f2618daULL, 0x02abe9baed311fcaULL, 0x04d06f7ed05b737aULL,
0x0e5ce43297e5c6aaULL, 0x082762f6aa8faa1aULL, 0x0d2497ba331cc1e7ULL,
0x0b5f117e0e76ad57ULL, 0x01d39a3249c81887ULL, 0x07a81cf674a27437ULL,
0x14ca8caac6b57327ULL, 0x12b10a6efbdf1f97ULL, 0x183d8122bc61aa47ULL,
0x1e4607e6810bc6f7ULL
};
^ permalink raw reply
* Re: make update-index --chmod work with multiple files and --stdin
From: Alex Riesen @ 2006-04-23 7:01 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1wvpi010.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano, Sun, Apr 23, 2006 02:54:51 +0200:
> > I had a project where lots of files were "accidentally" marked +x, and
> > doing plain "git-update-index --chmod=-x" for each file was too slow.
> > Besides, it's somewhat inconsistent, that --chmod does work only for
> > one subsequent file.
>
> If you are doing that on the command line, people may want to
> have a way to mean "from here on do not do chmod, just do normal
> update-index and nothing else" by resetting the chmod_mode thing
> back to zero. Nothing major, and we do not do that to allow_add
> and allow_remove either, but just a thought.
Not sure about that, but did it anyway (as separate patches).
I updated the patch with the other remarks regarding
set_executable_bit, whitespaces and die in chmod_path (thought about
this one myself, but was lazy).
---
update-index.c | 23 ++++++++++++++++-------
1 files changed, 16 insertions(+), 7 deletions(-)
92d1372fd0358811a5f2670b99a6a304dadb7864
diff --git a/update-index.c b/update-index.c
index 1efac27..a8582ea 100644
--- a/update-index.c
+++ b/update-index.c
@@ -328,7 +328,7 @@ static int add_cacheinfo(unsigned int mo
return 0;
}
-static int chmod_path(int flip, const char *path)
+static void chmod_path(int flip, const char *path)
{
int pos;
struct cache_entry *ce;
@@ -336,21 +336,24 @@ static int chmod_path(int flip, const ch
pos = cache_name_pos(path, strlen(path));
if (pos < 0)
- return -1;
+ goto _fail;
ce = active_cache[pos];
mode = ntohl(ce->ce_mode);
if (!S_ISREG(mode))
- return -1;
+ goto _fail;
switch (flip) {
case '+':
ce->ce_mode |= htonl(0111); break;
case '-':
ce->ce_mode &= htonl(~0111); break;
default:
- return -1;
+ goto _fail;
}
active_cache_changed = 1;
- return 0;
+ report("chmod %cx '%s'", flip, path);
+ return;
+_fail:
+ die("git-update-index: cannot chmod %cx '%s'", flip, path);
}
static struct cache_file cache_file;
@@ -478,6 +481,7 @@ int main(int argc, const char **argv)
int read_from_stdin = 0;
const char *prefix = setup_git_directory();
int prefix_length = prefix ? strlen(prefix) : 0;
+ char set_executable_bit = 0;
git_config(git_default_config);
@@ -544,8 +548,7 @@ int main(int argc, const char **argv)
!strcmp(path, "--chmod=+x")) {
if (argc <= i+1)
die("git-update-index: %s <path>", path);
- if (chmod_path(path[8], argv[++i]))
- die("git-update-index: %s cannot chmod %s", path, argv[i]);
+ set_executable_bit = path[8];
continue;
}
if (!strcmp(path, "--assume-unchanged")) {
@@ -594,6 +597,8 @@ int main(int argc, const char **argv)
die("unknown option %s", path);
}
update_one(path, prefix, prefix_length);
+ if (set_executable_bit)
+ chmod_path(set_executable_bit, path);
}
if (read_from_stdin) {
struct strbuf buf;
@@ -608,6 +613,10 @@ int main(int argc, const char **argv)
else
path_name = buf.buf;
update_one(path_name, prefix, prefix_length);
+ if (set_executable_bit) {
+ const char *p = prefix_path(prefix, prefix_length, path_name);
+ chmod_path(set_executable_bit, p);
+ }
if (path_name != buf.buf)
free(path_name);
}
--
1.3.0.gc2941
^ permalink raw reply related
* Re: make update-index --chmod work with multiple files and --stdin
From: Alex Riesen @ 2006-04-23 7:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1wvpi010.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 950 bytes --]
Junio C Hamano, Sun, Apr 23, 2006 02:54:51 +0200:
> Alex Riesen <raa.lkml@gmail.com> writes:
>
> > I had a project where lots of files were "accidentally" marked +x, and
> > doing plain "git-update-index --chmod=-x" for each file was too slow.
> > Besides, it's somewhat inconsistent, that --chmod does work only for
> > one subsequent file.
>
> If you are doing that on the command line, people may want to
> have a way to mean "from here on do not do chmod, just do normal
> update-index and nothing else" by resetting the chmod_mode thing
> back to zero. Nothing major, and we do not do that to allow_add
> and allow_remove either, but just a thought.
I am unsure about this. I'm even attaching instead of inlining the
patches, to make it clear how unsure I am :)
I have a feeling that it's more understandable to just use two
separate commands. Besides, the reset switch makes it impossible to
use pathname disambiguation ("--"). Unsure...
[-- Attachment #2: 0002-git-update-index-no-chmod.txt --]
[-- Type: text/plain, Size: 1352 bytes --]
>From nobody Mon Sep 17 00:00:00 2001
From: Junio C Hamano <junkio@cox.net>
Date: Sun Apr 23 08:38:04 2006 +0200
Subject: git-update-index --no-chmod
Message-ID: <7v1wvpi010.fsf@assigned-by-dhcp.cox.net>
Alex Riesen <raa.lkml@gmail.com> writes:
> I had a project where lots of files were "accidentally" marked +x, and
> doing plain "git-update-index --chmod=-x" for each file was too slow.
> Besides, it's somewhat inconsistent, that --chmod does work only for
> one subsequent file.
If you are doing that on the command line, people may want to
have a way to mean "from here on do not do chmod, just do normal
update-index and nothing else" by resetting the chmod_mode thing
back to zero. Nothing major, and we do not do that to allow_add
and allow_remove either, but just a thought.
---
update-index.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
2972ef33fa4b04f07d4f4dbb9e13d5b9b2d593b4
diff --git a/update-index.c b/update-index.c
index a8582ea..1ed36fa 100644
--- a/update-index.c
+++ b/update-index.c
@@ -551,6 +551,10 @@ int main(int argc, const char **argv)
set_executable_bit = path[8];
continue;
}
+ if (!strcmp(path, "--no-chmod")) {
+ set_executable_bit = 0;
+ continue;
+ }
if (!strcmp(path, "--assume-unchanged")) {
mark_valid_only = MARK_VALID;
continue;
--
1.3.0.gc2941
[-- Attachment #3: 0003-git-update-index-add-no-add-and-no-remove.txt --]
[-- Type: text/plain, Size: 1595 bytes --]
>From nobody Mon Sep 17 00:00:00 2001
From: Junio C Hamano <junkio@cox.net>
Date: Sun Apr 23 08:43:42 2006 +0200
Subject: git-update-index: add --no-add and --no-remove
Message-ID: <7v1wvpi010.fsf@assigned-by-dhcp.cox.net>
Alex Riesen <raa.lkml@gmail.com> writes:
> I had a project where lots of files were "accidentally" marked +x, and
> doing plain "git-update-index --chmod=-x" for each file was too slow.
> Besides, it's somewhat inconsistent, that --chmod does work only for
> one subsequent file.
If you are doing that on the command line, people may want to
have a way to mean "from here on do not do chmod, just do normal
update-index and nothing else" by resetting the chmod_mode thing
back to zero. Nothing major, and we do not do that to allow_add
and allow_remove either, but just a thought.
---
update-index.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
89bceee48996f366a779b0c95ba230ec24fea340
diff --git a/update-index.c b/update-index.c
index 1ed36fa..cbee859 100644
--- a/update-index.c
+++ b/update-index.c
@@ -509,6 +509,10 @@ int main(int argc, const char **argv)
allow_add = 1;
continue;
}
+ if (!strcmp(path, "--no-add")) {
+ allow_add = 0;
+ continue;
+ }
if (!strcmp(path, "--replace")) {
allow_replace = 1;
continue;
@@ -517,6 +521,10 @@ int main(int argc, const char **argv)
allow_remove = 1;
continue;
}
+ if (!strcmp(path, "--no-remove")) {
+ allow_remove = 0;
+ continue;
+ }
if (!strcmp(path, "--unmerged")) {
allow_unmerged = 1;
continue;
--
1.3.0.gc2941
^ permalink raw reply related
* lstat() call in rev-parse.c
From: Paul Mackerras @ 2006-04-23 12:03 UTC (permalink / raw)
To: git
Why does git-rev-parse do an lstat on some of its arguments, at line
345 of rev-parse.c, and die if the lstat fails? It doesn't seem to do
anything with the result.
The effect is that if you do "gitk a b", it works as long as a and b
exist (as files or directories), but fails if they don't, and some
users have found this confusing. Yes they should put in a --, but
it's not obvious to users why this should make it work in the case
when a or b doesn't exist.
(And yes I just took out the git-rev-parse call from gitk, but I'm
going to need to do git-rev-parse --no-refs --no-flags for some
changes I'm doing at the moment.)
Paul.
^ permalink raw reply
* Re: lstat() call in rev-parse.c
From: Linus Torvalds @ 2006-04-23 16:19 UTC (permalink / raw)
To: Paul Mackerras; +Cc: git
In-Reply-To: <17483.27938.890830.375324@cargo.ozlabs.ibm.com>
On Sun, 23 Apr 2006, Paul Mackerras wrote:
>
> Why does git-rev-parse do an lstat on some of its arguments, at line
> 345 of rev-parse.c, and die if the lstat fails? It doesn't seem to do
> anything with the result.
>
> The effect is that if you do "gitk a b", it works as long as a and b
> exist (as files or directories), but fails if they don't, and some
> users have found this confusing.
Because it's even _more_ common to do
gitk v2.6.16
(in the git directory) and be very confused when that returns an empty
history.
So the rule is: if you don't give that "--", then we have to be able to
confirm that the filenames are really files. Not a misspelled revision
name, or a revision name that was correctly spelled, but for the wrong
project, because you were in the wrong subdirectory ;)
And yes, this actually happened to me. I was demonstrating git before we
did that fix, and I used the wrong tag-name, and gitk would think for a
minute and them show "No commits selected" with no error, because
"v2.6.16" didn't exist at that time, and it used the "tag-name" as a
filename, and that filename didn't actually exist, so the number of
commits that changed it was exactly zero.
So now, if you do "gitk v2.6.16" in the git directory, it will return a
nice and understandable
Error reading commits: fatal: 'v2.6.16': No such file or directory
which is _exactly_ what you want. The only problem is that gitk will
actually open the big window too, and the error window is small and can be
non-obvious if the window manager hides it in some corner. So I actually
think you should try to make the error window come up smack dab in front
of the main gitk window and make the error clearer.
So the rules are simple:
- the filenames are _always_ separated by "--"
- we have a short-hand, which allows the "--" to be dropped iff it is
unambiguous
Where "unambiguous" means that
- the revision name cannot possible be interpreted as a filename (we
don't check this part yet, but I think we should)
- all filenames are obviously not revision names, since they not
only aren't valid revisions, they actually exist as files.
Otherwise, misspellings, typos, and thinkos result in total confusion.
Linus
^ permalink raw reply
* git-clone --reference problem?
From: David Woodhouse @ 2006-04-23 16:34 UTC (permalink / raw)
To: git
Should I expect cloning with alternates using '--reference' to be
transitive?
Using '--reference clone1 --reference linux-2.6' for the second clone
works OK, but surely it ought to work with just '--reference clone1'?
It doesn't work -- it can't find the objects which are in the original
linux-2.6 tree....
(linux-2.6 contains a current copy of linus' tree)
shinybook /shiny/git $ git-clone --reference linux-2.6 git://git.infradead.org/mtd-2.6.git clone1
Checking files out...
100% (19552/19552) done
shinybook /shiny/git $ git-clone --reference clone1 git://git.infradead.org/mtd-2.6.git clone2
error: refs/reference-tmp/refs/tags/v2.6.13-rc7 does not point to a valid commit object!
error: refs/reference-tmp/refs/tags/v2.6.13-rc2 does not point to a valid commit object!
error: refs/reference-tmp/refs/tags/v2.6.14 does not point to a valid commit object!
< ..... >
error: refs/reference-tmp/refs/tags/v2.6.14-rc1 does not point to a valid commit object!
error: refs/reference-tmp/refs/tags/v2.6.15-rc2 does not point to a valid commit object!
error: refs/reference-tmp/refs/tags/v2.6.13-rc6 does not point to a valid commit object!
error: refs/reference-tmp/refs/tags/v2.6.13-rc4 does not point to a valid commit object!
error: Could not read 7e6684741b15e98dd52bd0dbcb08a4eb69857c23
error: Could not read 7e6684741b15e98dd52bd0dbcb08a4eb69857c23
error: Could not read 7260448207915a170bb812f8639a90a30329adce
error: Could not read 7260448207915a170bb812f8639a90a30329adce
error: Could not read acf8d9bd83be879328c558400d94ee61fc229672
error: Could not read acf8d9bd83be879328c558400d94ee61fc229672
error: Could not read c7270e76718f635bed33afe6c4751a270b2d031b
error: Could not read c7270e76718f635bed33afe6c4751a270b2d031b
error: Could not read 0a8763981774041f3fee0a71e016dcaa096fa3f8
error: Could not read 0a8763981774041f3fee0a71e016dcaa096fa3f8
error: Could not read 4a47136ddde07488a5741e6be267b8f5bddc407b
error: Could not read 4a47136ddde07488a5741e6be267b8f5bddc407b
error: Could not read 6cad1d2664ec091ba5a6f3e3e552cf550ec8c2e0
error: Could not read 6cad1d2664ec091ba5a6f3e3e552cf550ec8c2e0
< ..... >
error: Could not read a0d4c65cd5642e7f7bbd2f806a69d20b2e43edc4
error: Could not read 611dd7a56906343db81c9fe340be0eb78c4ec260
error: Could not read 611dd7a56906343db81c9fe340be0eb78c4ec260
error: Could not read 227b4665ae0105348868d7a0a577209c8d16c6e3
error: Could not read 227b4665ae0105348868d7a0a577209c8d16c6e3
error: Could not read 9f19a4bfe0d0f0d203113d34d7455ceb82ff8341
error: Could not read 9f19a4bfe0d0f0d203113d34d7455ceb82ff8341
Checking files out...
error: git-checkout-index: unable to read sha1 file of .gitignore (27fd37621255799602d74e94d670ff7a1658d40a)
error: git-checkout-index: unable to read sha1 file of COPYING (ca442d313d86dc67e0a2e5d584b465bd382cbf5c)
error: git-checkout-index: unable to read sha1 file of CREDITS (787564bc248b1d6125fc42f3932966b60aa2f7f4)
error: git-checkout-index: unable to read sha1 file of Kbuild (2d4f95e4b89f7f81da6cb94b07e8449b3689ba37)
error: git-checkout-index: unable to read sha1 file of Makefile (fc8e08c419f09e81252f3aa41cb7f47524c0af60)
error: git-checkout-index: unable to read sha1 file of README (05e055530bbb687599dd732d6753c77ffa281ae5)
< .....>
--
dwmw2
^ permalink raw reply
* Re: git-clone --reference problem?
From: Junio C Hamano @ 2006-04-23 17:50 UTC (permalink / raw)
To: David Woodhouse; +Cc: git
In-Reply-To: <1145810080.16166.223.camel@shinybook.infradead.org>
David Woodhouse <dwmw2@infradead.org> writes:
> Should I expect cloning with alternates using '--reference' to be
> transitive?
Not with the current code and design, but a patch that cleanly
does that can be considered for inclusion. Adjusting relative
paths obtained from other repositories correctly, and avoiding
circular alternates by mistake would be tricky, though.
^ permalink raw reply
* Re: git-clone --reference problem?
From: Linus Torvalds @ 2006-04-23 18:34 UTC (permalink / raw)
To: David Woodhouse; +Cc: git
In-Reply-To: <1145810080.16166.223.camel@shinybook.infradead.org>
On Sun, 23 Apr 2006, David Woodhouse wrote:
>
> Should I expect cloning with alternates using '--reference' to be
> transitive?
Well, certainly not now.
> Using '--reference clone1 --reference linux-2.6' for the second clone
> works OK, but surely it ought to work with just '--reference clone1'?
Actually, I don't think using "--reference clone1 --reference linux-2.6"
works OK at all - in the sense that it doesn't do what you _think_ it
does.
It doesn't use two reference repos at all: it uses just one, which is the
last one (ie linux-2.6).
Maybe something like this could work.
Untested, of course. It probably isn't even syntactically correct shell.
Whatever. You get the idea.
(That while-loop could probably be simplified to just a
cat ""$reference/objects/info/alternates" >> "$GIT_DIR/objects/info/alternates"
because all alternates _should_ already be absolute paths, but hey,
whatever. I also forget whether we decided that non-absolute paths were
relative to the $reference directory, or to the $reference/objects/
directory. The while-loop should be fixed to match whatever that decision
was (or just not accept anything but absolute paths: make it use a
grep '^/' ..
instead of "cat"?)
Linus
---
diff --git a/git-clone.sh b/git-clone.sh
index 0805168..df4c135 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -221,6 +221,13 @@ then
fi
reference=$(cd "$reference" && pwd)
echo "$reference/objects" >"$GIT_DIR/objects/info/alternates"
+ if test -s "$reference/objects/info/alternates"
+ then
+ while read alt
+ do
+ echo $(cd "$reference" && cd "$alt" && pwd) >> "$GIT_DIR/objects/info/alternates"
+ done < "$reference/objects/info/alternates"
+ fi
(cd "$reference" && tar cf - refs) |
(cd "$GIT_DIR/refs" &&
mkdir reference-tmp &&
^ permalink raw reply related
* Re: git-clone --reference problem?
From: Linus Torvalds @ 2006-04-23 18:40 UTC (permalink / raw)
To: David Woodhouse; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0604231122490.3701@g5.osdl.org>
On Sun, 23 Apr 2006, Linus Torvalds wrote:
>
> I also forget whether we decided that non-absolute paths were
> relative to the $reference directory, or to the $reference/objects/
> directory.
Just checked. It should be relative to $reference/objects, and we should
strip out lines that start with '#', since we allow comments.
Blah. That whole shell-thing is cerainly convenient for prototyping, but
it would be wonderful if we had some enterprising young soul that rewrote
these things in C and made them built-ins. It may be wasteful to use C for
this, but it would make portability easier, and we have all those nice
routines for validating and building alternate db lists already that do it
right.
Oh, well.
Linus
^ permalink raw reply
* [PATCH 1/4] read-cache/write-cache: optionally return cache checksum SHA1.
From: Junio C Hamano @ 2006-04-23 23:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
read_cache_1() and write_cache_1() takes an extra parameter
*sha1 that returns the checksum of the index file when non-NULL.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* This is a low-impact small preparation for the following
three, which is an interesting optimization.
cache.h | 5 ++++-
read-cache.c | 35 +++++++++++++++++++++++++++--------
2 files changed, 31 insertions(+), 9 deletions(-)
c2a742f3ac14e93704c917e4d9b08881d6032281
diff --git a/cache.h b/cache.h
index 69801b0..8c9947e 100644
--- a/cache.h
+++ b/cache.h
@@ -138,8 +138,11 @@ extern const char *prefix_filename(const
#define alloc_nr(x) (((x)+16)*3/2)
/* Initialize and use the cache information */
+extern int read_cache_1(unsigned char *);
+extern int write_cache_1(int, struct cache_entry **, int, unsigned char *);
extern int read_cache(void);
-extern int write_cache(int newfd, struct cache_entry **cache, int entries);
+extern int write_cache(int, struct cache_entry **, int);
+
extern int cache_name_pos(const char *name, int namelen);
#define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
#define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */
diff --git a/read-cache.c b/read-cache.c
index f97f92d..50e094e 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -496,10 +496,12 @@ int add_cache_entry(struct cache_entry *
return 0;
}
-static int verify_hdr(struct cache_header *hdr, unsigned long size)
+static int verify_hdr(struct cache_header *hdr, unsigned long size, unsigned char *sha1)
{
SHA_CTX c;
- unsigned char sha1[20];
+ unsigned char sha1_buf[20];
+ if (!sha1)
+ sha1 = sha1_buf;
if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
return error("bad signature");
@@ -513,7 +515,7 @@ static int verify_hdr(struct cache_heade
return 0;
}
-int read_cache(void)
+int read_cache_1(unsigned char *cache_sha1)
{
int fd, i;
struct stat st;
@@ -547,7 +549,7 @@ int read_cache(void)
die("index file mmap failed (%s)", strerror(errno));
hdr = map;
- if (verify_hdr(hdr, size) < 0)
+ if (verify_hdr(hdr, size, cache_sha1) < 0)
goto unmap;
active_nr = ntohl(hdr->hdr_entries);
@@ -595,7 +597,7 @@ static int ce_write(SHA_CTX *context, in
return 0;
}
-static int ce_flush(SHA_CTX *context, int fd)
+static int ce_flush(SHA_CTX *context, int fd, unsigned char *sha1)
{
unsigned int left = write_buffer_len;
@@ -612,7 +614,8 @@ static int ce_flush(SHA_CTX *context, in
}
/* Append the SHA1 signature at the end */
- SHA1_Final(write_buffer + left, context);
+ SHA1_Final(sha1, context);
+ memcpy(write_buffer + left, sha1, 20);
left += 20;
if (write(fd, write_buffer, left) != left)
return -1;
@@ -663,11 +666,14 @@ static void ce_smudge_racily_clean_entry
}
}
-int write_cache(int newfd, struct cache_entry **cache, int entries)
+int write_cache_1(int newfd, struct cache_entry **cache, int entries,
+ unsigned char *cache_sha1)
{
SHA_CTX c;
struct cache_header hdr;
int i, removed;
+ int status;
+ unsigned char sha1[20];
for (i = removed = 0; i < entries; i++)
if (!cache[i]->ce_mode)
@@ -691,5 +697,18 @@ int write_cache(int newfd, struct cache_
if (ce_write(&c, newfd, ce, ce_size(ce)) < 0)
return -1;
}
- return ce_flush(&c, newfd);
+ status = ce_flush(&c, newfd, sha1);
+ if (cache_sha1)
+ memcpy(cache_sha1, sha1, 20);
+ return status;
+}
+
+int read_cache(void)
+{
+ return read_cache_1(NULL);
+}
+
+int write_cache(int newfd, struct cache_entry **cache, int entries)
+{
+ return write_cache_1(newfd, cache, entries, NULL);
}
--
1.3.0.g623a
^ permalink raw reply related
* [PATCH 2/4] Add cache-tree.
From: Junio C Hamano @ 2006-04-23 23:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
The cache_tree data structure is to cache tree object names that
would result from the current index file.
The idea is to have an optional file to record each tree object
name that corresponds to a directory path in the cache when we
run write_cache(), and read it back when we run read_cache().
During various index manupulations, we selectively invalidate
the parts so that the next write-tree can bypass regenerating
tree objects for unchanged parts of the directory hierarchy.
We could perhaps make the cache-tree data an optional part of
the index file, but that would involve the index format updates,
so unless we need it for performance reasons, the current plan
is to use a separate file, $GIT_DIR/index.aux to store this
information and link it with the index file with the checksum
that is already used for index file integrity check.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* This is just the data structure and its maintenance, and not
tied to the rest of the system yet, which will be done with
the next two patches.
Makefile | 2
cache-tree.c | 522 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cache-tree.h | 29 +++
3 files changed, 552 insertions(+), 1 deletions(-)
create mode 100644 cache-tree.c
create mode 100644 cache-tree.h
c37a2dc93fb49dada5eec78f002eea9354e4fb4f
diff --git a/Makefile b/Makefile
index d9a3a82..518c3c1 100644
--- a/Makefile
+++ b/Makefile
@@ -204,7 +204,7 @@ DIFF_OBJS = \
diffcore-delta.o log-tree.o
LIB_OBJS = \
- blob.o commit.o connect.o csum-file.o \
+ blob.o commit.o connect.o csum-file.o cache-tree.o \
date.o diff-delta.o entry.o exec_cmd.o ident.o index.o \
object.o pack-check.o patch-delta.o path.o pkt-line.o \
quote.o read-cache.o refs.o run-command.o \
diff --git a/cache-tree.c b/cache-tree.c
new file mode 100644
index 0000000..c79da33
--- /dev/null
+++ b/cache-tree.c
@@ -0,0 +1,522 @@
+#include "cache.h"
+#include "tree.h"
+#include "cache-tree.h"
+
+#define DEBUG 0
+
+struct cache_tree *cache_tree(void)
+{
+ struct cache_tree *it = xcalloc(1, sizeof(struct cache_tree));
+ it->entry_count = -1;
+ return it;
+}
+
+void cache_tree_free(struct cache_tree *it)
+{
+ int i;
+
+ if (!it)
+ return;
+ for (i = 0; i < it->subtree_nr; i++)
+ cache_tree_free(it->down[i]->cache_tree);
+ free(it->down);
+ free(it);
+}
+
+static struct cache_tree_sub *find_subtree(struct cache_tree *it,
+ const char *path,
+ int pathlen,
+ int create)
+{
+ int i;
+ struct cache_tree_sub *down;
+ for (i = 0; i < it->subtree_nr; i++) {
+ down = it->down[i];
+ if (down->namelen == pathlen &&
+ !memcmp(down->name, path, pathlen))
+ return down;
+ }
+ if (!create)
+ return NULL;
+ if (it->subtree_alloc <= it->subtree_nr) {
+ it->subtree_alloc = alloc_nr(it->subtree_alloc);
+ it->down = xrealloc(it->down, it->subtree_alloc *
+ sizeof(*it->down));
+ }
+ down = xmalloc(sizeof(*down) + pathlen + 1);
+ down->cache_tree = NULL; /* cache_tree(); */
+ down->namelen = pathlen;
+ memcpy(down->name, path, pathlen);
+ down->name[pathlen] = 0; /* not strictly needed */
+ it->down[it->subtree_nr++] = down;
+ return down;
+}
+
+void cache_tree_invalidate_path(struct cache_tree *it, const char *path)
+{
+ /* a/b/c
+ * ==> invalidate self
+ * ==> find "a", have it invalidate "b/c"
+ * a
+ * ==> invalidate self
+ * ==> if "a" exists as a subtree, remove it.
+ */
+ const char *slash;
+ int namelen;
+ struct cache_tree_sub *down;
+
+ if (!it)
+ return;
+ slash = strchr(path, '/');
+ it->entry_count = -1;
+ if (!slash) {
+ int i;
+ namelen = strlen(path);
+ for (i = 0; i < it->subtree_nr; i++) {
+ if (it->down[i]->namelen == namelen &&
+ !memcmp(it->down[i]->name, path, namelen))
+ break;
+ }
+ if (i < it->subtree_nr) {
+ cache_tree_free(it->down[i]->cache_tree);
+ free(it->down[i]);
+ /* 0 1 2 3 4 5
+ * ^ ^subtree_nr = 6
+ * i
+ * move 4 and 5 up one place (2 entries)
+ * 2 = 6 - 3 - 1 = subtree_nr - i - 1
+ */
+ memmove(it->down+i, it->down+i+1,
+ sizeof(struct cache_tree_sub *) *
+ (it->subtree_nr - i - 1));
+ it->subtree_nr--;
+ }
+ return;
+ }
+ namelen = slash - path;
+ down = find_subtree(it, path, namelen, 0);
+ if (down)
+ cache_tree_invalidate_path(down->cache_tree, slash + 1);
+}
+
+static int verify_cache(struct cache_entry **cache,
+ int entries)
+{
+ int i, funny;
+
+ /* Verify that the tree is merged */
+ funny = 0;
+ for (i = 0; i < entries; i++) {
+ struct cache_entry *ce = cache[i];
+ if (ce_stage(ce)) {
+ if (10 < ++funny) {
+ fprintf(stderr, "...\n");
+ break;
+ }
+ fprintf(stderr, "%s: unmerged (%s)\n",
+ ce->name, sha1_to_hex(ce->sha1));
+ }
+ }
+ if (funny)
+ return -1;
+
+ /* Also verify that the cache does not have path and path/file
+ * at the same time. At this point we know the cache has only
+ * stage 0 entries.
+ */
+ funny = 0;
+ for (i = 0; i < entries - 1; i++) {
+ /* path/file always comes after path because of the way
+ * the cache is sorted. Also path can appear only once,
+ * which means conflicting one would immediately follow.
+ */
+ const char *this_name = cache[i]->name;
+ const char *next_name = cache[i+1]->name;
+ int this_len = strlen(this_name);
+ if (this_len < strlen(next_name) &&
+ strncmp(this_name, next_name, this_len) == 0 &&
+ next_name[this_len] == '/') {
+ if (10 < ++funny) {
+ fprintf(stderr, "...\n");
+ break;
+ }
+ fprintf(stderr, "You have both %s and %s\n",
+ this_name, next_name);
+ }
+ }
+ if (funny)
+ return -1;
+ return 0;
+}
+
+static void discard_unused_subtrees(struct cache_tree *it)
+{
+ struct cache_tree_sub **down = it->down;
+ int nr = it->subtree_nr;
+ int dst, src;
+ for (dst = src = 0; src < nr; src++) {
+ struct cache_tree_sub *s = down[src];
+ if (s->used)
+ down[dst++] = s;
+ else {
+ cache_tree_free(s->cache_tree);
+ free(s);
+ it->subtree_nr--;
+ }
+ }
+}
+
+static int update_one(struct cache_tree *it,
+ struct cache_entry **cache,
+ int entries,
+ const char *base,
+ int baselen,
+ int missing_ok)
+{
+ unsigned long size, offset;
+ char *buffer;
+ int i;
+
+ if (0 <= it->entry_count)
+ return it->entry_count;
+
+ /*
+ * We first scan for subtrees and update them; we start by
+ * marking existing subtrees -- the ones that are unmarked
+ * should not be in the result.
+ */
+ for (i = 0; i < it->subtree_nr; i++)
+ it->down[i]->used = 0;
+
+ /*
+ * Find the subtrees and update them.
+ */
+ for (i = 0; i < entries; i++) {
+ struct cache_entry *ce = cache[i];
+ struct cache_tree_sub *sub;
+ const char *path, *slash;
+ int pathlen, sublen, subcnt;
+
+ path = ce->name;
+ pathlen = ce_namelen(ce);
+ if (pathlen <= baselen || memcmp(base, path, baselen))
+ break; /* at the end of this level */
+
+ slash = strchr(path + baselen, '/');
+ if (!slash)
+ continue;
+ /*
+ * a/bbb/c (base = a/, slash = /c)
+ * ==>
+ * path+baselen = bbb/c, sublen = 3
+ */
+ sublen = slash - (path + baselen);
+ sub = find_subtree(it, path + baselen, sublen, 1);
+ if (!sub->cache_tree)
+ sub->cache_tree = cache_tree();
+ subcnt = update_one(sub->cache_tree,
+ cache + i, entries - i,
+ path,
+ baselen + sublen + 1,
+ missing_ok);
+ i += subcnt - 1;
+ sub->used = 1;
+ }
+
+ discard_unused_subtrees(it);
+
+ /*
+ * Then write out the tree object for this level.
+ */
+ size = 8192;
+ buffer = xmalloc(size);
+ offset = 0;
+
+ for (i = 0; i < entries; i++) {
+ struct cache_entry *ce = cache[i];
+ struct cache_tree_sub *sub;
+ const char *path, *slash;
+ int pathlen, entlen;
+ const unsigned char *sha1;
+ unsigned mode;
+
+ path = ce->name;
+ pathlen = ce_namelen(ce);
+ if (pathlen <= baselen || memcmp(base, path, baselen))
+ break; /* at the end of this level */
+
+ slash = strchr(path + baselen, '/');
+ if (slash) {
+ entlen = slash - (path + baselen);
+ sub = find_subtree(it, path + baselen, entlen, 0);
+ if (!sub)
+ die("cache-tree.c: '%.*s' in '%s' not found",
+ entlen, path + baselen, path);
+ i += sub->cache_tree->entry_count - 1;
+ sha1 = sub->cache_tree->sha1;
+ mode = S_IFDIR;
+ }
+ else {
+ sha1 = ce->sha1;
+ mode = ntohl(ce->ce_mode);
+ entlen = pathlen - baselen;
+ }
+ if (!missing_ok && !has_sha1_file(sha1))
+ return error("invalid object %s", sha1_to_hex(sha1));
+
+ if (!ce->ce_mode)
+ continue; /* entry being removed */
+
+ if (size < offset + entlen + 100) {
+ size = alloc_nr(offset + entlen + 100);
+ buffer = xrealloc(buffer, size);
+ }
+ offset += sprintf(buffer + offset,
+ "%o %.*s", mode, entlen, path + baselen);
+ buffer[offset++] = 0;
+ memcpy(buffer + offset, sha1, 20);
+ offset += 20;
+
+#if DEBUG
+ fprintf(stderr, "cache-tree %o %.*s\n",
+ mode, entlen, path + baselen);
+#endif
+ }
+
+ write_sha1_file(buffer, offset, tree_type, it->sha1);
+ free(buffer);
+ it->entry_count = i;
+#if DEBUG
+ fprintf(stderr, "cache-tree (%d ent, %d subtree) %s\n",
+ it->entry_count, it->subtree_nr,
+ sha1_to_hex(it->sha1));
+#endif
+ return i;
+}
+
+int cache_tree_update(struct cache_tree *it,
+ struct cache_entry **cache,
+ int entries,
+ int missing_ok)
+{
+ int i;
+ i = verify_cache(cache, entries);
+ if (i)
+ return i;
+ i = update_one(it, cache, entries, "", 0, missing_ok);
+ if (i < 0)
+ return i;
+ return 0;
+}
+
+static void *write_one(struct cache_tree *it,
+ char *path,
+ int pathlen,
+ char *buffer,
+ unsigned long *size,
+ unsigned long *offset)
+{
+ int i;
+
+ /* One "cache-tree" entry consists of the following:
+ * path (NUL terminated)
+ * entry_count, subtree_nr ("%d %d\n")
+ * tree-sha1 (missing if invalid)
+ * subtree_nr "cache-tree" entries for subtrees.
+ */
+ if (*size < *offset + pathlen + 100) {
+ *size = alloc_nr(*offset + pathlen + 100);
+ buffer = xrealloc(buffer, *size);
+ }
+ *offset += sprintf(buffer + *offset, "%.*s%c%d %d\n",
+ pathlen, path, 0,
+ it->entry_count, it->subtree_nr);
+
+#if DEBUG
+ if (0 <= it->entry_count)
+ fprintf(stderr, "cache-tree <%.*s> (%d ent, %d subtree) %s\n",
+ pathlen, path, it->entry_count, it->subtree_nr,
+ sha1_to_hex(it->sha1));
+ else
+ fprintf(stderr, "cache-tree <%.*s> (%d subtree) invalid\n",
+ pathlen, path, it->subtree_nr);
+#endif
+
+ if (0 <= it->entry_count) {
+ memcpy(buffer + *offset, it->sha1, 20);
+ *offset += 20;
+ }
+ for (i = 0; i < it->subtree_nr; i++) {
+ struct cache_tree_sub *down = it->down[i];
+ int len = pathlen + down->namelen;
+ memcpy(path + pathlen, down->name, down->namelen);
+ path[len] = '/';
+ buffer = write_one(down->cache_tree, path, len+1,
+ buffer, size, offset);
+ }
+ return buffer;
+}
+
+static void *cache_tree_write(const unsigned char *cache_sha1,
+ struct cache_tree *root,
+ unsigned long *offset_p)
+{
+ char path[PATH_MAX];
+ unsigned long size = 8192;
+ char *buffer = xmalloc(size);
+
+ /* the cache checksum of the corresponding index file. */
+ memcpy(buffer, cache_sha1, 20);
+ *offset_p = 20;
+ path[0] = 0;
+ return write_one(root, path, 0, buffer, &size, offset_p);
+}
+
+static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
+{
+ const char *buf = *buffer;
+ unsigned long size = *size_p;
+ struct cache_tree *it;
+ int i, subtree_nr;
+
+ it = NULL;
+ /* skip name, but make sure name exists */
+ while (size && *buf) {
+ size--;
+ buf++;
+ }
+ if (!size)
+ goto free_return;
+ buf++; size--;
+ it = cache_tree();
+ if (sscanf(buf, "%d %d\n", &it->entry_count, &subtree_nr) != 2)
+ goto free_return;
+ while (size && *buf && *buf != '\n') {
+ size--;
+ buf++;
+ }
+ if (!size)
+ goto free_return;
+ buf++; size--;
+ if (0 <= it->entry_count) {
+ if (size < 20)
+ goto free_return;
+ memcpy(it->sha1, buf, 20);
+ buf += 20;
+ size -= 20;
+ }
+
+#if DEBUG
+ if (0 <= it->entry_count)
+ fprintf(stderr, "cache-tree <%s> (%d ent, %d subtree) %s\n",
+ *buffer, it->entry_count, subtree_nr,
+ sha1_to_hex(it->sha1));
+ else
+ fprintf(stderr, "cache-tree <%s> (%d subtrees) invalid\n",
+ *buffer, subtree_nr);
+#endif
+
+ /*
+ * Just a heuristic -- we do not add directories that often but
+ * we do not want to have to extend it immediately when we do,
+ * hence +2.
+ */
+ it->subtree_alloc = subtree_nr + 2;
+ it->down = xcalloc(it->subtree_alloc, sizeof(struct cache_tree_sub *));
+ for (i = 0; i < subtree_nr; i++) {
+ /* read each subtree */
+ struct cache_tree *sub;
+ const char *name = buf;
+ int namelen;
+ sub = read_one(&buf, &size);
+ if (!sub)
+ goto free_return;
+ namelen = strlen(name);
+ it->down[i] = find_subtree(it, name, namelen, 1);
+ it->down[i]->cache_tree = sub;
+ }
+ if (subtree_nr != it->subtree_nr)
+ die("cache-tree: internal error");
+ *buffer = buf;
+ *size_p = size;
+ return it;
+
+ free_return:
+ cache_tree_free(it);
+ return NULL;
+}
+
+static struct cache_tree *cache_tree_read(unsigned char *sha1,
+ const char *buffer,
+ unsigned long size)
+{
+ /* check the cache-tree matches the index */
+ if (memcmp(buffer, sha1, 20))
+ return NULL; /* checksum mismatch */
+ if (buffer[20])
+ return NULL; /* not the whole tree */
+ buffer += 20;
+ size -= 20;
+ return read_one(&buffer, &size);
+}
+
+struct cache_tree *read_cache_tree(unsigned char *sha1)
+{
+ int fd;
+ struct stat st;
+ char path[PATH_MAX];
+ unsigned long size = 0;
+ void *map;
+ struct cache_tree *it;
+
+ sprintf(path, "%s.aux", get_index_file());
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return cache_tree();
+
+ if (fstat(fd, &st))
+ return cache_tree();
+ size = st.st_size;
+ map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+ if (map == MAP_FAILED)
+ return cache_tree();
+ it = cache_tree_read(sha1, map, size);
+ munmap(map, size);
+ if (!it)
+ return cache_tree();
+ return it;
+}
+
+int write_cache_tree(const unsigned char *sha1, struct cache_tree *root)
+{
+ char path[PATH_MAX];
+ unsigned long size = 0;
+ void *buf, *buffer;
+ int fd, ret = -1;
+
+ sprintf(path, "%s.aux", get_index_file());
+ if (!root) {
+ unlink(path);
+ return -1;
+ }
+ fd = open(path, O_WRONLY|O_CREAT, 0666);
+ if (fd < 0)
+ return -1;
+ buffer = buf = cache_tree_write(sha1, root, &size);
+ while (size) {
+ int written = xwrite(fd, buf, size);
+ if (written <= 0)
+ goto fail;
+ buf += written;
+ size -= written;
+ }
+ ret = 0;
+
+ fail:
+ close(fd);
+ free(buffer);
+ if (ret)
+ unlink(path);
+ return ret;
+}
diff --git a/cache-tree.h b/cache-tree.h
new file mode 100644
index 0000000..7b149af
--- /dev/null
+++ b/cache-tree.h
@@ -0,0 +1,29 @@
+#ifndef CACHE_TREE_H
+#define CACHE_TREE_H
+
+struct cache_tree;
+struct cache_tree_sub {
+ struct cache_tree *cache_tree;
+ int namelen;
+ int used;
+ char name[FLEX_ARRAY];
+};
+
+struct cache_tree {
+ int entry_count; /* negative means "invalid" */
+ unsigned char sha1[20];
+ int subtree_nr;
+ int subtree_alloc;
+ struct cache_tree_sub **down;
+};
+
+struct cache_tree *cache_tree(void);
+void cache_tree_free(struct cache_tree *);
+void cache_tree_invalidate_path(struct cache_tree *, const char *);
+
+int write_cache_tree(const unsigned char *, struct cache_tree *);
+struct cache_tree *read_cache_tree(unsigned char *);
+int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int);
+
+
+#endif
--
1.3.0.g623a
^ permalink raw reply related
* [PATCH 3/4] Update write-tree to use cache-tree.
From: Junio C Hamano @ 2006-04-23 23:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
The updated write-tree reads from $GIT_DIR/index.aux to pick up
subtree objects information, updates the cache-tree with the
index, and updates index.aux file after writing a tree out of
the index file.
Until update-index and other programs that modify the index are
updated to maintain index.aux file, the index.aux file written
by the last write-tree will become stale immediately after they
update the index, which will result in the whole tree
recomputation just like the original write-tree.
The idea is to convert those commands to invalidate cache-tree
whenever they touch the index entries, and write updated
index.aux out. After the index is updated with them, write-tree
will be able to reuse the parts of the cache-tree that have not
been touched.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* And this is the "Willie the Coyote waiting for the big rock
to fail" patch. Right now nobody uses the cache but...
write-tree.c | 135 +++++-----------------------------------------------------
1 files changed, 11 insertions(+), 124 deletions(-)
ff283e7fafdd0740f74dfa65d8efaaaf9a5a0bbf
diff --git a/write-tree.c b/write-tree.c
index dcad6e6..dbcfe8c 100644
--- a/write-tree.c
+++ b/write-tree.c
@@ -5,96 +5,23 @@
*/
#include "cache.h"
#include "tree.h"
+#include "cache-tree.h"
-static int missing_ok = 0;
-
-static int check_valid_sha1(unsigned char *sha1)
-{
- int ret;
-
- /* If we were anal, we'd check that the sha1 of the contents actually matches */
- ret = has_sha1_file(sha1);
- if (ret == 0)
- perror(sha1_file_name(sha1));
- return ret ? 0 : -1;
-}
-
-static int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1)
-{
- unsigned char subdir_sha1[20];
- unsigned long size, offset;
- char *buffer;
- int nr;
-
- /* Guess at some random initial size */
- size = 8192;
- buffer = xmalloc(size);
- offset = 0;
-
- nr = 0;
- while (nr < maxentries) {
- struct cache_entry *ce = cachep[nr];
- const char *pathname = ce->name, *filename, *dirname;
- int pathlen = ce_namelen(ce), entrylen;
- unsigned char *sha1;
- unsigned int mode;
-
- /* Did we hit the end of the directory? Return how many we wrote */
- if (baselen >= pathlen || memcmp(base, pathname, baselen))
- break;
-
- sha1 = ce->sha1;
- mode = ntohl(ce->ce_mode);
-
- /* Do we have _further_ subdirectories? */
- filename = pathname + baselen;
- dirname = strchr(filename, '/');
- if (dirname) {
- int subdir_written;
+static unsigned char active_cache_sha1[20];
+static struct cache_tree *active_cache_tree;
- subdir_written = write_tree(cachep + nr, maxentries - nr, pathname, dirname-pathname+1, subdir_sha1);
- nr += subdir_written;
-
- /* Now we need to write out the directory entry into this tree.. */
- mode = S_IFDIR;
- pathlen = dirname - pathname;
-
- /* ..but the directory entry doesn't count towards the total count */
- nr--;
- sha1 = subdir_sha1;
- }
-
- if (!missing_ok && check_valid_sha1(sha1) < 0)
- exit(1);
-
- entrylen = pathlen - baselen;
- if (offset + entrylen + 100 > size) {
- size = alloc_nr(offset + entrylen + 100);
- buffer = xrealloc(buffer, size);
- }
- offset += sprintf(buffer + offset, "%o %.*s", mode, entrylen, filename);
- buffer[offset++] = 0;
- memcpy(buffer + offset, sha1, 20);
- offset += 20;
- nr++;
- }
-
- write_sha1_file(buffer, offset, tree_type, returnsha1);
- free(buffer);
- return nr;
-}
+static int missing_ok = 0;
static const char write_tree_usage[] = "git-write-tree [--missing-ok]";
int main(int argc, char **argv)
{
- int i, funny;
int entries;
- unsigned char sha1[20];
setup_git_directory();
- entries = read_cache();
+ entries = read_cache_1(active_cache_sha1);
+ active_cache_tree = read_cache_tree(active_cache_sha1);
if (argc == 2) {
if (!strcmp(argv[1], "--missing-ok"))
missing_ok = 1;
@@ -108,51 +35,11 @@ int main(int argc, char **argv)
if (entries < 0)
die("git-write-tree: error reading cache");
- /* Verify that the tree is merged */
- funny = 0;
- for (i = 0; i < entries; i++) {
- struct cache_entry *ce = active_cache[i];
- if (ce_stage(ce)) {
- if (10 < ++funny) {
- fprintf(stderr, "...\n");
- break;
- }
- fprintf(stderr, "%s: unmerged (%s)\n", ce->name, sha1_to_hex(ce->sha1));
- }
- }
- if (funny)
- die("git-write-tree: not able to write tree");
-
- /* Also verify that the cache does not have path and path/file
- * at the same time. At this point we know the cache has only
- * stage 0 entries.
- */
- funny = 0;
- for (i = 0; i < entries - 1; i++) {
- /* path/file always comes after path because of the way
- * the cache is sorted. Also path can appear only once,
- * which means conflicting one would immediately follow.
- */
- const char *this_name = active_cache[i]->name;
- const char *next_name = active_cache[i+1]->name;
- int this_len = strlen(this_name);
- if (this_len < strlen(next_name) &&
- strncmp(this_name, next_name, this_len) == 0 &&
- next_name[this_len] == '/') {
- if (10 < ++funny) {
- fprintf(stderr, "...\n");
- break;
- }
- fprintf(stderr, "You have both %s and %s\n",
- this_name, next_name);
- }
- }
- if (funny)
- die("git-write-tree: not able to write tree");
+ if (cache_tree_update(active_cache_tree, active_cache, active_nr,
+ missing_ok))
+ die("git-write-tree: error building trees");
+ write_cache_tree(active_cache_sha1, active_cache_tree);
- /* Ok, write it out */
- if (write_tree(active_cache, entries, "", 0, sha1) != entries)
- die("git-write-tree: internal error");
- printf("%s\n", sha1_to_hex(sha1));
+ printf("%s\n", sha1_to_hex(active_cache_tree->sha1));
return 0;
}
--
1.3.0.g623a
^ permalink raw reply related
* [PATCH 4/4] Invalidate cache-tree entries for touched paths in git-apply.
From: Junio C Hamano @ 2006-04-23 23:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This updates git-apply to maintain cache-tree information. With
this and the previous write-tree patch, repeated "apply --index"
followed by "write-tree" on a huge tree will hopefully become
faster.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* ... then the big rock falls. With this, I tried to apply and
then write-tree "diff-tree -p $commit^1 $commit" on top of
"$commit^1" for the last 20 or so commits in the kernel tree.
The "master" version takes 0.15 second per patch on my Duron
750 with 700MB, while this one does that in 0.06 second.
This also helps the memory pressure because we do not have to
regenerate unchanged trees. 810 minor faults with the patch
vs 2150 minor faults without.
apply.c | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
94005d7bb4b55e9984f6505a8916d23d304ccc4d
diff --git a/apply.c b/apply.c
index 269210a..f7cdefa 100644
--- a/apply.c
+++ b/apply.c
@@ -8,9 +8,14 @@
*/
#include <fnmatch.h>
#include "cache.h"
+#include "cache-tree.h"
#include "quote.h"
#include "blob.h"
+static unsigned char active_cache_sha1[20];
+static struct cache_tree *active_cache_tree;
+
+
// --check turns on checking that the working tree matches the
// files that are being modified, but doesn't apply the patch
// --stat does just a diffstat, and doesn't actually apply
@@ -1717,6 +1722,7 @@ static void remove_file(struct patch *pa
if (write_index) {
if (remove_file_from_cache(patch->old_name) < 0)
die("unable to remove %s from index", patch->old_name);
+ cache_tree_invalidate_path(active_cache_tree, patch->old_name);
}
unlink(patch->old_name);
}
@@ -1815,6 +1821,7 @@ static void create_file(struct patch *pa
mode = S_IFREG | 0644;
create_one_file(path, mode, buf, size);
add_index_file(path, mode, buf, size);
+ cache_tree_invalidate_path(active_cache_tree, path);
}
static void write_out_one_result(struct patch *patch)
@@ -1912,8 +1919,9 @@ static int apply_patch(int fd, const cha
if (write_index)
newfd = hold_index_file_for_update(&cache_file, get_index_file());
if (check_index) {
- if (read_cache() < 0)
+ if (read_cache_1(active_cache_sha1) < 0)
die("unable to read index file");
+ active_cache_tree = read_cache_tree(active_cache_sha1);
}
if ((check || apply) && check_patch_list(list) < 0)
@@ -1923,9 +1931,13 @@ static int apply_patch(int fd, const cha
write_out_results(list, skipped_patch);
if (write_index) {
- if (write_cache(newfd, active_cache, active_nr) ||
+ if (write_cache_1(newfd, active_cache, active_nr,
+ active_cache_sha1) ||
commit_index_file(&cache_file))
die("Unable to write new cachefile");
+ cache_tree_update(active_cache_tree,
+ active_cache, active_nr, 1);
+ write_cache_tree(active_cache_sha1, active_cache_tree);
}
if (show_index_info)
--
1.3.0.g623a
^ permalink raw reply related
* weird pull behavior as of late
From: David S. Miller @ 2006-04-24 0:59 UTC (permalink / raw)
To: git
I just pulled from Linus's linux-2.6.git tree knowing there was a bit
of activity over the past day:
Generating pack...
Done counting 446 objects.
Deltifying 446 objects.
100% (446/446) done
Unpacking 446 objects
Total 446, written 446 (delta 235), reused 0 (delta 0)
100% (446/446) done
* refs/heads/origin: fast forward to branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
from f4ffaa452e71495a06376f12f772342bc57051fc to 6b426e785cb81e53dc2fc4dcf997661472b470ef
Updating from f4ffaa452e71495a06376f12f772342bc57051fc to 6b426e785cb81e53dc2fc4dcf997661472b470ef
Fast forward
MAINTAINERS | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
I got 446 objects and this amounted to just a 4 line change to the
MAINTAINERS file? :-)
If I do a "gitk ORIG_HEAD.." all the changes are there, just the
diffstat it spits out during the pull is weird.
Just FYI...
^ permalink raw reply
* Re: weird pull behavior as of late
From: Junio C Hamano @ 2006-04-24 1:18 UTC (permalink / raw)
To: David S. Miller; +Cc: git
In-Reply-To: <20060423.175953.52710961.davem@davemloft.net>
"David S. Miller" <davem@davemloft.net> writes:
> Updating from f4ffaa452e71495a06376f12f772342bc57051fc to 6b426e785cb81e53dc2fc4dcf997661472b470ef
> Fast forward
> MAINTAINERS | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>
> I got 446 objects and this amounted to just a 4 line change to the
> MAINTAINERS file? :-)
That is weird, certainly, and does not match what I am getting...
Updating from f4ffaa452e71495a06376f12f772342bc57051fc to 6b426e785cb81e53dc2fc4dcf997661472b470ef
Fast forward
MAINTAINERS | 4
arch/parisc/Kconfig | 31 +
arch/parisc/defconfig | 494 +++++++++++------
... (many lines later)
sound/ppc/tumbler.c | 2
91 files changed, 3008 insertions(+), 1286 deletions(-)
create mode 100644 drivers/char/tpm/tpm_tis.c
^ permalink raw reply
* Re: [PATCH 4/4] Invalidate cache-tree entries for touched paths in git-apply.
From: Junio C Hamano @ 2006-04-24 1:25 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <7v3bg3etnv.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> * ... then the big rock falls. With this, I tried to apply and
> then write-tree "diff-tree -p $commit^1 $commit" on top of
> "$commit^1" for the last 20 or so commits in the kernel tree.
> The "master" version takes 0.15 second per patch on my Duron
> 750 with 700MB, while this one does that in 0.06 second.
> This also helps the memory pressure because we do not have to
> regenerate unchanged trees. 810 minor faults with the patch
> vs 2150 minor faults without.
Sorry, but not really. The patch is wrong and the measurement
was flawed.
It was doing unnecessarily more work in git-apply, which made
git-write-tree a no-op, and I was measuring only git-write-tree.
The following goes on top of the series to remove that
unnecessary work from git-apply. Unfortunately this makes the
overall combination a bit slower than before X-<.
But I have not optimized cache-tree.c for speed; for example,
its subtree lists are not even sorted. Once that is done we may
get decent speedups from the combo.
---
diff --git a/apply.c b/apply.c
index 5fa2c1e..e283df3 100644
--- a/apply.c
+++ b/apply.c
@@ -1935,8 +1935,6 @@ static int apply_patch(int fd, const cha
active_cache_sha1) ||
commit_index_file(&cache_file))
die("Unable to write new cachefile");
- cache_tree_update(active_cache_tree,
- active_cache, active_nr, 1);
write_cache_tree(active_cache_sha1, active_cache_tree);
}
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox