คอมไพล์สามารถละเว้นบรรทัดเฉพาะได้หรือไม่?


116

ฉันใช้ git เพื่อซิงค์กับ phonegap ในขณะที่ทดสอบบนเบราว์เซอร์ดั้งเดิมของโทรศัพท์ ดังนั้นฉันจึงมีบรรทัดต่อไปนี้:

var isPhoneGap = false;

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

ฉันใช้ Gitx และเทอร์มินัลบน OSX 10.6


@ user494461: ตัวกรอง Git เป็นวิธีที่จะทำ: stackoverflow.com/a/16244970/520162
eckes

1
คุณตรวจไม่พบสภาพแวดล้อมและใช้ไฟล์กำหนดค่าสภาพแวดล้อมได้หรือไม่?
exussum

กล่าวโดยย่อ: ไม่ แต่ฉันได้เขียนสคริปต์ตัวประมวลผลก่อนที่จะค้นหาโค้ดที่แสดงความคิดเห็นและลบออกก่อนที่จะเผยแพร่เพื่อคอมไพล์ ตรวจสอบได้ที่นี่: github.com/franklinchou/ahk_config/blob/master/preprocess.sh
franklin

คำตอบ:


104

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

http://git-scm.com/figures/18333fig0702-tn.png

*.yourType filter=yourFilterName

(คุณสามารถตั้งค่าตัวกรองสำหรับไฟล์เฉพาะได้หากต้องการ)

ดำเนินการ:

  • yourFilterName.smudge(เปิดใช้งานgit checkout) และ

    git config --global filter.yourFilterName.smudge 'sed "s/isPhoneGap = .*/isPhoneGap = true/"'
    
  • yourFilterName.clean(เปิดใช้งานgit add)

    git config --global filter.yourFilterName.clean 'sed "s/isPhoneGap = .*/isPhoneGap = false/"'
    

ไฟล์ของคุณจะปรากฏในไม่เปลี่ยนแปลงแต่การตรวจสอบออกรุ่นจะมีค่าที่เหมาะสมสำหรับgit statusisPhoneGap


