سؤال

لقد أفسد أحد زملائي محتويات دليل في مستودع CVS الرئيسي. أحتاج فقط إلى إعادة الوحدة بأكملها إلى الحالة التي كانت في نهاية العام الماضي. ما هو أمر CVS للقيام بذلك من فضلك؟

لقد أضاف وإزالة مئات الملفات ، لذا فإن "نسخ عبر الملفات من Old Checkout and Complay" لا يكفي.

لدي RTFM و STFW ، وجربت هذا:

cvs co modulename  # Note no -P option
cvs up -jHEAD -jMAIN:2008-12-30 modulename

لكن هذا لا يعمل - يتم إزالة الملفات الجديدة التي أنشأها ، لكن الملفات والأدلة القديمة لا يتم إحياءها. (لم ارتكبها).

ربما يمكنني كتابة نص Shell لهذا ، ولكن بالتأكيد يجب أن تكون هذه الوظيفة في CVS بالفعل؟

تحديث: بعض التوضيحات:

  • يمكنني الحصول على ملف الخروج المحلي من الوحدة في تاريخ محدد. والسؤال هو كيفية إعادة ذلك إلى السير الذاتية.

  • لديّ نسخ احتياطية ، لكن النقطة التي تستخدم نظام التحكم في المراجعة مثل CVS هو أنه من المفترض أن يكون من السهل الحصول على أي حالة تاريخية. في المرة القادمة التي يحدث فيها شيء من هذا القبيل ، قد لا أكون محظوظًا بما يكفي للحصول على نسخ احتياطية (على سبيل المثال ، النسخ الاحتياطية يوميًا ، لذلك قد أخسر حتى يوم عمل واحد).

  • أعلم أن السير الذاتية قديمة ، ويجب أن ننتقل إلى شيء أحدث. ولكن في فريق كبير يحتوي على عدد كبير من الأدوات القائمة على السير الذاتية (الخروج والبرامج النصية للبناء ، خادم البناء الليلي ، إلخ) تكون تكلفة الوقت لهذه الخطوة كبيرة. (التقييم ، تحديث البرامج النصية ، الاختبار ، الترحيل ، التدريب ، وقت المطور المفقود ، الحفاظ على كلا النظامين بالتوازي مع CVS لا يزال هناك حاجة للفروع القديمة). وبالتالي ، يجب التخطيط لها وجدولة من قبل الإدارة.

تحديث رقم 2: سأبدأ مكافأة على هذا. للتأهل للحصول على المكافأة ، عليك أن تشرح كيفية العودة باستخدام أوامر CVS العادية ، وليس باستخدام البرنامج النصي Shell.

التحديث رقم 3: الخادم هو CVS 1.12.13. الوصول هو عبر pserver. يمكنني استخدام نفس الإصدار من CVS على جهاز كمبيوتر Linux ، أو CVSNT 2.0.51D العميل على Windows.

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

المحلول

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

mkdir code_base1 && cd code_base1
cvs co -D "2008-12-30" modulename
cvs tag code_base_2008_12_30

الآن قم بالانضمام المستند إلى علامة ، وطرح جميع التغييرات من الآن و 2008-12-30:

cd .. && mkdir code_base2 && cd code_base2
cvs co modulename
cvs update -d -j HEAD -j code_base_2008_12_30  # use -d to resurrect deleted directories

قارن محتويات code_base1 و code_base2. يجب أن تكون متطابقة باستثناء معلومات التعريف CVS. أخيرًا ارتكب الرمز كما كان في الفترة 2008-12-30 كرئيس جديد:

cvs commit -m "Revert all changes this year"

لاحظ أن وضع علامة الرمز الذي ترغب في الانضمام إليه مثل هذا لن يعمل ، لأن RTAG لا تتعامل مع الملفات والأدلة التي تمت إزالتها بشكل صحيح ، عند استخدام -D:

cvs rtag -D "2008-12-30" code_base_2008_12_30 modulename

نصائح أخرى

هناك العديد من المشكلات في CVS وأنت تضربهم بمثل هذه المشكلة.

  1. CVS موجهة نحو الملف ، لا مفهوم للتغييرات أو snasphot. هذا يعني أن التغييرات مثل تلك التي تريد العودة إليها من الصعب بعض الشيء التعامل معها. الالتزامات ذرية داخل دليل معين ، وليس خارج.

  2. الدلائل ليست نسخة. هذا يعني أنه سيتم حذف الدلائل الفارغة (إذا قمت بالتحديث مع -P) وعليك تحديدها -d لإنشاءها على الخروج/التحديث.

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

تعليقي حول النسخ الاحتياطية هو أنه قد يكون من الأسهل استعادة الريبو بأكمله من النسخ الاحتياطية بدلاً من محاولة تصحيح الأشياء التي ليست جيدة حقًا.

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

أعتقد أن أمرك الثاني يجب أن يكون أيضًا الخروج ، بدلاً من التحديث. لا يمكنني تبرير ذلك بالمنطق ، حيث لا يوجد منطق في عالم السير الذاتية ، لكنه نجح بالنسبة لي. جرب هذا:

