سؤال

من المفترض أن يكون تشغيل هذا أمرًا بسيطًا للغاية، ولكن لسبب ما لن يعمل مع مستودع Mercurial الخاص بي.كل ما أريده هو أن يتم تشغيل الريبو عن بعد تلقائيًا hg update كلما دفع شخص ما لذلك.لدي هذا في ملف .hg/hgrc الخاص بي:

[hook]
changegroup = hg update

بسيطة، أليس كذلك؟ولكن لسبب ما، هذا لا ينفذ أبدا.لقد حاولت أيضًا كتابة برنامج نصي لشل قام بذلك.بدا .hg/hgrc هكذا:

[hooks]
changegroup = /home/marc/bin/hg-update

وبدا تحديث hg كما يلي:

#!/bin/sh
hg help >> /home/marc/works.txt;
hg update >> /home/marc/works.txt;
exit 0;

ولكن مرة أخرى، هذا لا يتم تحديثه.محتويات hg help مكتوبة ل works.txt, ، ولكن لم يتم كتابة أي شيء من أجله hg update.هل هناك شيء واضح أفتقده هنا؟لقد كان هذا يضايقني منذ أيام ولا يبدو أنني أستطيع تشغيله.

تحديث

حسنًا، مرة أخرى، باستخدام -v تشغيل سطر الأوامر من محطة العمل الخاصة بي، والدفع إلى الريبو البعيد لا يطبع أي رسائل مطولة حتى عندما يكون لدي تلك الرسائل echo خطوط في .hg/hgrc.ومع ذلك، عندما أقوم بالدفع من نسخة الريبو على نفس نظام الملفات (لقد قمت بتسجيل الدخول عبر SSH)، هذا ما أحصل عليه:

bash-3.00$ hg -v push ../test-repo/
pushing to ../test-repo/
searching for changes
1 changesets found
running hook prechangegroup: echo "Remote repo is at `hg tip -q`"
echo "Remote repo wdir is at `hg parents -q`"
Remote repo is at 821:1f2656753c98
Remote repo wdir is at 821:1f2656753c98
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
running hook changegroup: echo "Updating.... `hg update -v`"
echo "Remote repo is at `hg tip -q`"
echo "Remote repo wdir is at `hg parents -q`"
Updating.... resolving manifests
getting license.txt
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Remote repo is at 822:389a6c7276c6
Remote repo wdir is at 822:389a6c7276c6

لذا فهو يعمل، ولكن مرة أخرى فقط عندما أقوم بالدفع من نفس نظام الملفات.لا يعمل إذا حاولت الدفع إلى الريبو من محطة عمل أخرى عبر الشبكة.

هل كانت مفيدة؟

المحلول

قضيت بعض الوقت في البحث عن هذا بنفسي.أعتقد أن الإجابة على المشكلة موصوفة بإيجاز هنا:

يجب إعادة توجيه الإخراج إلى Stderr (أو /dev /null) ، لأنه يتم استخدام stdout لدفق البيانات.

في الأساس، أنت لا تقوم بإعادة التوجيه إلى stderr، وبالتالي تلويث stdout.

نصائح أخرى

حسنًا، بعد المرور بنفس خطوات الإحباط التي مر بها مارك دبليو منذ فترة، وجدت أخيرًا حل المشكلة، على الأقل عند انتهاء الخدمة عن بُعد باستخدام البرنامج النصي hgwebdir WSGI.

لقد اكتشفت أنه عند استخدام هذا النوع من الدفع عن بعد عبر HTTP أو HTTPS، يتجاهل Mercurial ببساطة كل ما تكتبه في ملف .hg/hgrc أو مستودعك.ومع ذلك، دخول هوك في التكوين hgwebdir عمل الحيلة.

لذلك إذا كان المحصلة النهائية في الخاص بك hgwebdir.wsgi البرنامج النصي هو شيء من هذا القبيل

application = hgwebdir('hgweb.config')

يحتاج قسم التكوين [الخطافات] إلى الدخول في ما ذكر hgweb.config.

