การฟอร์แมตและการควบคุมเวอร์ชัน


23

เรื่องการจัดรูปแบบรหัส แม้เรื่องการเยื้อง และความมั่นคงมีความสำคัญมากกว่าการปรับปรุงเล็กน้อย แต่โครงการมักจะไม่มีคู่มือสไตล์ชัดเจนชัดเจนตรวจสอบได้และบังคับใช้ตั้งแต่วันที่ 1 และการปรับปรุงที่สำคัญอาจมาถึงทุกวัน บางทีคุณอาจพบว่า

SELECT id, name, address
FROM persons JOIN addresses ON persons.id = addresses.person_id;

อาจเขียนได้ดีกว่า / เขียนได้ดีกว่า

SELECT persons.id,
       persons.name,
       addresses.address
  FROM persons
  JOIN addresses ON persons.id = addresses.person_id;

ในขณะที่ทำงานเพื่อเพิ่มคอลัมน์เพิ่มเติมในแบบสอบถาม บางทีนี่อาจเป็นคำถามที่ซับซ้อนที่สุดในทั้งสี่ข้อความในรหัสของคุณหรือข้อความค้นหาเล็กน้อยในหมู่คนนับพัน ไม่ว่าการเปลี่ยนแปลงจะทำได้ยากเพียงใดคุณตัดสินใจได้ว่ามันคุ้มค่า แต่คุณจะติดตามการเปลี่ยนแปลงของรหัสในการเปลี่ยนแปลงการจัดรูปแบบที่สำคัญได้อย่างไร คุณเพียงแค่ยอมแพ้และพูดว่า "นี่คือจุดที่เราเริ่มต้นอีกครั้ง" หรือคุณสามารถฟอร์แมตแบบสอบถามทั้งหมดในประวัติพื้นที่เก็บข้อมูลทั้งหมด

หากคุณใช้ระบบควบคุมเวอร์ชันแบบกระจายเช่น Git คุณสามารถย้อนกลับไปสู่การคอมมิทครั้งแรกและฟอร์แมตใหม่จากที่นี่ไปเป็นสถานะปัจจุบัน แต่มันเป็นงานจำนวนมากและทุกคนจะต้องหยุดทำงานชั่วคราว (หรือเตรียมพร้อมสำหรับแม่ของการรวมทั้งหมด) ในขณะที่มันกำลังดำเนินอยู่ มีวิธีที่ดีกว่าในการเปลี่ยนประวัติศาสตร์ซึ่งให้ผลลัพธ์ที่ดีที่สุด:

  • สไตล์เดียวกันในทุกการกระทำ
  • ผสานงานน้อยที่สุด

?

การชี้แจงนี้ไม่ได้เกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดเมื่อเริ่มต้นโครงการ แต่ควรทำอย่างไรเมื่อการปรับโครงสร้างขนาดใหญ่ถือว่าเป็น Good Thing ™ แต่คุณยังต้องการประวัติย้อนหลังได้ ไม่เคยเขียนประวัติศาสตร์ใหม่ยอดเยี่ยมหากเป็นวิธีเดียวที่จะทำให้แน่ใจว่าเวอร์ชันของคุณใช้งานได้เหมือนเดิมเสมอ แต่ประโยชน์ของนักพัฒนาของการเขียนใหม่ทั้งหมดจะเป็นอย่างไร โดยเฉพาะอย่างยิ่งถ้าคุณมีวิธี (การทดสอบคำจำกัดความของไวยากรณ์หรือไบนารีที่เหมือนกันหลังจากการรวบรวม) เพื่อให้แน่ใจว่ารุ่นที่เขียนใหม่จะทำงานในลักษณะเดียวกับต้นฉบับหรือไม่


24
เหตุใดคุณต้องการเขียนประวัติใหม่ มันเอาชนะวัตถุประสงค์ของการควบคุมเวอร์ชัน คุณต้องการตรวจสอบให้แน่ใจว่าแอปพลิเคชันที่คุณจัดส่ง 3 เดือนที่ผ่านมาตรงกับฉบับแก้ไข xxxxxx โดยไม่ต้องสงสัยเลยแม้แต่น้อย แม้แต่การฟอร์แมตใหม่ก็ไม่อาจยอมรับได้
Simon Bergot

5
ฉันต้องการแสดงความคิดเห็นยอมรับว่าฉันทำสิ่งนี้ด้วยการติดแท็กด้วย "Reformat. ไม่มีการเปลี่ยนแปลงการทำงาน"
Rig

