2010-02-07 15 views
56

मैं सोच रहा था कि एक टीम प्रोजेक्ट से दूसरे टीम प्रोजेक्ट तक इतिहास के साथ स्रोत कोड को स्थानांतरित करने में सबसे अच्छा तरीका क्या हो सकता है। मैं काम की वस्तुओं, रिपोर्टिंग, या शेयरपॉइंट साइटों से चिंतित नहीं हूं, क्योंकि जिस प्रणाली को हम बहाल करने जा रहे हैं, वह इन कार्यक्षमताओं का उपयोग नहीं करता है। एक अलग टीम प्रोजेक्ट में जाने की इच्छा रखने का कारण यह भी तथ्य है कि मूल कार्यान्वयन (किसी तीसरे पक्ष द्वारा बनाए गए बैकअप से बहाल किया जा रहा है) एक तृतीय-पक्ष प्रक्रिया टेम्पलेट का उपयोग कर रहे थे जिसे हम उपयोग नहीं करना चाहते हैं आगे जा रहा है। हम माइग्रेशन पूर्ण होने के बाद कार्य आइटम ट्रैकिंग और रिपोर्टिंग का उपयोग शुरू करना चाहते हैं।टीम फाउंडेशन सर्वर - इतिहास के साथ चलती स्रोत

TFS Integration Platform एक संभावित परिदृश्य प्रतीत होता है। प्रलेखन के अनुसार, प्रक्रिया टेम्पलेट को बदलने के लिए इसका उपयोग किया जा सकता है। हालांकि, मैं उत्सुक था अगर tf.exe चाल वाक्यविन्यास काम कर सकता है? कुछ की तरह:

tf.exe चाल $/PROJECTA $/ProjectB

यह मेरी समझ है कि इस आदेश को ज्यादा एक नाम बदलने की कार्रवाई की तरह चल रही है, जबकि "चाल" स्रोत नियंत्रण Explorer में मेनू आइटम के साथ आगे बढ़ रहा है एक डिलीट की तरह और ऑपरेशन जोड़ें। साथ ही, क्या tf.exe move पथ वास्तव में उपयुक्त टीम प्रोजेक्ट के साथ फ़ोल्डरों के नीचे कोड को जोड़ता है, यह मानते हुए कि $/ProjectA एक प्रोजेक्ट के लिए रूट स्रोत नियंत्रण फ़ोल्डर है और $/ProjectB दूसरे के लिए रूट स्रोत नियंत्रण फ़ोल्डर है? यदि संभव हो तो इतिहास को संरक्षित करने में सक्षम होना महत्वपूर्ण है।

कोई सलाह या सुझावों की बहुत सराहना की जाएगी!

संपादित करें - इस परिदृश्य को संभालने के लिए किसी अन्य प्रोजेक्ट को ब्रांच करना - माइक्रोसॉफ्ट की तरह Branching Guidance दस्तावेज में चर्चा करता है? मुझे लगता है कि यह जवाब हो सकता है, क्योंकि इतिहास शाखा के साथ संरक्षित किया जाएगा। हालांकि, इस समय परीक्षण करने के लिए मुझे टीम फाउंडेशन सर्वर 2008 इंस्टेंस तक पहुंच नहीं है।

उत्तर

37

स्थानांतरित करें और नाम बदलें उपनाम हैं। कमांड लाइन या यूआई से टीएफएस के किसी भी संस्करण में बिल्कुल कोई फर्क नहीं पड़ता है।

उनमें से दोनों इतिहास को संरक्षित करते हैं। कम से कम 2005/2008 में, आप वर्जनेड इटिम टेबल में वही भौतिक वस्तु रखते हैं इससे कोई फर्क नहीं पड़ता कि नाम और/या पैरेंट पथ कितनी बार या कितना भारी रूप से बदलता है। वास्तव में आपके हिस्से पर बहुत सारे मैन्युअल काम किए बिना "फर्जी" नाम (हटाएं + जोड़ें) प्राप्त करने का कोई तरीका नहीं है।