1
ขอบคุณสำหรับสิ่งนี้. ทำให้มันใช้งานได้ คุณรู้วิธีสร้างgit diff or git status` หรือไม่ไม่สนใจตัวกรอง ฉันยังสามารถมองเห็นสิ่งที่แตกต่างกัน? กรณีการใช้งานของฉันใช้สำหรับบันทึกการดีบัก ... ซึ่งในที่สุดฉันก็ต้องการลบ ... @jthill @VonC
timh

1
@timh ถ้าตัวกรองทำงานสถานะ git หรือ git diff ไม่ควรแสดงอะไรเลย
VonC

1
น่าเสียดายที่ไม่มีวิธีที่ง่ายกว่านี้ใน GIT git ละเว้น <filename> <linenumber> จะสะดวกมาก!
kiedysktos

22
@kiedysktos ผ้าลินินเบอร์? จะเกิดอะไรขึ้นถ้าหมายเลขบรรทัดเปลี่ยนไป?
VonC

วิธีนี้ใช้งานได้ดี แต่ผู้ใช้ Windows ระวัง gitconfig นั้นจู้จี้จุกจิกมากกับอักขระที่ต้องการเก็บไว้ดังนั้นเมื่อลองใช้นิพจน์ทั่วไปกึ่งแปลกใหม่คุณอาจประสบปัญหา ฉันลงเอยด้วยการวางสาย sed ในไฟล์ helper.sh แยกต่างหากที่ฉันเรียกจาก gitconfig ของฉันโดยsh ".git/helper.sh"ตรวจสอบให้แน่ใจว่าได้ส่งผ่านพารามิเตอร์ใด ๆ ที่จะ sed ด้วย"$@"(ฉันคิดว่าแค่ส่งผ่าน filepath)
ohaal

43

คุณสามารถใช้ได้

git update-index --assume-unchanged [file]

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

เมื่อไฟล์มีการเปลี่ยนแปลงที่สำคัญคุณต้องทำสิ่งนี้:

git update-index --no-assume-unchanged [file]

นอกจากนี้โปรดดูที่Git doc update-indexสำหรับ--[no-]assume-unchangedพารามิเตอร์

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


2
การทำเช่นนี้จะยังคงดึงเวอร์ชันใหม่เมื่อฉันทำการดึง git หรือไม่
Saad Rehman Shah

1
@ คาเฟอีนเมื่อคุณดึงคอมไพล์คุณจะได้รับเวอร์ชันล่าสุดที่คอมมิชชันนี่จะเป็นไฟล์สุดท้ายก่อนที่คุณจะเปลี่ยนเป็นไฟล์ '- สมมติ - ไม่เปลี่ยนแปลง'
Carlos

1
ฉันเชื่อว่า--skip-worktreeเป็นตัวเลือกที่ดีกว่าสำหรับวัตถุประสงค์ส่วนใหญ่ stackoverflow.com/a/39583010/4233593
Jeff Puckett


3
สิ่งนี้จะละเว้นการอัปเดตไฟล์ทั้งหมดไม่ใช่บรรทัดเฉพาะ
nikoss

6

Gitx ควรให้คุณยอมรับหรือเพิกเฉยต่อแต่ละบรรทัด (คุณอาจรู้อยู่แล้ว) แต่คุณต้องทำทุกครั้งที่กระทำ ฉันคิดว่ามันจะดีกว่าถ้ามีไฟล์กำหนดค่าต่อเป้าหมายการปรับใช้ (คุณสามารถกำหนดเวอร์ชันได้) และพารามิเตอร์รันไทม์บางตัวสำหรับอย่างไรก็ตามคุณกำลังเริ่มเซิร์ฟเวอร์ (เช่น./myserver --config=whatever.js)


5

ดำเนินการต่อhttps://stackoverflow.com/a/20574486/4935114 , @Mikeเสนอให้สร้างpre-commithook ซึ่งจะgrepอยู่ในไฟล์ที่จัดฉากสำหรับบรรทัดที่อาจต้องการละเว้น เบ็ดจะตรวจสอบว่าเส้นเหล่านั้นถูกจัดฉากหรือไม่ หากเป็นเช่นนั้นจะมีechoคำเตือนและexitมีรหัส1ดังนั้นกระบวนการคอมมิตจะไม่ดำเนินต่อไป

ได้รับแรงบันดาลใจจากคำตอบของ @ Mikeฉันพบว่าตัวเองใช้ตะขอรุ่นปรับปรุงซึ่งจะใช้ reset (พร้อม-pธง) บรรทัดเฉพาะที่เราต้องการเพิกเฉยโดยอัตโนมัติ

ฉันไม่แน่ใจว่าเบ็ดนี้จะทำงานให้สถานการณ์ที่คุณมีไฟล์จำนวนมากที่มีเส้นนี้ที่จะละเลย แต่เบ็ดจะมองหาการเปลี่ยนแปลงในสายนี้ในแฟ้มที่เฉพาะเจาะจงpre-commit buildVars.javaสคริปต์ hook มีลักษณะเช่นนี้เมื่อฉันทดสอบบนเครื่องของฉัน

#!/bin/sh

# this hook looks for lines with the text `var isPhoneGap = false;` in the file `buildVars.java` and it resets these lines to the previous state before staged with `reset -p`

if [[ $(git diff --no-ext-diff --cached buildVars.java | grep --count -e "var\ isPhoneGap[\ ]*=[\ ]*") -ne 0 ]]; then
    cat <<EOW
WARNING: You are attempting to commit changes which are not supposed to be commited according to this \`pre-commit\` hook
This \`pre-commit\` hook will reset all the files containing this line to it's previous state in the last commit.
EOW
    echo /$'\n'isPhoneGap$'\n'y$'\n'q | git reset -p
    # BONUS: Check if after reseting, there is no actual changes to be commited and if so, exit 1 so the commit process will abort.
    if [[ $(git diff --no-ext-diff --cached | wc -l) -eq 0 ]]; then
        echo there are no actual changes to be commited and besides the change to the variable \'isPhoneGap\' so I won\'t commit.
        exit 1
    fi
fi

คำอธิบาย

สิ่งที่ฉันทำคือการสะท้อนลำดับการควบคุมซึ่งค้นหานิพจน์ทั่วไปisPhoneGapในระหว่างresetกระบวนการโต้ตอบ ดังนั้นการลอกเลียนแบบผู้ใช้ที่กด/เพื่อค้นหาisPhoneGap, เครื่องรีดyเมื่อถามว่าเขาต้องการที่จะทิ้งแพทช์นี้และในที่สุดก็กดเพื่อออกจากการโต้ตอบqreset

กระบวนการแพทช์ย้อนกลับแบบโต้ตอบมีการบันทึกไว้ที่นี่: https://git-scm.com/docs/git-add#git-add-patch


หมายเหตุ:สคริปต์ข้างต้นสมมติว่าตัวแปรinteractive.singleKeyคือfalse. หากคุณกำหนดค่าเป็นของคุณให้trueลบคำสั่งใด ๆ ออก$'\n'จากechoคำสั่งทันทีหลังคำเตือน


3

นี่คือวิธีที่คุณสามารถทำได้ด้วยตัวกรอง git :

  1. สร้าง / เปิดไฟล์ gitattributes:
    • <project root> /. gitattributes (จะถูกผูกมัดใน repo)
      หรือ
    • <project root> /. git / info / attributes (จะไม่ผูกมัดกับ repo)
  2. เพิ่มบรรทัดกำหนดไฟล์ที่จะกรอง:
    • *.rb filter=gitignoreเช่นเรียกใช้ตัวกรองที่ตั้งชื่อgitignoreบน*.rbไฟล์ทั้งหมด
  3. กำหนดgitignoreตัวกรองในgitconfig:
    • $ git config --global filter.gitignore.clean "sed '/#gitignore$/'d"เช่นลบบรรทัดเหล่านี้
    • $ git config --global filter.gitignore.smudge catกล่าวคือไม่ต้องทำอะไรเลยเมื่อดึงไฟล์จาก repo

หมายเหตุ:
แน่นอนว่านี่เป็นไฟล์ทับทิมที่ใช้เมื่อบรรทัดลงท้ายด้วย#gitignoreนำไปใช้ทั่วโลกใน~/.gitconfigไฟล์. แก้ไขสิ่งนี้ตามที่คุณต้องการสำหรับวัตถุประสงค์ของคุณ

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

เพียงแค่git stash save "proj1-debug" ในขณะที่กรองไม่ได้ใช้งาน (เพียงปิดการใช้งานชั่วคราวgitconfigหรือบางอย่าง) ด้วยวิธีนี้รหัสดีบักของฉันสามารถgit stash apply'd เป็นรหัสของฉันได้ตลอดเวลาโดยไม่ต้องกลัวว่าบรรทัดเหล่านี้จะถูกผูกมัดโดยไม่ตั้งใจ

ฉันมีความคิดที่เป็นไปได้ในการจัดการกับปัญหาเหล่านี้ แต่จะลองนำไปใช้อีกครั้ง

ขอบคุณ Rudi และ jw013 ที่กล่าวถึงตัวกรอง git และ gitattributes


2

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

หากคุณต้องการให้บรรทัดนี้ออกจากการควบคุมเวอร์ชันจริงๆการเปลี่ยนเป็นอาร์กิวเมนต์บรรทัดคำสั่งหรือวางไว้ในไฟล์ include หรือ build ที่ละเว้นอาจเป็นวิธีการที่ใช้ได้จริงเท่านั้น


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

นั่นคือสิ่งที่ฉันเคยคิด ฉันใช้ GitExtensions และมันจะแสดงไฟล์ว่าถูกแก้ไขแม้ว่าบานหน้าต่าง diff จะว่างเปล่า อาจเป็นเพราะตัวกรองที่สะอาดไม่ทำงานจนกว่าจะเช็คอินไฟล์ อาจเป็นเพราะมันเป็น msysgit ไม่ใช่ git-git IDK, YMMV
patricktokeeffe

1

ฉันเดาว่านี่อาจเป็นสิ่งที่เกิดขึ้นในแหล่งที่มาของคุณมากกว่าหนึ่งบรรทัด

ฉันคิดว่ามันจะดีที่สุดที่จะมีไฟล์. userbuildconfig บางประเภทที่คุณเพิ่งรวมและตรวจสอบค่าเริ่มต้นจากนั้นคุณสามารถใช้คำแนะนำของ Carlosเพื่อทำเครื่องหมายไฟล์นั้นเพียงอย่างเดียวโดยถือว่าไม่เปลี่ยนแปลง วิธีนี้จะไม่พลาดการเปลี่ยนแปลงอื่น ๆ ในไฟล์ที่คุณต้องตรวจสอบการตั้งค่า

สิ่งนี้ช่วยให้คุณสามารถปรับแต่งมาโครตัวประมวลผลล่วงหน้าในเครื่องได้ (หรือสำหรับ java อะไรทำนองนี้https://stackoverflow.com/a/1813873/1270965 )


-1

ไม่ คุณสามารถละเว้นไฟล์แต่ละไฟล์ (และอื่น ๆ ) ได้เนื่องจากบรรทัดใน. gitignore ตรงกับชื่อไฟล์และไม่ใช่เนื้อหาไฟล์ คุณได้กล่าวถึงวิธีแก้ปัญหานี้แล้วเช่นละเว้นไฟล์เดียวที่มีเนื้อหาที่คุณต้องการละเว้น


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