3
ในหัวข้อที่ไม่เกี่ยวข้องดูเหมือนว่าคุณกำลังแนะนำให้เขียนประวัติ Git ใหม่โดยทำการฟอร์แมตโค้ดทั้งหมดใหม่ อย่าให้ความคิดของผู้อื่นการเขียนประวัติ Git ใหม่นั้นไม่ดีสำหรับ 99.9% ของคดีทั้งหมด การฟอร์แมตใหม่ไม่ใช่ตัวพิมพ์ขอบ. 1%
แอนดรูว์ T ฟินเนล

4
ในบางภาษา (ฉันกำลังมองคุณอยู่ Python) การจัดรูปแบบใหม่สามารถเปลี่ยนการทำงานแบบลอจิคัลของรหัสได้ คุณจะต้องสามารถแยกวิเคราะห์ภาษาทั้งหมดที่จัดเก็บใน VCS ของคุณเพื่อติดตามและเพิกเฉยการฟอร์แมตใหม่ได้อย่างปลอดภัย
Joris Timmermans

3
การจัดรูปแบบใหม่เป็นการเปลี่ยนแปลงรหัสและควรกระทำเช่นนี้
David Cowden

คำตอบ:


26

ทำการฟอร์แมตใหม่แยกต่างหาก สิ่งนี้จะรบกวนประวัติย่อเล็กน้อยและคุณควรเห็นได้อย่างรวดเร็วว่าการกระทำนั้นเป็นการฟอร์แมตใหม่และการเปลี่ยนรหัสจริง มันอาจเบ้git blameและคล้ายกัน แต่ถ้าชี้ไปที่การฟอร์แมตอย่างเดียวมันจะค่อนข้างตรงไปข้างหน้าเพื่อหาการเปลี่ยนแปลงก่อนหน้านี้ก่อนหน้านั้น


ฉันเคยเห็นโครงงานที่ตกรางมาหลายสัปดาห์เพราะหนึ่งในนักพัฒนาคิดว่านี่เป็นความคิดที่ดี หากคุณกำลังจะทำสิ่งนี้ให้เข้าใจความเสี่ยงล่วงหน้าและตัดสินใจว่าคุณจะใช้การจัดรูปแบบไปไกลแค่ไหน ฉันคิดว่า mjfgates มีคำตอบที่ถูก
Johntron

1
ดูเหมือนทีมที่มีปัญหาจะมีปัญหามากกว่าการฟอร์แมตโค้ด แต่ใช่ฉันไม่แนะนำให้ทำเช่นนี้เว้นแต่คุณจะทำในสิ่งที่คุณต้องการ หากคุณต้องการทำการจัดรูปแบบการเปลี่ยนแปลงใหม่อีกครั้งฉันยังคงพูดได้ดีกว่าว่าคุณต้องแยกความแตกต่างมากกว่าการผสมผสานกับการเปลี่ยนแปลงการทำงาน
แฮรัลด์

ใช่ปัญหามากมาย: PI เพียงต้องการเตือนนักพัฒนาใหม่ว่ามันไม่ง่ายอย่างที่คิด เครื่องมือการจัดรูปแบบจำนวนมากมีความเสี่ยง (โดยเฉพาะถ้าคุณสร้างด้วยตัวเองด้วย regex - อย่างน้อยก็ใช้ AST) และถ้าคุณสนใจเกี่ยวกับการตรวจสอบโค้ดและการติดตามบั๊กมันจะยุ่งกับกระบวนการของคุณ ส่วนตัวฉันเขียนรหัสของฉันให้สอดคล้องกับสไตล์ของแต่ละไฟล์แม้ว่าฉันจะไม่สนใจการตรวจสอบรหัสเมื่อฟังก์ชั่นบางอย่างมีการจัดรูปแบบใหม่ นักพัฒนาหลายคนได้รับการแขวนขึ้นอยู่กับรูปแบบรหัสและละเลยปัญหาที่ใหญ่กว่าเช่นสถาปัตยกรรมกระบวนการเครื่องมือ ฯลฯ
Johntron

ในการเขียนโปรแกรมไม่มีอะไรที่ง่ายอย่างที่คิด :)
46411

13

อย่าเขียนประวัติ VCSซ้ำอีก:มันขัดกับหลักการของ VCS