हालांकि, यह संस्करण मॉडल सैद्धांतिक अर्थ में बहुत शुद्ध है, लेकिन इसमें कुछ व्यावहारिक गठजोड़ हैं। चूंकि अलग-अलग आइटम समय पर अलग-अलग बिंदुओं पर एक ही नाम पर कब्जा कर सकते हैं, इसलिए टीएफएस को आपके द्वारा भेजे जाने वाले किसी भी इनपुट को विशिष्ट रूप से पहचानने के लिए पूर्ण नाम + संस्करण की आवश्यकता होती है। आम तौर पर आप इस प्रतिबंध को नहीं देखते हैं, लेकिन अगर आपने टीएफ [डूसमिंग] $/newname -version: oldversion तो यह भ्रमित हो जाएगा और या तो एक त्रुटि फेंक देगा या किसी आइटम पर काम करेगा आप इरादा नहीं हो सकता है। आदेशों को सुनिश्चित करने के लिए आपको मान्य संयोजन (नया नाम + नया संस्करण या पुराना नाम + पुराना संस्करण) पारित करने के लिए सावधान रहना होगा।

टीएफएस 2010 कुछ हद तक कहानी बदलता है: यह एक शाखा है + कवर के नीचे हटाएं, जिससे आइटम आईडी बदलना पड़ता है। फिर भी, हर रोज़ कमांड जैसे गेट एंड हिस्ट्री "फिक" बहुत अच्छी तरह से हैं; पुराने ग्राहक लगभग 95% संगत हैं। लाभ यह है कि जब आपके पास सिस्टम में एकाधिक नाम हैं और पथ-आधारित आइटम लुकअप ऊपर के लिए उल्लिखित अस्पष्ट बनने लगते हैं, तो सर्वर बस आपके द्वारा निर्दिष्ट नाम स्वीकार करेगा और इसके साथ चलाएगा। यह समग्र सिस्टम प्रदर्शन में सुधार करता है और कई जाल को समाप्त करता है जो अपरिचित उपयोगकर्ताओं को काफी लचीला नहीं होने और 100% परिशुद्धता के साथ इतिहास को संरक्षित नहीं करते हैं (उदाहरण के लिए जब दो शाखाओं के विलय के दौरान नाम टकराव होते हैं)।

हाथ में समस्या के लिए रिटर्निंग ...

यह कह नाम बदलने tf $/PROJECTA $/projectB के रूप में सरल नहीं है। स्रोत नियंत्रण पेड़ में शीर्ष स्तर फ़ोल्डर्स टीम प्रोजेक्ट क्रिएशन विज़ार्ड के लिए आरक्षित हैं; आप उनके खिलाफ मानक टीएफ कमांड नहीं चला सकते हैं। आपको क्या करना होगा एक स्क्रिप्ट की तरह है:

Get-TfsChildItem $/ProjectA | 
    select -Skip 1 | # skip the root dir 
    foreach { 
     tf rename $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB") 
    } 

[ज़ाहिर है, आप इसे हाथ से कर सकते हैं, अगर वहाँ $ के तहत भी कई बच्चे नहीं/PROJECTA]

जहाँ तक gotchas मैं उल्लेख किया, पुराने इतिहास को देखने के बाद से मैं आपके लिए बहुत महत्वपूर्ण हूं। एक बार जब आप नाम बदलते हैं, टीएफ इतिहास $/ProjectA/somefile.cs काम नहीं करेगा। डिफ़ॉल्ट रूप से, टीएफ कमांड संस्करण = "नवीनतम" मानते हैं। इन विकल्पों में से कोई पूरा इतिहास आप चाहते हैं जाएगा:

  • tf इतिहास $/PROJECTA/somefile.cs; 1234 जहां changeset 1234 कदम से पहले था
  • tf इतिहास $/ProjectB/somefile.cs ; 5678 जहां परिवर्तन 5678 के बाद परिवर्तन था। या आप सिर्फ संस्करण छोड़ सकते हैं।

पूर्णता & डीबगिंग उद्देश्यों के लिए एक अंतिम विकल्प:

  • tf इतिहास $/PROJECTA/somefile.cs -slotmode। आप केवल बदलावों से पहले हुए परिवर्तनों को देखेंगे; लेकिन आप भी ऐसी किसी भी वस्तु है कि आइटम आप बी
  • नीचे ले जाया गया

(TFS 2010 में करने के लिए करने से पहले $/PROJECTA/somefile.cs "स्लॉट" में रहते थे हो सकता है या फिर उसके बाद के इतिहास देखेंगे , "स्लॉट मोड" डिफ़ॉल्ट व्यवहार है; अनुरोध करने के लिए एक -इटम मोड विकल्प है कि आपका लुकअप इतिहास भर में पता लगाया गया है जैसे कि यह 2008 के बजाय पथ आधारित था।)

