* [PATCH] t6300: avoid creating refs/heads/HEAD
From: Jeff King @ 2017-02-27 9:29 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In one test, we use "git checkout --orphan HEAD" to create
an unborn branch. Confusingly, the resulting branch is named
"refs/heads/HEAD". The original probably meant something
like:
git checkout --orphan orphaned-branch HEAD
Let's just use "orphaned-branch" here to make this less
confusing. Putting HEAD in the second argument is already
implied.
Signed-off-by: Jeff King <peff@peff.net>
---
This comes originally from Junio's 84679d470. I cannot see how naming
the new branch HEAD would make any difference to the test, but perhaps I
am missing something.
I noticed this while digging on a nearby issue around "git branch -m @".
This does happen to be the only test that checks that we can make a
branch called refs/heads/HEAD, and I found it because it triggers if you
try to disallow "git branch -m HEAD". :)
If we care about that, though, I think we should make an explicit test
for "git branch HEAD". But I'm not sure we _do_ care about that. Making
a branch called HEAD is moderately insane, and I don't think it would be
unreasonable for us to outlaw it at some point.
t/t6300-for-each-ref.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index aea1dfc71..a468041c5 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -558,7 +558,7 @@ test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' '
test_when_finished "git checkout master" &&
git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual &&
sed -e "s/^\* / /" actual >expect &&
- git checkout --orphan HEAD &&
+ git checkout --orphan orphaned-branch &&
git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual &&
test_cmp expect actual
'
--
2.12.0.624.gbb1b07a2c
^ permalink raw reply related
* Re: SHA1 collisions found
From: Geert Uytterhoeven @ 2017-02-27 9:57 UTC (permalink / raw)
To: Jeff King; +Cc: Thomas Braun, Jakub Narębski, Joey Hess, Git Mailing List
In-Reply-To: <20170226213042.rd55ykgymmr37c7n@sigill.intra.peff.net>
On Sun, Feb 26, 2017 at 10:30 PM, Jeff King <peff@peff.net> wrote:
> On Sun, Feb 26, 2017 at 07:57:19PM +0100, Thomas Braun wrote:
>> While reading about the subject I came across [1]. The author reduced
>> the hash size to 4bits and then played around with git.
>>
>> Diff taken from the posting (not my code)
>> --- git-2.7.0~rc0+next.20151210.orig/block-sha1/sha1.c
>> +++ git-2.7.0~rc0+next.20151210/block-sha1/sha1.c
>> @@ -246,6 +246,8 @@ void blk_SHA1_Final(unsigned char hashou
>> blk_SHA1_Update(ctx, padlen, 8);
>>
>> /* Output hash */
>> - for (i = 0; i < 5; i++)
>> - put_be32(hashout + i * 4, ctx->H[i]);
>> + for (i = 0; i < 1; i++)
>> + put_be32(hashout + i * 4, (ctx->H[i] & 0xf000000));
>> + for (i = 1; i < 5; i++)
>> + put_be32(hashout + i * 4, 0);
>> }
>
> Yeah, that is a lot more flexible for experimenting. Though I'd think
> you'd probably want more than 4 bits just to avoid accidental
> collisions. Something like 24 bits gives you some breathing space (you'd
> expect a random collision after 4096 objects), but it's still easy to
> do a preimage attack if you need to.
Just shortening the hash causes lots of collisions between objects of
different types. While it's valuable to test git behavior for those cases, you
probably want some way to explicitly test collisions that do not change
the object type, as they're not trivial to detect.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] interpret_branch_name(): handle auto-namelen for @{-1}
From: Jeff King @ 2017-02-27 9:31 UTC (permalink / raw)
To: git; +Cc: Karthik Nayak
In-Reply-To: <20170227092540.ob2oy4qpgfukqwtc@sigill.intra.peff.net>
On Mon, Feb 27, 2017 at 04:25:40AM -0500, Jeff King wrote:
> However, before we do that auto-namelen magic, we call
> interpret_nth_prior_checkout(), which gets fed the bogus
> "0". This was broken by 8cd4249c4 (interpret_branch_name:
> always respect "namelen" parameter, 2014-01-15). Though to
> be fair to that commit, it was broken in the _opposite_
> direction before, where we would always treat "name" as a
> string even if a length was passed.
That commit is mine, by the way. More embarrassing than introducing the
bug is that I _noticed_ the problem at the time and wrote a paragraph in
the commit message rationalizing why it was OK, rather than just doing
this trivial fix.
-Peff
^ permalink raw reply
* Re: [BUG] branch renamed to 'HEAD'
From: Luc Van Oostenryck @ 2017-02-27 9:47 UTC (permalink / raw)
To: Jeff King; +Cc: Karthik Nayak, Git List
In-Reply-To: <20170227090233.uk7dfruggytgmuw2@sigill.intra.peff.net>
On Mon, Feb 27, 2017 at 04:02:33AM -0500, Jeff King wrote:
> Ugh. Actually, there are a few complications I found:
>
> 1. Checking "HEAD" afterwards means you can't actually have a branch
> named "HEAD". Doing so is probably insane, but we probably really
> _do_ want to just disallow the @-conversion here.
>
> 2. This isn't limited to just HEAD and @-conversion. For instance:
It's a bit what I was afraid of.
Luc
^ permalink raw reply
* Re: [PATCH v2] convert: add "status=delayed" to filter process protocol
From: Jeff King @ 2017-02-27 9:58 UTC (permalink / raw)
To: Lars Schneider; +Cc: git, gitster, tboegi, e, jnareb, ttaylorr
In-Reply-To: <20170226184816.30010-1-larsxschneider@gmail.com>
On Sun, Feb 26, 2017 at 07:48:16PM +0100, Lars Schneider wrote:
> +If the request cannot be fulfilled within a reasonable amount of time
> +then the filter can respond with a "delayed" status and a flush packet.
> +Git will perform the same request at a later point in time, again. The
> +filter can delay a response multiple times for a single request.
> +------------------------
> +packet: git< status=delayed
> +packet: git< 0000
> +------------------------
> +
So Git just asks for the same content again? I see two issues with that:
1. Does git have to feed the blob content again? That can be expensive
to access or to keep around in memory.
2. What happens when the item isn't ready on the second request? I can
think of a few options:
a. The filter immediately says "nope, still delayed". But then
Git ends up busy-looping with "is this one ready yet?"
b. The filter blocks until the item is ready. But then if other
items _are_ ready, Git cannot work on processing them. We lose
parallelism.
c. You could do a hybrid: block until _some_ item is ready, and
then issue "delayed" responses for everything that isn't
ready. Then if you assume that Git is looping over and over
through the set of objects, it will either block or pick up
_something_ on each loop.
But it makes a quadratic number of requests in the worst case.
E.g., imagine you have N items and the last one is available
first, then the second-to-last, and so on. You'll ask N times,
then N-1, then N-2, and so on.
I think it would be much more efficient to do something like:
[Git issues a request and gives it an opaque index id]
git> command=smudge
git> pathname=foo
git> index=0
git> 0000
git> CONTENT
git> 0000
[The data isn't ready yet, so the filter tells us so...]
git< status=delayed
git< 0000
[Git may make other requests, that are either served or delayed]
git> command=smudge
git> pathname=foo
git> index=1
git> 0000
git< status=success
git< 0000
git< CONTENT
git< 0000
[Now Git has processed all of the items, and each one either has its
final status, or has been marked as delayed. So we ask for a delayed
item]
git> command=wait
git> 0000
[Some time may pass if nothing is ready. But eventually we get...]
git< status=success
git< index=0
git< 0000
git< CONTENT
git< 0000
From Git's side, the loop is something like:
while (delayed_items > 0) {
/* issue a wait, and get back the status/index pair */
status = send_wait(&index);
delayed_items--;
/*
* use "index" to find the right item in our list of files;
* the format can be opaque to the filter, so we could index
* it however we like. But probably numeric indices in an array
* are the simplest.
*/
assert(index > 0 && index < nr_items);
item[index].status = status;
if (status == SUCCESS)
read_content(&item[index]);
}
and the filter side just attaches the "index" string to whatever its
internal queue structure is, and feeds it back verbatim when processing
that item finishes.
-Peff
^ permalink raw reply
* Re: [PATCH v2] convert: add "status=delayed" to filter process protocol
From: Lars Schneider @ 2017-02-27 10:32 UTC (permalink / raw)
To: Jeff King
Cc: Git List, Junio C Hamano, Torsten Bögershausen, Eric Wong,
Jakub Narębski, ttaylorr
In-Reply-To: <20170227095825.jhdspwy6oa6mvvvm@sigill.intra.peff.net>
> On 27 Feb 2017, at 10:58, Jeff King <peff@peff.net> wrote:
>
> On Sun, Feb 26, 2017 at 07:48:16PM +0100, Lars Schneider wrote:
>
>> +If the request cannot be fulfilled within a reasonable amount of time
>> +then the filter can respond with a "delayed" status and a flush packet.
>> +Git will perform the same request at a later point in time, again. The
>> +filter can delay a response multiple times for a single request.
>> +------------------------
>> +packet: git< status=delayed
>> +packet: git< 0000
>> +------------------------
>> +
>
> So Git just asks for the same content again? I see two issues with that:
>
> 1. Does git have to feed the blob content again? That can be expensive
> to access or to keep around in memory.
>
> 2. What happens when the item isn't ready on the second request? I can
> think of a few options:
>
> a. The filter immediately says "nope, still delayed". But then
> Git ends up busy-looping with "is this one ready yet?"
>
> b. The filter blocks until the item is ready. But then if other
> items _are_ ready, Git cannot work on processing them. We lose
> parallelism.
>
> c. You could do a hybrid: block until _some_ item is ready, and
> then issue "delayed" responses for everything that isn't
> ready. Then if you assume that Git is looping over and over
> through the set of objects, it will either block or pick up
> _something_ on each loop.
>
> But it makes a quadratic number of requests in the worst case.
> E.g., imagine you have N items and the last one is available
> first, then the second-to-last, and so on. You'll ask N times,
> then N-1, then N-2, and so on.
I completely agree - I need to change that. However, the goal of the v2
iteration was to get the "convert" interface in an acceptable state.
That's what I intended to say in the patch comment section:
"Please ignore all changes behind async_convert_to_working_tree() and
async_filter_finish() for now as I plan to change the implementation
as soon as the interface is in an acceptable state."
>
> I think it would be much more efficient to do something like:
>
> [Git issues a request and gives it an opaque index id]
> git> command=smudge
> git> pathname=foo
> git> index=0
> git> 0000
> git> CONTENT
> git> 0000
>
> [The data isn't ready yet, so the filter tells us so...]
> git< status=delayed
> git< 0000
>
> [Git may make other requests, that are either served or delayed]
> git> command=smudge
> git> pathname=foo
> git> index=1
> git> 0000
> git< status=success
> git< 0000
> git< CONTENT
> git< 0000
>
> [Now Git has processed all of the items, and each one either has its
> final status, or has been marked as delayed. So we ask for a delayed
> item]
> git> command=wait
> git> 0000
>
> [Some time may pass if nothing is ready. But eventually we get...]
> git< status=success
> git< index=0
> git< 0000
> git< CONTENT
> git< 0000
>
> From Git's side, the loop is something like:
>
> while (delayed_items > 0) {
> /* issue a wait, and get back the status/index pair */
> status = send_wait(&index);
> delayed_items--;
>
> /*
> * use "index" to find the right item in our list of files;
> * the format can be opaque to the filter, so we could index
> * it however we like. But probably numeric indices in an array
> * are the simplest.
> */
> assert(index > 0 && index < nr_items);
> item[index].status = status;
> if (status == SUCCESS)
> read_content(&item[index]);
> }
>
> and the filter side just attaches the "index" string to whatever its
> internal queue structure is, and feeds it back verbatim when processing
> that item finishes.
That could work! I had something like that in mind:
I teach Git a new command "list_completed" or similar. The filter
blocks this call until at least one item is ready for Git.
Then the filter responds with a list of paths that identify the
"ready items". Then Git asks for these ready items just with the
path and not with any content. Could that work? Wouldn't the path
be "unique" to identify a blob per filter run?
Thanks,
Lars
^ permalink raw reply
* Re: SHA1 collisions found
From: Jeff King @ 2017-02-27 10:43 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Thomas Braun, Jakub Narębski, Joey Hess, Git Mailing List
In-Reply-To: <CAMuHMdXZ2ZPsFbPUgmvx8=-xj3GBNBJwLaGAYj+R=Z2zDQJ+hQ@mail.gmail.com>
On Mon, Feb 27, 2017 at 10:57:37AM +0100, Geert Uytterhoeven wrote:
> > Yeah, that is a lot more flexible for experimenting. Though I'd think
> > you'd probably want more than 4 bits just to avoid accidental
> > collisions. Something like 24 bits gives you some breathing space (you'd
> > expect a random collision after 4096 objects), but it's still easy to
> > do a preimage attack if you need to.
>
> Just shortening the hash causes lots of collisions between objects of
> different types. While it's valuable to test git behavior for those cases, you
> probably want some way to explicitly test collisions that do not change
> the object type, as they're not trivial to detect.
Right, that's why I'm suggesting to make a longer truncation so that
you don't get accidental collisions, but can still find a few specific
ones for your testing.
24 bits is enough to make toy repositories. If you wanted to store a
real repository with the truncated sha1s, you might use 36 bits (that's
9 hex characters, which is enough for git.git to avoid any accidental
collisions). But you can still find a collision via brute force in 2^18
tries, which is not so bad.
I.e., something like:
diff --git a/block-sha1/sha1.c b/block-sha1/sha1.c
index 22b125cf8..9158e39ed 100644
--- a/block-sha1/sha1.c
+++ b/block-sha1/sha1.c
@@ -233,6 +233,10 @@ void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)
{
+ /* copy out only the first 36 bits */
+ static const uint32_t mask_bits[5] = {
+ 0xffffffff, 0xf0000000
+ };
static const unsigned char pad[64] = { 0x80 };
unsigned int padlen[2];
int i;
@@ -247,5 +251,5 @@ void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)
/* Output hash */
for (i = 0; i < 5; i++)
- put_be32(hashout + i * 4, ctx->H[i]);
+ put_be32(hashout + i * 4, ctx->H[i] & mask_bits[i]);
}
Build that and make it available as git.broken, and then feed your repo
into it, like:
git init --bare fake.git
git fast-export HEAD | git.broken -C fake.git fast-import
at which point you have an alternate-universe version of the repository,
which you can operate on as usual with your git.broken tool.
And then you can come up with collisions via brute force:
# hack to convince hash-object to do lots of sha1s in a single
# invocation
N=300000
for i in $(seq $N); do
echo $i >$i
done
seq 300000 | git.broken hash-object --stdin-paths >hashes
for collision in $(sort hashes | uniq -d); do
grep -n $collision hashes
done
The result is that "33713\n" and "170653\n" collide. So you can now add
those to your fake.git repository and watch the chaos ensue.
-Peff
^ permalink raw reply related
* Re: [PATCH v2] convert: add "status=delayed" to filter process protocol
From: Jeff King @ 2017-02-27 10:53 UTC (permalink / raw)
To: Lars Schneider
Cc: Git List, Junio C Hamano, Torsten Bögershausen, Eric Wong,
Jakub Narębski, ttaylorr
In-Reply-To: <E4A6D866-D046-4CF3-8050-666FD6C98F7B@gmail.com>
On Mon, Feb 27, 2017 at 11:32:47AM +0100, Lars Schneider wrote:
> I completely agree - I need to change that. However, the goal of the v2
> iteration was to get the "convert" interface in an acceptable state.
> That's what I intended to say in the patch comment section:
>
> "Please ignore all changes behind async_convert_to_working_tree() and
> async_filter_finish() for now as I plan to change the implementation
> as soon as the interface is in an acceptable state."
Ah, sorry, I missed that. I would think the underlying approach would
influence the interface to some degree. But as long as the interface
is sufficiently abstract, I think it gives you enough flexibility.
> > From Git's side, the loop is something like:
> >
> > while (delayed_items > 0) {
> > /* issue a wait, and get back the status/index pair */
> > status = send_wait(&index);
> > delayed_items--;
> >
> > /*
> > * use "index" to find the right item in our list of files;
> > * the format can be opaque to the filter, so we could index
> > * it however we like. But probably numeric indices in an array
> > * are the simplest.
> > */
> > assert(index > 0 && index < nr_items);
> > item[index].status = status;
> > if (status == SUCCESS)
> > read_content(&item[index]);
> > }
> >
> > and the filter side just attaches the "index" string to whatever its
> > internal queue structure is, and feeds it back verbatim when processing
> > that item finishes.
>
> That could work! I had something like that in mind:
>
> I teach Git a new command "list_completed" or similar. The filter
> blocks this call until at least one item is ready for Git.
> Then the filter responds with a list of paths that identify the
> "ready items". Then Git asks for these ready items just with the
> path and not with any content. Could that work? Wouldn't the path
> be "unique" to identify a blob per filter run?
I think that could work, though I think there are few minor downsides
compared to what I wrote above:
- if you respond with "these items are ready", and then make Git ask
for each again, it's an extra round-trip for each set of ready
items. You could just say "an item is ready; here it is" in a single
response. For a local pipe the latency is probably negligible,
though.
- using paths as the index would probably work, but it means Git has
to use the path to find the "struct checkout_entry" again. Which
might mean a hashmap (though if you have them all in a sorted list,
I guess you could also do a binary search).
- Using an explicit index communicates to the filter not only what the
index is, but also that Git is prepared to accept a delayed response
for the item. For backwards compatibility, the filter would probably
advertise "I have the 'delayed' capability", and then Git could
choose to use it or not on a per-item basis. Realistically it would
not change from item to item, but rather operation to operation. So
that means we can easily convert the call-sites in Git to the async
approach incrementally. As each one is converted, it turns on the
flag that causes the filter code to send the "index" tag.
-Peff
^ permalink raw reply
* [PATCH] cvs tests: When root, skip tests that call "cvs commit"
From: Ævar Arnfjörð Bjarmason @ 2017-02-27 11:26 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Robin Rosenberg,
Ævar Arnfjörð Bjarmason
Change the tests that fail to when we run the test suite as root, due
to calling "cvs commit".
The GNU cvs package has an optional compile-time CVS_BADROOT
flag. When compiled with this flag "cvs commit" will refuse to commit
anything as root. On my Debian box this isn't compiled in[1] in, but
on CentOS it is.
I've run all the t/t*cvs*.sh tests, and these are the only two that
fail. For some reason e.g. t9402-git-cvsserver-refs.sh still works as
root despite doing "cvs commit", I haven't dug into why.
This commit is technically being overzealous, we could do better by
making a mock cvs commit as root and run the tests if that works, but
I don't see any compelling reason to bend over backwards to run these
tests in all cases, just skipping them as root seems good enough.
1. Per: strings /usr/bin/cvs|grep 'is not allowed to commit'
Using cvs 1.11.23 on CentOS, 1.12.13-MirDebian-18 on Debian.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/t9200-git-cvsexportcommit.sh | 5 +++++
t/t9600-cvsimport.sh | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index bb879a527d..1319415ba8 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -18,6 +18,11 @@ then
test_done
fi
+if ! test_have_prereq NOT_ROOT; then
+ skip_all='When cvs is compiled with CVS_BADROOT commits as root fail'
+ test_done
+fi
+
CVSROOT=$PWD/tmpcvsroot
CVSWORK=$PWD/cvswork
GIT_DIR=$PWD/.git
diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
index 4c384ff023..804ce3850f 100755
--- a/t/t9600-cvsimport.sh
+++ b/t/t9600-cvsimport.sh
@@ -3,6 +3,11 @@
test_description='git cvsimport basic tests'
. ./lib-cvs.sh
+if ! test_have_prereq NOT_ROOT; then
+ skip_all='When cvs is compiled with CVS_BADROOT commits as root fail'
+ test_done
+fi
+
test_expect_success PERL 'setup cvsroot environment' '
CVSROOT=$(pwd)/cvsroot &&
export CVSROOT
--
2.11.0
^ permalink raw reply related
* Re: SHA1 collisions found
From: Morten Welinder @ 2017-02-27 12:39 UTC (permalink / raw)
To: Jeff King
Cc: Geert Uytterhoeven, Thomas Braun, Jakub Narębski, Joey Hess,
Git Mailing List
In-Reply-To: <20170227104338.qfaaktf3or4hwfw7@sigill.intra.peff.net>
Just swap in md5 in place of sha1. Pad with '0'. That'll give you
all the collisions you want and none of those you don't want.
On Mon, Feb 27, 2017 at 5:43 AM, Jeff King <peff@peff.net> wrote:
> On Mon, Feb 27, 2017 at 10:57:37AM +0100, Geert Uytterhoeven wrote:
>
>> > Yeah, that is a lot more flexible for experimenting. Though I'd think
>> > you'd probably want more than 4 bits just to avoid accidental
>> > collisions. Something like 24 bits gives you some breathing space (you'd
>> > expect a random collision after 4096 objects), but it's still easy to
>> > do a preimage attack if you need to.
>>
>> Just shortening the hash causes lots of collisions between objects of
>> different types. While it's valuable to test git behavior for those cases, you
>> probably want some way to explicitly test collisions that do not change
>> the object type, as they're not trivial to detect.
>
> Right, that's why I'm suggesting to make a longer truncation so that
> you don't get accidental collisions, but can still find a few specific
> ones for your testing.
>
> 24 bits is enough to make toy repositories. If you wanted to store a
> real repository with the truncated sha1s, you might use 36 bits (that's
> 9 hex characters, which is enough for git.git to avoid any accidental
> collisions). But you can still find a collision via brute force in 2^18
> tries, which is not so bad.
>
> I.e., something like:
>
> diff --git a/block-sha1/sha1.c b/block-sha1/sha1.c
> index 22b125cf8..9158e39ed 100644
> --- a/block-sha1/sha1.c
> +++ b/block-sha1/sha1.c
> @@ -233,6 +233,10 @@ void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
>
> void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)
> {
> + /* copy out only the first 36 bits */
> + static const uint32_t mask_bits[5] = {
> + 0xffffffff, 0xf0000000
> + };
> static const unsigned char pad[64] = { 0x80 };
> unsigned int padlen[2];
> int i;
> @@ -247,5 +251,5 @@ void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)
>
> /* Output hash */
> for (i = 0; i < 5; i++)
> - put_be32(hashout + i * 4, ctx->H[i]);
> + put_be32(hashout + i * 4, ctx->H[i] & mask_bits[i]);
> }
> Build that and make it available as git.broken, and then feed your repo
> into it, like:
>
> git init --bare fake.git
> git fast-export HEAD | git.broken -C fake.git fast-import
>
> at which point you have an alternate-universe version of the repository,
> which you can operate on as usual with your git.broken tool.
>
> And then you can come up with collisions via brute force:
>
> # hack to convince hash-object to do lots of sha1s in a single
> # invocation
> N=300000
> for i in $(seq $N); do
> echo $i >$i
> done
> seq 300000 | git.broken hash-object --stdin-paths >hashes
>
> for collision in $(sort hashes | uniq -d); do
> grep -n $collision hashes
> done
>
> The result is that "33713\n" and "170653\n" collide. So you can now add
> those to your fake.git repository and watch the chaos ensue.
>
> -Peff
^ permalink raw reply
* [PATCH] gitweb tests: Skip tests when we don't have Time::HiRes
From: Ævar Arnfjörð Bjarmason @ 2017-02-27 12:37 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason
Change the gitweb tests to skip when we can't load the Time::HiRes
module.
This module has bee in perl core since v5.8, which is the oldest
version we support, however CentOS (and perhaps some other
distributions) carve it into its own non-core-perl package that's not
installed along with /usr/bin/perl by default. Without this we'll hard
fail the gitweb tests when trying to load the module.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
t/gitweb-lib.sh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh
index d5dab5a94f..116c3890e6 100644
--- a/t/gitweb-lib.sh
+++ b/t/gitweb-lib.sh
@@ -114,4 +114,9 @@ perl -MCGI -MCGI::Util -MCGI::Carp -e 0 >/dev/null 2>&1 || {
test_done
}
+perl -mTime::HiRes -e 0 >/dev/null 2>&1 || {
+ skip_all='skipping gitweb tests, Time::HiRes module unusable'
+ test_done
+}
+
gitweb_init
--
2.11.0
^ permalink raw reply related
* Re: SHA1 collisions found
From: René Scharfe @ 2017-02-27 13:29 UTC (permalink / raw)
To: brian m. carlson; +Cc: Duy Nguyen, Joey Hess, Git Mailing List
In-Reply-To: <20170225190410.anvb7ll7tlhwgm3t@genre.crustytoothpaste.net>
Am 25.02.2017 um 20:04 schrieb brian m. carlson:
>>> So I think that the current scope left is best estimated by the
>>> following command:
>>>
>>> git grep -P 'unsigned char\s+(\*|.*20)' | grep -v '^Documentation'
>>>
>>> So there are approximately 1200 call sites left, which is quite a bit of
>>> work. I estimate between the work I've done and other people's
>>> refactoring work (such as the refs backend refactor), we're about 40%
>>> done.
>
> As a note, I've been working on this pretty much nonstop since the
> collision announcement was made. After another 27 commits, I've got it
> down from 1244 to 1119.
>
> I plan to send another series out sometime after the existing series has
> hit next. People who are interested can follow the object-id-part*
> branches at https://github.com/bk2204/git.
Perhaps the following script can help a bit; it converts local and static
variables in specified files. It's just a simplistic parser which can get
at least shadowing variables, strings and comments wrong, so its results
need to be reviewed carefully.
I failed to come up with an equivalent Coccinelle patch so far. :-/
René
#!/bin/sh
while test $# -gt 0
do
file="$1"
tmp="$file.new"
test -f "$file" &&
perl -e '
use strict;
my %indent;
my %old;
my %new;
my $in_struct = 0;
while (<>) {
if (/^(\s*)}/) {
my $len = length $1;
foreach my $key (keys %indent) {
if ($len < length($indent{$key})) {
delete $indent{$key};
delete $old{$key};
delete $new{$key};
}
}
$in_struct = 0;
}
if (!$in_struct and /^(\s*)(static )?unsigned char (\w+)\[20\];$/) {
my $prefix = "$1$2";
my $name = $3;
$indent{$.} = $1;
$old{$.} = qr/(?<!->)(?<!\.)(?<!-)\b$name\b/;
$name =~ s/sha1/oid/;
print $prefix . "struct object_id " . $name . ";\n";
$new{$.} = $name . ".hash";
next;
}
if (/^(\s*)(static )?struct (\w+ )?\{$/) {
$in_struct = 1;
}
if (!$in_struct and ! /\/\*/) {
foreach my $key (keys %indent) {
s/$old{$key}/$new{$key}/g;
}
}
print;
}
' "$file" >"$tmp" &&
mv "$tmp" "$file" ||
exit 1
shift
done
^ permalink raw reply
* 'git submodules update' ignores credential.helper config of the parent repository
From: Dmitry Neverov @ 2017-02-27 13:33 UTC (permalink / raw)
To: Git List
I'm checking out a repository in a non-interactive environment and
would like to disable interactive credential helpers. According to [1]
it can be done by specifying an empty helper in a local config:
[credential]
helper =
But the submodule update command ignores the helper specified in the
config of the parent repository. To reproduce it, fetch a repository
with submodules requiring authentication and run:
git submodule init;
git submodule sync;
git submodule update;
the 'git submodule update' runs a default credential helper. The only
way to disable it is specify helper in command-line:
git -c credential.helper= submodule update
Is it by design?
[1] http://marc.info/?l=git&m=147136396024768&w=2
^ permalink raw reply
* Transition plan for git to move to a new hash function
From: Ian Jackson @ 2017-02-27 13:00 UTC (permalink / raw)
To: Jeff King
Cc: Ævar Arnfjörð Bjarmason, Linus Torvalds,
brian m. carlson, Jason Cooper, ankostis, Junio C Hamano,
Git Mailing List, Stefan Beller, David Lang, Joey Hess
In-Reply-To: <20170226215220.jckz6yzgben4zbyz@sigill.intra.peff.net>
I said I was working on a transition plan. Here it is. This is
obviously a draft for review, and I have no official status in the git
project. But I have extensive experience of protocol compatibility
engineering, and I hope this will be helpful.
Ian.
Subject: Transition plan for git to move to a new hash function
BASIC PRINCIPLES
================
We run multiple hashes in parallel. Each object is named by exactly
one hash. We define that objects with identical content, but named by
different hash functions, are different objects.
Objects of one hash may refer to objects named by a different hash
function to their own. Preference rules arrange that normally, new
hash objects refer to other new hash objects.
The intention is that for most projects, the existing SHA-1 based
history will be retained and a new history built on top of it.
(Rewriting is also possible but means a per-project hard switch.)
We extend the textual object name syntax to explicitly name the hash
used. Every program that invokes git or speaks git protocols will
need to understand the extended object name syntax.
Packfiles need to be extended to be able to contain objects named by
new hash functions. Blob objects with identical contents but named by
different hash functions would ideally share storage.
Safety catches preferent accidental incorporation into a project of
incompatibly-new objects, or additional deprecatedly-old objects.
This allows for incremental deployment.
TEXTUAL SYNTAX
==============
The object name textual syntax is extended. The new syntax may be
used in all textual git objects and protocols (commits, tags, command
lines, etc.).
We declare that the object name syntax is henceforth
[A-Z]+[0-9a-z]+ | [0-9a-f]+
and that names [A-Z].* are deprecated as ref name components.
Rationale:
Full backwards compatibility (ie, without updating any software
that calls git) is impossible, because the hash function needs
to be evident in the name, so the new names must be disjoint
from all old SHA-1 names.
We want a short but extensible syntax. The syntax should impose
minimal extra requirements on existing git users. In most
contexts where existing git users use hashes, ASCII alphanumeric
object names will fit. Use of punctuation such as : or even _
may give trouble to existing users, who are already using
such things as delimiters.
In existing deployments, refnames that differ only in case are
generally avoided (because they are troublesome on
case-insensitive filesystems). And conventionally refnames are
lower case. So names starting with an upper case letter will be
disjoint from most existing ref name components.
(Note that there is no need to write the uppercase letter to a
filename in the object store; the object store can use a
different naming scheme.)
Even though we probably want to keep using hex, it is a good
idea to reserve the flexibility to use a more compact encoding,
while not excessively widening the existing permissible
character set.
Object names using SHA-1 are represented, in text, as at present.
Object names starting with uppercase ASCII letters H or later refer to
new hash functions. Programs that use `g<objectname>' should ideally
be changed to show `H<hash>' for hash function `H' rather than
`gH<hash>'.)
Rationale:
Object names starting with A-F might look like hex. G is
reserved because of the way that many programs write
`g<objectname>'.
This gives us 19 new hash function values until we have to
starting using two-letter hash function prefixes, or decide to
use A-F after all.
New hash names my be abbreviated, by truncation (just like old
hashes). The hash function indicator letter must be retained.
Initially we define and assign one new hash function (and textual
object name encoding):
H<hex> where <hex> is the BLAKE2b hash of the object
(in lowercase)
Note:
If the git project prefers a different new hash function to
BLAKE2b, that's fine. This proposal can even cope with two new
hash functions in parallel. One could even choose on a
per-project basis, or switch back and forth.
It would also be possible to define a multihash object name,
where the full object name is the concatenation of two different
hash function values. One of the hashes would have to be
preferred for use when a truncated object name is provided by
the human user.
We also reserve the following syntax for private experiments:
E[A-Z]+[0-9a-z]+
We declare that public releases of git will never accept such
object names.
Everywhere in the git object formats and git protocols, a new object
name (with hash function indicator) is permitted where an old object
name is permitted.
A single object may refer to other objects the hash function which
names the object itself, or by other hash functions, in any
combination. During git operations, hash function namespace
boundaries in the object graph are traversed freely.
Two additional restrictions: a tree object may be referenced only by
objects named by the same hash function as the tree object itself;
and, a tree object may reference only blobs named by the same hash
function.
IMPLEMENTATION REQUIREMENTS
===========================
The object store will need to store objects named by new hashes,
alongside SHA-1 objects.
In binary protocols, where a SHA-1 object name in binary form was
previously used, a new codepoint must be allocated in a containing
structure (eg a new typecode). Usually, the new-format binary object
will have a new typecode and also an additional name hash indicator,
and it may also need a length field (as new hashes may be of different
lengths).
Whenever a new hash function textual syntax is defined, corresponding
binary format codepoint(s) are assigned.
Implementation details such as the binary format and protocol
specifications, object store layout, and so on, are outside the scope
of this transition plan.
WHILE WE ARE HERE
=================
We should audit the git data formats for inextensible parsers. That
will make future changes (for whatever purpose) much less painful.
Specific instances I'm aware of:
* Permit commits and tags to contain unexpected header lines. Ie,
lines matching /^\w+\ / before the first blank like, where the
keyword is not recognised. These should be ignored.
* The signed push certificate format may need reviewing to check that
there is space for extension.
The test suite should contain tests of these extension possibilities.
A registry (a la IANA) should be created for the extensible namespaces
(eg of header keywords).
Since new objects can be received and understood only by new software,
anyway, it will be safe to insert extension info whenever we generate
objects named by new hash functions.
CHOICE OF HASH FUNCTION
=======================
Whenever objects are created, it is necessary to choose the hash
function which will be used to name it.
Hash functions are partially ordered, from `older' to `newer'
(implicitly, from worse to better). The ordering is configurable.
For details of the defaults, see _Transition Plan_.
Each ref has, optionally, a hash function hint associated with it.
Ie, a dropping in .git which names a particular hash function, with
the intent that the next objects made for that ref ought to use the
specified hash function.
Commits
-------
A commit is made (by default) as new as the newest of
(i) each of its parents
(ii) if applicable, the hash function hint for the ref to which the
new commit is to be written
Implicitly this normally means that if HEAD refers to a new commit,
further new commits will be generated on top of it.
The hash function naming an origin commit is controlled by the hint
left in .git for the ref named by HEAD (or for HEAD itself, if HEAD is
detached) by git checkout --orphan or git init.
At boundaries between old and new history, new commit(s) will refer to
old parent(s).
Tags
----
A tag is created (by default) to by named by the same hash function as
the object to which it refers.
Trees
-----
Trees are only referenced by objects named by the same hash function
as the tree.
To satisfy this rule, occasionally a tree object named by one hash
must be recursively rewritten into an equivalent tree named by another
hash.
When a tree refers to a commit (ie, a gitlink), it may refer to a
commit named by a different hash function.
Trees generated so that they can be referred to by the index, are
named by the hash function which would name the next commit to be made
on HEAD (see `Commits', above)
Rationale: we want to avoid new commits and tags relying on weak
hashes. But we should avoid demanding that commits be rewritten.
Blobs
----
Blobs are normally referred to by trees. Trees always refer to blobs
named by the tree's own hash function.
Where a blob is created in other circumstances, the caller should
specify the hash function.
Ref hints
---------
As noted above, each ref may also have a hash function hint associated
with it. The hint records an intent to switch hash function.
The hash hint is (by default) copied, when the ref value is copied.
So for exmple if `git checkout foo' makes refs/heads/foo out of
refs/remotes/origin/foo, it will copy the hash hint (or lack of one)
from refs/remotes/origin/foo.
Likewise, the hash hint is conveyed by `git fetch' (by default) and
can be updated with `git push' (though this is not done by default).
The ref hash hint may be set explicitly. That is how an individual
branch is upgraded. git checkout --orphan sets it to the hash which
names (or the hint of) the previous HEAD.
When a commit is made and stored in a ref, the hash hint for that ref
is removed iff hash naming the commit's is the same as the the hint.
CONFIGURATION - OBJECT STORE BEHAVIOUR
======================================
The object store has configuration to specify which hash functions are
enabled. Each hash function H has a combination of the following
behaviours, according to configuration:
* Collision behaviour:
What to do if we encounter an object we already have (eg as part of
a pack, or with hash-object) but with different contents.
(a) fail: print a scary message and abort operation (on the basis
that either (i) the source of the colliding object probably
intended the preimage that they provided, in which case proceeding
using our own version is wrong, or (ii) the source is conducting
(or unwittingly facilitating) an attack).
(b) tolerate: prefer our own data; print a message, but treat
the reference as referring to our version of the object.
In both cases we keep a copy of the second preimage in our .git, for
forensic purposes.
Rationale:
This is used as part of a gradual desupport strategy. Existing
history in all existing object stores is safe and cannot be
corrupted or modified by receiving colliding objects.
New trees which receive their initial data from a trustworthy
sender over a trustworthy channel will receive correct data.
Bad object stores or untrustworthy channels could exploit
collisions, but not in new regions of the history which are
presumably using new names. So even with untrustworthy
distribution channels, the collisons can only affect
archaeology.
Merging previously-unrelated histories does introduce a
collision hazard, but the collision would have had to have been
introduced while the colliding hash function was still a live
hash function in at least one of the two projects.
* Hash function enablement:
Each hash function is in one of the following states:
(a) enabled: this hash function is good and available for use
(b) deprecated (in favour of H2): this hash function is
available for use, but newly created objects will use another
hash function instead (specifically, when creating an object,
this has function is not considered as a candidate; if as a
result there are no candidate hash functions, we use the
specified replacement H2).
Existing refs referring to objects with this hash, with no ref
hint, are treated as having a ref hint specifying H2. If no H2
is specified, the newest hash is used.
(c) disabled: existing objects using this hash function can be
accessed, but no such objects can be created or received.
(again, a replacement may be specified). This is used both
initially to prevent unintended upgrade, and later to block the
introduction of vulnerable data generated by badly configured
clients.
* Preference ordering:
As mentioned in `CHOICE OF HASH FUNCTION', there is a configured
order on hash functions. This order should be consistent with the
enablement configuration.
Details of precise configuration option names are beyond the scope of
this document.
Remote protocol
---------------
During protocol negotation, a receiver needs to specify what hashes it
understands, and whether it is prepared to see only a partial view.
When the sender is listing its refs, refs naming objects the receiver
cannot understand are either elided (if the receiver is content with a
partial view), or cause an error.
Equality testing
----------------
Note that semantically identical trees (and blobs) may (now) have
different tree objects because those tree objects might use (and be
named by) different hashes. So (in some contexts at least) tree
comparison cannot any longer be done by comparing object names; rather
an invocation of git diff is needed, or explicit generation of a tree
object named by the right hash.
TRANSITION PLAN
===============
For brevity I will write `SHA' for hashing with SHA-1, using current
unqualified object names, and `BLAKE' for hasing with BLAKE2b, using
H<hex> object names.
Y<n> means `Year <n> after the start of the transition'.
Please adjust timescales to taste.
I will focus on the default configuration as shipped by git upstream,
and the recommended configuration for hosting providers.
Individual projects, and perhaps individual hosting providers, can
make their own choices, if they are willing to set appropriate
configuration (on clients, and servers).
Y0: Implement all of the above. Test it.
Default configuration:
SHA is enabled
BLAKE is disabled in trees without working trees
BLAKE is enabled in trees with working trees
SHA > BLAKE
Effects:
Clients are prepared to process BLAKE data, but it is not
generated by default and cannot be pushed to servers.
All old git clients still work.
Early adopters can start using the new hashes, at the cost of
compatibility. Projects that want to rewrite history right away
can do so. (In both cases, by setting configuration options.)
Y4: BLAKE by default for new projects.
Conversion enabled for existing projects.
Old git software is going to start rotting.
Default configuration change:
BLAKE > SHA
BLAKE enabled (even in trees without working trees)
Suggested multi-project hosting site configuration change:
Newly created projects should get BLAKE enabled
Existing projects should retain BLAKE disabled by default
Button should be provided to start conversion (see below)
Effects:
When creating a new working tree, it starts using BLAKE.
Servers which have been updated will accept BLAKE.
Servers which have not been updated to Y4's git will need a small
configuration change (enabling BLAKE) to cope with the new
projects that are using BLAKE.
To convert a project, an administrator (or project owner) would
set BLAKE to enabled, and SHA to deprecated, on the server(s). On
the next pull the server will provide ref hints naming BLAKE,
which will get copied to the client's HEAD. So the client is
infected with BLAKE.
To convert a project branch-by-branch, the administrator would set
BLAKE to enabled but leave SHA enabled. Then each branch retains
its own hash. A branch can be converted by pushing a BLAKE commit
to it, or by setting a ref hint on the server (or on the next
client to push).
Y6: BLAKE by default for all projects
Existing projects start being converted infectiously.
It is hard for a project to stop this happening if any of
their servers are updated.
Old git software is firmly stuffed.
Default configuration change
SHA deprecated in trees without working trees
Effects:
Existing projects are, by default, `converted', as described
above.
Y8: Clients hate SHA
Clients insist on trying to convert existing projects
It is very hard to stop this happening.
Unrepentant servers start being very hard to use.
Default configuration change
SHA deprecated (even in trees without working trees)
Effects:
Clients will generate only BLAKE. Hopefully their server will
accept this!
Y10: Stop accepting new SHA
No-one can manage to make new SHA commits
Default configuration change
SHA disabled in new trees, except during initial
`clone', `mirror' and similar
Effects:
Existing SHA history is retained, and copied to new clients and
servers. But established clients and servers reject any newly
introduced SHA.
--
Ian Jackson <ijackson@chiark.greenend.org.uk> These opinions are my own.
If I emailed you from an address @fyvzl.net or @evade.org.uk, that is
a private address which bypasses my fierce spamfilter.
^ permalink raw reply
* Re: show all merge conflicts
From: Michael J Gruber @ 2017-02-27 14:28 UTC (permalink / raw)
To: G. Sylvie Davies, Jeff King; +Cc: Michael Spiegel, git
In-Reply-To: <CAAj3zPx5fKHUTLLEuuZjmq+H5somp980j0hqWjmLyvLuk709GQ@mail.gmail.com>
G. Sylvie Davies venit, vidit, dixit 29.01.2017 07:45:
> On Sat, Jan 28, 2017 at 6:28 AM, Jeff King <peff@peff.net> wrote:
>> On Fri, Jan 27, 2017 at 09:42:41PM -0800, G. Sylvie Davies wrote:
>>
>>> Aside from the usual "git log -cc", I think this should work (replace
>>> HEAD with whichever commit you are analyzing):
>>>
>>> git diff --name-only HEAD^2...HEAD^1 > m1
>>> git diff --name-only HEAD^1...HEAD^2 > b1
>>> git diff --name-only HEAD^1..HEAD > m2
>>> git diff --name-only HEAD^2..HEAD > b2
>>>
>>> If files listed between m1 and b2 differ, then the merge is dirty.
>>> Similarly for m2 and b1.
>>>
>>> More information here:
>>>
>>> http://stackoverflow.com/questions/27683077/how-do-you-detect-an-evil-merge-in-git/41356308#41356308
>>
>> I don't think that can reliably find evil merges, since it looks at the
>> file level. If you had one hunk resolved for "theirs" and one hunk for
>> "ours" in a given file, then the file will be listed in each diff,
>> whether it has evil hunks or not.
>>
>
> Well, you have to do both. Do "git show -c" to catch that one
> ("theirs" for one hunk, "ours" for the other, same file).
>
> And then do that sequence of the 4 "git diff" commands to identify
> dirty merges where "theirs" or "ours" was applied to entire files, and
> thus not showing up in the "git show -c".
>
>> I don't think this is just about evil merges, though. For instance,
>> try:
>>
>> seq 1 10 >file
>> git add file
>> git commit -m base
>>
>> sed s/4/master/ <file >tmp && mv tmp file
>> git commit -am master
>>
>> git checkout -b other HEAD^
>> sed s/4/other/ <file >tmp && mv tmp file
>> git commit -am other
>>
>> git merge master
>> git checkout --ours file
>> git commit -am merged
>>
>> merge=$(git rev-parse HEAD)
>>
>> The question is: were there conflicts in $merge, and how were they
>> resolved?
>>
>> That isn't an evil merge, but there's still something interesting to
>> show that "git log --cc" won't display.
>>
>> Replaying the merge like:
>>
>> git checkout $merge^1
>> git merge $merge^2
>> git diff -R $merge
>>
>> shows you the patch to go from the conflict state to the final one.
>>
>
> I know the stackoverflow question asks "how to detect evil merges",
> and I go along with that in my answer. But honestly I prefer to call
> them dirty rather than evil, and by "dirty" I just mean merges that
> did not resolve cleanly via "git merge", and had some form of user
> intervention, be it conflict resolution, or other strange things.
>
> The trick I propose with the sequence of 4 "git diff" commands
> identifies that merge from your example as dirty:
>
> $ cat b1 m2
> file
>
> $ cat b2 m1
> file
> file
>
> The trick doesn't really tell you much except that the merge is dirty.
> If you notice that the "m2" file is empty, I think that's one way to
> realize that master's edit was dropped, and therefore "other" won.
>
> Maybe it even merged cleanly but someone did a "git commit --amend" to
> make it the merge dirty after the fact.
>
> I do like your approach, it's very simple and reliable. But in my
> situation I'm writing pre-receive hooks for bare repos, so I don't
> think I can actually do "git merge"!
>
> I think my suggestion would work for OP, as long as they also run "git
> show -c" alongside it. (And your suggestion would work, too, of
> course).
If you're curious, I kept rebasing Thomas' remerge-diff (on top of our
next) so far. You can find it at
https://github.com/mjg/git/tree/remerge-diff
if you're interested. I don't know what problems were found back then,
or what it would take to get this in-tree now.
Michael
^ permalink raw reply
* Bug: "git worktree add" Unable to checkout a branch with no local ref
From: Alexander Grigoriev @ 2017-02-27 14:22 UTC (permalink / raw)
To: git
git version 2.10.2.windows.1:
If a remote branch has never been checked out locally (its ref only exists
in remotes/<remote>/ directory), "git worktree add" command is unable to
check it out by its normal short name (not prefixed by remotes/<remote>),
while "git checkout" command has been able to handle such a branch and
properly convert it to a local branch.
^ permalink raw reply
* Re: Why BLAKE2?
From: Markus Trippelsdorf @ 2017-02-27 14:37 UTC (permalink / raw)
To: Ian Jackson
Cc: Jeff King, Ævar Arnfjörð Bjarmason, Linus Torvalds,
brian m. carlson, Jason Cooper, ankostis, Junio C Hamano,
Git Mailing List, Stefan Beller, David Lang, Joey Hess
In-Reply-To: <22708.8913.864049.452252@chiark.greenend.org.uk>
On 2017.02.27 at 13:00 +0000, Ian Jackson wrote:
>
> For brevity I will write `SHA' for hashing with SHA-1, using current
> unqualified object names, and `BLAKE' for hasing with BLAKE2b, using
> H<hex> object names.
Why do you choose BLAKE2? SHA-2 is generally considered still fine and
would be the obvious choice. And if you want to be adventurous then
SHA-3 (Keccak) would be the next logical candidate.
--
Markus
^ permalink raw reply
* Re: [PATCH 4/4] ident: do not ignore empty config name/email
From: Dennis Kaarsemaker @ 2017-02-27 15:08 UTC (permalink / raw)
To: Jeff King, Junio C Hamano; +Cc: bs.x.ttp, git
In-Reply-To: <20170224041807.5g3yogfnsoqegqkl@sigill.intra.peff.net>
On Thu, 2017-02-23 at 23:18 -0500, Jeff King wrote:
> On Thu, Feb 23, 2017 at 08:11:11PM -0800, Junio C Hamano wrote:
>
> > > So I dunno. I could really go either way on it. Feel free to drop it, or
> > > even move it into a separate topic to be cooked longer.
> >
> > If it were 5 years ago, it would have been different, but I do not
> > think cooking it longer in 'next' would smoke out breakages in
> > obscure scripts any longer. Git is used by too many people who have
> > never seen its source these days.
>
> Yeah, I have noticed that, too. I wonder if it would be interesting to
> cut "weeklies" or something of "master" or even "next" that people could
> install with a single click.
>
> Of course it's not like we have a binary installer in the first place,
> so I guess that's a prerequisite.
I provide daily[*] snapshots of git's master and next tree as packages
for Ubuntu, Debian, Fedora and CentOS on launchpad and SuSE's
openbuildservice. If there's sufficient interest in this (I know of
only a few users), I can try to put more effort into this.
--
Dennis Kaarsemaker
http://www.kaarsemaker.net
[*]When the tooling isn't broken for some reason.
^ permalink raw reply
* Re: Why BLAKE2?
From: Ian Jackson @ 2017-02-27 15:42 UTC (permalink / raw)
To: Markus Trippelsdorf
Cc: Jeff King, Ævar Arnfjörð Bjarmason, Linus Torvalds,
brian m. carlson, Jason Cooper, ankostis, Junio C Hamano,
Git Mailing List, Stefan Beller, David Lang, Joey Hess
In-Reply-To: <20170227143747.GB297@x4>
Markus Trippelsdorf writes ("Re: Why BLAKE2?"):
> On 2017.02.27 at 13:00 +0000, Ian Jackson wrote:
> > For brevity I will write `SHA' for hashing with SHA-1, using current
> > unqualified object names, and `BLAKE' for hasing with BLAKE2b, using
> > H<hex> object names.
>
> Why do you choose BLAKE2? SHA-2 is generally considered still fine and
> would be the obvious choice. And if you want to be adventurous then
> SHA-3 (Keccak) would be the next logical candidate.
I don't have a strong opinion. Keccak would be fine too.
We should probably avoid SHA-2.
The main point of my posting was not to argue in favour of a
particular hash function :-).
Ian.
--
Ian Jackson <ijackson@chiark.greenend.org.uk> These opinions are my own.
If I emailed you from an address @fyvzl.net or @evade.org.uk, that is
a private address which bypasses my fierce spamfilter.
^ permalink raw reply
* Re: [ANNOUNCE] Git v2.12.0
From: Ævar Arnfjörð Bjarmason @ 2017-02-27 16:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List, Linux Kernel
In-Reply-To: <xmqqd1e72xs5.fsf@gitster.mtv.corp.google.com>
On Fri, Feb 24, 2017 at 8:28 PM, Junio C Hamano <gitster@pobox.com> wrote:
> The latest feature release Git v2.12.0 is now available at the
> usual places. It is comprised of 517 non-merge commits since
> v2.11.0, contributed by 80 people, 24 of which are new faces.
Yay, some explanations / notes / elaborations:
> * "git diff" learned diff.interHunkContext configuration variable
> that gives the default value for its --inter-hunk-context option.
This is really cool. Now if you have e.g. lots of changed lines each
10 lines apart --inter-hunk-context=10 will show those all as one big
hunk, instead of needing to specify -U10 as you had to before, which
would give all hunks a context of 10 lines.
> * An ancient repository conversion tool left in contrib/ has been
> removed.
I thought "what tool?" so here's what this is. git.git was born on
April 7, 2005. For the first 13 days we'd hash the contents of
*compressed* blobs, not their uncompressed contents. Linus changed
this in: https://github.com/git/git/commit/d98b46f8d9
This tool was the ancient tool to convert these old incompatible
repositories from the old format. If someone hasn't gotten around to
this since 2005 they probably aren't ever going to do it :)
> * Some people feel the default set of colors used by "git log --graph"
> rather limiting. A mechanism to customize the set of colors has
> been introduced.
This is controlled via the log.graphColors variable. E.g.:
git -c log.graphColors="red, green, yellow" log --graph HEAD~100..
Does anyone have a prettier invocation?
> * "git diff" and its family had two experimental heuristics to shift
> the contents of a hunk to make the patch easier to read. One of
> them turns out to be better than the other, so leave only the
> "--indent-heuristic" option and remove the other one.
... the other one being --compaction-heuristic.
^ permalink raw reply
* Re: [PATCH] gitweb tests: Skip tests when we don't have Time::HiRes
From: Jakub Narębski @ 2017-02-27 17:48 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason, git; +Cc: Junio C Hamano
In-Reply-To: <20170227123720.8493-1-avarab@gmail.com>
W dniu 27.02.2017 o 13:37, Ævar Arnfjörð Bjarmason pisze:
> Change the gitweb tests to skip when we can't load the Time::HiRes
> module.
Could you tell us in the commit message why this module is needed?
Is it because gitweb loads it unconditionally, or does that at least
in the default configuration, or is it used in tests, or...?
[I see it is somewhat addressed below]
>
> This module has bee in perl core since v5.8, which is the oldest
s/bee/been/
> version we support, however CentOS (and perhaps some other
> distributions) carve it into its own non-core-perl package that's not
> installed along with /usr/bin/perl by default. Without this we'll hard
> fail the gitweb tests when trying to load the module.
I see that it because gitweb.perl as the following at line 20:
use Time::HiRes qw(gettimeofday tv_interval);
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Good catch (if a strange one...).
> ---
> t/gitweb-lib.sh | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh
> index d5dab5a94f..116c3890e6 100644
> --- a/t/gitweb-lib.sh
> +++ b/t/gitweb-lib.sh
> @@ -114,4 +114,9 @@ perl -MCGI -MCGI::Util -MCGI::Carp -e 0 >/dev/null 2>&1 || {
> test_done
> }
>
> +perl -mTime::HiRes -e 0 >/dev/null 2>&1 || {
> + skip_all='skipping gitweb tests, Time::HiRes module unusable'
Is "unusable" a good description, instead of "not found"?
> + test_done
> +}
> +
> gitweb_init
>
^ permalink raw reply
* [PATCH v4 01/22] config: mark an error message up for translation
From: Christian Couder @ 2017-02-27 17:59 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
config.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/config.c b/config.c
index c6b874a7bf..2ac1aa19b0 100644
--- a/config.c
+++ b/config.c
@@ -1728,8 +1728,8 @@ int git_config_get_untracked_cache(void)
if (!strcasecmp(v, "keep"))
return -1;
- error("unknown core.untrackedCache value '%s'; "
- "using 'keep' default value", v);
+ error(_("unknown core.untrackedCache value '%s'; "
+ "using 'keep' default value"), v);
return -1;
}
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 04/22] split-index: add {add,remove}_split_index() functions
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Also use the functions in cmd_update_index() in
builtin/update-index.c.
These functions will be used in a following commit to tweak
our use of the split-index feature depending on the setting
of a configuration variable.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin/update-index.c | 18 ++++++------------
split-index.c | 22 ++++++++++++++++++++++
split-index.h | 2 ++
3 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/builtin/update-index.c b/builtin/update-index.c
index d530e89368..24fdadfa4b 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -1099,18 +1099,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
}
if (split_index > 0) {
- init_split_index(&the_index);
- the_index.cache_changed |= SPLIT_INDEX_ORDERED;
- } else if (!split_index && the_index.split_index) {
- /*
- * can't discard_split_index(&the_index); because that
- * will destroy split_index->base->cache[], which may
- * be shared with the_index.cache[]. So yeah we're
- * leaking a bit here.
- */
- the_index.split_index = NULL;
- the_index.cache_changed |= SOMETHING_CHANGED;
- }
+ if (the_index.split_index)
+ the_index.cache_changed |= SPLIT_INDEX_ORDERED;
+ else
+ add_split_index(&the_index);
+ } else if (!split_index)
+ remove_split_index(&the_index);
switch (untracked_cache) {
case UC_UNSPECIFIED:
diff --git a/split-index.c b/split-index.c
index 615f4cac05..f519e60f87 100644
--- a/split-index.c
+++ b/split-index.c
@@ -317,3 +317,25 @@ void replace_index_entry_in_base(struct index_state *istate,
istate->split_index->base->cache[new->index - 1] = new;
}
}
+
+void add_split_index(struct index_state *istate)
+{
+ if (!istate->split_index) {
+ init_split_index(istate);
+ istate->cache_changed |= SPLIT_INDEX_ORDERED;
+ }
+}
+
+void remove_split_index(struct index_state *istate)
+{
+ if (istate->split_index) {
+ /*
+ * can't discard_split_index(&the_index); because that
+ * will destroy split_index->base->cache[], which may
+ * be shared with the_index.cache[]. So yeah we're
+ * leaking a bit here.
+ */
+ istate->split_index = NULL;
+ istate->cache_changed |= SOMETHING_CHANGED;
+ }
+}
diff --git a/split-index.h b/split-index.h
index c1324f521a..df91c1bda8 100644
--- a/split-index.h
+++ b/split-index.h
@@ -31,5 +31,7 @@ void merge_base_index(struct index_state *istate);
void prepare_to_write_split_index(struct index_state *istate);
void finish_writing_split_index(struct index_state *istate);
void discard_split_index(struct index_state *istate);
+void add_split_index(struct index_state *istate);
+void remove_split_index(struct index_state *istate);
#endif
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 03/22] config: add git_config_get_split_index()
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This new function will be used in a following commit to know
if we want to use the split index feature or not.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
cache.h | 1 +
config.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/cache.h b/cache.h
index 61fc86e6d7..014aa7ea11 100644
--- a/cache.h
+++ b/cache.h
@@ -1882,6 +1882,7 @@ extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);
extern int git_config_get_maybe_bool(const char *key, int *dest);
extern int git_config_get_pathname(const char *key, const char **dest);
extern int git_config_get_untracked_cache(void);
+extern int git_config_get_split_index(void);
/*
* This is a hack for test programs like test-dump-untracked-cache to
diff --git a/config.c b/config.c
index 2ac1aa19b0..2a97696be7 100644
--- a/config.c
+++ b/config.c
@@ -1736,6 +1736,16 @@ int git_config_get_untracked_cache(void)
return -1; /* default value */
}
+int git_config_get_split_index(void)
+{
+ int val;
+
+ if (!git_config_get_maybe_bool("core.splitindex", &val))
+ return val;
+
+ return -1; /* default value */
+}
+
NORETURN
void git_die_config_linenr(const char *key, const char *filename, int linenr)
{
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 10/22] config: add git_config_get_max_percent_split_change()
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This new function will be used in a following commit to get the
value of the "splitIndex.maxPercentChange" config variable.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
cache.h | 1 +
config.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/cache.h b/cache.h
index 014aa7ea11..955e80913e 100644
--- a/cache.h
+++ b/cache.h
@@ -1883,6 +1883,7 @@ extern int git_config_get_maybe_bool(const char *key, int *dest);
extern int git_config_get_pathname(const char *key, const char **dest);
extern int git_config_get_untracked_cache(void);
extern int git_config_get_split_index(void);
+extern int git_config_get_max_percent_split_change(void);
/*
* This is a hack for test programs like test-dump-untracked-cache to
diff --git a/config.c b/config.c
index 2a97696be7..35b6f02960 100644
--- a/config.c
+++ b/config.c
@@ -1746,6 +1746,21 @@ int git_config_get_split_index(void)
return -1; /* default value */
}
+int git_config_get_max_percent_split_change(void)
+{
+ int val = -1;
+
+ if (!git_config_get_int("splitindex.maxpercentchange", &val)) {
+ if (0 <= val && val <= 100)
+ return val;
+
+ return error(_("splitIndex.maxPercentChange value '%d' "
+ "should be between 0 and 100"), val);
+ }
+
+ return -1; /* default value */
+}
+
NORETURN
void git_die_config_linenr(const char *key, const char *filename, int linenr)
{
--
2.12.0.22.g0672473d40
^ 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