Git - ละเว้นไฟล์ระหว่างการผสาน


115

ฉันมี repo ที่เรียกว่าmyrepoบนbeanstalkเซิร์ฟเวอร์ระยะไกล

ฉันโคลนไปยังเครื่องในพื้นที่ของฉัน สร้างสาขาเพิ่มอีกสองสาขา: stagingและdev. ผลักดันสาขาเหล่านี้ไปยังระยะไกลเช่นกัน

ขณะนี้:

 local                   remote                   server
 --------------------------------------------------------  
 master  ==> Pushes to  `master`  ==> deployed to `prod`
 staging ==> Pushes to  `staging` ==> deployed to `staging`
 dev     ==> Pushes to  `dev`     ==> deployed to `dev`

ฉันมีไฟล์ที่เรียกว่าconfig.xmlแตกต่างกันในแต่ละสาขา

ฉันต้องการละเว้นไฟล์นี้ระหว่างการผสานเท่านั้น แต่ฉันต้องการให้รวมสิ่งนี้เมื่อฉันชำระเงินหรือโอนจาก / ไปยังสาขา repo

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

ฉันคิดว่า .gitignoreไม่ได้ผล ตัวเลือกอื่น ๆ คืออะไร? โปรดทราบว่าไฟล์ที่ละเว้นควรเป็นส่วนหนึ่งของการชำระเงินและการคอมมิตซึ่งเป็นสิ่งสำคัญ ควรละเว้นระหว่างการผสานเท่านั้น

ขอบคุณ!


ในโหมดเริ่มต้น git pull เป็นชวเลขสำหรับการดึงข้อมูลคอมไพล์ตามด้วย git ผสาน FETCH_HEAD ดังนั้นคุณจึงกล่าวถึงความขัดแย้งซึ่งกันและกัน
zzk

ฉันจะบอกว่ามันเป็นจุดชำระเงิน ไม่ดึง ฉันจะปรับปรุงคำถามให้ชัดเจน
Kevin Rave

การทำสำเนาGit ที่
givanse

2
คุณเคยหาวิธีแก้ปัญหานี้หรือไม่? แอตทริบิวต์ git มีประโยชน์เฉพาะในกรณีที่ไฟล์มีความขัดแย้งระหว่างสาขาที่ถูกรวมเข้าด้วยกันดังนั้นจึงไม่เพียงพอเสมอไป
pvinis

คุณมองเป็นสัญลักษณ์ (ไม่ตามด้วยคอมไพล์) หรือแม้แต่ฮาร์ดลิงก์เพื่อช่วยเหลือ?
Frank Nocke

คำตอบ:


94

ฉันแก้ไขปัญหานี้ได้โดยใช้คำสั่ง git merge กับ--no-commitตัวเลือกจากนั้นลบไฟล์ที่จัดขั้นไว้อย่างชัดเจนและเพิกเฉยต่อการเปลี่ยนแปลงไฟล์ เช่น: พูดว่าฉันต้องการละเว้นการเปลี่ยนแปลงใด ๆ ที่จะmyfile.txtดำเนินการดังนี้:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

คุณสามารถใส่คำสั่ง 2 & 3 ใน for loop ได้หากคุณมีรายการไฟล์ที่จะข้าม


2
ฉันจะเพิ่ม "--no-ff" หากคุณไม่ต้องการให้ไฟล์ถูกเขียนทับเมื่อการผสานเกิดขึ้นในกลยุทธ์กรอไปข้างหน้า
Ilia Shakitko

1
แล้วgit reset HEAD myfile.txtทำยังไงกันแน่? มันช่วยเป้าหมายของเราที่นี่ได้อย่างไร?
Kid_Learning_C

คุณวางบรรทัดที่ 2 และ 3 ในลูปได้อย่างไร?
AndroidDev

52

attributesฉันสิ้นสุดการหาคอมไพล์ พยายามแล้ว. ทำงานจนถึงตอนนี้ ยังไม่ได้ตรวจสอบสถานการณ์ทั้งหมด แต่มันควรจะเป็นทางออก

ผสานกลยุทธ์ - คุณลักษณะ Git



1
นี่คือลิงค์ที่ถูกต้องสำหรับส่วนกลยุทธ์การผสานของเอกสารแอตทริบิวต์ git: git-scm.com/book/en/v2/…
Adrian Laurenzi

3
พบสิ่งนี้อธิบายได้ดีในบทความmedium.com/@porteneuve/…
ShawnFeatherly

10
สิ่งนี้ดูเหมือนจะเป็นปัญหาหากไม่มีความขัดแย้ง? ไฟล์จะยังคงถูกรวม?
Brett

18

.gitattributes - เป็นไฟล์ระดับรูทของที่เก็บของคุณที่กำหนดแอ็ตทริบิวต์สำหรับไดเร็กทอรีย่อยหรือเซ็ตย่อยของไฟล์

คุณสามารถระบุแอตทริบิวต์เพื่อบอกให้ Git ใช้กลยุทธ์การผสานที่แตกต่างกันสำหรับไฟล์เฉพาะ ที่นี่เราต้องการรักษาสิ่งที่มีอยู่config.xmlสำหรับสาขาของเรา เราจำเป็นต้องตั้งค่าmerge=oursที่จะconfig.xmlอยู่ใน.gitattributesไฟล์