cvs co -P modulename
cvs co -P -jHEAD -jMAIN:2008-12-30 modulename

إذا كنت تعود فرعًا بخلاف الرأس ، على سبيل المثال ، قم بتمرير وسيطة -rx في كلا الأوامر:

cvs co -P -rX modulename
cvs co -P -rX -jHEAD -jMAIN:2008-12-30 modulename

ما زلت مهتمًا بمعرفة ما إذا كانت هناك طريقة أسهل. (يجب أن يكون هناك بالتأكيد طريقة أسهل). ما انتهى بي الأمر هو ، على جهاز كمبيوتر Linux باستخدام Bash:

# Get woking copy we're going to change
cd ~/work
rm -rf modulename
cvs up -dP modulename
cd modulename

# Remove all files
find . -name CVS -prune -o -type f -print | xargs cvs rm -f

# Get the old revision
cd ~
mkdir scratch
cd scratch
cvs -q co -D 2008-12-31 modulename
cd modulename

# Copy everything to the working dir and do "cvs add" on it
find . -name CVS -prune -o -type f -print | \
    xargs tar c | \
    (cd ~/work/modulename && tar xv | \
    xargs cvs add)

# Check everything is OK before we commit
cd ~/work/modulename
cvs -nq up

# it gave me an error on readme.txt because I'd deleted and then added it, so:
mv readme.txt x # save good rev
cvs add readme.txt # resurrect the bad rev
mv x readme.txt # clobber file with good rev

# Commit it
cvs commit -m "Revert all changes this year"

# Delete now-empty directories
cvs -q up -dP

# Double-check everything is back how it was
diff -ur -xCVS ~/scratch/modulename ~/work/modulename

ثم اكتشفت أنه لا تزال هناك اختلافات - أضاف زميلي أسماء ملفات تحتوي على مساحات ، لم يتم حذفها بواسطة العملية أعلاه. اضطررت إلى حذف هؤلاء بشكل منفصل. (كان يجب أن أستخدم find ... -print0 عوضا عن -print, ، ومرت -0 حجة ل xargs. لم أدرك أن هناك ملفات ذات مسافات.)

يمكنك النظر في CVSPs. ابحث في جوجل.

أيضًا ، مع لحاف (أو تصحيحات Andrew Morton ، وهو ما بدأه لحاف AS) و CVSPs ، يمكن الحصول على تقريب وثيق جدًا للتغييرات.

نرى http://geocities.com/smcameron/cvs_changesets.html

هل حاولت استخدام -d اختيار؟ (بناء الدلائل الفرعية)

بقدر ما أستطيع أن أتذكر ، فهو ضمني ل cvs co, ، ولكن ليس ل cvs up.

وفق http://www.astro.ku.dk/~aake/mhd/docs/cvs.html, ما يلي هو ما تحتاجه:

cvs update -D "30 Dec 2008 23:59"

مشكلة كبيرة ، ليس لديك إجابة كاملة ، مجرد نصيحة على البرمجة النصية الخاصة بك للتعامل مع المساحات في أسماء الملفات.

بدلاً من

find ... | xargs tar c - | ...

حاول وضع

find ... | perl -e '@names = <>;' -e 'chomp @names;' -e 'system( "tar", "c", "-", @names);' | ...

وبهذه الطريقة ، لن يعاني إنشاء الأرشيف (أو العمليات المماثلة) من مسافات في الأسماء ، يتم تخطي تحليل Shell Argv قبل استدعاء القطران.

شيء آخر ، على فرصة الخروج ، يعمل فعليًا: إذا كانت هناك CVS إلى الأداة المساعدة SVN ، استخدمها (أفترض أن هذه الأداة المساعدة ستسحب الملفات المحذوفة من "CVS Attic") ، و إذا إنه يوفر كل لحظة من الزمن كنقطة تفتيش مستوى المشروع (نظرًا لأن SVN تقوم بذلك ، على عكس CVS) ، استخدم SVN لجلب اللحظة المناسبة في الوقت المناسب. الكثير من ifs ...

إذا كنت أو زميلًا مرتاحين لـ GIT ، فيمكنك استخدامها git cvsimport لإنشاء مستودع GIT يعكس مستودع CVS. يعد عودة الالتزام/التغييرات في GIT تافهة (باستخدام git revert). يمكنك بعد ذلك الاستخدام git cvsexportcommit لإرسال الالتزام بالعودة إلى CVS.

قد يبدو كل هذا أمرًا معقدًا بشكل مفرط ، ولكن في تجربتي git cvsimport و git cvsexportcommit تعمل بشكل جيد بمجرد إعداد كل شيء. ينتهي بك الأمر بكل قوة GIT شخصيًا على الرغم من أن المشروع لا يزال يستخدم CVS.

إذا كان لديك نسخة احتياطية من مستودعك (ملفات RCS الفعلية على الخادم ، على سبيل المثال على الشريط) ، يمكنك فقط استعادة هذا المجلد على خادم CVS إلى الحالة التي كان من قبل. لا تنس إيقاف خادم CVS قبل القيام بذلك (وأعد تشغيله بعد ذلك).

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