* 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
* Re: weird pull behavior as of late
From: Kyle McMartin @ 2006-04-24 1:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: David S. Miller, git
In-Reply-To: <7vy7xvdb3x.fsf@assigned-by-dhcp.cox.net>
On Sun, Apr 23, 2006 at 06:18:58PM -0700, Junio C Hamano wrote:
> "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...
>
Hmm, I saw this when I did a git diff linus..master on my tree on hera
before I sent the pull request, but when I did git request-pull it
had All The Right Stuff (tm), so I assumed I just mucked something up
with my command-line options. When I looked at the tree in gitk,
everything looked sane as well.
Hope I didn't break anything...
Cheers,
Kyle
^ permalink raw reply
* Re: [PATCH 4/4] Invalidate cache-tree entries for touched paths in git-apply.
From: Junio C Hamano @ 2006-04-24 2:47 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <7vodyrdas9.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> 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.
Again, sorry, but there are some more bugs in the cache-tree
code that I need to fix and re-measure.
In the meantime, please do not use it on your production
repositories. It does not seem to produce corrupt trees, but it
creates broken index.aux for no good reason.
^ permalink raw reply
* Re: RFC: New diff-delta.c implementation
From: Geert Bosch @ 2006-04-24 2:57 UTC (permalink / raw)
To: Rene Scharfe; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <444A2334.3030501@lsrfire.ath.cx>
On Sat, Apr 22, 2006 at 02:36:04PM +0200, Rene Scharfe wrote:
> Could you please send your code inline, not as an attachment? And
> possibly as a patch with a Signed-off-by: tag (see
> Documentation/SubmittingPatches)?
For various reasons, mostly to do with managing and searching huge
mailboxes, I'm using Apple Mail. What sucks though is that automatic
line wrapping can't be turned off. This never got fixed, so it's useless
for posting inline patches. That said, I now leave a synchronized copy
of the git repository on my mailserver and use mutt for this reply.
Hopefully things will be better.
Note that I sent this code as a RFC, with explicit disclaimers about
style. So, I did not want to sign off on this code, since I pretty
much knew there would be some problems with the undocumented
("proprietary", according the libxdiff site) file format. In contrast
the GDIFF fileformat was documented very well, and I have a version
of this code that works flawlessly with that format.
> Regarding your FIXME comment about endianess: I think you are looking
> for htonl(). Use it to convert the values from host byte order to
> network byte order (= big endian) and you can get rid of those ugly
> branches.
Ah, I'll use that. It's of course a slight change that all processing
now is big-endian centric, but that might actually even result in
better code in this case. I'm just assuming any decent system has
some highly optimized macro for this and will never do a function call.
This is used in the most performance critical loops, and doing function
calls here will lead to horrendous performance.
>
> You can use "indent -npro -kr -i8 -ts8 -l80 -ss -ncs" to reformat your
> code into a similar style as used in the rest of git (settings taken
> from Lindent which is shipped with the Linux source).
Although I cringe at 8-space indenting, and find much of the GIT
code close to unreadable for lack of design-level comments, I'll
gladly reformat any code to conform to existing code standards.
Please let me know if you've got documentation on that, as it would
be helpful for me to know what the standard is. (No flame intended. :-)
>
> After converting to htonl() "make test" ran fine on my x86 box. Here is
> what I get when I try to repack the git repo, though:
>
> $ git repack -a -d
> Generating pack...
> Done counting 18985 objects.
> Deltifying 18985 objects.
> git-pack-objects: diff-delta.c:766: create_delta: Assertion `ptr -
> delta == (int)delta_size' failed.
>
> Please let me know if you need more details.
This was a result of incorrect calculation of the size of copy and
data commands. I fixed this in a follow-up patch sent to the list.
For any bug reports, they're easiest to fix if you can find a reproducer
using test-delta.
-Geert
^ permalink raw reply
* [PATCH 5/4] Minimum fixups to cache-tree
From: Junio C Hamano @ 2006-04-24 3:03 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <7vodyrdas9.fsf@assigned-by-dhcp.cox.net>
The first hunk is the repeat of the previous "oops". The second
is a real fix.
With this applied, 100-patch series (going from present to past
at the Linux 2.6 kernel tip) applies correctly with the
following stats:
Trying w/o the patch...
24.57user 4.48system 0:34.47elapsed 84%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+322156minor)pagefaults 0swaps
Trying w/ the patch...
15.81user 3.00system 0:20.84elapsed 90%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+252063minor)pagefaults 0swaps
So there definitely is an improvement. *Grin*.
The script used to bench this is attached at the end. "linus" is the tracking
branch and currently it points at v2.6.17-rc2-g6b426e7
$HOME/git-master/bin is where I installed the "master" version,
and $J (aka ../git.junio/) is the freshly compiled area with the
patch series applied (all five of four ;-).
-- >8 --
Minimum fixups to make things usable.
---
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);
}
diff --git a/cache-tree.c b/cache-tree.c
index 4dbdb65..f6d1dd1 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -348,10 +348,7 @@ #endif
}
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 = write_one(down->cache_tree, down->name, down->namelen,
buffer, size, offset);
}
return buffer;
--
#!/bin/sh
J=../git.junio
M=$HOME/git-master/bin
export J M
git reset --hard linus
previous=
git rev-list -n 100 HEAD |
while read commit
do
if test -n "$previous"
then
git-diff-tree -p "$previous" "$commit" >"$commit-$previous"
echo "$commit $previous"
fi
previous="$commit"
done >series
git reset --hard linus
echo "Trying w/o the patch..."
/usr/bin/time sh -c '
while read commit previous
do
$M/git-apply --whitespace=nowarn --index "$commit-$previous"
$M/git-write-tree
done <series
' >out-1
tree1=`git write-tree`
git reset --hard linus
echo "Trying w/ the patch..."
$J/git-write-tree
/usr/bin/time sh -c '
while read commit previous
do
$J/git-apply --whitespace=nowarn --index "$commit-$previous"
$J/git-write-tree
done <series
' >out-2
tree2=`git write-tree`
test "$tree1" = "$tree2" || exit 1
cmp out-1 out-2
^ permalink raw reply related
* How do I quickly check what heads a particular commit is in?
From: Martin Langhoff @ 2006-04-24 4:23 UTC (permalink / raw)
To: Git Mailing List
In the middle of a merge of 2 of a bunch of closely related heads, I
found a few odd things, so I've pickaxe'd and found the (potentially
bogus) commits. I am using gitk, and while I do find the commit, it's
not very clear what heads have the dodgy commit. They've probably been
for a few months in there <sigh>.
Is there a practical way to ask in what heads they are?
martin
^ permalink raw reply
* Re: How do I quickly check what heads a particular commit is in?
From: Junio C Hamano @ 2006-04-24 4:40 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
In-Reply-To: <46a038f90604232123r7f35660aufbb9da0f561f8ea@mail.gmail.com>
"Martin Langhoff" <martin.langhoff@gmail.com> writes:
> In the middle of a merge of 2 of a bunch of closely related heads, I
> found a few odd things, so I've pickaxe'd and found the (potentially
> bogus) commits. I am using gitk, and while I do find the commit, it's
> not very clear what heads have the dodgy commit. They've probably been
> for a few months in there <sigh>.
>
> Is there a practical way to ask in what heads they are?
git merge-base $broken_commit "master"
would show $broken_commit if "master" is a fast-forward of
$broken_commit (i.e. "master" is a descendant). I think that is
what you are calling "$broken_commit is in master".
^ permalink raw reply
* Re: How do I quickly check what heads a particular commit is in?
From: Jeff King @ 2006-04-24 4:41 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <46a038f90604232123r7f35660aufbb9da0f561f8ea@mail.gmail.com>
On Mon, Apr 24, 2006 at 04:23:24PM +1200, Martin Langhoff wrote:
> Is there a practical way to ask in what heads they are?
This should work:
$ cat <<'EOF' >find-commit
#!/bin/sh
commit=$1; shift
for i in "$@"; do
git rev-list $i | fgrep -q $commit && echo $i
done
EOF
$ sh find-commit full-40char-sha1-of-commit head1 head2 ...
You potentially end up traversing parts of the history multiple times
(if they are shared by multiple heads) but git is fast enough that
performance is fine.
I don't know of a way to do it all in a git command without the fgrep.
-Peff
^ permalink raw reply
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