merge=ours บอกให้คอมไพล์ใช้ไฟล์ (สาขาปัจจุบัน) ของเราหากเกิดข้อขัดแย้งในการผสาน

  1. เพิ่ม.gitattributesไฟล์ที่ระดับรูทของที่เก็บ

  2. คุณสามารถตั้งค่าแอตทริบิวต์สำหรับ confix.xml ใน.gitattributesไฟล์

    config.xml merge=ours
    
  3. จากนั้นกำหนดกลยุทธ์การผสานหุ่นจำลองของเราด้วย:

    $ git config --global merge.ours.driver true
    

หากคุณผสานstagฟอร์มdevสาขาแทนที่จะมีข้อขัดแย้งในการผสานกับไฟล์ config.xml ให้เก็บ config.xml ของสาขา stag ไว้ที่เวอร์ชันใดก็ตามที่คุณมีในตอนแรก


16
แต่ถ้าไม่มีความขัดแย้งล่ะ? จะเก็บไฟล์บางไฟล์ระหว่างการผสานได้อย่างไร?
Igor Yalovoy

2
@IgorYalovoy: ถ้าไม่มีความขัดแย้ง ... ดีนี้เป็นเรื่องยุ่งยากเล็ก ๆ น้อย ๆ ที่มันใช้งานได้จริงจากรหัสกัญชา แต่ถ้าconfig.xmlเป็นอย่างสมบูรณ์ไม่เปลี่ยนแปลงจากฐานรวมทั้งรุ่นปลายสาขา Git ใช้เวลาเพียงรุ่นที่มีการเปลี่ยนแปลงโดยไม่ต้อง กำลังดูการmerge.ours.driverตั้งค่า ดังนั้นคุณถูกต้องที่จะกังวล
torek

1
คัดลอกวางจาก Git Docs: Merge Strategies - Git attributes Link
kyb

วิธีนี้ส่งผลให้ "รวมคอมมิต" ทุกครั้ง FYI
rsmets

2
"ของเรา" ดูเหมือนจะเป็นชื่อที่กำหนดเองสำหรับกลยุทธ์ใหม่ที่กำลังนำมาใช้ ฉันพบว่าสิ่งนี้สับสนเนื่องจากtheirsเป็นกลยุทธ์การผสานในตัว แต่ดูเหมือนว่าใคร ๆ ก็เขียน<pattern> merge=fooได้แล้วgit config --global merge.foo.driver trueก็จะได้ผลเหมือนกัน
Kyle Strand

8

คุณสามารถเริ่มต้นด้วยการใช้git merge --no-commitจากนั้นแก้ไขการผสานตามที่คุณต้องการเช่นโดยการยกเลิกการจัดเตรียมconfig.xmlหรือไฟล์อื่น ๆ จากนั้นทำการคอมมิต ฉันสงสัยว่าคุณต้องการทำให้มันเป็นอัตโนมัติต่อไปหลังจากนั้นโดยใช้ hooks แต่ฉันคิดว่ามันคุ้มค่าที่จะทำด้วยตนเองอย่างน้อยหนึ่งครั้ง


2
ไม่git attributesนำเสนอโซลูชั่นตรงหรือไม่? ฉันไม่เข้าใจเรื่องนี้ git-scm.com/book/th/…
Kevin Rave

4

คุณสามารถใช้.gitignoreเพื่อไม่ให้config.xmlออกจากที่เก็บจากนั้นใช้โพสต์คอมมิต hookเพื่ออัปโหลดconfig.xmlไฟล์ที่เหมาะสมไปยังเซิร์ฟเวอร์


1
ฉันรู้ว่านั่นเป็นการแฮ็ค ฉันพยายามหาวิธีแก้ปัญหาที่สะอาด แล้วคอมไพล์attributesล่ะ มีความคิดอย่างไรบ้าง? ฉันไม่เข้าใจเรื่องนี้ git-scm.com/book/th/…
Kevin Rave

1
ฉันไม่เคยได้ยินสิ่งเหล่านี้ฉันกำลังพยายามใช้แอตทริบิวต์ merge = our ซึ่งดูมีแนวโน้มดี
tlehman

1
คุณลักษณะ Git นั้นยอดเยี่ยมมาก! คุณยังสามารถบอกวิธีการกระจายไฟล์ที่ไม่ใช่ข้อความด้วยคอมไพล์ดังนั้นคุณสามารถใช้ pdf2text เพื่อ diff PDFs ได้!
tlehman

2

ตัวอย่าง:

  1. คุณมีสองสาขา: master,develop
  2. คุณสร้างไฟล์ในdevelopสาขาและต้องการละเว้นในขณะที่ผสาน

รหัส:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

คุณยังสามารถละเว้นไฟล์ที่มีนามสกุลเดียวกันได้

ตัวอย่างเช่นไฟล์ทั้งหมดที่มี.txtนามสกุล:

echo "*.txt merge=ours" >> .gitattributes

1

ที่นี่ git-update-index - ลงทะเบียนเนื้อหาไฟล์ในแผนผังการทำงานไปยังดัชนี

git update-index --assume-unchanged <PATH_OF_THE_FILE>

ตัวอย่าง:-

git update-index --assume-unchanged somelocation/pom.xml


เป็นเรื่องดีเมื่อกด แต่ก็ยังบ่นเมื่อการดึงอาจเขียนทับไฟล์
Rolf

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