อย่าพยายามแก้ไขการจัดรูปแบบโดยอัตโนมัติ:เป็นการรักษาอาการไม่ใช่ปัญหาจริง (= นักพัฒนาไม่ปฏิบัติตามมาตรฐานการเข้ารหัส)

กำหนดมาตรฐานการเข้ารหัสและการจัดรูปแบบแนวปฏิบัติที่ดีที่สุดในเอกสารทั่วไปและให้นักพัฒนาทั้งหมดเห็นด้วย

คุณพูดถึง Git ซึ่งยอดเยี่ยมเพราะมันเผยแพร่ ด้วย DVCS มันง่ายมากที่จะบังคับใช้ปฏิบัติที่ดีที่สุดผ่านขั้นตอนการทำงานยาม Gatekeepers ปฏิเสธข้อเสนอการรวม (= คำขอการดึงใน Git) ที่ไม่สอดคล้องกับหลักเกณฑ์ทั่วไป และฉันหมายถึงการปฏิเสธเป็นตัวอักษรหนามิฉะนั้น coder ที่ละเมิดจะไม่สนใจที่จะปฏิบัติตามกฎและทำซ้ำความผิดพลาดเดิมต่อไป

เทคนิคนี้ใช้ได้ดีสำหรับฉัน โคเดอร์ต้องการให้งานของพวกเขารวมเข้าด้วยกันดังนั้นหลังจากความผิดพลาดเล็กน้อยในตอนแรกพวกเขาก็เริ่มทำตามกฎ

ตามการแก้ไขรหัสฐานที่มีอยู่ ... ฉันขอแนะนำให้ทำอย่างค่อยเป็นค่อยไปบางทีอาจเป็นโมดูลโดยโมดูลหรือตามที่เหมาะสมสำหรับโครงการของคุณ ทดสอบอย่างรอบคอบในแต่ละขั้นตอน อาจฟังดูงี่เง่า แต่มีข้อผิดพลาดเกิดขึ้นแม้ว่าจะมีการเปลี่ยนแปลงเล็กน้อยเช่นการจัดรูปแบบดังนั้นควรเตรียมพร้อมสำหรับการกระแทกเล็กน้อยบนท้องถนน


1
ลดลงเนื่องจากผู้เขียนระบุอย่างชัดเจนว่าสิ่งนี้อยู่ในบริบทของโครงการที่ไม่ได้ขึ้นต้นด้วย "... คู่มือสไตล์ที่ชัดเจนสมบูรณ์ตรวจสอบได้และมีผลบังคับใช้ตั้งแต่วันที่ 1" เขาไม่สามารถรักษาปัญหาที่แท้จริงได้เพราะมันเกิดขึ้นแล้ว ฉันเห็นด้วยกับคุณ :)
Johntron

2
ปฏิเสธหมายความว่าจะมีการต่อสู้ระหว่างมนุษย์กับหุ่นยนต์ เคยไปที่นั่น. ไม่ช้าก็เร็วหุ่นยนต์จะต้องใช้โค้ดที่ซับซ้อนจริงๆในการจัดรูปแบบในแบบที่อ่านไม่ได้ ตัวอย่าง: สตริง Java เป็นจริงคำสั่ง SQL แต่หุ่นยนต์ไม่ทราบสิ่งนี้ ช่องว่างก่อนปิด parens อาจมีข้อมูลเกี่ยวกับโครงสร้างของรหัสสำหรับมนุษย์ แต่ไม่ใช่สำหรับหุ่นยนต์ พารามิเตอร์ฟังก์ชันรับการแบ่งข้ามหลายบรรทัดในวิธีที่ไร้ความหมายที่สุด ...
18446744073709551615

9

คำตอบสำหรับคำถามที่แท้จริงของคุณคือ "คุณทำไม่ได้" ฉันรู้ว่าไม่มีเครื่องมือ SCM ในปัจจุบันที่สามารถติดตามการเปลี่ยนแปลงในตรรกะจากโค้ดที่จัดรูปแบบในวิธีเดียวผ่านการเปลี่ยนแปลงการจัดรูปแบบที่สำคัญและผ่านการเปลี่ยนแปลงเพิ่มเติมหลังจากโค้ดถูกจัดรูปแบบในรูปแบบใหม่ และคุณรู้สิ่งนี้การสูญเสียประวัติในโค้ดบางส่วนนั้นไม่ดี