أحد العيوب هو أن هذه الخطافات يتم تنفيذها من أجلها كل مستودع المدرجة في قسم [المسارات] من هذا التكوين.على الرغم من أن HG تقدم وظيفة أخرى قادرة على WSGI (hgweb بدلاً من hgwebdir) لخدمة مستودع واحد فقط، إلا أنه لا يبدو أن هذه الوظيفة تدعم أي خطافات (كما أنها لا تحتوي على أي تكوين).ومع ذلك، يمكن التحايل على ذلك باستخدام hgwebdir كما هو موضح أعلاه وجعل Apache RewriteRule يرسم كل شيء في الدليل الفرعي المطلوب.هذا واحد يعمل بالنسبة لي:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/reponame
RewriteRule ^(.*)$ reponame/$2 [QSA]

استمتع باستخدام الخطافات البعيدة عبر HTTP :D

في البداية، أريد تصحيح بعض التعليقات أعلاه.

  • يتم استدعاء الخطافات أيضًا عند الضغط على نظام الملفات.
  • ليس من الضروري الاحتفاظ بالخطاف في الريبو الذي تريد أن يعملوا عليه.يمكنك أيضًا كتابة نفس الخطاف الموجود في سؤالك من جانب المستخدم.يجب عليك تغيير الحدث من Changegroup إلى Outgoing وأيضًا تحديد عنوان URL لمستودع الريبو البعيد باستخدام مفتاح -R.ثم إذا كان لدى المستخدم الذي يدفع امتيازات كافية في الريبو البعيد، فسيتم تنفيذ الخطاف بنجاح.

.hg/hgrc

[hooks]
outgoing = hg update -R $HG_URL

والآن نحو مشكلتك....أقترح إنشاء خطافات prechangegroup وchangegroup وطباعة بعض مخرجات تصحيح الأخطاء.

.hg/hgrc

[hooks]
prechangegroup = echo "Remote repo is at `hg tip -q`"
                 echo "Remote repo wdir is at `hg parents -q`"
changegroup    = echo "Updating.... `hg update -v`"
                 echo "Remote repo is at `hg tip -q`"
                 echo "Remote repo wdir is at `hg parents -q`"

واضغط أيضًا باستخدام المفتاح -v، حتى تتمكن من معرفة الخطاف الذي يعمل.إذا كنت لا تزال غير قادر على معرفة ذلك، قم بنشر النتيجة.كنت قد تكون قادرة على مساعدة.

كانت مشكلتي هي أن تطبيق hgwebdir الخاص بي كان يعمل كمستخدم "hg"، لكن المستودع كان مملوكًا لي، لذلك اضطررت إلى إضافة هذا الجزء من التكوين إلى hgweb.config لتشغيل الخطافات:

[trusted]
users = me

تحتاج إلى الحصول عليه في بعيد hgrc للمستودع.يبدو كما لو كان في الريبو المحلي الخاص بك.

يحرر:يعتمد ذلك أيضًا على كيفية الدفع.بعض الطرق لا تستدعي الخطافات على الجانب الأيمن.(SSH يفعل ذلك، أعتقد أن HTTP يفعل ذلك، ونظام الملفات يفعل ذلك لا)

تحرير 2:ماذا لو قمت بالضغط على "محليًا" على كمبيوتر الريبو البعيد.قد يكون لديك مستخدمين/أذونات مختلفة بين خادم الويب وملف hgrc.(راجع [الخادم] والتوجيهات الموثوقة لـ hgrc.)

واجهت نفس المشكلة في الدفع من Windows Eclipse عبر http، ولكن بعد التقاط stderr، وجدت أن المسار الكامل مطلوب لملف hg.bat.يبدو قسم الخطافات الخاص بي الآن كما يلي:

[hooks]
incoming = c:\Python27\Scripts\hg.bat update > hg_log.txt 2>>hg_err.txt

آمل أن يساعد هذا شخص آخر.ستيف تي

يحاول تشغيل تصحيح أخطاء الخطاف لمعرفة سبب عدم تشغيله.

من المحتمل أن يكون هناك مشكلة في الأذونات أو شيء من هذا القبيل.

