เป็นไปได้หรือไม่ที่จะขอให้คอมไพล์ diff รวมไฟล์ที่ไม่ได้ติดตามในเอาต์พุต diff หรือเป็นทางออกที่ดีที่สุดของฉันในการคอมไพล์เพิ่มไฟล์ใหม่ที่ฉันได้สร้างและไฟล์ที่มีอยู่ฉันได้แก้ไขและใช้
git diff --cached
?
เป็นไปได้หรือไม่ที่จะขอให้คอมไพล์ diff รวมไฟล์ที่ไม่ได้ติดตามในเอาต์พุต diff หรือเป็นทางออกที่ดีที่สุดของฉันในการคอมไพล์เพิ่มไฟล์ใหม่ที่ฉันได้สร้างและไฟล์ที่มีอยู่ฉันได้แก้ไขและใช้
git diff --cached
?
คำตอบ:
ด้วยเวอร์ชัน git ที่ผ่านมาคุณสามารถgit add -N
ไฟล์ (หรือ--intent-to-add
) ซึ่งเพิ่ม blob ความยาวเป็นศูนย์ให้กับดัชนีที่ตำแหน่งนั้น ผลที่สุดคือตอนนี้ไฟล์ "untracked" ของคุณกลายเป็นการดัดแปลงเพื่อเพิ่มเนื้อหาทั้งหมดไปยังไฟล์ที่มีความยาวเป็นศูนย์และที่แสดงในเอาต์พุต "git diff"
git diff
echo "this is a new file" > new.txt
git diff
git add -N new.txt
git diff
diff --git a/new.txt b/new.txt
index e69de29..3b2aed8 100644
--- a/new.txt
+++ b/new.txt
@@ -0,0 +1 @@
+this is a new file
น่าเศร้าที่คุณไม่สามารถทำได้git stash
ในขณะที่คุณมี--intent-to-add
ไฟล์ที่ค้างอยู่เช่นนี้ แม้ว่าคุณต้องการซ่อนคุณเพียงแค่เพิ่มไฟล์ใหม่แล้วซ่อนไฟล์เหล่านั้น หรือคุณสามารถใช้วิธีแก้ปัญหาการจำลอง:
git update-index --add --cacheinfo \
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
(ตั้งค่านามแฝงคือเพื่อนของคุณที่นี่)
git add -N .
ฉันเชื่อว่าคุณสามารถแตกต่างกับไฟล์ในดัชนีของคุณและไฟล์ที่ไม่ได้ติดตามโดยเพียงระบุเส้นทางไปยังไฟล์ทั้งสอง
git diff --no-index tracked_file untracked_file
git diff --no-index untracked_file_1 untracked_file_2
เพื่อให้ได้git diff
สีไวยากรณ์และอื่น ๆ ใน diffs ... สวยงาม
/dev/null
แทน: git diff --no-index -- /dev/null <untracked_file>
.
cat untracked_file_1
หรือบางทีprintf '\e[1;32m%s\e[0m\n' "$(cat untracked_file_1)"
ถ้าคุณต้องการผลผลิตสีเขียว :) (แม้ว่าจะเป็นเรื่องที่ร้ายแรงกว่านี้โปรดทราบว่าการแทนที่คำสั่งจะลบบรรทัดใหม่ต่อท้ายออกจากไฟล์ของคุณ)
สำหรับการ gitting แบบโต้ตอบแบบวันต่อวันของฉัน (ที่ฉันแตกต้นไม้ทำงานกับหัวตลอดเวลาและต้องการที่จะมีไฟล์ที่ไม่ได้ติดตามรวมอยู่ใน diff) add -N/--intent-to-add
ใช้ไม่ได้เพราะมันแตก git stash
แบ่ง
ดังนั้นนี่คือการgit diff
ทดแทนของฉัน มันไม่ได้เป็นโซลูชั่นที่สะอาดเป็นพิเศษ แต่เนื่องจากฉันใช้เพียงแบบโต้ตอบเท่านั้นฉันจึงตกลงกับแฮ็ค:
d() {
if test "$#" = 0; then
(
git diff --color
git ls-files --others --exclude-standard |
while read -r i; do git diff --color -- /dev/null "$i"; done
) | `git config --get core.pager`
else
git diff "$@"
fi
}
การพิมพ์d
จะรวมไฟล์ที่ไม่ได้ติดตามในส่วนต่าง (ซึ่งเป็นสิ่งที่ฉันสนใจในเวิร์กโฟลว์ของฉัน) และd args...
จะทำงานเหมือนปกติgit diff
จะทำตัวเหมือนปกติ
หมายเหตุ:
git diff
เป็นเพียงส่วนบุคคลที่แตกต่างกันตัดแบ่งดังนั้นจึงเป็นไปไม่ได้ที่จะบอกd
เอาต์พุตจาก "diff จริง" - ยกเว้นความจริงที่ว่าไฟล์ที่ไม่ได้ติดตามทั้งหมดถูกเรียงลำดับล่าสุดgit diff
ฉันไม่สามารถหาวิธีที่จะได้รับไฟล์ที่ไม่ได้ติดตามรวมโดยเพียงแค่การรวบรวมรายการอาร์กิวเมนต์เนียนสำหรับ หากมีคนคิดวิธีการทำเช่นนี้หรืออาจมีการเพิ่มgit
สถานที่ในอนาคตโปรดฝากข้อความไว้ที่นี่!git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
วิธีแก้ปัญหาผมแนะนำสำหรับ GITS เก่าไม่ทำงานร่วมกับgit stash
สมมติว่าคุณมีอยู่แล้ว e69de29bb ในฐานข้อมูลของคุณเช่นโดยพยายามที่จะใช้add -N
ก่อนหน้านี้ เห็นได้ชัดว่ามันไม่เทียบเท่าgit add -N
ในบางวิธี: tbh ฉันไม่แน่ใจว่าอย่างไร
test
คำสั่งของคุณ ไม่ควรส่งผลกระทบต่อสิ่งใด แต่test "$#" -eq 0
มีความแม่นยำมากกว่าสิ่งที่ตั้งใจไว้
less
ดังนั้นคุณไม่จำเป็นต้องกดq
แต่ละไฟล์และมันให้ความรู้สึกเหมือนgit diff
กันโดยการลบเลขหน้าต่อไฟล์ ( -P
) เพิ่มเข้าไปอีกหลังจากนั้น ( | less
), รักษาสี ( --color=always
) และตีความมันเป็นสี ( less -r
หรือless -R
) ดังนั้นทั้งหมด:do git -P diff --color=always -- /dev/null "$i"; done | less -r
test -t 1
(เช่นif [ -t 1 ]; then color_arg=--color; fi
หรือบางสิ่งบางอย่าง) เป็นวิธีที่เชลล์จะตรวจสอบว่าเอาต์พุตของมันเป็นเทอร์มินัลซึ่งเป็นวิธีที่มีประโยชน์ในการตัดสินใจเลือกสี และxargs
อาจให้วิธีกำจัดขณะลูป คุณจะยังคงต้องการ-n 1
มันดังนั้นมันจะยังคงเปิดใช้งานได้หลายครั้งและยังคงต้องเป็นแบบคู่กัน แต่ ... มันจะกำจัดwhile
และread
ดังนั้นอาจจะดีกว่า! ฉันปล่อยให้ผู้อ่าน
ไม่ใช่จุด 100% แต่ถ้าด้วยเหตุผลบางอย่างคุณไม่ต้องการเพิ่มไฟล์ของคุณไปยังดัชนีตามคำแนะนำที่ยอมรับโดยคำตอบที่ยอมรับนี่คือตัวเลือกอื่น:
หากไฟล์นั้นไม่ได้ติดตามอย่างเห็นได้ชัด diff คือไฟล์ทั้งหมดดังนั้นคุณสามารถดูไฟล์เหล่านั้นได้โดยใช้น้อย:
less $(git ls-files --others --exclude-standard)
นำทางระหว่างพวกเขาด้วย:n
และ:p
สำหรับถัดไปและก่อนหน้า ..
อัปเดตจากความคิดเห็น:หากคุณต้องการรูปแบบแพตช์คุณสามารถรวมเข้ากับgit diff
:
git ls-files --others --exclude-standard | xargs -n 1 git --no-pager diff /dev/null | less
คุณยังสามารถเปลี่ยนทิศทางเอาต์พุตไปยังไฟล์หรือใช้คำสั่ง diff อื่นในกรณีนี้
git diff /dev/null <untracked_tile>
และรับแพตช์ในรูปแบบแพทช์ได้มากกว่า "เพียงแค่" ไฟล์
git add -A
git diff HEAD
สร้างแพตช์หากจำเป็นและจากนั้น:
git reset HEAD
git add -p
บ่อยมาก (ซึ่งโดยทั่วไปฉันแนะนำโดยวิธีการ) ... นี้จะให้วิธีการทำสิ่งพื้นฐานเพียงแค่ ... ควรสังเกตว่ามันมีศักยภาพสำหรับด้านที่ไม่พึงประสงค์ ผลกระทบ
สิ่งนี้ใช้ได้กับฉัน:
git add my_file.txt
git diff --cached my_file.txt
git reset my_file.txt
ขั้นตอนสุดท้ายเป็นทางเลือกมันจะปล่อยให้ไฟล์อยู่ในสถานะก่อนหน้า (ไม่ได้ติดตาม)
มีประโยชน์ถ้าคุณกำลังสร้างแพตช์ด้วย:
git diff --cached my_file.txt > my_file-patch.patch
การเปลี่ยนแปลงทำงานเมื่อ staged และ non-staged ด้วยคำสั่งนี้ ไฟล์ใหม่จะทำงานเมื่อฉาก:
$ git diff HEAD
หากไฟล์เหล่านี้ไม่ถูกจัดฉากคุณจะเห็นความแตกต่างของไฟล์เท่านั้น
git add
จากไฟล์ที่ไม่ได้ติดตามทุกไฟล์
git add
ที่ง่ายที่สุดถ้ากรณีการใช้งานของคุณคือการตรวจสอบสิ่งที่คุณเพิ่งเพิ่ม / ต้องการเพิ่ม
สำหรับหนึ่งไฟล์:
git diff --no-index /dev/null new_file
สำหรับไฟล์ใหม่ทั้งหมด:
for next in $( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null $next; done;
เป็นนามแฝง:
alias gdnew="for next in \$( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null \$next; done;"
สำหรับไฟล์ที่ถูกแก้ไขและใหม่ทั้งหมดจะรวมกันเป็นคำสั่งเดียว:
{ git --no-pager diff; gdnew }
โดยปกติเมื่อฉันทำงานกับทีมที่ตั้งระยะไกลเป็นสิ่งสำคัญสำหรับฉันที่ฉันมีความรู้ก่อนว่าการเปลี่ยนแปลงที่ทำโดยทีมอื่นในไฟล์เดียวกันก่อนที่ฉันจะทำตามขั้นตอนคอมไพล์ untrack -> ฉาก -> กระทำเพื่อที่ฉันเขียนสคริปต์ทุบตี ช่วยฉันหลีกเลี่ยงการแก้ไขข้อขัดแย้งผสานกับทีมระยะไกลหรือสร้างสาขาในพื้นที่ใหม่และเปรียบเทียบและผสานกับสาขาหลัก
#set -x
branchname=`git branch | grep -F '*' | awk '{print $2}'`
echo $branchname
git fetch origin ${branchname}
for file in `git status | grep "modified" | awk "{print $2}" `
do
echo "PLEASE CHECK OUT GIT DIFF FOR "$file
git difftool FETCH_HEAD $file ;
done
ในสคริปต์ข้างต้นฉันดึงสาขาหลักระยะไกล (ไม่จำเป็นต้องสาขาหลักของมัน) เพื่อ FETCH_HEAD พวกเขาทำรายการของไฟล์ที่แก้ไขของฉันเท่านั้นและเปรียบเทียบไฟล์ที่แก้ไขไปยังคอมไพล์โฟล
ที่นี่มี difftool รองรับโดย git ฉันกำหนดค่า 'Meld Diff Viewer' สำหรับการเปรียบเทียบ GUI ที่ดี
สมมติว่าคุณไม่มีข้อผูกพันในท้องถิ่น
git diff origin/master
git diff
คำสั่งที่มีไฟล์ที่ไม่ได้ติดตาม คำสั่งนี้ไม่รวมพวกเขา นอกจากนี้ไม่ว่าจะมีความมุ่งมั่นในท้องถิ่นหรือไม่ก็ไม่มีอะไรเกี่ยวข้องกับคำถาม
git merge --squash mybranch
และgit diff master
แสดงให้ฉันเห็นการเปลี่ยนแปลงในไฟล์ที่ไม่ได้ติดตาม
git diff
ไม่แสดงความแตกต่างในไฟล์ที่ไม่ได้ติดตาม: เนื่องจากไฟล์เหล่านั้นไม่ได้ติดตามไม่มีการแสดงผลตามนิยาม มันเป็นเพียงวิธีการทำงานของ Git :)