ดังนั้นฉันจะโต้แย้งประโยคแรกของคุณเล็กน้อย รหัสการจัดรูปแบบไม่สำคัญว่ามาก สวยดี แต่ไม่ใช่สิ่งที่เราทำ ผมเข้าใจเช่นเดียวกับทุกคนที่ได้รับการโยนลงไปคนอัปรีย์เก่าแปลก K & R ตัวแปรรหัสกับเยื้องสองพื้นที่ดูด (1) แต่ ... การจัดรูปแบบไม่จริงเป็นอุปสรรคต่อการทำความเข้าใจสิ่งที่เกิดขึ้นนอกจากจะเป็นสิ่งที่พิเศษเกี่ยวกับพยาธิวิทยา และในกรณีนี้คุณจะมีปัญหาในการเปลี่ยนรหัสอย่างไรก็ตามไม่ควรรบกวนมัน

ดังนั้นจึงไม่คุ้มค่าที่จะทำการเปลี่ยนแปลงโค้ดที่สร้างขึ้นอย่างเข้มงวดเพื่อทำการฟอร์แมทใหม่ การเปลี่ยนชื่อตัวแปรการเลิกใช้ฟังก์ชันที่ยาวนานสิ่งที่ refactoring ที่ดีทั้งหมดที่เปลี่ยนแปลงเนื้อหาใช่ แต่ไม่ใช่การฟอร์แมตใหม่

1) - ฉันเคยเป็นเจ้าของ Windows Clipboard Viewer มาระยะหนึ่งแล้ว สิ่งทั้งหมดคือหนึ่งโมดูล 150k โมดูล ฉันพบจุดที่ผู้คนต่างใช้กันฉันคิดว่ารูปแบบวงเล็บปีกกาห้าแบบภายในสามสิบบรรทัดของกันและกัน แต่ส่วนของสิ่งที่ทำงาน ฉันอุ้มโค้ดที่พิมพ์มาสิบปี แต่ฉันไม่ได้กระตุ้นเพราะประวัตินั้นสำคัญและรหัสนั้นอยู่ในซอร์สต้นไม้อย่างน้อยสามต้น (Windows 3.x, NT, 95 ในอนาคต) ที่อาศัยอยู่ทั้งหมด ในอาคารต่าง ๆ


ในอดีตการใช้hgงานฉันพบว่าการผสานชิ้นส่วนเป็นเครื่องมือที่มีค่ายิ่งในการจัดการกับการรวมตัวกันครั้งใหญ่เข้าด้วยกัน โดยทั่วไปสิ่งที่ฉันจะทำคือการรวมการกระทำก่อนที่จะรวมปัจจัยขนาดใหญ่เข้าด้วยกันจากนั้นรวมการรวมตัวกันครั้งใหญ่เข้าด้วยกันอีกครั้ง การรวมสามอย่างนี้ด้วยตนเองนั้นง่ายกว่ามากแล้วพยายามที่จะแก้ปัญหาความยุ่งเหยิงที่เกิดจากการผสานทั้งหมดในคราวเดียว
Mark Booth

ฉันเห็นด้วยอย่างยิ่ง! นอกจากนี้ฉันได้เห็นนักพัฒนาหลายคนลงน้ำ (รุ่นน้องของฉันรวมอยู่) ในการฟอร์แมตและสไตล์โค้ดและพวกเขาก็จบลงด้วยการแนะนำข้อบกพร่อง เครื่องหมายจุลภาค / อัฒภาคที่ขาดหายไปที่นี่การประกาศตัวแปรย้ายไปที่ด้านบนสุดของฟังก์ชั่น for-loops เปลี่ยนเป็นสำหรับแต่ละคน - พวกเขาทั้งหมดสามารถแนะนำข้อบกพร่องที่ลึกซึ้ง ต้องใช้ทักษะที่หลอกลวงเพื่อทำการเปลี่ยนแปลงเหล่านี้อย่างปลอดภัย
Johntron

4

แต่คุณจะติดตามการเปลี่ยนแปลงของรหัสในการเปลี่ยนแปลงการจัดรูปแบบที่สำคัญได้อย่างไร

การเปลี่ยนแปลงการจัดรูปแบบที่มีการเปลี่ยนแปลงรหัส; ปฏิบัติต่อพวกเขาเหมือนที่คุณจะเปลี่ยนแปลงรหัสของคุณ ทุกคนที่ทำงานในโครงการสำคัญอาจจะเห็นข้อบกพร่องและปัญหาอื่น ๆ ที่สร้างขึ้นเมื่อมีคนตัดสินใจที่จะ "ฟอร์แมต" เพียงแค่ฟอร์แมตโค้ดใหม่

