* Re: [QGIT PATCH/RFC]
From: Abdelrazak Younes @ 2009-11-05 10:13 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <e5bfff550911050141t751d45a0r4e340fa0d10af366@mail.gmail.com>
Marco Costalba wrote:
>
>> uint qHash(const ShaString& s) { // fast path, called 6-7 times per
>> revision
>>
>>
>
> Function:
>
> uint qHash(const QByteArray&);
>
> is already defined in the Qt Core libraries, so I have a link error
> with your patch.
>
By the way, this function of yours is not used anywhere AFAICS.
Abdel.
^ permalink raw reply
* Re: [QGIT PATCH/RFC]
From: Abdelrazak Younes @ 2009-11-05 10:19 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <4AF2A538.7040303@lyx.org>
Abdelrazak Younes wrote:
> Marco Costalba wrote:
>>
>>> uint qHash(const ShaString& s) { // fast path, called 6-7 times per
>>> revision
>>>
>>>
>>
>> Function:
>>
>> uint qHash(const QByteArray&);
>>
>> is already defined in the Qt Core libraries, so I have a link error
>> with your patch.
>>
>
> By the way, this function of yours is not used anywhere AFAICS.
Ok, now I understand that this is used by QHash, sorry.
I have gcc-4.4.1 so maybe that's the reason why linking works in my
case. But I don't which version of the qhash() function does take
precedence...
Abdel.
^ permalink raw reply
* [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Andrzej K. Haczewski @ 2009-11-05 10:18 UTC (permalink / raw)
To: git; +Cc: Nicolas Pitre, kusmabite, Johannes Sixt, Andrzej K. Haczewski
In-Reply-To: <16cee31f0911050100v76316dacye7edd8718a893f01@mail.gmail.com>
This patch implements native to Windows subset of pthreads API used by Git.
It allows to remove Pthreads for Win32 dependency for msysgit and Cygwin.
The patch modifies Makefile only for MSVC (that's the environment I'm
capable of testing on), so it requires further corrections to compile
with MinGW or Cygwin.
Signed-off-by: Andrzej K. Haczewski <ahaczewski@gmail.com>
---
Makefile | 7 ++-
builtin-pack-objects.c | 31 ++++++++++--
compat/mingw.c | 2 +-
compat/mingw.h | 5 ++
compat/win32/pthread.c | 39 +++++++++++++++
compat/win32/pthread.h | 125 ++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 201 insertions(+), 8 deletions(-)
create mode 100644 compat/win32/pthread.c
create mode 100644 compat/win32/pthread.h
diff --git a/Makefile b/Makefile
index bc039ac..30089a8 100644
--- a/Makefile
+++ b/Makefile
@@ -453,6 +453,7 @@ LIB_H += commit.h
LIB_H += compat/bswap.h
LIB_H += compat/cygwin.h
LIB_H += compat/mingw.h
+LIB_H += compat/win32/pthread.h
LIB_H += csum-file.h
LIB_H += decorate.h
LIB_H += delta.h
@@ -971,15 +972,15 @@ ifdef MSVC
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
NO_REGEX = YesPlease
NO_CURL = YesPlease
- NO_PTHREADS = YesPlease
+ THREADED_DELTA_SEARCH = YesPlease
BLK_SHA1 = YesPlease
CC = compat/vcbuild/scripts/clink.pl
AR = compat/vcbuild/scripts/lib.pl
CFLAGS =
BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
- COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o
- COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -DSTRIP_EXTENSION=\".exe\"
+ COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o
+ COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib
lib =
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 02f9246..00594fd 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1255,15 +1255,15 @@ static int delta_cacheable(unsigned long src_size, unsigned long trg_size,
#ifdef THREADED_DELTA_SEARCH
-static pthread_mutex_t read_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t read_mutex;
#define read_lock() pthread_mutex_lock(&read_mutex)
#define read_unlock() pthread_mutex_unlock(&read_mutex)
-static pthread_mutex_t cache_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t cache_mutex;
#define cache_lock() pthread_mutex_lock(&cache_mutex)
#define cache_unlock() pthread_mutex_unlock(&cache_mutex)
-static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t progress_mutex;
#define progress_lock() pthread_mutex_lock(&progress_mutex)
#define progress_unlock() pthread_mutex_unlock(&progress_mutex)
@@ -1590,7 +1590,26 @@ struct thread_params {
unsigned *processed;
};
-static pthread_cond_t progress_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t progress_cond;
+
+/*
+ * Mutex and conditional variable can't be statically-initialized on Windows.
+ */
+static void init_threaded_search()
+{
+ pthread_mutex_init(&read_mutex, NULL);
+ pthread_mutex_init(&cache_mutex, NULL);
+ pthread_mutex_init(&progress_mutex, NULL);
+ pthread_cond_init(&progress_cond, NULL);
+}
+
+static void cleanup_threaded_search()
+{
+ pthread_cond_destroy(&progress_cond);
+ pthread_mutex_destroy(&read_mutex);
+ pthread_mutex_destroy(&cache_mutex);
+ pthread_mutex_destroy(&progress_mutex);
+}
static void *threaded_find_deltas(void *arg)
{
@@ -1629,8 +1648,11 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
struct thread_params *p;
int i, ret, active_threads = 0;
+ init_threaded_search();
+
if (delta_search_threads <= 1) {
find_deltas(list, &list_size, window, depth, processed);
+ cleanup_threaded_search();
return;
}
if (progress > pack_to_stdout)
@@ -1745,6 +1767,7 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
active_threads--;
}
}
+ cleanup_threaded_search();
free(p);
}
diff --git a/compat/mingw.c b/compat/mingw.c
index 6b5b5b2..f2e9f02 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -5,7 +5,7 @@
#include <shellapi.h>
-static int err_win_to_posix(DWORD winerr)
+int err_win_to_posix(DWORD winerr)
{
int error = ENOSYS;
switch(winerr) {
diff --git a/compat/mingw.h b/compat/mingw.h
index 6907345..7e25fb5 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -294,3 +294,8 @@ struct mingw_dirent
#define readdir(x) mingw_readdir(x)
struct dirent *mingw_readdir(DIR *dir);
#endif // !NO_MINGW_REPLACE_READDIR
+
+/*
+ * Used by Pthread API implementation for Windows
+ */
+extern int err_win_to_posix(DWORD winerr);
diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c
new file mode 100644
index 0000000..a7ab7af
--- /dev/null
+++ b/compat/win32/pthread.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Andrzej K. Haczewski <ahaczewski@gmail.com>
+ */
+
+#include "pthread.h"
+
+static DWORD __stdcall win32_start_routine(LPVOID arg)
+{
+ pthread_t *thread = arg;
+ thread->value = thread->start_routine(thread->arg);
+ return 0;
+}
+
+int pthread_create(pthread_t *thread, const void *unused,
+ void *(*start_routine)(void*), void *arg)
+{
+ thread->arg = arg;
+ thread->handle = CreateThread(NULL, 0, win32_start_routine, thread, 0, NULL);
+
+ if (!thread->handle)
+ return err_win_to_posix(GetLastError());
+ else
+ return 0;
+}
+
+int win32_pthread_join(pthread_t *thread, void **value_ptr)
+{
+ DWORD result = WaitForSingleObject(thread->handle, INFINITE);
+ switch (result) {
+ case WAIT_OBJECT_0:
+ if (value_ptr)
+ *value_ptr = thread.value;
+ return 0;
+ case WAIT_ABANDONED:
+ return EINVAL;
+ default:
+ return err_win_to_posix(GetLastError());
+ }
+}
diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h
new file mode 100644
index 0000000..e50eb6b
--- /dev/null
+++ b/compat/win32/pthread.h
@@ -0,0 +1,125 @@
+/*
+ * Header used to adapt pthread-based POSIX code to Windows API threads.
+ *
+ * Copyright (C) 2009 Andrzej K. Haczewski <ahaczewski@gmail.com>
+ */
+
+#ifndef PTHREAD_H
+#define PTHREAD_H
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+/*
+ * Implement simple condition variable for Windows threads, based on ACE
+ * implementation.
+ *
+ * See original implementation: http://bit.ly/1vkDjo
+ * ACE homepage: http://www.cse.wustl.edu/~schmidt/ACE.html
+ * See also: http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
+ */
+typedef struct {
+ LONG waiters;
+ CRITICAL_SECTION waiters_lock;
+ HANDLE sema;
+} pthread_cond_t;
+
+static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused)
+{
+ cond->waiters = 0;
+
+ InitializeCriticalSection(&cond->waiters_lock);
+
+ cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
+ if (!cond->sema)
+ die("");
+ return 0;
+}
+
+static inline int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ CloseHandle(cond->sema);
+ cond->sema = NULL;
+
+ DeleteCriticalSection(&cond->waiters_lock);
+
+ return 0;
+}
+
+static inline int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)
+{
+ /* serialize access to waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ ++cond->waiters;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /*
+ * Unlock external mutex and wait for signal.
+ * NOTE: we've held mutex locked long enough to increment
+ * waiters count above, so there's no problem with
+ * leaving mutex unlocked before we wait on semaphore.
+ */
+ LeaveCriticalSection(mutex);
+
+ /* let's wait */
+ WaitForSingleObject(cond->sema, INFINITE))
+
+ /* we're done waiting, so make sure we decrease waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ --cond->waiters;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /* lock external mutex again */
+ EnterCriticalSection(mutex);
+
+ return 0;
+}
+
+static inline int pthread_cond_signal(pthread_cond_t *cond)
+{
+ int have_waiters;
+
+ /* serialize access to waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ have_waiters = cond->waiters > 0;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /*
+ * Signal only when there are waiters
+ */
+ if (have_waiters)
+ return ReleaseSemaphore(cond->sema, 1, NULL) ?
+ 0 : err_win_to_posix(GetLastError();
+ else
+ return 0;
+}
+
+#define pthread_mutex_t CRITICAL_SECTION
+
+#define pthread_mutex_init(a,b) InitializeCriticalSection((a))
+#define pthread_mutex_destroy(a) DeleteCriticalSection((a))
+#define pthread_mutex_lock EnterCriticalSection
+#define pthread_mutex_unlock LeaveCriticalSection
+
+typedef struct {
+ HANDLE handle;
+ void *(*start_routine)(void*);
+ void *arg;
+ void *value;
+} pthread_t;
+
+extern int pthread_create(pthread_t *thread, const void *unused,
+ void *(*start_routine)(void*), void *arg);
+
+/*
+ * To avoid the need of allocating struct, we use small macro wrapper to pass
+ * pointer to win32_pthread_join instead of using typedef struct {} *pthread_t
+ */
+#define pthread_join(a, b) win32_pthread_join(&(a), (b))
+
+extern int win32_pthread_join(pthread_t *thread, void **value_ptr);
+
+#endif /* PTHREAD_H */
--
1.6.5.2
^ permalink raw reply related
* Re: [QGIT PATCH/RFC]
From: Abdelrazak Younes @ 2009-11-05 10:37 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <4AF2A69F.1090802@lyx.org>
Abdelrazak Younes wrote:
> Abdelrazak Younes wrote:
> > Marco Costalba wrote:
> >>
> >>> uint qHash(const ShaString& s) { // fast path, called 6-7 times
> >>> per revision
> >>>
> >>>
> >>
> >> Function:
> >>
> >> uint qHash(const QByteArray&);
> >>
> >> is already defined in the Qt Core libraries, so I have a link
> >> error with your patch.
> >>
> >
> > By the way, this function of yours is not used anywhere AFAICS.
>
> Ok, now I understand that this is used by QHash, sorry.
>
> I have gcc-4.4.1 so maybe that's the reason why linking works in my
> case. But I don't which version of the qhash() function does take
> precedence...
FYI I just verified that your version does take precedence over the Qt one.
Anyway, if you like the patch, we could just inherit from QByteArray
instead of typedef it so that it links with your system.
Out of curiosity I just had a look at the two versions, yours:
********************************
// definition of an optimized sha hash function
static inline uint hexVal(const uchar* ch) {
return (*ch < 64 ? *ch - 48 : *ch - 87);
}
uint qHash(const ShaString& s) { // fast path, called 6-7 times per revision
const uchar* ch = reinterpret_cast<const uchar*>(s.data());
return (hexVal(ch ) << 24)
+ (hexVal(ch + 2) << 20)
+ (hexVal(ch + 4) << 16)
+ (hexVal(ch + 6) << 12)
+ (hexVal(ch + 8) << 8)
+ (hexVal(ch + 10) << 4)
+ hexVal(ch + 12);
}
********************************
And Qt's version:
********************************
static uint hash(const uchar *p, int n)
{
uint h = 0;
uint g;
while (n--) {
h = (h << 4) + *p++;
if ((g = (h & 0xf0000000)) != 0)
h ^= g >> 23;
h &= ~g;
}
return h;
}
uint qHash(const QBitArray &bitArray)
{
int m = bitArray.d.size() - 1;
uint result = hash(reinterpret_cast<const uchar
*>(bitArray.d.constData()), qMax(0, m));
// deal with the last 0 to 7 bits manually, because we can't trust that
// the padding is initialized to 0 in bitArray.d
int n = bitArray.size();
if (n & 0x7)
result = ((result << 4) + bitArray.d.at(m)) & ((1 << n) - 1);
return result;
}
********************************
I recompiled qgit with the Qt version and I didn't notice any
performance problem with a big repo (Qt).
Just tell me if this is not interesting to you and I'll shut up :-)
Abdel.
^ permalink raw reply
* [PATCH] pre-commit.sample: Diff against the empty tree when HEAD is invalid
From: Björn Steinbrink @ 2009-11-05 10:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Heiko Voigt, git
This was already the case for the old "diff --check" call, but the new
one that checks whether there are any non-ascii file names was missing
it, making that check fail for root commits.
Signed-off-by: Björn Steinbrink <B.Steinbrink@gmx.de>
---
templates/hooks--pre-commit.sample | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/templates/hooks--pre-commit.sample b/templates/hooks--pre-commit.sample
index 043970a..439eefd 100755
--- a/templates/hooks--pre-commit.sample
+++ b/templates/hooks--pre-commit.sample
@@ -7,6 +7,14 @@
#
# To enable this hook, rename this file to "pre-commit".
+if git-rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)
@@ -17,7 +25,7 @@ if [ "$allownonascii" != "true" ] &&
# Note that the use of brackets around a tr range is ok here, (it's
# even required, for portability to Solaris 10's /usr/bin/tr), since
# the square bracket bytes happen to fall in the designated range.
- test "$(git diff --cached --name-only --diff-filter=A -z |
+ test "$(git diff --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0')"
then
echo "Error: Attempt to add a non-ascii file name."
@@ -35,12 +43,4 @@ then
exit 1
fi
-if git-rev-parse --verify HEAD >/dev/null 2>&1
-then
- against=HEAD
-else
- # Initial commit: diff against an empty tree object
- against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-fi
-
exec git diff-index --check --cached $against --
--
1.6.5.2.143.g8cc62
^ permalink raw reply related
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Johannes Sixt @ 2009-11-05 12:27 UTC (permalink / raw)
To: Andrzej K. Haczewski; +Cc: git, Nicolas Pitre, kusmabite
In-Reply-To: <1257416325-5605-1-git-send-email-ahaczewski@gmail.com>
Andrzej K. Haczewski schrieb:
> diff --git a/Makefile b/Makefile
> index bc039ac..30089a8 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -453,6 +453,7 @@ LIB_H += commit.h
> LIB_H += compat/bswap.h
> LIB_H += compat/cygwin.h
> LIB_H += compat/mingw.h
> +LIB_H += compat/win32/pthread.h
> LIB_H += csum-file.h
> LIB_H += decorate.h
> LIB_H += delta.h
> @@ -971,15 +972,15 @@ ifdef MSVC
> OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
> NO_REGEX = YesPlease
> NO_CURL = YesPlease
> - NO_PTHREADS = YesPlease
> + THREADED_DELTA_SEARCH = YesPlease
> BLK_SHA1 = YesPlease
>
> CC = compat/vcbuild/scripts/clink.pl
> AR = compat/vcbuild/scripts/lib.pl
> CFLAGS =
> BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
> - COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o
> - COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -DSTRIP_EXTENSION=\".exe\"
> + COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o
> + COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
> BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
> EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib
> lib =
What compiles compat/win32/pthread.c?
Please don't forget to add compat/win32/*.o to the clean target.
> +int pthread_create(pthread_t *thread, const void *unused,
> + void *(*start_routine)(void*), void *arg)
> +{
> + thread->arg = arg;
> + thread->handle = CreateThread(NULL, 0, win32_start_routine, thread, 0, NULL);
Elsewhere we use _beginthreadex(). What's the difference?
> +static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused)
> +{
> + cond->waiters = 0;
> +
> + InitializeCriticalSection(&cond->waiters_lock);
> +
> + cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
> + if (!cond->sema)
> + die("");
> + return 0;
> +}
> +
> +static inline int pthread_cond_destroy(pthread_cond_t *cond)
> +{
> + CloseHandle(cond->sema);
> + cond->sema = NULL;
> +
> + DeleteCriticalSection(&cond->waiters_lock);
> +
> + return 0;
> +}
> +
> +static inline int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)
> +{
> + /* serialize access to waiters count */
> + EnterCriticalSection(&cond->waiters_lock);
> + ++cond->waiters;
> + LeaveCriticalSection(&cond->waiters_lock);
> +
> + /*
> + * Unlock external mutex and wait for signal.
> + * NOTE: we've held mutex locked long enough to increment
> + * waiters count above, so there's no problem with
> + * leaving mutex unlocked before we wait on semaphore.
> + */
> + LeaveCriticalSection(mutex);
> +
> + /* let's wait */
> + WaitForSingleObject(cond->sema, INFINITE))
> +
> + /* we're done waiting, so make sure we decrease waiters count */
> + EnterCriticalSection(&cond->waiters_lock);
> + --cond->waiters;
> + LeaveCriticalSection(&cond->waiters_lock);
> +
> + /* lock external mutex again */
> + EnterCriticalSection(mutex);
> +
> + return 0;
> +}
> +
> +static inline int pthread_cond_signal(pthread_cond_t *cond)
> +{
> + int have_waiters;
> +
> + /* serialize access to waiters count */
> + EnterCriticalSection(&cond->waiters_lock);
> + have_waiters = cond->waiters > 0;
> + LeaveCriticalSection(&cond->waiters_lock);
> +
> + /*
> + * Signal only when there are waiters
> + */
> + if (have_waiters)
> + return ReleaseSemaphore(cond->sema, 1, NULL) ?
> + 0 : err_win_to_posix(GetLastError();
> + else
> + return 0;
> +}
The pthread_cond_* functions are quite voluminous, but not performance
critical. Could you please move them to pthread.c as well?
-- Hannes
^ permalink raw reply
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Andrzej K. Haczewski @ 2009-11-05 12:53 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, Nicolas Pitre, kusmabite
In-Reply-To: <4AF2C4B9.10402@viscovery.net>
2009/11/5 Johannes Sixt <j.sixt@viscovery.net>:
> Elsewhere we use _beginthreadex(). What's the difference?
Oh my, I've just run through MSDN documentation and I'm wrongly using
CreateThread. I should have used _beginthread from the start, because
besides calling CreateThread it initializes local thread storage for
global C-runtime variables (errno etc.), which CreateThread does not
do. That could lead to very unpleasant consequences. I'll redo thread
creation to use _beginthreadex(). Thanks for that question!
> The pthread_cond_* functions are quite voluminous, but not performance
> critical. Could you please move them to pthread.c as well?
Ok, will do.
--
Andrzej
^ permalink raw reply
* Re: Automatically remote prune
From: Dmitry Potapov @ 2009-11-05 13:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: John Tapsell, Git List
In-Reply-To: <7viqdpemki.fsf@alter.siamese.dyndns.org>
On Wed, Nov 04, 2009 at 06:23:57PM -0800, Junio C Hamano wrote:
>
> There are two reasons I could think of that the user might want to know
> this.
>
> (1) The user wants to keep the remotes/<origin>/* namespace clean (iow,
> the user does not care to keep old commits that were deemed bad by
> the remote side) by removing stale tracking refs. But in this case,
> it is very unlikely that the user would use "git branch -d -r" to
> remove stale ones one-by-one after seeing '[Deleted]' label in the
> output from "git branch -r". Rather he would run "git remote prune
> origin" to blindly remove them all.
>
> (2) The user does want to be careful not to lose commits that now only
> exists in his repository. Perhaps he saw something worthwhile to
> base his topic later on. But these stale remote tracking refs are
> not removed until the user runs "git remote prune origin". As long
> as we give him a way to check what will be pruned before running "git
> remote prune", there is not much point in showing that information in
> output of "git branch -r". There is no need to keep extra info by
> creating a new file in .git by "fetch". Nor showing that to the user
> when he does "fetch" either, for that matter.
>
> A better approach to please the first class of audience may be to
> introduce an option that tells fetch to cull tracking refs that are stale.
'git remote update' already has the --prune option, so it would be only
logical if 'git fetch' has it too... Perhaps, it would be useful to add
a configuration option to automatically prune remote branches on fetch.
> Such an option won't be very useful for the second class of audience,
> though. For them we would need something else, and it would likely be an
> enhancement to "git remote".
'git remote prune' has --dry-run:
$ git remote prune --dry-run origin
Pruning origin
URL: git://git.kernel.org/pub/scm/git/git.git
* [would prune] origin/offcuts
* [would prune] origin/old-next
(Hmm... I did not know I had them in my git repo....)
So, it is possible to do now, but personally, I would prefer if 'git
fetch' would tell what references are removed. It may appear a bit too
chatty if someone has a lot of deleted references in a remote repo, but
I really do not see any good reason to keep stale branches. If you think
that some reference is useful and you want to preserve it then you can
create a local branch, but in 99.9% cases people want just to remove a
stale branch.
Actually, accumulation of stale branches is only half of the problem.
In some cases, the stale branch can mislead people. For instance, some
feature has been implemented and was merged to 'pu'. After that, this
feature was re-worked and later merged to the 'master' branch, after
that the feature branch was removed. Yet, some users may have the stale
branch pointing on the original version and may think that it is still
not merged and buggy...
BTW, the current behavior of 'git fetch' does not really protect you from
losing commits. It protects commits only in the case when the branch is
deleted, but not when it is force-updated, which feels inconsistent to
me. Personally, I would prefer if 'git fetch' removed branches, but when
it removes or force-updates some branch, it adds a record to the reflog.
Dmitry
^ permalink raw reply
* Re: [PATCH] MSVC: port pthread code to native Windows threads
From: Dmitry Potapov @ 2009-11-05 13:48 UTC (permalink / raw)
To: Andrzej K. Haczewski; +Cc: Johannes Sixt, git
In-Reply-To: <16cee31f0911040547m69e5b9cbi30e20d2a7790bd6f@mail.gmail.com>
On Wed, Nov 04, 2009 at 02:47:09PM +0100, Andrzej K. Haczewski wrote:
> 2009/11/4 Johannes Sixt <j.sixt@viscovery.net>:
>
> > - pthread_cond_signal is called while the mutex is held.
>
> AFAIK that is a requirement for condition variable to be signaled
> while holding the same mutex that other threads cond_wait on. I just
> don't check that it is true, because Git is locking mutex.
There is no such requirement in POSIX:
The pthread_cond_broadcast() or pthread_cond_signal() functions may
be called by a thread whether or not it currently owns the mutex that
threads calling pthread_cond_wait() or pthread_cond_timedwait() have
associated with the condition variable during their waits; however,
if predictable scheduling behavior is required, then that mutex shall
be locked by the thread calling pthread_cond_broadcast() or
pthread_cond_signal().
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html
Dmitry
^ permalink raw reply
* [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Andrzej K. Haczewski @ 2009-11-05 16:45 UTC (permalink / raw)
To: git
Cc: Andrzej K. Haczewski, Nicolas Pitre, kusmabite,
Johannes Schindelin, Johannes Sixt, Paolo Bonzini
In-Reply-To: <1257283802-29726-1-git-send-email-ahaczewski@gmail.com>
This patch implements native to Windows subset of pthreads API used by Git.
It allows to remove Pthreads for Win32 dependency for MSVC, msysgit and
Cygwin.
The patch modifies Makefile only for MSVC (that's the environment I'm
capable of testing on), so it requires further corrections to compile
with MinGW or Cygwin.
Signed-off-by: Andrzej K. Haczewski <ahaczewski@gmail.com>
---
Here is another round of that patch with all comments considered. There is
no workaround to make static initialization of mutexes and condition
variables work for Windows, that's why there's explicit initialization
added.
I hope I added to Cc all interested in this patch. Excuse me if I omitted
someone.
Makefile | 7 ++-
builtin-pack-objects.c | 31 +++++++++++--
compat/mingw.c | 2 +-
compat/mingw.h | 5 ++
compat/win32/pthread.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++
compat/win32/pthread.h | 69 ++++++++++++++++++++++++++++
6 files changed, 222 insertions(+), 8 deletions(-)
create mode 100644 compat/win32/pthread.c
create mode 100644 compat/win32/pthread.h
diff --git a/Makefile b/Makefile
index bc039ac..30089a8 100644
--- a/Makefile
+++ b/Makefile
@@ -453,6 +453,7 @@ LIB_H += commit.h
LIB_H += compat/bswap.h
LIB_H += compat/cygwin.h
LIB_H += compat/mingw.h
+LIB_H += compat/win32/pthread.h
LIB_H += csum-file.h
LIB_H += decorate.h
LIB_H += delta.h
@@ -971,15 +972,15 @@ ifdef MSVC
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
NO_REGEX = YesPlease
NO_CURL = YesPlease
- NO_PTHREADS = YesPlease
+ THREADED_DELTA_SEARCH = YesPlease
BLK_SHA1 = YesPlease
CC = compat/vcbuild/scripts/clink.pl
AR = compat/vcbuild/scripts/lib.pl
CFLAGS =
BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
- COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o
- COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -DSTRIP_EXTENSION=\".exe\"
+ COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o
+ COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib
lib =
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 02f9246..00594fd 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1255,15 +1255,15 @@ static int delta_cacheable(unsigned long src_size, unsigned long trg_size,
#ifdef THREADED_DELTA_SEARCH
-static pthread_mutex_t read_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t read_mutex;
#define read_lock() pthread_mutex_lock(&read_mutex)
#define read_unlock() pthread_mutex_unlock(&read_mutex)
-static pthread_mutex_t cache_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t cache_mutex;
#define cache_lock() pthread_mutex_lock(&cache_mutex)
#define cache_unlock() pthread_mutex_unlock(&cache_mutex)
-static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t progress_mutex;
#define progress_lock() pthread_mutex_lock(&progress_mutex)
#define progress_unlock() pthread_mutex_unlock(&progress_mutex)
@@ -1590,7 +1590,26 @@ struct thread_params {
unsigned *processed;
};
-static pthread_cond_t progress_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t progress_cond;
+
+/*
+ * Mutex and conditional variable can't be statically-initialized on Windows.
+ */
+static void init_threaded_search()
+{
+ pthread_mutex_init(&read_mutex, NULL);
+ pthread_mutex_init(&cache_mutex, NULL);
+ pthread_mutex_init(&progress_mutex, NULL);
+ pthread_cond_init(&progress_cond, NULL);
+}
+
+static void cleanup_threaded_search()
+{
+ pthread_cond_destroy(&progress_cond);
+ pthread_mutex_destroy(&read_mutex);
+ pthread_mutex_destroy(&cache_mutex);
+ pthread_mutex_destroy(&progress_mutex);
+}
static void *threaded_find_deltas(void *arg)
{
@@ -1629,8 +1648,11 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
struct thread_params *p;
int i, ret, active_threads = 0;
+ init_threaded_search();
+
if (delta_search_threads <= 1) {
find_deltas(list, &list_size, window, depth, processed);
+ cleanup_threaded_search();
return;
}
if (progress > pack_to_stdout)
@@ -1745,6 +1767,7 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
active_threads--;
}
}
+ cleanup_threaded_search();
free(p);
}
diff --git a/compat/mingw.c b/compat/mingw.c
index 6b5b5b2..f2e9f02 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -5,7 +5,7 @@
#include <shellapi.h>
-static int err_win_to_posix(DWORD winerr)
+int err_win_to_posix(DWORD winerr)
{
int error = ENOSYS;
switch(winerr) {
diff --git a/compat/mingw.h b/compat/mingw.h
index 6907345..7e25fb5 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -294,3 +294,8 @@ struct mingw_dirent
#define readdir(x) mingw_readdir(x)
struct dirent *mingw_readdir(DIR *dir);
#endif // !NO_MINGW_REPLACE_READDIR
+
+/*
+ * Used by Pthread API implementation for Windows
+ */
+extern int err_win_to_posix(DWORD winerr);
diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c
new file mode 100644
index 0000000..e4d21bd
--- /dev/null
+++ b/compat/win32/pthread.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009 Andrzej K. Haczewski <ahaczewski@gmail.com>
+ */
+
+#include "../../git-compat-util.h"
+#include "pthread.h"
+
+#include <errno.h>
+#include <limits.h>
+
+static unsigned __stdcall win32_start_routine(void *arg)
+{
+ pthread_t *thread = arg;
+ thread->value = thread->start_routine(thread->arg);
+ return 0;
+}
+
+int pthread_create(pthread_t *thread, const void *unused,
+ void *(*start_routine)(void*), void *arg)
+{
+ thread->arg = arg;
+ thread->start_routine = start_routine;
+ thread->value = NULL;
+ thread->handle =
+ _beginthreadex(NULL, 0, win32_start_routine, thread, 0, NULL);
+
+ if (!thread->handle)
+ return errno;
+ else
+ return 0;
+}
+
+int win32_pthread_join(pthread_t *thread, void **value_ptr)
+{
+ DWORD result = WaitForSingleObject((HANDLE)thread->handle, INFINITE);
+ switch (result) {
+ case WAIT_OBJECT_0:
+ if (value_ptr)
+ *value_ptr = thread->value;
+ return 0;
+ case WAIT_ABANDONED:
+ return EINVAL;
+ default:
+ return err_win_to_posix(GetLastError());
+ }
+}
+
+int pthread_cond_init(pthread_cond_t *cond, const void *unused)
+{
+ cond->waiters = 0;
+
+ InitializeCriticalSection(&cond->waiters_lock);
+
+ cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
+ if (!cond->sema)
+ die("CreateSemaphore() failed");
+ return 0;
+}
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ CloseHandle(cond->sema);
+ cond->sema = NULL;
+
+ DeleteCriticalSection(&cond->waiters_lock);
+
+ return 0;
+}
+
+int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)
+{
+ /* serialize access to waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ ++cond->waiters;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /*
+ * Unlock external mutex and wait for signal.
+ * NOTE: we've held mutex locked long enough to increment
+ * waiters count above, so there's no problem with
+ * leaving mutex unlocked before we wait on semaphore.
+ */
+ LeaveCriticalSection(mutex);
+
+ /* let's wait - ignore return value */
+ WaitForSingleObject(cond->sema, INFINITE);
+
+ /* we're done waiting, so make sure we decrease waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ --cond->waiters;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /* lock external mutex again */
+ EnterCriticalSection(mutex);
+
+ return 0;
+}
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ int have_waiters;
+
+ /* serialize access to waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ have_waiters = cond->waiters > 0;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /*
+ * Signal only when there are waiters
+ */
+ if (have_waiters)
+ return ReleaseSemaphore(cond->sema, 1, NULL) ?
+ 0 : err_win_to_posix(GetLastError());
+ else
+ return 0;
+}
diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h
new file mode 100644
index 0000000..a7594cc
--- /dev/null
+++ b/compat/win32/pthread.h
@@ -0,0 +1,69 @@
+/*
+ * Header used to adapt pthread-based POSIX code to Windows API threads.
+ *
+ * Copyright (C) 2009 Andrzej K. Haczewski <ahaczewski@gmail.com>
+ */
+
+#ifndef PTHREAD_H
+#define PTHREAD_H
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+/*
+ * Defines that adapt Windows API threads to pthreads API
+ */
+#define pthread_mutex_t CRITICAL_SECTION
+
+#define pthread_mutex_init(a,b) InitializeCriticalSection((a))
+#define pthread_mutex_destroy(a) DeleteCriticalSection((a))
+#define pthread_mutex_lock EnterCriticalSection
+#define pthread_mutex_unlock LeaveCriticalSection
+
+/*
+ * Implement simple condition variable for Windows threads, based on ACE
+ * implementation.
+ *
+ * See original implementation: http://bit.ly/1vkDjo
+ * ACE homepage: http://www.cse.wustl.edu/~schmidt/ACE.html
+ * See also: http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
+ */
+typedef struct {
+ LONG waiters;
+ CRITICAL_SECTION waiters_lock;
+ HANDLE sema;
+} pthread_cond_t;
+
+extern int pthread_cond_init(pthread_cond_t *cond, const void *unused);
+
+extern int pthread_cond_destroy(pthread_cond_t *cond);
+
+extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex);
+
+extern int pthread_cond_signal(pthread_cond_t *cond);
+
+/*
+ * Simple thread creation implementation using pthread API
+ */
+typedef struct {
+ uintptr_t handle;
+ void *(*start_routine)(void*);
+ void *arg;
+ void *value;
+} pthread_t;
+
+extern int pthread_create(pthread_t *thread, const void *unused,
+ void *(*start_routine)(void*), void *arg);
+
+/*
+ * To avoid the need of allocating struct, we use small macro wrapper to pass
+ * pointer to win32_pthread_join instead of using typedef struct {} *pthread_t
+ */
+#define pthread_join(a, b) win32_pthread_join(&(a), (b))
+
+extern int win32_pthread_join(pthread_t *thread, void **value_ptr);
+
+#endif /* PTHREAD_H */
--
1.6.5.2
^ permalink raw reply related
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Johannes Sixt @ 2009-11-05 17:31 UTC (permalink / raw)
To: Andrzej K. Haczewski
Cc: git, Nicolas Pitre, kusmabite, Johannes Schindelin, Paolo Bonzini
In-Reply-To: <1257439548-9258-1-git-send-email-ahaczewski@gmail.com>
Thanks.
I pushed this to
git://repo.or.cz/git/mingw/j6t.git pthreads-for-windows
together with Nico's patch and another patch to enable pthreads on
MinGW unconditionally. Feedback welcome!
Andrzej K. Haczewski (1):
MSVC: Windows-native implementation for subset of Pthreads API
Johannes Sixt (1):
MinGW: enable pthreads
Nicolas Pitre (1):
pack-objects: move thread autodetection closer to relevant code
This is my patch:
--- >8 ---
From: Johannes Sixt <j6t@kdbg.org>
Subject: [PATCH] MinGW: enable pthreads
If the MinGW build was built as part of the msysgit build environment,
then threading was already enabled because the pthreads package from
GNU-Win32 is available in msysgit.
The previous patch added a minimal pthreads implementation for Windows.
Therefore, we can now enable code that uses pthreads unconditionally.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
Makefile | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index db7ffb0..4b8603a 100644
--- a/Makefile
+++ b/Makefile
@@ -986,9 +986,11 @@ ifneq (,$(findstring MINGW,$(uname_S)))
UNRELIABLE_FSTAT = UnfortunatelyYes
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
NO_REGEX = YesPlease
+ THREADED_DELTA_SEARCH = YesPlease
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
- COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
+ COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
+ compat/win32/pthread.o
EXTLIBS += -lws2_32
X = .exe
ifneq (,$(wildcard ../THIS_IS_MSYSGIT))
@@ -998,10 +1000,8 @@ ifneq (,$(wildcard ../THIS_IS_MSYSGIT))
EXTLIBS += /mingw/lib/libz.a
NO_R_TO_GCC_LINKER = YesPlease
INTERNAL_QSORT = YesPlease
- THREADED_DELTA_SEARCH = YesPlease
else
NO_CURL = YesPlease
- NO_PTHREADS = YesPlease
endif
endif
endif
--
1.6.5.2.1198.ge698c
^ permalink raw reply related
* Preserving branches after merging on ancestor
From: Richard Lee @ 2009-11-05 18:30 UTC (permalink / raw)
To: git
Hello gits,
I've been using various version control systems for several years now before
coming to git two months ago. So far I've been just doing linear commits
without any branches on my source code so that I end up with a linear
history. This makes it very hard to see where you started and stopped
working on something on the git graph.
So I tried using branches for features today. Most of the time I'm the only
person working on a project. So when I've finished working on a feature
branch and ready to merge it back into the master branch, the master head IS
the common ancestor of the two branches. As shown below
* b6d75f1 [feature] stuff on feature branch
* 43dba08 stuff on feature branch
* ab7efdd [master] init
When I merge the graph looks likes this:
* b6d75f1 [master] [feature] stuff on feature branch
* 43dba08 stuff on feature branch
* ab7efdd init
Now I lose the start point of where I satrted on the feature branch. And if
I decided to reuse the name of the branch 'feature' to work on it again by
resetting it to somewhere else, I loose to finish point. (Should I be using
git-reset like this?)
One way of getting round this problem is to use empty commits on the master
branch, as shown below.
* 6fc04b5 Merge branch 'feature2'
|\
| * 07a117b stuff on feature2
* | 52f5ba1 Empty commit
|/
* 5deaa93 Merge branch 'feature1'
|\
| * b163b17 stuff on feature1
| * 53bb820 stuff on feature1
| * c9ef14c stuff on feature1
* | 34227a3 Empty commit
|/
* e88d332 Init
But is this correct? It seems rather hackish to create empty commits on the
master branch just to historically preserve commits on a seperate branch.
Should I be using feature branches in git like this or another way? For
example more informative commit messages.
I cannot imagine using this empty commits fix in other VCS if they don't
allow empty commits like svn or hg.
Cheers,
Richard
--
View this message in context: http://old.nabble.com/Preserving-branches-after-merging-on-ancestor-tp26217077p26217077.html
Sent from the git mailing list archive at Nabble.com.
^ permalink raw reply
* git pull -s subtree doesn't work properly
From: Oliver Kullmann @ 2009-11-05 18:09 UTC (permalink / raw)
To: git
Hello,
using
IntroductionJava> git remote add -f CSM41 /home/kullmann/csoliver/UofT/Java0910/ProgrammingJava/CS-M41_Programs
IntroductionJava> git merge -s ours --no-commit CSM41/master
IntroductionJava> git read-tree --prefix=Artikel/Skripte/IntroductionJava/CS_M41/ -u CSM41/master
IntroductionJava> git commit -m "Einfuegen des CS-M41-Projektes als Verzeichnis CS_M41"
I have imported repository "CS-M41_Programs" into another repository. Later then
I replaced in the config-file the old url /home/kullmann/csoliver/UofT/Java0910/ProgrammingJava/CS-M41_Programs
by the new one
[remote "CSM41"]
url = git://github.com/OKullmann/CS-M41-Programming-in-Java.git
fetch = +refs/heads/*:refs/remotes/CSM41/*
But now
IntroductionJava> git pull -s subtree CSM41 master
doesn't work anymore: In the CSM41 repository just one file index.html was changed,
and apparently the merge strategy recognises that the other files haven't
been changed, while index.html is placed just as if the relative path would
start from the root of the repository.
IntroductionJava> git pull -s subtree CSM41 master
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From git://github.com/OKullmann/CS-M41-Programming-in-Java
* branch master -> FETCH_HEAD
CONFLICT (delete/modify): Artikel/LaTeX/SystemStile/Html/index.html deleted in HEAD a
nd modified in 38b11a96fa009a5b2c24cfc94c0268ab9ca7ce39. Version 38b11a96fa009a5b2c24
cfc94c0268ab9ca7ce39 of Artikel/LaTeX/SystemStile/Html/index.html left in tree.
Automatic merge failed; fix conflicts and then commit the result.
IntroductionJava> git status
# On branch master
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add <file>..." to mark resolution)
#
# deleted by us: ../../LaTeX/SystemStile/Html/index.html
#
no changes added to commit (use "git add" and/or "git commit -a")
The path of index.html is Artikel/Skripte/IntroductionJava/CS_M41/Html/index.html.
Why git thinks that index.html should be placed into another directory Artikel/LaTeX/SystemStile/Html/
I have no clue (this directory doesn't exist).
Is it possible to tell "git pull" where the subtree really is, or is that
not really the cause of the problem?
Thanks for your consideration!
Oliver
^ permalink raw reply
* Re: Preserving branches after merging on ancestor
From: Eric Raible @ 2009-11-05 18:38 UTC (permalink / raw)
To: git
In-Reply-To: <26217077.post@talk.nabble.com>
Richard Lee <richard <at> webdezign.co.uk> writes:
> So I tried using branches for features today. Most of the time I'm the only
> person working on a project. So when I've finished working on a feature
> branch and ready to merge it back into the master branch, the master head IS
> the common ancestor of the two branches. As shown below
>
> * b6d75f1 [feature] stuff on feature branch
> * 43dba08 stuff on feature branch
> * ab7efdd [master] init
>
> When I merge the graph looks likes this:
>
> * b6d75f1 [master] [feature] stuff on feature branch
> * 43dba08 stuff on feature branch
> * ab7efdd init
You're getting a so-called "fast-forward" merge,
which is the default. Turn it off with:
git merge --no-ff
^ permalink raw reply
* Re: [PATCH v2] commit -c/-C/--amend: reset timestamp and authorship to committer with --reset-author
From: Erick Mattos @ 2009-11-05 19:11 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nanako Shiraishi, git
In-Reply-To: <7vws25a5s2.fsf@alter.siamese.dyndns.org>
Hey, I do understand you can be very stressed. It is a huge project.
Very important for an uncountable group of people. A lot of demands
and argumentation from all over.
I know too that it is human nature to ask other people to agree with
them completely. Much more when they are in charge.
So, no problem. It was just a big surprise when I read your email.
You had been so nice to me until that moment...
But let's keep talking about code. I am not a big fan of human nature subjects.
Although I have to be more personal for just a little. I want to show
you my way of seeing things:
I love defaults! A command or an option already set for the most
common scenario... It's wonderful.
But I like to have full control of any tool I use. If I want to do
any bizarre thing nobody has
ever thought about... I think I should be able to. Without any hacking.
I can hammer a nail with a wrench. But I would prefer a hammer for that.
I think your suggestions which changed the path of this intended
function since the beginning were very good for a default. So I think
--reset-author did it. Normally 95% of the time its behavior is what
people will be needing.
But cutting off a remote possibility for no heavy and unbearable
reason imho makes features incomplete. That is why I had suggested
not cutting off --author functionality when using --reset-author.
I did not try to conceive all possible uses for this combination but I
knew someone could find some. I have told you a simple case just to
picture some figures. Nanako showed you a case you agreed. Thanks
Nanako.
I was not defying your judgment or showing lack of respect to you. My
text after "---" was very clear about that. Thank you again Nanako
for showing me the importance of this little text.
About scripting abilities: I don't see a way to compare scripting
"levels". Scripts are so easy that you just know or not.
Different approaches could be compared. At start I really did not get
the use of the "t" folder tests. I thought it was just to show
functionalities.
Nanako in her critics made me understand within her speach the
importance of those tests. Then you clarified it much more later. So
I got those informations and made another script trying to test
--reset-author completely. Separating every bit of data that could
show a malfunctioning. And taking also the care of letting auditing
more reliable and informational.
So I accepted your rough saying about "teaching" as an explosion of stress.
I have to tell that our work-flow on that time was: you demanded and I
made a change. The script you added was an example to me under this
work-flow.
I am not a kid and I have a real and busy life but I do think spending
time sharing some changes I use to improve something which I value is
not a lost time. As you can see by the time I had sent the emails, I
was doing them overtime.
So I would like to make clear that I did and do want to help as much
as I can. If it is not possible to use my work then just know you and
every free software coder has a big fan in me. I will be transmitting
good energies to you all in any case.
No hard feelings. :-)
I hope you can continue doing the wonderful work you have been doing
for a very long future.
Best regards.
2009/11/5 Junio C Hamano <gitster@pobox.com>:
> Nanako Shiraishi <nanako3@lavabit.com> writes:
>
>> It may be wise to forbid a combination of options if it
>> encourages mistakes or a wrong workflow, but I don't think
>> using --author and --reset-author with 'git commit --amend'
>> is such a case.
>>
>> Imagine somebody other than you (eg. me) were the maintainer,
>> and a message by Szeder was sent with a good commit log message.
>>
>> http://article.gmane.org/gmane.comp.version-control.git/132029
>>
>> Then you sent a replacement patch that solves the same problem
>> in a more elegant way, but without anything that is usable as the
>> commit log message.
>>
>> http://article.gmane.org/gmane.comp.version-control.git/132041
>>
>> If I were the maintainer, I would find it very convenient if I can
>> work like this:
>>
>> % git am -s 132029 --- first I apply Szeder's version
>>
>> Then I see your message. Replace the code change but use Szeder's
>> log message.
>>
>> % git reset --hard HEAD^
>> % git am 132041 --- your version with no usable log message
>> % git commit --amend -s -c @{2} --author='Junio C Hamano <...>'
>
> Thanks.
>
> So you commit Szeder's and then commit mine (make them independent), and
> amend the log message of the latter using the message from the former, and
> assign the authorship of the latter to the resulting commit?
>
> That is a much more understandable argument than just claiming "--author
> should be usable with --reset-author" without clearly stating why that
> would help. I think you forgot to add --reset-author to the last command
> line, though.
>
> But I think it is showing that --reset-author is actually suboptimal way
> to solve your scenario. In the last command in your sequence, you don't
> want to add "--reset-author --author=X" but want "--reuse-only-message"
> option.
>
> And I think it makes much more sense than the alternative semantics we
> came up with during this discussion. --mine (or --reset-author) to
> declare that "I am the author" was not what we wanted after all(yes, I am
> guilty for suggesting it). What we want is "I am using -C/-c/--amend and
> I want to borrow only the message part from the named commit (obviously
> "amend" names the HEAD commit implicitly). Determine the authorship
> information (including author timestamp) as if I didn't use that option."
>
^ permalink raw reply
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Nicolas Pitre @ 2009-11-05 19:17 UTC (permalink / raw)
To: Andrzej K. Haczewski; +Cc: git, Johannes Sixt
In-Reply-To: <16cee31f0911050045t7a7301cdm39114997edfbfa60@mail.gmail.com>
On Thu, 5 Nov 2009, Andrzej K. Haczewski wrote:
> > However, my pthread_cond_init man page says:
>
> And that is weird, because mine man page says:
> [[[
> pthread_cond_init, pthread_cond_signal, pthread_cond_broadcast, and
> pthread_cond_wait never return an error code.
> ]]]
Maybe that's for a particular implementation.
Nicolas
^ permalink raw reply
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Nicolas Pitre @ 2009-11-05 19:22 UTC (permalink / raw)
To: Andrzej K. Haczewski; +Cc: git, Johannes Sixt
In-Reply-To: <16cee31f0911050051m4cd29827nca9c8238b21461a0@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1074 bytes --]
On Thu, 5 Nov 2009, Andrzej K. Haczewski wrote:
> 2009/11/5 Nicolas Pitre <nico@fluxnic.net>:
> > Careful. At the beginning of the function you'll find:
> >
> > if (delta_search_threads <= 1) {
> > find_deltas(list, &list_size, window, depth, processed);
> > return;
> > }
> >
> > That is, if we have thread support compiled in but we're told to use
> > only one thread, then the bulk of the work splitting is bypassed
> > entirely. Inside find_deltas() there will still be pthread_mutex_lock()
> > and pthread_mutex_unlock() calls even if no threads are spawned.
>
> Ah, I wasn't aware of that. Actually why would find_deltas lock if no
> threads are used? Maybe, for non-threaded call to find_deltas, locking
> could be factored out?
It is already factored out when thread support is not enabled.
When thread support is enabled but there is only one thread, there was
no point duplicating the code just to have a path without any mutexes,
especially on Linux where no performance difference could be measured.
Nicolas
^ permalink raw reply
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Nicolas Pitre @ 2009-11-05 19:25 UTC (permalink / raw)
To: Andrzej K. Haczewski; +Cc: kusmabite, git, Johannes Sixt
In-Reply-To: <16cee31f0911050100v76316dacye7edd8718a893f01@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1498 bytes --]
On Thu, 5 Nov 2009, Andrzej K. Haczewski wrote:
> 2009/11/5 Nicolas Pitre <nico@fluxnic.net>:
> > On Wed, 4 Nov 2009, Andrzej K. Haczewski wrote:
> >
> > What about:
> >
> > typedef struct {
> > HANDLE handle;
> > void *(*start_routine)(void *);
> > void *arg;
> > } pthread_t;
> >
> > DWORD __stdcall windows_thread_start(LPVOID _self)
> > {
> > pthread_t *self = _self;
> > void *ret = self->start_routine(self->arg);
> > return (DWORD)ret;
> > }
> >
> > static inline int pthread_create(pthread_t *thread, const void *unused,
> > void *(*start_routine)(void *), void *arg)
> > {
> > thread->handle = CreateThread(NULL, 0, windows_thread_start,
> > thread, 0, NULL);
> > [...]
> > }
>
> The problem I see is not with pthread_init, but pthread_join. Here's
> how it looks:
>
> int pthread_join(pthread_t thread, void **value_ptr);
>
> If pthread_t would be a struct, then we can't call pthread_join like
> that...
Why not? At least gcc is quite happy with such a construct. It
probably makes a copy of the stack before passing it though.
> At least that's what I though yesterday, but maybe it can be done like
> this:
>
> int win32_pthread_join(pthread_t *thread, void **value_ptr)
> {
> [...]
> }
>
> #define pthread_join(a, b) win32_pthread_join(&(a), (b))
>
> That way we don't need allocations to simulate pthread init/join API
Right.
Nicolas
^ permalink raw reply
* Re: [PATCH 1/4] MSVC: Fix an "unresolved symbol" linker error on cygwin
From: Junio C Hamano @ 2009-11-05 19:37 UTC (permalink / raw)
To: Johannes Sixt
Cc: Ramsay Jones, Junio C Hamano, GIT Mailing-list,
Marius Storm-Olsen
In-Reply-To: <4AF284EF.2030606@viscovery.net>
Johannes Sixt <j.sixt@viscovery.net> writes:
> Ramsay Jones schrieb:
>> Junio C Hamano wrote:
>>> Shouldn't this be solved by teaching the Makefile about this new "Cygwin
>>> but using MSVC as compiler toolchain" combination?
>>
>> Yes. Err... see patch #3 :-P
>
> A clarifiction: Junio talks about using the MSVC tools to build Cygwin
> programs, that is, to merely substitute Cygwin's gcc by MSVC, but to still
> link against cygwin's C runtime.
Actually I do not talk about that; at least I meant to.
> When the "MSVC build" of git is made, then the MSVC compiler is used, and
> this will always use Microsoft libraries in the resulting executables,
> regardless of whether "make MSVC=1" was called from a "cygwin environment"
> or from and "msys environment".
> This series is about fixing "make MSVC=1" when it is run from a "cygwin
> environment" by disentangling the MSVC and Cygwin configuration sections
> in the Makefile.
Yup.
I think we all three are in agreement that "When on Cygwin we do this"
part of the Makefile should be adjusted. Even though I lost track of the
exact text in "patch #3", I can tell from Ramsay's response that the
series is about that.
^ permalink raw reply
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Nicolas Pitre @ 2009-11-05 19:39 UTC (permalink / raw)
To: Andrzej K. Haczewski
Cc: git, kusmabite, Johannes Schindelin, Johannes Sixt, Paolo Bonzini
In-Reply-To: <1257439548-9258-1-git-send-email-ahaczewski@gmail.com>
On Thu, 5 Nov 2009, Andrzej K. Haczewski wrote:
> +static unsigned __stdcall win32_start_routine(void *arg)
> +{
> + pthread_t *thread = arg;
> + thread->value = thread->start_routine(thread->arg);
> + return 0;
> +}
I suppose you could reuse thread->arg for both the argument and the
returned value to save a word.
> +int win32_pthread_join(pthread_t *thread, void **value_ptr)
> +{
> + DWORD result = WaitForSingleObject((HANDLE)thread->handle, INFINITE);
Why are you casting thread->handle here? Why not simply declaring it as
a HANDLE?
Otherwise this looks pretty good now.
Nicolas
^ permalink raw reply
* Re: how to rebase backwards
From: David Kågedal @ 2009-11-05 19:12 UTC (permalink / raw)
To: Junio C Hamano, git, bill lam
In-Reply-To: <20091103093716.GD7117@debian.b2j>
bill lam <cbill.lam@gmail.com> writes:
> Thank you for detail explanation. From what you described, I begin
> with master commit D,
> $ git checkout -b deploy
> $ git commit --allow-empty -m deploy
But why on earth would you want to use --allow-empty? There is no reason
for that. Just let deploy be where it is when you created it (until you
actually add something to it).
> E
> /^ deploy
> ---A---B---C---D
> ^ master
>
> $ git rebase -i A
>
> v deploy
> B'--C'--D'--E'
> /
> ---A---B---C---D
> ^ master
>
> since E is an empty commit, I suppose content of D' E' and D are
> identical at this point. Is that correct?
Assuming you didn't intentionally change it during rebase, yes.
> If several months later, I forget which is the common ancestor for
> master and deploy, how do I generate the above graph or identify
> commit A as the common ancestor for these two branches?
That is exactly what git does all the time. You can use many
command. For instance git log --graph master...deply whill show you both
branches, starting from their common ancestor. "git merge-base deploy
master" will tell you that the common ancestor is. Etc.
--
David Kågedal
^ permalink raw reply
* Re: Automatically remote prune
From: Junio C Hamano @ 2009-11-05 20:05 UTC (permalink / raw)
To: John Tapsell; +Cc: Junio C Hamano, Git List
In-Reply-To: <43d8ce650911050005l6d120cb0h374f3c04b3948b25@mail.gmail.com>
John Tapsell <johnflux@gmail.com> writes:
> I omitted it just because, imho, it's not what I 'care about'. I'm
> not trying to help advanced users (Users that _want_ to keep
> remotes/origin/* clean and users that _want_ to be careful to not lose
> commits are both advanced users, imho). I'm just interested in
> reducing confusion for non-advanced users.
I _think_ you are saying that your non-advanced users expect "branch -r"
output to be in sync (to the extent possible without going over the
network every time it is run) with the remote side. It is the same thing
as keeping remotes/origin/* free of stale remote branches, i.e. they are
in the first camp. There is nothing advanced about either of the camps.
The former wants the view to be in sync, the latter wants a way to avoid
information loss.
It is understandable to expect "branch -r" output to be in sync with the
other end, especially if one has CVS/SVN mentality but even if one
doesn't, I would say it is a reasonable thing to expect.
I am open to an optional feature to "git fetch' to prune them, but I would
not make it the default from day one. When introducing a change that
causes information loss, our migration strategy has always been "Give an
option first, release and wait for two releases or so, and then start
discussing to change the default behaviour."
The necessary change to "git fetch" shouldn't be too hard to code, as we
are already doing this in mirror mode.
^ permalink raw reply
* Re: [PATCH] MSVC: Windows-native implementation for subset of Pthreads API
From: Andrzej K. Haczewski @ 2009-11-05 20:09 UTC (permalink / raw)
To: Nicolas Pitre
Cc: git, kusmabite, Johannes Schindelin, Johannes Sixt, Paolo Bonzini
In-Reply-To: <alpine.LFD.2.00.0911051434090.10340@xanadu.home>
2009/11/5 Nicolas Pitre <nico@fluxnic.net>:
> On Thu, 5 Nov 2009, Andrzej K. Haczewski wrote:
>
>> +static unsigned __stdcall win32_start_routine(void *arg)
>> +{
>> + pthread_t *thread = arg;
>> + thread->value = thread->start_routine(thread->arg);
>> + return 0;
>> +}
>
> I suppose you could reuse thread->arg for both the argument and the
> returned value to save a word.
You're right! J6t committed already, what can I do now?
> Why are you casting thread->handle here? Why not simply declaring it as
> a HANDLE?
Just to silence MSVC warnings. WaitForSingleObject requires HANDLE,
_beginthreadex() returns uintptr_t. It's just a matter of where would
I put cast ;).
--
Andrzej
^ permalink raw reply
* Re: Problem signing a tag
From: Junio C Hamano @ 2009-11-05 20:09 UTC (permalink / raw)
To: Michael J Gruber; +Cc: Joshua J. Kugler, Alex Riesen, git
In-Reply-To: <4AF28CE4.5000906@drmicha.warpmail.net>
Michael J Gruber <git@drmicha.warpmail.net> writes:
> Dig dig dig... gpg exits with 2 in a lot of cases, one would need to
> parse fd-error to find out more. But it also looks as if gpg exits
> normally with a good passphrase. So I tried, and at least with gpg 1.4.9
> and git 1.6.5.2 I can sign tags with "use-agent" and without a running
> agent: I get asked for the passphrase (after reporting the agent MIA),
> and everything's fine.
>
> My gpg returns 0 in this case; it returns 2 only if I don't enter the
> passphrase. So, this seems to depend on the version of gpg. Or on
> entering the correct passphrase ;)
If the problematic gpg that gives 2 is older than yours, the situation
looks to me that "exiting 2 when failed to contact agent but got a good
passphrase some other way and successfully signed" was diagnosed as a bug
and then fixed in gpg. If that is the case can we find out which version
that fix is in, and add an entry to FAQ to help next person who will be
hit by this when using "tag -s"?
^ permalink raw reply
* Re: [PATCHv5 2/5] gitweb: Incremental blame (using JavaScript)
From: Petr Baudis @ 2009-11-05 20:22 UTC (permalink / raw)
To: Jakub Narebski
Cc: git, Fredrik Kuivinen, Giuseppe Bilotta, Luben Tuikov,
Martin Koegler
In-Reply-To: <1251805160-5303-3-git-send-email-jnareb@gmail.com>
Hi!
Many thanks for nurturing this patch.
On Tue, Sep 01, 2009 at 01:39:17PM +0200, Jakub Narebski wrote:
> Roads not taken (perhaps that should be part of commit message?):
> * Move most (or all) of "git blame --incremental" output parsing to
> server side, and instead of sending direct output in text/plain,
> send processed data in JSON format, e.g.
>
> {"commit": {
> "sha1": "e83c5163316f89bfbde7d9ab23ca2e25604af290",
> "info": "Kay Sievers, 2005-08-07 21:49:46 +0200",
> "author-initials": "KS",
> ...
> },
> "src-line": 13,
> "dst-line": 16,
> "numlines": 3,
> "filename": "README"
> }
>
> (line wrapping added for readibility). This would require however
> taking care on Perl side to send properly formatted JSON, and on
> JavaScript side including json2.js code to read JSON in gitweb.js
> (unless we rely on eval).
I don't know that much about web programming, what is wrong with
relying on eval?
(BTW, I have always thought that somewhat inevitable course in the
future will be to provide a web API, and basing it on JSON is probably
most natural choice. However, such an initiative needs to come from
actual web programmers.)
> * Using some lightweight JavaScript library (framework), like jQuery,
> Prototype, ExtJS, MooTools, etc. One one hand side this means not
> having to worry about browser incompatibilities as this would be
> taken care of by library; on the other hand side we want gitweb to
> have as few dependences as possible.
Normally, particular version of the library is simply included within
the project. E.g. in Girocco, I use MooTools for the tiny bit of
javascript I do. It is probably overkill to include it just for
incremental blame, but if we ever do much more, I think the much easier
web programming is worth the little trouble.
--
Petr "Pasky" Baudis
A lot of people have my books on their bookshelves.
That's the problem, they need to read them. -- Don Knuth
^ 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