संपादित करें - नहीं, शाखाकरण एक अच्छा विकल्प नहीं है। जबकि शाखाकरण पूरे सिस्टम को & पर प्रोजेक्टबी से प्राप्त करने के लिए सिस्टम में पर्याप्त मेटाडेटा छोड़ देता है, यह 2008 में बहुत उपयोगकर्ता के अनुकूल नहीं है। टीएफ विलय कमांड (कोई यूआई समकक्ष) सीखने में बहुत समय व्यतीत करने की योजना है। 2010 नाटकीय रूप से कई शाखाओं में बदलावों को देखने की आपकी क्षमता में सुधार करता है, लेकिन यह अभी भी एक नाम से साफ एकीकृत अनुभव नहीं है।

+0

वाह, रिचर्ड। बिल्कुल शानदार जानकारी। मैं इसे अपने परीक्षण प्रयोगशाला में कल की कोशिश करेंगे। आप पटकथा कहा था क्योंकि जड़ आरक्षित है बैकटिक' के उपयोग की आवश्यकता अगर मैं किसी फ़ोल्डर से नाम बदल रहा था जो रूट के नीचे एक स्तर था, तो मैं स्क्रिप्ट को छोड़ सकता था, फिर - सही? किसी भी तरह से - भयानक उत्तर। आपके समय के लिए धन्यवाद! –

+0

हाँ। मूल विचार प्रोजेक्टए का नाम बदलना है \ folder1 -> ProjectB \ folder1, ProjectA \ folder2 -> ProjectB \ folder2, आदि। स्क्रिप्ट सिर्फ आपके पास 50 फाइलें और फ़ोल्डर्स होने पर समय और प्रयास को बचाने के लिए है। –

+0

उत्कृष्ट। यह स्पष्ट करने के लिए बहुत बहुत धन्यवाद और आसान टी ओ समझो! –

16

ऊपर रिचर्ड का जवाब अच्छी तरह से लिखा गया है और स्थिति अच्छी तरह से बताता है। हालांकि, मेरे पास जोड़ने के लिए कुछ और व्यावहारिक गोचा था।

TFS2010 में, डिफ़ॉल्ट व्यवहार इसे लगता है फ़ाइल को स्थानांतरित करने की तरह आपको चाल से पहले सभी इतिहास खोने का कारण बनता है। आदेश मेरा उपयोगकर्ताओं का उपयोग करने की संभावना है (और प्रयोग किया जाता, ऐसा लगता है, VS2010 जीयूआई द्वारा) है:

tf history $/ProjectB/somefile.cs 

मेरे उपयोगकर्ताओं, somefile.cs के सभी इतिहास प्राप्त करने का इरादा से पहले और चाल के बाद । वे "उस कोड का इतिहास जो वर्तमान में $/ProjectB/somefile.cs में संग्रहीत हैं", किसी भी समय फ़ाइल नाम के बावजूद। शायद अन्य लोग इसे अलग-अलग देखेंगे।

पहले पकड़ लिया कि जीयूआई कि VS2010 TFS2010 का उपयोग करने में मेरे लिए प्रकट होता है initally कदम के बाद से ही इतिहास से पता चलता है। सूची में कम से कम हालिया आइटम नाम बदलें ऑपरेशन है। इसे एक सूक्ष्म छोटे ड्रॉप-डाउन तीर के साथ विस्तारित किया जा सकता है। नीचे के स्थान से इतिहास नीचे है। यदि आप इसे देखने के लिए नहीं जानते हैं, तो ऐसा लगता है कि आपका इतिहास खत्म हो गया है।

दूसरा पकड़ लिया है कि यदि आप बाद में PROJECTA हटाना (क्योंकि आप ProjectB के लिए प्रवास समाप्त होने पर, कहना है), इतिहास वास्तव में चला गया है है। $/ProjectB/somefile.cs के इतिहास में ड्रॉप-डाउन का विस्तार पुराने इतिहास का उत्पादन नहीं करता है।

+2

"ProjectA" को हटाने के खतरे को इंगित करने के लिए धन्यवाद और यह दृश्य इतिहास को कैसे प्रभावित करता है। –