แต่มันเป็นงานจำนวนมากและทุกคนจะต้องหยุดทำงานชั่วคราว (หรือเตรียมพร้อมสำหรับแม่ของการรวมทั้งหมด) ในขณะที่มันกำลังดำเนินอยู่

ทำไมคุณต้องฟอร์แมตใหม่ทุกอย่างในเวลาเดียวกัน โดยเฉพาะอย่างยิ่งหากการจัดรูปแบบไม่เปลี่ยนความหมายของรหัสคุณควรจะสามารถฟอร์แมตไฟล์แยกต่างหากและตรวจสอบในขณะที่คุณไป ดีกว่าให้ทุกคนในทีมของคุณเห็นด้วยกับสไตล์ (ไม่เช่นนั้นจะไม่มีประเด็นในการจัดรูปแบบใหม่) และให้พวกเขาดูแลการฟอร์แมตในงานอื่น ๆ ของพวกเขา หลังจากผ่านไปครู่หนึ่งคุณจะได้ครอบคลุมส่วนใหญ่ของรหัสโดยไม่กระทบกับส่วนที่เหลือของโครงการ


1

มีสองแนวทางปฏิบัติที่ฉันได้เห็นในเรื่องนี้

1. ฟอร์แมตโค้ดบน commit-hook

แม้ว่าขั้นตอนแรกคือการปลูกผมเพื่อเปลี่ยนรหัสหลังจากที่พวกเขาส่งมันหากขั้นตอนการจัดรูปแบบของคุณ (เช่นastyle ) ไม่ทำให้รหัสเกิดความเสียหาย แต่เป็นการทำงานที่ปลอดภัย เมื่อเวลาผ่านไปทีมงานทุกคนจะชื่นชมว่ารหัสทั้งหมดในที่สุดดูเหมือนกัน เห็นได้ชัดว่ามีการทดสอบหน่วย / อัตโนมัติที่ครอบคลุมจะช่วยให้มั่นใจได้ว่าไม่มีอะไรพัง

2. การฟอร์แมตใหม่เพียงครั้งเดียวของรหัสทั้งหมด

สิ่งนี้เป็นสิ่งที่อันตรายมากสำหรับประสบการณ์ของฉันและทำให้ปัญหาการติดตามของบิ๊กแบงยาก แต่ก็เป็นไปได้ การรันการทดสอบทั้งหมดหลังจากนั้นเป็นสิ่งจำเป็น สำหรับรูปแบบการเข้ารหัสความแตกต่างส่วนใหญ่เกี่ยวข้องกับการใช้ช่องว่าง - เยื้องหรือการขึ้นบรรทัดใหม่ เครื่องมือผสานที่ดีควรบอกให้ละเว้นความแตกต่างของช่องว่างทั้งหมดดังนั้นสิ่งนี้จะช่วยในการผสาน


1
ตัวเลือกหนึ่งจะไม่เมื่อเปิดกระเพื่อมข้ามส่วนใหญ่ของรหัสฐานอย่างรวดเร็วส่งผลให้บิ๊กแบงเดียวกันของการเปลี่ยนแปลงแต่ละไฟล์?
ลงชื่อ

@ เข้าสู่ระบบ: จุดของฉันแน่นอน - เมื่อการเปลี่ยนแปลงเบ็ดกระทำประวัติของคุณอาจลดลงเป็นสิ่งที่ไร้ประโยชน์เกือบ การจัดรูปแบบที่ไม่เปลี่ยนแปลงการทำงานไม่ควรกระทำ แต่ควรทำการปลูกถ่ายตลอดประวัติรหัส
l0b0

1
หากการสนับสนุนของ IDE มันก็มี 3) มีการจัดรูปแบบอัตโนมัติ IDE ที่บันทึก จากนั้นใช้การตั้งค่าเดียวกันทุกที่ - นี่เป็นวิธีที่ง่ายที่สุดถ้าคุณใช้ค่าเริ่มต้นกับ IDE

ฉันได้ทำทั้งสองวิธีแล้ว วิธีแรกนั้นไม่น่าไว้วางใจมากนักเนื่องจากจะมีการเปลี่ยนแปลงมากมายทุกครั้งที่มีการสร้างไฟล์ใหม่เป็นครั้งแรก วิธีที่สองดีกว่าสำหรับทีมเช่นการริพแบนด์ bandaid อย่างรวดเร็ว
Druska
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.