استغرق بعض الوقت ولكن حصلت عليه العمل.

لقد بدأت مع

[hooks]
tag=set >&2
commit=set >&2

يقوم >&2 بتوجيهه إلى الخطأ القياسي حتى تظهره وحدات التحكم عن بعد.

عند التحكم عن بعد، يجب أن يتم إخراج ذلك في وحدة التحكم إذا كانت قيد التشغيل

hg push https://host/hg   -v

لم يكن كذلك.

كنت أستخدم hgweb.cgi لذلك قمت بالتبديل إلى hgweb.wsgi دون أي فرق.

ما اكتشفته هو أن بعض الخطافات لا يتم استدعاؤها عن بعد.

عندما قمت بالتبديل إليه

[hooks]
incoming= set >&2

يبدو أنه لا يتم استدعاء علامة الخطافات والالتزام ولكن يتم استدعاء مجموعة التغييرات والواردة.ولم أؤكد الآخرين.

الآن بعد أن نجحت في ذلك، عدت مرة أخرى إلى hgweb.cgi وكل شيء يعمل بنفس الطريقة.

السبب الذي وجدته لهذا لا علاقة له بإعادة التوجيه stdout ل stderr.وكما ترى في صفحة الويكي، لم يتم تحديدها في الإصدار الحالي للويكيhttps://www.mercurial-scm.org/wiki/FAQ#FAQ.2FCommonProblems.Any_way_to_.27hg_push.27_and_have_an_automatic_.27hg_update.27_on_the_remote_server.3F

المشكلة التي وجدتها موجودة الأذونات.

في الإعداد الأصلي الخاص بي، كان لدي مستخدم، دعنا نقول hguser مع الريبو في منزله، والنص /etc/init.d/hg.init للاطلاق hg serve.المشكلة هي hg serve كان يدار من قبل root, ، في حين أن معظم الملفات ضمن الريبو تتعلق بـ hguser (وقد تحول بعضهم إلى root في مرحلة ما، لكنه لن يمانع، لأنني سأصححها chown)

حل:

  • chown -R hguser:hguser /home/hguser/repo (لتصحيح كافة الملفات، العودة إلى hguser)
  • يطلق su hguser -c "hg serve ..." (في حالتي من /etc/init.d/hg.init)
  • changegroup = hg update -C تحت [hooks] في repo/.hg/hgrc كل عادة

الآن يجب أن تعمل على push

ملاحظة:في حالتي، أفضل التحديث لرئيس فرع معين، لذلك أستخدمه hg update -C -r staging, ، لإجراء تحديث الخادم المرحلي فقط على رأس الفرع المقصود، حتى لو كان tip من فرع آخر (مثل development على سبيل المثال)

راجع للشغل بلدي hg.init انتهى البرنامج النصي مثل هذا:(لاحظ ال su hguser جزء)

#!/bin/sh
#
# Startup script for mercurial server.
#
# @see http://jf.blogs.teximus.com/2011/01/running-mercurial-hg-serve-on-linux.html

HG=/usr/bin/hg
CONF=/etc/mercurial/hgweb.config
# Path to PID file of running mercurial process.
PID_FILE=/etc/mercurial/hg.pid

state=$1

case "$state" in
'start')
    echo "Mecurial Server service starting."
    (su hguser -c "${HG} serve -d --webdir-conf ${CONF} -p 8000 --pid-file ${PID_FILE}")
  ;;

'stop')
  if [ -f "${PID_FILE}" ]; then
    PID=`cat "${PID_FILE}"`
    if [ "${PID}" -gt 1 ]; then
      kill -TERM ${PID}
      echo "Stopping the Mercurial service PID=${PID}."
    else
      echo Bad PID for Mercurial -- \"${PID}\"
    fi
  else

    echo No PID file recorded for mercurial
  fi
  ;;

*)
  echo "$0 {start|stop}"
  exit 1
  ;;
esac

ملاحظة:الائتمان المستحق ل http://jf.blogs.teximus.com/2011/01/running-mercurial-hg-serve-on-linux.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top