+0

चेंजसेट आईडी के बाईं ओर छोटे तीर के माध्यम से "कम से कम हालिया" सूची को इंगित करने के लिए धन्यवाद। मैंने सोचा था कि मैंने अपना पूरा इतिहास खो दिया है :-( –

1

एक अन्य विकल्प (और मैं आसान लगता है) तो Git TFS the Git-TF कमांड लाइन उपकरण का उपयोग कर वापस करने के लिए निर्यात करने के लिए आयात करने के लिए है।

  • द्विआधारी, चॉकलेट या स्रोत कोड से गिट-टीएफ स्थापित करें।

  • क्लोन एक TFS फ़ोल्डर:

git tf clone https://myAcc.visualstudio.com/mycollection $/TeamProjectA/Main --deep

  • .Git/tf फ़ोल्डर और .Git/git-tf फ़ाइल को हटाने से TFS सर्वर से Git रेपो अलग।

  • खाली TFS फ़ोल्डर से कनेक्ट करने के लिए नए गिट रेपो को कॉन्फ़िगर करें।

git tf configure https://myAcc.visualstudio.com/mycollection $/TeamProjectB/Main --deep

  • मत भूलना --deep

git tf pull

आप इस बिंदु पर एक संदेश मिलना चाहिए "Git-tf: यह एक नव कॉन्फ़िगर किया गया भंडार है । TFS से लाने के लिए कुछ भी नहीं है। "

git commit -a -m "merge commit"

git tf checkin --deep

+0

प्रिय डेविड 4004। मैंने कोशिश की और कोड इतिहास बनाए रखा गया है, लेकिन सभी टाइमस्टैम्प आज सेट हो गए हैं और सभी उपयोगकर्ता मेरे अंदर बदल गए हैं। क्या यह काम करता है या मैं गायब हूं कुछ? – AllWorkNoPlay

+0

हां, यह एक उपद्रव है। मुझे नहीं पता कि इससे कैसे बचा जा सकता है, हालांकि मुझे संदेह है कि किसी प्रकार का संस्करण नियंत्रण निंजा टीएफएस के लिए एक स्क्रिप्ट लिख सकता है जो तारीख और लेखक की जानकारी निकालता है और सम्मिलित करता है। – david004

0

ऊपर मूल आदेश के बारे में: -

Get-TfsChildItem $/ProjectA | 
select -Skip 1 | # skip the root dir 
foreach { 
    tf rename $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB") 
} 

दोनों स्रोत और लक्ष्य नाम केस में उद्धरण से घिरा हो करने के लिए पूर्ण pathfilename में कोई भी स्पेस देखते हैं की जरूरत है । मैं यह मुश्किल $ पर यह करने के लिए मिल गया _। ServerItem के रूप में भाग निकले साथ "इसके आसपास रिटर्न कि पूरे बच्चे वस्तु और न सिर्फ .serverItem स्ट्रिंग। या अगर मैं स्ट्रिंग प्राप्त करने के लिए प्रबंधन कैसे किया, मैं जैसे अवांछित कैरिएज रिटर्न मिला

"
$ proj/फ़ोल्डर/फ़ाइल
"

अंततः मैं निम्नलिखित के साथ काम करने आदेश मिल गया है, लेकिन मैंने पाया कि इतिहास अभी भी स्थानांतरित हो नहीं करता है, जो पूरे मुद्दे था!तो मेरा मानना ​​है कि यह आदेश केवल स्रोत एक्सप्लोरर में दाहिने माउस क्लिक का उपयोग करने और नाम बदलने (या स्थानांतरित) का चयन करने का प्रत्यक्ष समतुल्य है।

$tfsServerString = "http://machine:8080/tfs/DefaultCollection" 
$tfs = Get-TfsServer $tfsServerString 
Get-TfsChildItem -server $tfs "$/Dest Project/MyTestProject" | select -Skip 1 | foreach { $sourceName = $_.serveritem; $targetName = $_.serveritem.replace("$/Dest Project/MyTestProject/", "$/Dest Project/Source/StoreControllers/dSprint/dSprint2/") ; ./tf rename `"$sourceName`" `"$targetName`" /login:myUser } 

यह भी ध्यान रखें, यह "से बचने के लिए

संबंधित मुद्दे