* Re: GIT get corrupted on lustre
From: Eric Chamberland @ 2013-01-17 16:30 UTC (permalink / raw)
To: Philippe Vaucher
Cc: git@vger.kernel.org, Maxime Boissonneault,
Sébastien Boisvert
In-Reply-To: <CAGK7Mr4R=OwfWt4Kat75C8YDi3iLTavMLxeoLxkf1-gKhxrucg@mail.gmail.com>
On 01/17/2013 09:23 AM, Philippe Vaucher wrote:
>> Anyone has a new idea?
>
> Did you try Jeff King's code to confirm his idea?
>
> Philippe
>
Yes I did, but it was running without any problem....
I find that my test case is "simple" (fresh git clone then "git gc" in a
crontab), I bet anyone who has access to a Lustre filesystem can
reproduce the problem... The problem is to have such a filesystem to do
the tests....
But I am available to do it...
Thanks,
Eric
^ permalink raw reply
* RE: GIT get corrupted on lustre
From: Pyeron, Jason J CTR (US) @ 2013-01-17 16:40 UTC (permalink / raw)
To: Eric Chamberland, Philippe Vaucher
Cc: git@vger.kernel.org, Maxime Boissonneault,
Sébastien Boisvert
In-Reply-To: <50F8273E.5050803@giref.ulaval.ca>
[-- Attachment #1: Type: text/plain, Size: 728 bytes --]
> -----Original Message-----
> From: Eric Chamberland
> Sent: Thursday, January 17, 2013 11:31 AM
>
> On 01/17/2013 09:23 AM, Philippe Vaucher wrote:
> >> Anyone has a new idea?
> >
> > Did you try Jeff King's code to confirm his idea?
> >
> > Philippe
> >
>
> Yes I did, but it was running without any problem....
>
> I find that my test case is "simple" (fresh git clone then "git gc" in
> a
> crontab), I bet anyone who has access to a Lustre filesystem can
> reproduce the problem... The problem is to have such a filesystem to
> do
> the tests....
Stabbing in the dark, but can you log the details with ProcessMon?
http://technet.microsoft.com/en-us/sysinternals/bb896645
>
> But I am available to do it...
-Jason
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5615 bytes --]
^ permalink raw reply
* Re: GIT get corrupted on lustre
From: Maxime Boissonneault @ 2013-01-17 16:41 UTC (permalink / raw)
To: Pyeron, Jason J CTR (US)
Cc: Eric Chamberland, Philippe Vaucher, git@vger.kernel.org,
Sébastien Boisvert
In-Reply-To: <871B6C10EBEFE342A772D1159D1320853A042AD7@umechphj.easf.csd.disa.mil>
I don't know of any lustre filesystem that is used on Windows. Barely
anybody uses Windows in the HPC industry.
This is a Linux cluster.
Maxime Boissonneault
Le 2013-01-17 11:40, Pyeron, Jason J CTR (US) a écrit :
>> -----Original Message-----
>> From: Eric Chamberland
>> Sent: Thursday, January 17, 2013 11:31 AM
>>
>> On 01/17/2013 09:23 AM, Philippe Vaucher wrote:
>>>> Anyone has a new idea?
>>> Did you try Jeff King's code to confirm his idea?
>>>
>>> Philippe
>>>
>> Yes I did, but it was running without any problem....
>>
>> I find that my test case is "simple" (fresh git clone then "git gc" in
>> a
>> crontab), I bet anyone who has access to a Lustre filesystem can
>> reproduce the problem... The problem is to have such a filesystem to
>> do
>> the tests....
> Stabbing in the dark, but can you log the details with ProcessMon?
>
> http://technet.microsoft.com/en-us/sysinternals/bb896645
>
>> But I am available to do it...
> -Jason
--
---------------------------------
Maxime Boissonneault
Analyste de calcul - Calcul Québec, Université Laval
Ph. D. en physique
^ permalink raw reply
* Re: [PATCH 2/2] fix clang -Wtautological-compare with unsigned enum
From: Linus Torvalds @ 2013-01-17 16:44 UTC (permalink / raw)
To: John Keeping
Cc: Antoine Pelisse, Max Horn, git, Johannes Sixt, Junio C Hamano
In-Reply-To: <20130117110008.GD4574@serenity.lan>
On Thu, Jan 17, 2013 at 3:00 AM, John Keeping <john@keeping.me.uk> wrote:
>
> There's also a warning that triggers with clang 3.2 but not clang trunk, which
> I think is a legitimate warning - perhaps someone who understands integer type
> promotion better than me can explain why the code is OK (patch->score is
> declared as 'int'):
>
> builtin/apply.c:1044:47: warning: comparison of constant 18446744073709551615
> with expression of type 'int' is always false
> [-Wtautological-constant-out-of-range-compare]
> if ((patch->score = strtoul(line, NULL, 10)) == ULONG_MAX)
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
The warning seems to be very very wrong, and implies that clang has
some nasty bug in it.
Since patch->score is 'int', and UNLONG_MAX is 'unsigned long', the
conversion rules for the comparison is that the int result from the
assignment is cast to unsigned long. And if you cast (int)-1 to
unsigned long, you *do* get ULONG_MAX. That's true regardless of
whether "long" has the same number of bits as "int" or is bigger. The
implicit cast will be done as a sign-extension (unsigned long is not
signed, but the source type of 'int' *is* signed, and that is what
determines the sign extension on casting).
So the "is always false" is pure and utter crap. clang is wrong, and
it is wrong in a way that implies that it actually generates incorrect
code. It may well be worth making a clang bug report about this.
That said, clang is certainly understandably confused. The code
depends on subtle conversion rules and bit patterns, and is clearly
very confusingly written.
So it would probably be good to rewrite it as
unsigned long val = strtoul(line, NULL, 10);
if (val == ULONG_MAX) ..
patch->score = val;
instead. At which point you might as well make the comparison be ">=
INT_MAX" instead, since anything bigger than that is going to be
bogus.
So the git code is probably worth cleaning up, but for git it would be
a cleanup. For clang, this implies a major bug and bad code
generation.
Linus
Linus
^ permalink raw reply
* Re: [PATCH 2/2] fix clang -Wtautological-compare with unsigned enum
From: Antoine Pelisse @ 2013-01-17 16:56 UTC (permalink / raw)
To: John Keeping, Linus Torvalds; +Cc: Max Horn, git, Johannes Sixt, Junio C Hamano
In-Reply-To: <CA+55aFxYSX2iYPSafKdCDSfWSMfQxP3R3Hqh8GuiiR6EbWfk3w@mail.gmail.com>
BTW, I think it has been addressed [1] by clang already and that would
explain why you don't have the warning when using clang trunk version.
[1]: http://llvm-reviews.chandlerc.com/D113
Antoine,
On Thu, Jan 17, 2013 at 5:44 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Thu, Jan 17, 2013 at 3:00 AM, John Keeping <john@keeping.me.uk> wrote:
>>
>> There's also a warning that triggers with clang 3.2 but not clang trunk, which
>> I think is a legitimate warning - perhaps someone who understands integer type
>> promotion better than me can explain why the code is OK (patch->score is
>> declared as 'int'):
>>
>> builtin/apply.c:1044:47: warning: comparison of constant 18446744073709551615
>> with expression of type 'int' is always false
>> [-Wtautological-constant-out-of-range-compare]
>> if ((patch->score = strtoul(line, NULL, 10)) == ULONG_MAX)
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
>
> The warning seems to be very very wrong, and implies that clang has
> some nasty bug in it.
>
> Since patch->score is 'int', and UNLONG_MAX is 'unsigned long', the
> conversion rules for the comparison is that the int result from the
> assignment is cast to unsigned long. And if you cast (int)-1 to
> unsigned long, you *do* get ULONG_MAX. That's true regardless of
> whether "long" has the same number of bits as "int" or is bigger. The
> implicit cast will be done as a sign-extension (unsigned long is not
> signed, but the source type of 'int' *is* signed, and that is what
> determines the sign extension on casting).
>
> So the "is always false" is pure and utter crap. clang is wrong, and
> it is wrong in a way that implies that it actually generates incorrect
> code. It may well be worth making a clang bug report about this.
>
> That said, clang is certainly understandably confused. The code
> depends on subtle conversion rules and bit patterns, and is clearly
> very confusingly written.
>
> So it would probably be good to rewrite it as
>
> unsigned long val = strtoul(line, NULL, 10);
> if (val == ULONG_MAX) ..
> patch->score = val;
>
> instead. At which point you might as well make the comparison be ">=
> INT_MAX" instead, since anything bigger than that is going to be
> bogus.
>
> So the git code is probably worth cleaning up, but for git it would be
> a cleanup. For clang, this implies a major bug and bad code
> generation.
>
> Linus
> Linus
^ permalink raw reply
* Re: [PATCH 2/2] fix clang -Wtautological-compare with unsigned enum
From: John Keeping @ 2013-01-17 17:02 UTC (permalink / raw)
To: Linus Torvalds
Cc: Antoine Pelisse, Max Horn, git, Johannes Sixt, Junio C Hamano
In-Reply-To: <CA+55aFxYSX2iYPSafKdCDSfWSMfQxP3R3Hqh8GuiiR6EbWfk3w@mail.gmail.com>
On Thu, Jan 17, 2013 at 08:44:20AM -0800, Linus Torvalds wrote:
> On Thu, Jan 17, 2013 at 3:00 AM, John Keeping <john@keeping.me.uk> wrote:
>>
>> There's also a warning that triggers with clang 3.2 but not clang trunk, which
>> I think is a legitimate warning - perhaps someone who understands integer type
>> promotion better than me can explain why the code is OK (patch->score is
>> declared as 'int'):
>>
>> builtin/apply.c:1044:47: warning: comparison of constant 18446744073709551615
>> with expression of type 'int' is always false
>> [-Wtautological-constant-out-of-range-compare]
>> if ((patch->score = strtoul(line, NULL, 10)) == ULONG_MAX)
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
>
> The warning seems to be very very wrong, and implies that clang has
> some nasty bug in it.
>
> Since patch->score is 'int', and UNLONG_MAX is 'unsigned long', the
> conversion rules for the comparison is that the int result from the
> assignment is cast to unsigned long. And if you cast (int)-1 to
> unsigned long, you *do* get ULONG_MAX. That's true regardless of
> whether "long" has the same number of bits as "int" or is bigger. The
> implicit cast will be done as a sign-extension (unsigned long is not
> signed, but the source type of 'int' *is* signed, and that is what
> determines the sign extension on casting).
>
> So the "is always false" is pure and utter crap. clang is wrong, and
> it is wrong in a way that implies that it actually generates incorrect
> code. It may well be worth making a clang bug report about this.
The warning doesn't occur with a build from their trunk so it looks like
it's already fixed - it just won't make into into a release for about 5
months going by their timeline.
Thanks for the clear explanation.
^ permalink raw reply
* RE: GIT get corrupted on lustre
From: Pyeron, Jason J CTR (US) @ 2013-01-17 17:17 UTC (permalink / raw)
To: Maxime Boissonneault
Cc: Eric Chamberland, Philippe Vaucher, git@vger.kernel.org,
Sébastien Boisvert
In-Reply-To: <50F829A9.7090606@calculquebec.ca>
[-- Attachment #1: Type: text/plain, Size: 1843 bytes --]
Sorry, I am in cygwin mode, and I had crossed wires in my head. s/ProcessMon/strace/
> -----Original Message-----
> From: git-owner@vger.kernel.org [mailto:git-owner@vger.kernel.org] On
> Behalf Of Maxime Boissonneault
> Sent: Thursday, January 17, 2013 11:41 AM
> To: Pyeron, Jason J CTR (US)
> Cc: Eric Chamberland; Philippe Vaucher; git@vger.kernel.org; Sébastien
> Boisvert
> Subject: Re: GIT get corrupted on lustre
>
> I don't know of any lustre filesystem that is used on Windows. Barely
> anybody uses Windows in the HPC industry.
> This is a Linux cluster.
>
> Maxime Boissonneault
>
> Le 2013-01-17 11:40, Pyeron, Jason J CTR (US) a écrit :
> >> -----Original Message-----
> >> From: Eric Chamberland
> >> Sent: Thursday, January 17, 2013 11:31 AM
> >>
> >> On 01/17/2013 09:23 AM, Philippe Vaucher wrote:
> >>>> Anyone has a new idea?
> >>> Did you try Jeff King's code to confirm his idea?
> >>>
> >>> Philippe
> >>>
> >> Yes I did, but it was running without any problem....
> >>
> >> I find that my test case is "simple" (fresh git clone then "git gc"
> in
> >> a
> >> crontab), I bet anyone who has access to a Lustre filesystem can
> >> reproduce the problem... The problem is to have such a filesystem
> to
> >> do
> >> the tests....
> > Stabbing in the dark, but can you log the details with ProcessMon?
> >
> > http://technet.microsoft.com/en-us/sysinternals/bb896645
> >
> >> But I am available to do it...
> > -Jason
>
>
> --
> ---------------------------------
> Maxime Boissonneault
> Analyste de calcul - Calcul Québec, Université Laval
> Ph. D. en physique
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5615 bytes --]
^ permalink raw reply
* [PATCH v2 0/8] Initial Python 3 support
From: John Keeping @ 2013-01-17 18:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358018078.git.john@keeping.me.uk>
This series does enough so that everything except git-p4 runs under
Python 3.
As discussed with Pete, it may not make sense to change git-p4 to
support Python 3 until Perforce's Python output mode is changed. So
does it make sense to merge this now and say "use Python 2 if you want
git-p4"?
Changes since v1:
* rebased on master after fc/remote-testgit-feature-done was merged,
leading to an extra change in patch 8 (git-remote-testpy: call print
as a function)
* changed patch 2 (git_remote_helpers: fix input when running under
Python 3) to treat ref names as byte strings
John Keeping (8):
git_remote_helpers: Allow building with Python 3
git_remote_helpers: fix input when running under Python 3
git_remote_helpers: Force rebuild if python version changes
git_remote_helpers: Use 2to3 if building with Python 3
svn-fe: allow svnrdump_sim.py to run with Python 3
git-remote-testpy: hash bytes explicitly
git-remote-testpy: don't do unbuffered text I/O
git-remote-testpy: call print as a function
contrib/svn-fe/svnrdump_sim.py | 4 ++--
git-remote-testpy.py | 42 +++++++++++++++++++-------------------
git_remote_helpers/.gitignore | 1 +
git_remote_helpers/Makefile | 10 +++++++--
git_remote_helpers/git/importer.py | 9 +++++---
git_remote_helpers/setup.py | 10 +++++++++
6 files changed, 48 insertions(+), 28 deletions(-)
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply
* [PATCH v2 1/8] git_remote_helpers: allow building with Python 3
From: John Keeping @ 2013-01-17 18:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
Change inline Python to call "print" as a function not a statement.
This is harmless because Python 2 will see the parentheses as redundant
grouping but they are necessary to run this code with Python 3.
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git_remote_helpers/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile
index 74b05dc..f65f064 100644
--- a/git_remote_helpers/Makefile
+++ b/git_remote_helpers/Makefile
@@ -23,7 +23,7 @@ endif
PYLIBDIR=$(shell $(PYTHON_PATH) -c \
"import sys; \
- print 'lib/python%i.%i/site-packages' % sys.version_info[:2]")
+ print('lib/python%i.%i/site-packages' % sys.version_info[:2])")
all: $(pysetupfile)
$(QUIET)$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* [PATCH v2 2/8] git_remote_helpers: fix input when running under Python 3
From: John Keeping @ 2013-01-17 18:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
Although 2to3 will fix most issues in Python 2 code to make it run under
Python 3, it does not handle the new strict separation between byte
strings and unicode strings. There is one instance in
git_remote_helpers where we are caught by this, which is when reading
refs from "git for-each-ref".
Fix this by operating on the returned string as a byte string rather
than a unicode string. As this method is currently only used internally
by the class this does not affect code anywhere else.
Note that we cannot use byte strings in the source as the 'b' prefix is
not supported before Python 2.7 so in order to maintain compatibility
with the maximum range of Python versions we use an explicit call to
encode().
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git_remote_helpers/git/importer.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/git_remote_helpers/git/importer.py b/git_remote_helpers/git/importer.py
index e28cc8f..d3f90e1 100644
--- a/git_remote_helpers/git/importer.py
+++ b/git_remote_helpers/git/importer.py
@@ -18,13 +18,16 @@ class GitImporter(object):
def get_refs(self, gitdir):
"""Returns a dictionary with refs.
+
+ Note that the keys in the returned dictionary are byte strings as
+ read from git.
"""
args = ["git", "--git-dir=" + gitdir, "for-each-ref", "refs/heads"]
- lines = check_output(args).strip().split('\n')
+ lines = check_output(args).strip().split('\n'.encode('ascii'))
refs = {}
for line in lines:
- value, name = line.split(' ')
- name = name.strip('commit\t')
+ value, name = line.split(' '.encode('ascii'))
+ name = name.strip('commit\t'.encode('ascii'))
refs[name] = value
return refs
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* [PATCH v2 3/8] git_remote_helpers: force rebuild if python version changes
From: John Keeping @ 2013-01-17 18:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
When different version of python are used to build via distutils, the
behaviour can change. Detect changes in version and pass --force in
this case.
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git_remote_helpers/.gitignore | 1 +
git_remote_helpers/Makefile | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/git_remote_helpers/.gitignore b/git_remote_helpers/.gitignore
index 2247d5f..06c664f 100644
--- a/git_remote_helpers/.gitignore
+++ b/git_remote_helpers/.gitignore
@@ -1,2 +1,3 @@
+/GIT-PYTHON_VERSION
/build
/dist
diff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile
index f65f064..91f458f 100644
--- a/git_remote_helpers/Makefile
+++ b/git_remote_helpers/Makefile
@@ -25,8 +25,14 @@ PYLIBDIR=$(shell $(PYTHON_PATH) -c \
"import sys; \
print('lib/python%i.%i/site-packages' % sys.version_info[:2])")
+py_version=$(shell $(PYTHON_PATH) -c \
+ 'import sys; print("%i.%i" % sys.version_info[:2])')
+
all: $(pysetupfile)
- $(QUIET)$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build
+ $(QUIET)test "$$(cat GIT-PYTHON_VERSION 2>/dev/null)" = "$(py_version)" || \
+ flags=--force; \
+ $(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build $$flags
+ $(QUIET)echo "$(py_version)" >GIT-PYTHON_VERSION
install: $(pysetupfile)
$(PYTHON_PATH) $(pysetupfile) install --prefix $(DESTDIR_SQ)$(prefix)
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* [PATCH v2 4/8] git_remote_helpers: use 2to3 if building with Python 3
From: John Keeping @ 2013-01-17 18:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
Using the approach detailed on the Python wiki[1], run 2to3 on the code
as part of the build if building with Python 3.
The code itself requires no changes to convert cleanly.
[1] http://wiki.python.org/moin/PortingPythonToPy3k
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git_remote_helpers/setup.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/git_remote_helpers/setup.py b/git_remote_helpers/setup.py
index 4d434b6..6de41de 100644
--- a/git_remote_helpers/setup.py
+++ b/git_remote_helpers/setup.py
@@ -4,6 +4,15 @@
from distutils.core import setup
+# If building under Python3 we need to run 2to3 on the code, do this by
+# trying to import distutils' 2to3 builder, which is only available in
+# Python3.
+try:
+ from distutils.command.build_py import build_py_2to3 as build_py
+except ImportError:
+ # 2.x
+ from distutils.command.build_py import build_py
+
setup(
name = 'git_remote_helpers',
version = '0.1.0',
@@ -14,4 +23,5 @@ setup(
url = 'http://www.git-scm.com/',
package_dir = {'git_remote_helpers': ''},
packages = ['git_remote_helpers', 'git_remote_helpers.git'],
+ cmdclass = {'build_py': build_py},
)
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* [PATCH v2 5/8] svn-fe: allow svnrdump_sim.py to run with Python 3
From: John Keeping @ 2013-01-17 18:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
The changes to allow this script to run with Python 3 are minimal and do
not affect its functionality on the versions of Python 2 that are
already supported (2.4 onwards).
Signed-off-by: John Keeping <john@keeping.me.uk>
---
contrib/svn-fe/svnrdump_sim.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/contrib/svn-fe/svnrdump_sim.py b/contrib/svn-fe/svnrdump_sim.py
index 17cf6f9..4e78a1c 100755
--- a/contrib/svn-fe/svnrdump_sim.py
+++ b/contrib/svn-fe/svnrdump_sim.py
@@ -14,7 +14,7 @@ if sys.hexversion < 0x02040000:
def getrevlimit():
var = 'SVNRMAX'
- if os.environ.has_key(var):
+ if var in os.environ:
return os.environ[var]
return None
@@ -44,7 +44,7 @@ def writedump(url, lower, upper):
if __name__ == "__main__":
if not (len(sys.argv) in (3, 4, 5)):
- print "usage: %s dump URL -rLOWER:UPPER"
+ print("usage: %s dump URL -rLOWER:UPPER")
sys.exit(1)
if not sys.argv[1] == 'dump': raise NotImplementedError('only "dump" is suppported.')
url = sys.argv[2]
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* [PATCH v2 6/8] git-remote-testpy: hash bytes explicitly
From: John Keeping @ 2013-01-17 18:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
Under Python 3 'hasher.update(...)' must take a byte string and not a
unicode string. Explicitly encode the argument to this method as UTF-8
so that this code works under Python 3.
This moves the required Python version forward to 2.0.
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git-remote-testpy.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/git-remote-testpy.py b/git-remote-testpy.py
index d94a66a..f8dc196 100644
--- a/git-remote-testpy.py
+++ b/git-remote-testpy.py
@@ -31,9 +31,9 @@ from git_remote_helpers.git.exporter import GitExporter
from git_remote_helpers.git.importer import GitImporter
from git_remote_helpers.git.non_local import NonLocalGit
-if sys.hexversion < 0x01050200:
- # os.makedirs() is the limiter
- sys.stderr.write("git-remote-testgit: requires Python 1.5.2 or later.\n")
+if sys.hexversion < 0x02000000:
+ # string.encode() is the limiter
+ sys.stderr.write("git-remote-testgit: requires Python 2.0 or later.\n")
sys.exit(1)
def get_repo(alias, url):
@@ -45,7 +45,7 @@ def get_repo(alias, url):
repo.get_head()
hasher = _digest()
- hasher.update(repo.path)
+ hasher.update(repo.path.encode('utf-8'))
repo.hash = hasher.hexdigest()
repo.get_base_path = lambda base: os.path.join(
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* [PATCH v2 7/8] git-remote-testpy: don't do unbuffered text I/O
From: John Keeping @ 2013-01-17 18:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
Python 3 forbids unbuffered I/O in text mode. Change the reading of
stdin in git-remote-testpy so that we read the lines as bytes and then
decode them a line at a time.
This allows us to keep the I/O unbuffered in order to avoid
reintroducing the bug fixed by commit 7fb8e16 (git-remote-testgit: fix
race when spawning fast-import).
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git-remote-testpy.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/git-remote-testpy.py b/git-remote-testpy.py
index f8dc196..bc5e3cf 100644
--- a/git-remote-testpy.py
+++ b/git-remote-testpy.py
@@ -154,7 +154,7 @@ def do_import(repo, args):
refs = [ref]
while True:
- line = sys.stdin.readline()
+ line = sys.stdin.readline().decode()
if line == '\n':
break
if not line.startswith('import '):
@@ -225,7 +225,7 @@ def read_one_line(repo):
line = sys.stdin.readline()
- cmdline = line
+ cmdline = line.decode()
if not cmdline:
warn("Unexpected EOF")
@@ -277,7 +277,7 @@ def main(args):
more = True
- sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0)
+ sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)
while (more):
more = read_one_line(repo)
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* [PATCH v2 8/8] git-remote-testpy: call print as a function
From: John Keeping @ 2013-01-17 18:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Keeping, Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <cover.1358448207.git.john@keeping.me.uk>
This is harmless in Python 2, which sees the parentheses as redundant
grouping, but is required for Python 3. Since this is the only change
required to make this script just run under Python 3 without needing
2to3 it seems worthwhile.
The case of an empty print must be handled specially because in that
case Python 2 will interpret '()' as an empty tuple and print it as
'()'; inserting an empty string fixes this.
Signed-off-by: John Keeping <john@keeping.me.uk>
---
git-remote-testpy.py | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/git-remote-testpy.py b/git-remote-testpy.py
index bc5e3cf..ccdb2dc 100644
--- a/git-remote-testpy.py
+++ b/git-remote-testpy.py
@@ -87,9 +87,9 @@ def do_capabilities(repo, args):
"""Prints the supported capabilities.
"""
- print "import"
- print "export"
- print "refspec refs/heads/*:%s*" % repo.prefix
+ print("import")
+ print("export")
+ print("refspec refs/heads/*:%s*" % repo.prefix)
dirname = repo.get_base_path(repo.gitdir)
@@ -98,11 +98,11 @@ def do_capabilities(repo, args):
path = os.path.join(dirname, 'git.marks')
- print "*export-marks %s" % path
+ print("*export-marks %s" % path)
if os.path.exists(path):
- print "*import-marks %s" % path
+ print("*import-marks %s" % path)
- print # end capabilities
+ print('') # end capabilities
def do_list(repo, args):
@@ -115,16 +115,16 @@ def do_list(repo, args):
for ref in repo.revs:
debug("? refs/heads/%s", ref)
- print "? refs/heads/%s" % ref
+ print("? refs/heads/%s" % ref)
if repo.head:
debug("@refs/heads/%s HEAD" % repo.head)
- print "@refs/heads/%s HEAD" % repo.head
+ print("@refs/heads/%s HEAD" % repo.head)
else:
debug("@refs/heads/master HEAD")
- print "@refs/heads/master HEAD"
+ print("@refs/heads/master HEAD")
- print # end list
+ print('') # end list
def update_local_repo(repo):
@@ -164,7 +164,7 @@ def do_import(repo, args):
ref = line[7:].strip()
refs.append(ref)
- print "feature done"
+ print("feature done")
if os.environ.get("GIT_REMOTE_TESTGIT_FAILURE"):
die('Told to fail')
@@ -172,7 +172,7 @@ def do_import(repo, args):
repo = update_local_repo(repo)
repo.exporter.export_repo(repo.gitdir, refs)
- print "done"
+ print("done")
def do_export(repo, args):
@@ -192,8 +192,8 @@ def do_export(repo, args):
repo.non_local.push(repo.gitdir)
for ref in changed:
- print "ok %s" % ref
- print
+ print("ok %s" % ref)
+ print('')
COMMANDS = {
--
1.8.1.1.260.g99b33f4.dirty
^ permalink raw reply related
* Re: [PATCH 2/3] Allow Git::get_tz_offset to properly handle DST boundary times
From: Junio C Hamano @ 2013-01-17 19:09 UTC (permalink / raw)
To: Ben Walton; +Cc: esr, git
In-Reply-To: <1358291405-10173-3-git-send-email-bdwalton@gmail.com>
Ben Walton <bdwalton@gmail.com> writes:
> The Git::get_tz_offset is meant to provide a workalike replacement for
> the GNU strftime %z format specifier. The algorithm used failed to
> properly handle DST boundary cases.
>
> For example, the unix time 1162105199 in CST6CDT saw set_tz_offset
> improperly return -0600 instead of -0500.
>
> TZ=CST6CDT date -d @1162105199 +"%c %z"
> Sun 29 Oct 2006 01:59:59 AM CDT -0500
>
> $ zdump -v /usr/share/zoneinfo/CST6CDT | grep 2006
> /usr/share/zoneinfo/CST6CDT Sun Apr 2 07:59:59 2006 UTC = Sun Apr 2
> 01:59:59 2006 CST isdst=0 gmtoff=-21600
> /usr/share/zoneinfo/CST6CDT Sun Apr 2 08:00:00 2006 UTC = Sun Apr 2
> 03:00:00 2006 CDT isdst=1 gmtoff=-18000
> /usr/share/zoneinfo/CST6CDT Sun Oct 29 06:59:59 2006 UTC = Sun Oct 29
> 01:59:59 2006 CDT isdst=1 gmtoff=-18000
> /usr/share/zoneinfo/CST6CDT Sun Oct 29 07:00:00 2006 UTC = Sun Oct 29
> 01:00:00 2006 CST isdst=0 gmtoff=-21600
>
> To determine how many hours/minutes away from GMT a particular time
> was, we calculated the gmtime() of the requested time value and then
> used Time::Local's timelocal() function to turn the GMT-based time
> back into a scalar value representing seconds from the epoch. Because
> GMT has no daylight savings time, timelocal() cannot handle the
> ambiguous times that occur at DST boundaries since there are two
> possible correct results.
>
> To work around the ambiguity at these boundaries, we must take into
> account the pre and post conversion values for is_dst as provided by
> both the original time value and the value that has been run through
> timelocal(). If the is_dst field of the two times disagree then we
> must modify the value returned from timelocal() by an hour in the
> correct direction.
It seems to me that it is a very roundabout way. It may be correct,
but it is unclear why the magic +/-3600 shift is the right solution
and I suspect even you wouldn't notice if I sent you back your patch
with a slight change to swap $gm += 3600 and $gm -= 3600 lines ;-).
For that timestamp in question, the human-readable representation of
gmtime($t) and localtime($t) look like these two strings:
my $t = 1162105199;
print gmtime($t), "\n"; # Sun Oct 29 06:59:59 2006
print localtime($t), "\n"; # Sun Oct 29 01:59:59 2006
As a human, you can easily see that these two stringified timestamps
look 5 hours apart. Think how you managed to do so.
If we convert these back to the seconds-since-epoch, as if these
broken-down times were both in a single timezone that does not have
any DST issues, you can get the offset (in seconds) by subtraction,
and that is essentially the same as the way in which your eyes saw
they are 5 hours apart, no? In other words, why do you need to run
timelocal() at all?
my $t = 1162105199;
my $lct = timegm(localtime($t));
# of course, timegm(gmtime($t)) == $t
my $minutes = int(($lct - $t)/60);
my $sign "+";
if ($minutes < 0) {
$sign = "-";
$minutes = -$minutes;
}
my $hours = int($minutes/60);
$minutes -= $hours * 60;
sprintf("%s%02d%02d", $sign, $hours, $minutes);
Confused...
>
> Signed-off-by: Ben Walton <bdwalton@gmail.com>
> ---
> perl/Git.pm | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/perl/Git.pm b/perl/Git.pm
> index 5649bcc..788b9b4 100644
> --- a/perl/Git.pm
> +++ b/perl/Git.pm
> @@ -528,7 +528,27 @@ If TIME is not supplied, the current local time is used.
> sub get_tz_offset {
> # some systmes don't handle or mishandle %z, so be creative.
> my $t = shift || time;
> + # timelocal() has a problem when it comes to DST ambiguity so
> + # times that are on a DST boundary cannot be properly converted
> + # using it. we will possibly adjust its result depending on whehter
> + # pre and post conversions agree on DST
> my $gm = timelocal(gmtime($t));
> +
> + # we need to know whether we were originally in DST or not
> + my $orig_dst = (localtime($t))[8];
> + # and also whether timelocal thinks we're in DST
> + my $conv_dst = (localtime($gm))[8];
> +
> + # re-adjust $gm based on the DST value for the two times we're
> + # handling.
> + if ($orig_dst != $conv_dst) {
> + if ($orig_dst == 1) {
> + $gm -= 3600;
> + } else {
> + $gm += 3600;
> + }
> + }
> +
> my $sign = qw( + + - )[ $t <=> $gm ];
> return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
> }
^ permalink raw reply
* Changing Spell checker under GIT
From: Mike Hall @ 2013-01-17 19:08 UTC (permalink / raw)
To: git@vger.kernel.org
As my organization has change from RedHat 5 to RedHat 6 Linux,
it appears that RedHat is trying to replace (deprecate) ispell/aspell
with a different tool (hunspell).
It appears that GIT GUI current supports changing the dictionary used
to support spell checks. Is there currently a way to change the
spell check program to be used(can't find in documentation or version
of code that I'm currently installing), or would someone consider this
as a future program change?
Thanks for your time.
Mike Hall
^ permalink raw reply
* git pull - reporting that I modified files, but I did not
From: Jay Vee @ 2013-01-17 19:29 UTC (permalink / raw)
To: git
When I do a git pull, I am getting a messages that changes to local
files would be overwritten by a merge, but I have not changed these
files locally at all, I have not opened them in my IDE.
This happens every now and then.
1) Why does this happen?
2) How do I prevent this from happening in the future?
3) How do I get out of this state so that I can do a git pull and
rebuild my code?
---
In other instances, when I do a git pull (not getting the message
above, I will see something like:
M src/MyClass.java <= a file that I did not touch or modify
D src/AnotherClass.java <= a file that I did not delete or touch
M src/MyModifiedClass.java <= a file that I indeed modified for
which in the pull there are no merge conflicts.
and the pull is successful, (then I want to push my changes), but I
did not change either of the above two files
If I see the above, am I OK to push? My thinking is that git thinks I
changed 'src/MyClass.java' and if I do a diff there are differences,
but I do not want to push because I NEVER TOUCHED THAT FILE IN ANY
WAY.
What is going on here? Maybe this is normal and I simply do not
understand correctly.
What is happening? I would expect to see only line items 'M' and 'D'
for files that I personally have modified and deleted.
If I push at this point, will I overwrite changes in the repo pushed
by others and muck things up?
thanks
J.V.
^ permalink raw reply
* Re: Changing Spell checker under GIT
From: Jonathan Nieder @ 2013-01-17 20:17 UTC (permalink / raw)
To: Mike Hall; +Cc: git@vger.kernel.org, Pat Thoyts
In-Reply-To: <189327E1D7E3B64286ED8625AAEC642C08633B01@MDHQEXCH01.enginsol.com>
Hi Mike,
Mike Hall wrote:
> As my organization has change from RedHat 5 to RedHat 6 Linux,
> it appears that RedHat is trying to replace (deprecate) ispell/aspell
> with a different tool (hunspell).
>
> It appears that GIT GUI current supports changing the dictionary used
> to support spell checks. Is there currently a way to change the
> spell check program to be used(can't find in documentation or version
> of code that I'm currently installing), or would someone consider this
> as a future program change?
git-gui uses the aspell command as a spellchecker. A patch to add
hunspell support sounds like it would be a nice addition. If you'd
like to work on it, then "lib/spellcheck.tcl" in
git://repo.or.cz/git-gui
might be a good place to start.
Hope that helps,
Jonathan
^ permalink raw reply
* Re: [PATCH v2 6/8] git-remote-testpy: hash bytes explicitly
From: Junio C Hamano @ 2013-01-17 20:36 UTC (permalink / raw)
To: John Keeping; +Cc: Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <66c42ff65eddde494f40d0a582e89a081b4ab8e8.1358448207.git.john@keeping.me.uk>
John Keeping <john@keeping.me.uk> writes:
> Under Python 3 'hasher.update(...)' must take a byte string and not a
> unicode string. Explicitly encode the argument to this method as UTF-8
> so that this code works under Python 3.
>
> This moves the required Python version forward to 2.0.
>
> Signed-off-by: John Keeping <john@keeping.me.uk>
> ---
Hmph. So what happens when the path is _not_ encoded in UTF-8?
Is the repo.hash (and local.hash that gets a copy of it) something
that needs to stay the same across multiple invocations of this
remote helper, and between the currently shipped Git and the version
of Git after applying this patch? If that is not the case, and if
this is used only to get a randomly-looking 40-byte hexadecimal
string, then a lossy attempt to .encode('utf-8') and falling back to
replace or ignore bytes in the original that couldn't be interpreted
as part of a UTF-8 string would be OK, but doesn't .encode('utf-8')
throw an exception if not told to 'ignore' or something?
> git-remote-testpy.py | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/git-remote-testpy.py b/git-remote-testpy.py
> index d94a66a..f8dc196 100644
> --- a/git-remote-testpy.py
> +++ b/git-remote-testpy.py
> @@ -31,9 +31,9 @@ from git_remote_helpers.git.exporter import GitExporter
> from git_remote_helpers.git.importer import GitImporter
> from git_remote_helpers.git.non_local import NonLocalGit
>
> -if sys.hexversion < 0x01050200:
> - # os.makedirs() is the limiter
> - sys.stderr.write("git-remote-testgit: requires Python 1.5.2 or later.\n")
> +if sys.hexversion < 0x02000000:
> + # string.encode() is the limiter
> + sys.stderr.write("git-remote-testgit: requires Python 2.0 or later.\n")
> sys.exit(1)
>
> def get_repo(alias, url):
> @@ -45,7 +45,7 @@ def get_repo(alias, url):
> repo.get_head()
>
> hasher = _digest()
> - hasher.update(repo.path)
> + hasher.update(repo.path.encode('utf-8'))
> repo.hash = hasher.hexdigest()
>
> repo.get_base_path = lambda base: os.path.join(
^ permalink raw reply
* Re: [PATCH v2 6/8] git-remote-testpy: hash bytes explicitly
From: Junio C Hamano @ 2013-01-17 20:43 UTC (permalink / raw)
To: John Keeping; +Cc: Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <7vtxqftulq.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> John Keeping <john@keeping.me.uk> writes:
>
>> Under Python 3 'hasher.update(...)' must take a byte string and not a
>> unicode string. Explicitly encode the argument to this method as UTF-8
>> so that this code works under Python 3.
>>
>> This moves the required Python version forward to 2.0.
>>
>> Signed-off-by: John Keeping <john@keeping.me.uk>
>> ---
>
> Hmph. So what happens when the path is _not_ encoded in UTF-8?
Oh, my brain was not working. Forget this part, and sorry for the
noise. We are not decoding a bytestring to an array of unicode
characters, but going the other way around here.
^ permalink raw reply
* Re: [PATCH] Add --unannotate option to git-subtree
From: James Nylen @ 2013-01-17 20:56 UTC (permalink / raw)
To: greened; +Cc: git
In-Reply-To: <87a9st4sb8.fsf@waller.obbligato.org>
On Mon, Dec 31, 2012 at 8:15 PM, <greened@obbligato.org> wrote:
> James Nylen <jnylen@gmail.com> writes:
>
>> Rather than adding a marker to each commit when splitting out the
>> commits back to the subproject, --unannotate removes the specified
>> string (or bash glob pattern) from the beginning of the first line of
>> the commit message. This enables the following workflow:
>
> I applied the patch to my working copy but it doesn't seem to do
> what I'd expect. The test script does something like this:
>
> - create project A
> - add file to project A with message "subproj: add F1"
> - add file to project A with message "subproj: add F2"
> - add project A as a subtree of project B under directory subdir
> - add a file to subdir with message "subproj: add F3"
> - do a split --unannotate="subproj:"
>
> I expected to see a log with no mention of "subproj" anywhere. Instead
> I get:
>
> add F3
> subproj: add F2
> subproj: add F1
>
> Is this as you intend? Is --unannotate only supposed to strip the
> string for commits added when A was a subtree of B?
>
> I guess this behavior makes sense in that the user would want to
> see the same commits that existed before A became a subproject.
>
> -David
Wow, I missed a bunch of emails on this. Thanks for applying and for
writing tests!
This is as intended. You wouldn't want subtree to modify commits that
occurred in the full repository for project A. Furthermore, you
wouldn't have a "subproj:" commit in project A's standalone repo since
it wasn't a subproject at that time.
The --annotate option confused me because it was the reverse of what I
wanted. As in your example, a typical use would be 'add a file to
subdir with message "subproj: add F3" ' to make it clear that you were
committing to the "subproj" part of a larger repository. Then, when
splitting back out to subproj's main repository, you'd want to remove
the prefix.
^ permalink raw reply
* Re: [PATCH v2 6/8] git-remote-testpy: hash bytes explicitly
From: John Keeping @ 2013-01-17 21:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <7vtxqftulq.fsf@alter.siamese.dyndns.org>
On Thu, Jan 17, 2013 at 12:36:33PM -0800, Junio C Hamano wrote:
> John Keeping <john@keeping.me.uk> writes:
>
>> Under Python 3 'hasher.update(...)' must take a byte string and not a
>> unicode string. Explicitly encode the argument to this method as UTF-8
>> so that this code works under Python 3.
>>
>> This moves the required Python version forward to 2.0.
>>
>> Signed-off-by: John Keeping <john@keeping.me.uk>
>> ---
>
> Hmph. So what happens when the path is _not_ encoded in UTF-8?
Do you mean encodable? As you say below it will currently throw an
exception.
> Is the repo.hash (and local.hash that gets a copy of it) something
> that needs to stay the same across multiple invocations of this
> remote helper, and between the currently shipped Git and the version
> of Git after applying this patch?
It's used to specify the path of the repository for importing or
exporting, so it should stay consistent across invocations. However,
this is only an example remote helper so I don't think we should worry
if it changes from one Git release to the next.
> If that is not the case, and if
> this is used only to get a randomly-looking 40-byte hexadecimal
> string, then a lossy attempt to .encode('utf-8') and falling back to
> replace or ignore bytes in the original that couldn't be interpreted
> as part of a UTF-8 string would be OK, but doesn't .encode('utf-8')
> throw an exception if not told to 'ignore' or something?
You're right - I think we need to add ", errors='replace'" to the call
to encode.
> > git-remote-testpy.py | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/git-remote-testpy.py b/git-remote-testpy.py
> > index d94a66a..f8dc196 100644
> > --- a/git-remote-testpy.py
> > +++ b/git-remote-testpy.py
> > @@ -31,9 +31,9 @@ from git_remote_helpers.git.exporter import GitExporter
> > from git_remote_helpers.git.importer import GitImporter
> > from git_remote_helpers.git.non_local import NonLocalGit
> >
> > -if sys.hexversion < 0x01050200:
> > - # os.makedirs() is the limiter
> > - sys.stderr.write("git-remote-testgit: requires Python 1.5.2 or later.\n")
> > +if sys.hexversion < 0x02000000:
> > + # string.encode() is the limiter
> > + sys.stderr.write("git-remote-testgit: requires Python 2.0 or later.\n")
> > sys.exit(1)
> >
> > def get_repo(alias, url):
> > @@ -45,7 +45,7 @@ def get_repo(alias, url):
> > repo.get_head()
> >
> > hasher = _digest()
> > - hasher.update(repo.path)
> > + hasher.update(repo.path.encode('utf-8'))
> > repo.hash = hasher.hexdigest()
> >
> > repo.get_base_path = lambda base: os.path.join(
^ permalink raw reply
* Re: [PATCH v2 6/8] git-remote-testpy: hash bytes explicitly
From: John Keeping @ 2013-01-17 21:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Michael Haggerty, git, Pete Wyckoff
In-Reply-To: <20130117210048.GI4574@serenity.lan>
On Thu, Jan 17, 2013 at 09:00:48PM +0000, John Keeping wrote:
> On Thu, Jan 17, 2013 at 12:36:33PM -0800, Junio C Hamano wrote:
>> John Keeping <john@keeping.me.uk> writes:
>>
>>> Under Python 3 'hasher.update(...)' must take a byte string and not a
>>> unicode string. Explicitly encode the argument to this method as UTF-8
>>> so that this code works under Python 3.
>>>
>>> This moves the required Python version forward to 2.0.
>>>
>>> Signed-off-by: John Keeping <john@keeping.me.uk>
>>> ---
>>
>> Hmph. So what happens when the path is _not_ encoded in UTF-8?
>
> Do you mean encodable? As you say below it will currently throw an
> exception.
Now my brain's not working - we shouldn't get an error converting from a
Unicode string to UTF-8, so I think this patch is OK as it is.
> > Is the repo.hash (and local.hash that gets a copy of it) something
> > that needs to stay the same across multiple invocations of this
> > remote helper, and between the currently shipped Git and the version
> > of Git after applying this patch?
>
> It's used to specify the path of the repository for importing or
> exporting, so it should stay consistent across invocations. However,
> this is only an example remote helper so I don't think we should worry
> if it changes from one Git release to the next.
^ 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