ฉันจะเพิ่มไดเรกทอรีว่างในที่เก็บ Git ได้อย่างไร


4263

ฉันจะเพิ่มไดเรกทอรีว่างเปล่า (ที่ไม่มีไฟล์) ไปยังที่เก็บ Git ได้อย่างไร?


16
ในขณะที่มันไม่เป็นประโยชน์มีวิธีการตัดที่ว่างเปล่า (ที่ว่างเปล่าจริงๆ) ไดเรกทอรีเข้าไปใน repo อย่างไรก็ตามจะไม่checkoutใช้ Git เวอร์ชันปัจจุบัน
tiwo

335
@tiwo ฉันไม่เห็นด้วยอย่างใดอย่างหนึ่งว่ามันไม่มีประโยชน์ ลำดับชั้นไดเรกทอรีของคุณเป็นส่วนหนึ่งของโครงการของคุณดังนั้นจึงควรมีการควบคุมเวอร์ชัน
JBentley

114
ในกรณีของฉันฉันต้องการเพิ่มโครงสร้างไดเรกทอรีสำหรับไฟล์ tmp แต่ไม่ใช่ไฟล์ tmp ด้วยตนเอง โดยการทำเช่นนี้ผู้ทดสอบของฉันมีโครงสร้างที่ถูกต้อง (มิฉะนั้นจะมีข้อผิดพลาด) แต่ฉันไม่ได้ปิดกั้นการกระทำของฉันกับข้อมูล tmp ใช่แล้วมันมีประโยชน์สำหรับฉัน!
Adam Marshall

45
@ AdamMarshall ฉันคิดว่า tiwo บอกว่าการแฮ็คนั้นไม่มีประโยชน์เพราะถูกเพิกเฉยจากการชำระเงิน Tmp dirs ทำเสียงเหมือนคุณสมบัติที่มีประโยชน์สำหรับ VCS
Quantum7

31
ทำไมไม่มีโพรซีเดอร์ที่สร้างไฟล์ tmp ก็สร้างไดเรคทอรี tmp ด้วย?
RyPeck

คำตอบ:


4125

อีกวิธีในการทำให้ไดเรกทอรีอยู่ (เกือบ) ว่าง (ในที่เก็บ) คือการสร้าง.gitignoreไฟล์ภายในไดเรกทอรีนั้นที่มีสี่บรรทัดเหล่านี้:

# Ignore everything in this directory
*
# Except this file
!.gitignore

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

สิ่งนี้ยังให้ประโยชน์ที่ไฟล์ในไดเรกทอรีนั้นจะไม่ปรากฏเป็น "untracked" เมื่อคุณทำสถานะ git

การทำให้ความคิดเห็นของ@GreenAsJadeยังคงอยู่:

ฉันคิดว่ามันน่าสังเกตว่าโซลูชันนี้ทำในสิ่งที่คำถามถามมาอย่างแม่นยำ แต่อาจไม่ใช่สิ่งที่หลาย ๆ คนกำลังดูคำถามนี้ วิธีการแก้ปัญหานี้รับประกันว่าไดเรกทอรียังคงว่างเปล่า มีข้อความแจ้งว่า "ฉันไม่ต้องการให้มีการเช็คอินไฟล์ที่นี่" ตรงข้ามกับ "ฉันยังไม่มีไฟล์ที่จะเช็คอินที่นี่ แต่ฉันต้องการไดเรกทอรีที่นี่ไฟล์อาจจะมาในภายหลัง"


25
ฉันคิดว่าโซลูชัน README ที่เสนอโดย @JohnMee ควรใช้ร่วมกับโซลูชันนี้ ไฟล์. gitignore ให้คำอธิบายเกี่ยวกับสิ่งที่เราต้องการหลีกเลี่ยงการควบคุมเวอร์ชันในขณะที่ไฟล์ README อธิบายถึงวัตถุประสงค์ของไดเรกทอรีซึ่งเป็นข้อมูลที่สำคัญมาก
pedromanoel

18
@pedromanoel ผมเขียนเอกสารที่คุณจะใส่ในREADMEภายใน.gitignoreไฟล์ (เท่าที่เห็น)
Carlos Campderrós

69
จุดที่แตกต่าง 1: 1. ) โฟลเดอร์ที่ว่างเปล่า 2. ) โฟลเดอร์ที่มีไฟล์. gitignore อยู่ ;-)
Peter Perháč

6
เหมาะสำหรับโฟลเดอร์แคช
redolent

10
น่าเสียดายที่ผลลัพธ์นี้อยู่ในไดเรกทอรีที่ไม่ว่างเปล่า แต่ก็มีไฟล์ที่ซ่อนอยู่
pedorro

1090

คุณทำไม่ได้ ดูGit คำถามที่พบบ่อย

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

ไดเรกทอรีจะถูกเพิ่มโดยอัตโนมัติเมื่อเพิ่มไฟล์ภายใน กล่าวคือไม่ต้องเพิ่มไดเรกทอรีในที่เก็บและไม่ได้ติดตามด้วยตนเอง

คุณสามารถพูดว่า " git add <dir>" แล้วมันจะเพิ่มไฟล์เข้าไป

หากคุณต้องการไดเรกทอรีที่มีอยู่จริงในจุดชำระเงินคุณควรสร้างไฟล์ไว้ในนั้น . gitignore ทำงานได้ดีสำหรับวัตถุประสงค์นี้ คุณสามารถปล่อยว่างไว้หรือเติมชื่อไฟล์ที่คุณคาดว่าจะปรากฏในไดเรกทอรี


67
คำตอบด้านล่างดีกว่ามาก ความจริงที่ว่าซอฟต์แวร์ระดับต่ำของคอมไพล์ไม่อนุญาตให้มันไม่สำคัญสำหรับฉันเท่าที่จะใช้ Git ได้จริงเมื่อฉันต้องการไดเรกทอรีที่ว่างเปล่า การเพิ่ม. gitignore 2 บรรทัดนั้นเป็นที่ยอมรับสำหรับฉัน
Amala

1
ดีถ้าใครต้องการที่จะย้ายไฟล์ไปยังไดเรกทอรีใหม่ที่พวกเขาไม่สามารถทำมันได้ผ่านการgit mvเป็นคอมไพล์จะบ่นว่าไดเรกทอรีใหม่ไม่อยู่ภายใต้การควบคุมเวอร์ชัน
lulalala

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

2
แม้ว่าฉันจะคิดถึงมันมากกว่านี้ แต่ยิ่งรู้สึกเหมือน "SHA hash ของสตริงว่าง" ถ้ามีจริง ๆ แล้วจะเป็นตัวระบุที่ชัดเจนสำหรับต้นไม้ที่ว่างเปล่าเว้นแต่ว่ามันเป็นไปไม่ได้ที่จะบอกว่าวัตถุนั้นเป็น ต้นไม้หรือหยด
Emil Lundberg

21
ฉันเห็น repos มากมายที่ใช้ไฟล์เปล่าที่เรียกว่า.gitkeepสำหรับจุดประสงค์นี้
Sukima

759

สร้างไฟล์ว่างที่เรียกว่า.gitkeepในไดเรกทอรีและเพิ่มไฟล์นั้น


58
ฉันได้เพิ่มคำตอบให้กำลังใจในการสร้าง.keepแทน
คิวเมนตัส

205
.gitkeepไม่ได้ถูกกำหนดโดย Git และจะทำให้คนอื่นเดาความหมายของมันซึ่งจะนำพวกเขาไปสู่การค้นหาของ Google ซึ่งจะนำพวกเขามาที่นี่ .gitประชุมคำนำหน้าควรจะสงวนไว้สำหรับไฟล์และไดเรกทอรีที่ตัวเองใช้ Git
t-mart

10
@ t-mart " .gitควรสงวนการประชุมคำนำหน้า ... " เพราะอะไร คอมไพล์ขอจองนี้หรือไม่?
การชดเชย จำกัด

9
ในกรณีนี้ไฟล์READMEหรือABOUTจะเป็นดีหรือดีกว่า ออกจากบันทึกย่อสำหรับคนต่อไปเช่นเดียวกับที่เราทุกคนเคยทำก่อน URL
เดฟ

5
ไม่ทำงานหากคุณกำลังเขียนการทดสอบหน่วยที่ควรทดสอบโค้ดในไดเรกทอรีว่าง ...
thebjorn

436

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


39
+1, คำแนะนำที่ดี, ไดเรกทอรีว่างเปล่าไม่มีเหตุผลใด ๆ เว้นแต่ว่ามันจะถูกใช้ในอนาคต ดังนั้นสร้างไฟล์ README ข้างในและเขียนว่าไดเรคทอรี่นี้มีไว้เพื่ออะไรและจะใส่ไฟล์อะไรในอนาคต ที่แก้ปัญหาทั้งสอง
saeedgnu

63
@ilius Nonsense โครงสร้างไดเรกทอรีที่มีไดเรกทอรีว่างอาจเป็นที่ต้องการอย่างมากในหลาย ๆ สถานการณ์ (เช่นแอป MVC ที่คุณต้องการไดเรกทอรีรุ่น แต่ยังไม่ได้สร้างการสร้างแบบจำลองใด ๆ หรือไดเรกทอรีมุมมองที่ใช้ร่วมกันที่คุณวางแผนที่จะเพิ่มมุมมองที่ใช้ร่วมกันในภายหลัง ) ยิ่งกว่านั้นการวาง README ในแต่ละรายการนั้นเกินความจริงเพราะเห็นได้ชัดว่ามันมีอะไรและง่ายที่จะลืมใส่ README ในแต่ละรายการ และคุณต้องอย่าลืมลบ README เมื่อคุณเพิ่มไฟล์อื่น ๆ โดยทั่วไปคอมไพล์ควรอนุญาตไดเรกทอรีที่ว่างเปล่าอย่างแน่นอน
Jez

20
@Jez: ฉันไม่เห็นด้วย ประเด็นก็คือ git ถูกออกแบบมาเพื่อควบคุม (และดัชนี) ซอร์สโค้ด ที่สำคัญ id ของการกระทำคือการแฮชเนื้อหา กล่าวคือต้องมีเนื้อหา คุณไม่จำเป็นต้องมี README ในทุกส่วนของต้นไม้มีเพียงโหนดโหนดเท่านั้น หากคุณมีสถานที่ที่คุณต้องการใส่รหัส แต่ไม่มีรหัสและคุณจะไม่ต้องใช้เวลาในการสะท้อน "สถานที่สำหรับแบบจำลอง" >> README สิ่งที่คุณมีคือความคิดที่ไม่ใช่ความมุ่งมั่น มันไม่น่าสนใจที่จะคอมไพล์ การพูดว่า "ฉันต้องการให้แอปที่รันอยู่มีไดเรกทอรี XYZ ว่างเปล่า" เป็นปัญหารันไทม์ไม่ใช่ปัญหาที่มา จัดการกับตัวติดตั้งของคุณ
Joe Atzberger

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

7
@ jbo5112 ใช่ "รหัสพิเศษ" ที่คุณอ้างถึงคือ "ตัวติดตั้ง" ที่ฉันพูดถึง การติดตั้ง webapp ของคุณมีอยู่แล้วเพื่อจัดการการสร้างฐานข้อมูลการกำหนดค่าในท้องถิ่นการดึงการพึ่งพาหรือการดำเนินการอื่น ๆ 100 รายการ แต่มีไดเรกทอรีว่างสองสามรายการที่อยู่นอกเหนือหรือไม่ ลอง gradle, ผู้โดยสาร, เชฟ, Makefile ดั้งเดิม ฯลฯ ไม่มีความแตกต่างด้านความปลอดภัยระหว่างการสร้างไดเรกทอรีและงานอื่น ๆ (อาจมีความซับซ้อน / เป็นอันตราย) ในการติดตั้งแอป และถ้าคุณไม่มี deps, config, DB, ฯลฯ และไม่มีตัวติดตั้งจริงๆให้ใช้ README ไม่จำเป็นต้องให้คุณทำทั้งสองกรณี
Joe Atzberger

348
touch .keep

บน Linux .keepนี้จะสร้างไฟล์ที่ว่างเปล่าชื่อ สำหรับสิ่งที่คุ้มค่าชื่อนี้ไม่เชื่อเรื่อง Git ในขณะที่.gitkeepเฉพาะเจาะจงกับ Git ประการที่สองตามที่ผู้ใช้รายอื่นได้บันทึกไว้.gitอนุสัญญาคำนำหน้าควรสำรองไว้สำหรับไฟล์และไดเรกทอรีที่ Git ใช้

อีกวิธีหนึ่งดังที่ระบุไว้ในคำตอบอื่นไดเร็กทอรีสามารถมีคำอธิบายREADMEหรือREADME.mdไฟล์แทน

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


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

14
คำถามและข้อกังวลทั่วไปที่เด่น ๆ เกี่ยวกับการเพิ่มไดเรกทอรีว่างเปล่า หากภายหลังมีไฟล์ที่อยู่อาศัยให้ลบ.keepไฟล์ดังกล่าวหรือเพียงเพิกเฉย หากแทนที่จะเพิกเฉยไฟล์ในไดเรกทอรีนั่นเป็นคำถามที่ต่างออกไปโดยสิ้นเชิง
Acumenus

3
แนะนำว่าgit clean -nd | sed s/'^Would remove '// | xargs -I{} touch "{}.keep"จะทำเช่นนี้ในไดเรกทอรีว่างเปล่าที่ไม่ได้ติดตามทั้งหมด
คิวเมนตัส

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

1
Windows ไม่ชอบไฟล์ที่ไม่มีชื่อและต้องใช้เวทย์มนตร์พิเศษในการทำสิ่งนี้ให้สำเร็จ (เช่นแอปเทอร์มินัลเหมือนทุบตีหรือเทียบเท่า)
EntangledLoops

303

ทำไมเราต้องมีโฟลเดอร์ที่ว่างเปล่า

สิ่งแรกแรก:

directory ว่างไม่สามารถเป็นส่วนหนึ่งของต้นไม้ภายใต้ระบบเวอร์ชันคอมไพล์

มันจะไม่ถูกติดตาม แต่มีบางสถานการณ์ที่ไดเรกทอรีว่าง "รุ่น" อาจมีความหมายตัวอย่างเช่น:

  • นั่งร้านโครงสร้างโฟลเดอร์ที่กำหนดไว้ล่วงหน้าทำให้ผู้ใช้ทุกคน / ผู้มีส่วนร่วมของที่เก็บ; หรือเป็นกรณีพิเศษของด้านบนสร้างโฟลเดอร์สำหรับไฟล์ชั่วคราวเช่น a cache/หรือlogs/ไดเรกทอรีที่เราต้องการให้โฟลเดอร์ แต่.gitignoreเนื้อหา
  • เกี่ยวข้องกับด้านบนบางโครงการจะไม่ทำงานหากไม่มีโฟลเดอร์ (ซึ่งมักจะเป็นคำใบ้ของโครงการที่ออกแบบมาไม่ดี แต่เป็นสถานการณ์ที่เกิดขึ้นบ่อยครั้งในโลกแห่งความเป็นจริง

บางวิธีแก้ไขปัญหาที่แนะนำ

ผู้ใช้หลายคนแนะนำ:

  1. วางREADMEไฟล์หรือไฟล์อื่นที่มีเนื้อหาบางส่วนเพื่อทำให้ไดเรกทอรีไม่ว่างเปล่าหรือ
  2. การสร้าง.gitignoreไฟล์ด้วย "reverse logic" (เช่นเพื่อรวมไฟล์ทั้งหมด) ซึ่งในตอนท้ายจะให้บริการด้วยจุดประสงค์เดียวกันของวิธีการ # 1

ในขณะที่โซลูชันทั้งสองทำงานได้อย่างแน่นอนฉันพบว่าพวกเขาไม่สอดคล้องกับแนวทางที่มีความหมายต่อการกำหนดเวอร์ชันของ Git

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

. gitkeep approach

ใช้ไฟล์ว่างที่เรียกว่า.gitkeepเพื่อบังคับให้มีโฟลเดอร์ในระบบการกำหนดเวอร์ชัน

แม้ว่ามันอาจจะดูไม่แตกต่างกันมากนัก:

  • คุณใช้ไฟล์ที่มีจุดประสงค์เดียวในการเก็บรักษาโฟลเดอร์ คุณไม่ได้ใส่ข้อมูลใด ๆ ที่คุณไม่ต้องการใส่

    ตัวอย่างเช่นคุณควรใช้ README เช่นกันกับ README ที่มีข้อมูลที่เป็นประโยชน์ไม่ใช่ข้ออ้างในการเก็บโฟลเดอร์

    การแยกข้อกังวลออกมาเป็นสิ่งที่ดีเสมอและคุณยังสามารถเพิ่ม a .gitignoreเพื่อละเว้นไฟล์ที่ไม่ต้องการได้

  • การตั้งชื่อ.gitkeepทำให้ชัดเจนและตรงไปตรงมาจากชื่อไฟล์เอง (รวมถึงนักพัฒนาอื่น ๆซึ่งดีสำหรับโครงการที่ใช้ร่วมกันและเป็นหนึ่งในวัตถุประสงค์หลักของที่เก็บ Git) ว่าไฟล์นี้เป็น

    • ไฟล์ที่ไม่เกี่ยวข้องกับรหัส (เพราะจุดนำและชื่อ)
    • ไฟล์ที่เกี่ยวข้องกับ Git อย่างชัดเจน
    • วัตถุประสงค์ ( Keep ) มีการระบุไว้อย่างชัดเจนและสอดคล้องและไม่เชิงความหมายในความหมายที่จะเพิกเฉย

การรับเป็นบุตรบุญธรรม

ผมเคยเห็น.gitkeepวิธีการที่นำมาใช้โดยกรอบความสำคัญมากเช่นLaravel , เชิงมุม-CLI


8
คุณพลาดความคิดไปแล้ว - เหตุผลในการเก็บรักษาและลบโฟลเดอร์ (เช่น / logs, / tmp, / uploads) คืออะไร? ใช่ - เพื่อทำให้โฟลเดอร์ว่างเปล่า :) ดังนั้นหากคุณต้องการทำให้โฟลเดอร์ว่างเปล่าคุณต้องเพิกเฉยต่อไฟล์ที่อยู่ข้างใน
โรมัน

14
@ RomanAllenstein: ไม่จำเป็น อาจเป็นได้ว่าคุณสร้าง repo ด้วยโครงสร้างที่กำหนดซึ่งสามารถกลายเป็นที่เก็บในภายหลัง ไฟล์เหล่านั้นจะถูกเพิ่มลงใน repo ทันทีที่มีการสร้างขึ้นและมันจะน่ารำคาญที่จะเริ่มต้นการลบหรือแก้ไขไฟล์. gitignore (และเป็นอันตรายเพราะอาจเป็นไปได้ว่าคุณอาจไม่รู้ด้วยซ้ำว่าพวกเขาไม่ได้ติดตาม: git ไม่สนใจพวกเขา )
blueFast

45
@Behnam: ฉันจะลงคะแนน แต่งานวิจัยของฉันเกี่ยวกับ meta SO แสดงให้เห็นว่าไม่ต้องกังวลกับคำตอบที่ละเอียดตราบใดที่พวกเขาให้รายละเอียดและความชัดเจนเพียงพอที่จะเป็นประโยชน์สำหรับผู้อ่านทุกคน (และทุกระดับทักษะ) ถึงกระนั้นฉันก็ยังเปิดกว้างต่อการวิจารณ์และขอบคุณที่ประกาศเหตุผลให้สาธารณชนทราบ
Cranio

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

5
ฉันสงสัยว่าทำไมคนถึงยากลำบากในการทำความเข้าใจว่าทำไมคนเราต้องการเพิ่มโฟลเดอร์ "empty" เพื่อคอมไพล์ คุณต้องเริ่มต้นที่ไหนสักแห่งใช่มั้ย ดังนั้นโดยปกติคุณจะเริ่มต้นด้วยโครงสร้างโฟลเดอร์โครงการและ - อนิจจา - ในช่วงเริ่มต้นของโครงการ เมื่อ repo โครงการของคุณเสร็จสิ้นทีมงานสามารถโคลนและเริ่มทำงานกับโครงสร้างเดียวกัน
BitTickler

127

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

find . -type d -empty -exec touch {}/.gitignore \;

21
คุณอาจต้องการละเว้นไดเรกทอรี. git: find . -name .git -prune -o -type d -empty -exec touch {}/.gitignore \;
steffen

3
รูปแบบที่เรียบง่ายสำหรับสถานการณ์ส่วนใหญ่คือfind * -type d -empty -exec touch {}/.gitignore \;
akhan

2
เนื่องจาก OS X สร้างไฟล์. DS_Store ในแทบทุก directoy จึงไม่สามารถใช้งานได้ วิธีแก้ปัญหาที่ฉันพบ (DANGEROUS!) เพียงอย่างเดียวคือการลบไฟล์. DS_Store ทั้งหมดก่อนfind . -name .DS_Store -exec rm {} \;จากนั้นจึงใช้ตัวแปรที่ต้องการจากคำตอบนี้ ต้องแน่ใจว่าใช้คำสั่งนี้ในโฟลเดอร์ที่ถูกต้องเท่านั้น!
zerweck

1
ไม่มีใครรู้วิธีการทำเช่นนี้ใน Windows จากบรรทัดคำสั่ง? ฉันเห็นโซลูชันบางอย่างที่นี่ใน Ruby และ Python แต่ฉันต้องการโซลูชัน barebones หากสามารถจัดการได้
Mig82

1
@akhan การเพิ่มบางสิ่งเพื่อ.gitignoreไม่มีผลกับ-emptyแฟล็กของfindคำสั่ง ความคิดเห็นของฉันเกี่ยวกับการลบ.DS_Storeไฟล์ในแผนผังไดเรกทอรีดังนั้นจึง-emptyสามารถใช้การตั้งค่าสถานะ
zerweck

68

Andy Lester ถูกต้อง แต่ถ้าไดเรกทอรีของคุณต้องว่างเปล่าและไม่ว่างเปล่าคุณสามารถใส่ค่าว่างได้.gitignoreไฟล์ไว้ในนั้นเป็นวิธีแก้ปัญหา

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


4
นั่นคือสิ่งที่ฉันพูด ทั้งสองย่อหน้ามีการระบุไว้ในตัวอย่างของคำถามที่พบบ่อยที่ฉันโพสต์
Andy Lester

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

ขออภัยฉันไม่ได้อ่านย่อหน้าสุดท้ายและในขณะที่ฉันอ่านย่อหน้าแรกฉันไม่แน่ใจว่าทำไมฉันจึงซ้ำข้อมูลนั้น
อริสโตเติล Pagaltzis

2
แน่นอนคำตอบพิเศษนี้ใช้เพื่อชี้ให้เห็นความจริง
Michael Johnson

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

33

Ruby on Railsเข้าสู่ระบบโฟลเดอร์วิธีการสร้าง:

mkdir log && touch log/.gitkeep && git add log/.gitkeep

ตอนนี้ไดเรกทอรีบันทึกจะรวมอยู่ในต้นไม้ มันมีประโยชน์มากเมื่อใช้งานดังนั้นคุณไม่ต้องเขียนรูทีนเพื่อสร้างไดเรกทอรีบันทึก

ล็อกไฟล์สามารถถูกเก็บไว้โดยการออก

echo log/dev.log >> .gitignore

แต่คุณอาจรู้ว่า


23
สิ่งที่เกี่ยวข้องกับ Ruby on Rails?
คำถาม Quolonel


30

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

ฉันแนะนำให้ใส่ไฟล์ README ในไดเรกทอรีว่างที่อธิบายว่าทำไมไดเรกทอรีว่างเปล่าและทำไมต้องมีการติดตามใน Git เมื่อมีไฟล์ README อยู่แล้วเท่าที่ Git เกี่ยวข้องไดเรกทอรีจะไม่ว่างเปล่าอีกต่อไป

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

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


ในการแสดงรายการไดเร็กทอรีว่างทั้งหมดให้ใช้คำสั่งต่อไปนี้:

find -name .git -prune -o -type d -empty -print

ในการสร้างตัวยึด READMEs ในทุกไดเรกทอรีว่าง:

find -name .git -prune -o -type d -empty -exec sh -c \
  "echo this directory needs to be empty because reasons > {}/README.emptydir" \;

หากต้องการละเว้นทุกสิ่งในไดเรกทอรียกเว้นไฟล์ README ให้วางบรรทัดต่อไปนี้ใน.gitignore:

path/to/emptydir/*
!path/to/emptydir/README.emptydir
path/to/otheremptydir/*
!path/to/otheremptydir/README.emptydir

หรือมิฉะนั้นคุณสามารถยกเว้นไฟล์ README ทุกไฟล์จากการถูกละเว้น:

path/to/emptydir/*
path/to/otheremptydir/*
!README.emptydir

ในการแสดง README ทุกรายการหลังจากสร้างเสร็จแล้ว:

find -name README.emptydir

28

คำเตือน: การปรับแต่งนี้ไม่ทำงานอย่างแท้จริงตามที่ปรากฎ ขออภัยในความไม่สะดวก.

โพสต์ต้นฉบับด้านล่าง:

ฉันพบวิธีแก้ปัญหาขณะเล่นกับ internals Git!

  1. สมมติว่าคุณอยู่ในพื้นที่เก็บข้อมูลของคุณ
  2. สร้างไดเรกทอรีว่างเปล่าของคุณ:

    $ mkdir path/to/empty-folder
    
  3. เพิ่มไปยังดัชนีโดยใช้คำสั่ง plumbing และแผนผังว่างSHA-1 :

    $ git update-index --index-info
    040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904    path/to/empty-folder
    

    พิมพ์คำสั่งแล้วป้อนบรรทัดที่สอง กดEnterและจากนั้นCtrl+ Dเพื่อยุติอินพุตของคุณ หมายเหตุ: รูปแบบคือโหมด [SPACE] ประเภท [SPACE] SHA-1hash [TAB]พา ธ (แท็บมีความสำคัญการจัดรูปแบบคำตอบไม่ได้เก็บไว้)

  4. แค่นั้นแหละ! โฟลเดอร์ว่างของคุณอยู่ในดัชนีของคุณ สิ่งที่คุณต้องทำคือกระทำ

วิธีแก้ปัญหานี้สั้นและเห็นได้ชัดว่าทำงานได้ดี ( ดูการแก้ไข! ) แต่มันไม่ง่ายที่จะจำ ...

แผนผังว่างเปล่า SHA-1 สามารถพบได้โดยการสร้างที่เก็บ Git ว่างใหม่cdลงในและออกgit write-treeซึ่งจะส่งออกต้นไม้ว่าง SHA-1

แก้ไข:

ฉันใช้โซลูชันนี้ตั้งแต่ฉันพบมัน ดูเหมือนว่าจะทำงานในลักษณะเดียวกับการสร้าง submodule ยกเว้นว่าจะไม่มีการกำหนดโมดูลใด ๆ git submodule init|updateนี้นำไปสู่ข้อผิดพลาดเมื่อออก ปัญหาคือการgit update-indexเขียน040000 treeส่วนเข้าไป160000 commitใหม่

ยิ่งกว่านั้นไฟล์ใด ๆ ที่วางภายใต้เส้นทางนั้นจะไม่ถูกสังเกตเห็นโดย Git เนื่องจากมันคิดว่าเป็นของที่เก็บอื่น ๆ นี่เป็นสิ่งที่น่ารังเกียจเพราะมองข้ามไปได้ง่าย!

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


หลังจากวางโฟลเดอร์เปล่าในดัชนีและยืนยันแล้วมันจะเป็นไปgit svn dcommitได้ด้วยผลลัพธ์ที่ต้องการหรือไม่?
การชดเชย จำกัด

2
ไม่น่าเป็นไปได้ที่การบิดนี้จะทำงานกับเครื่องมืออื่น ๆ เช่นเดียวกับที่ระบุไว้ในคำเตือนและการแก้ไขฉันไม่แนะนำให้ใช้ยกเว้นในกรณีที่ค่อนข้าง จำกัด
ofavre

1
และนี่คือเหตุผลว่าทำไมการล้อเล่นกับผู้ฝึกสอนวงในจึงมีข้อห้าม
Casey

@abhisekp เป็นไปได้ยังไง?
PyRulez

1
@PyRulez ดีในโลกของซอฟต์แวร์ไม่มีอะไรที่เป็นไปไม่ได้ : D จริงๆแล้วฉันทำตามคำตอบแล้ว
abhisekp

21

สมมติว่าคุณต้องการไดเร็กทอรีว่างชื่อtmp :

$ mkdir tmp
$ touch tmp/.gitignore
$ git add tmp
$ echo '*' > tmp/.gitignore
$ git commit -m 'Empty directory' tmp

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


11
สองสิ่ง: คุณสามารถ "echo '*'> tmp / .gitignore" แทนการแตะและ "git commit -m" ไม่ยอมรับการเปลี่ยนแปลงที่ทำหลังจากคุณเพิ่มไฟล์ไปยังดัชนี
Christoffer Hammarström

6
ถ้าคุณทำecho bla > fileคุณจะไม่ได้รับfile: File existsเพราะ>จะเขียนทับไฟล์ถ้ามันมีอยู่แล้วหรือสร้างใหม่หากมันไม่อยู่
psyrendust

3
/bin/shสมมติฐานทางวัฒนธรรม! * ถ้า "ที่นี่" เป็นcshและตัวแปรมีการตั้งค่าที่คุณจะได้รับแน่นอนnoclobber file: File existsหากมีคนพูดว่า "ฉันได้รับสิ่งนี้" อย่าคิดว่าพวกเขาเป็นคนงี่เง่าและตอบกลับว่า "คุณไม่ได้ทำ" * c2.com/cgi/wiki?AmericanCulturalAssumption
clacke

1
@clacke หากมีคนตัดสินใจที่จะใช้เปลือกที่แตกต่างจากคนอื่น ๆ พวกเขาควรระบุว่าชัดเจนหากพวกเขากำลังประสบปัญหา ทุกคนมีตัวเลือกกระสุนฟรี
SeldomNeedy

2
@SeldomNeedy บางทีพวกเขากำลังมองหาความช่วยเหลือเพราะพวกเขาไม่รู้ด้วยซ้ำว่าพวกเขากำลังใช้กระสุนที่แตกต่างจากคนอื่น
clacke

20

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

mkdir --parents .generated/bin ## create a folder for storing generated binaries
mv myprogram1 myprogram2 .generated/bin ## populate the directory as needed

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

ln -sf .generated/bin bin
git add bin

เมื่อคุณต้องการล้างทรีซอร์สของคุณคุณสามารถทำได้เพียง:

rm -rf .generated ## this should be in a "clean" script or in a makefile

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

คุณสามารถละเว้นไฟล์ทั้งหมดที่สร้างขึ้นได้โดยเพิ่มสิ่งต่อไปนี้ในรูต. gitignore ของคุณ:

.generated

1
หมายเหตุ: ลิงก์สัญลักษณ์ที่ฉันแนะนำคือ "เสีย" ในการชำระเงินที่สะอาดเนื่องจาก.generatedไดเรกทอรีไม่มีอยู่ในตอนแรก มันจะไม่ถูกทำลายอีกต่อไปเมื่อคุณสร้างงาน
nobar

2
ฉันเห็นด้วยในบางกรณีนี่เป็นความคิดที่ดีมาก แต่ในบางกรณี (เช่นกระจายโครงการที่คุณมีโครงกระดูกว่างเปล่าเป็นอย่างอื่นที่มีโฟลเดอร์เช่นรุ่น / และมุมมอง /) คุณต้องการให้ผู้ใช้มีไดเรกทอรีเหล่านี้อยู่ในมือ กว่าที่จะต้องอ่านด้วยตนเองอ่านเอกสารและมันอาจเป็นเรื่องเล็กน้อยที่จะคาดหวังว่าพวกเขาจะเรียกใช้สคริปต์การติดตั้งบางประเภทหลังจากโคลน repo ฉันคิดว่าคำตอบนี้ประกอบกับคำตอบ README ของ @ john-mee ควรจะครอบคลุมมากที่สุดหากไม่ใช่ทุกกรณี
moopet

14

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

นี่คือเหตุผลที่ฉันตัดสินใจที่จะเขียนเครื่องมือโอเพนซอร์สซึ่งสามารถจัดการการสร้าง / ลบไฟล์ตัวยึดดังกล่าวโดยอัตโนมัติ มันถูกเขียนขึ้นสำหรับแพลตฟอร์ม. NET และทำงานภายใต้ Mono (.NET สำหรับ Linux) และ Windows

เพียงดูได้ที่: http://code.google.com/p/markemptydirs


14

ฉันชอบคำตอบของ @ Artur79 และ @mjs ดังนั้นฉันจึงใช้ทั้งสองอย่างร่วมกันและทำให้เป็นมาตรฐานสำหรับโครงการของเรา

find . -type d -empty -exec touch {}/.gitkeep \;

อย่างไรก็ตามมีนักพัฒนาของเราเพียงไม่กี่คนเท่านั้นที่ทำงานบน Mac หรือ Linux ทำงานได้มากบน Windows และฉันไม่สามารถหาหนึ่งซับง่าย ๆ เพื่อทำสิ่งเดียวกันได้ บางคนโชคดีพอที่จะได้Cygwinติดตั้งด้วยเหตุผลอื่น ๆ แต่การที่ Cygwin สั่งให้ทำเช่นนี้ดูเหมือนจะเกินความจริง

แก้ไขเพื่อทางออกที่ดีกว่า

ดังนั้นเนื่องจากนักพัฒนาซอฟต์แวร์ส่วนใหญ่ของเราติดตั้งAntอยู่แล้วสิ่งแรกที่ฉันคิดคือการรวมไฟล์ Ant build เข้าด้วยกันเพื่อทำสิ่งนี้โดยไม่ขึ้นกับแพลตฟอร์ม ยังสามารถพบได้ที่นี่

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

pip3 install gitkeep2

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

$ gitkeep --help
Usage: gitkeep [OPTIONS] PATH

  Add a .gitkeep file to a directory in order to push them into a Git repo
  even if they're empty.

  Read more about why this is necessary at: https://git.wiki.kernel.org/inde
  x.php/Git_FAQ#Can_I_add_empty_directories.3F

Options:
  -r, --recursive     Add or remove the .gitkeep files recursively for all
                      sub-directories in the specified path.
  -l, --let-go        Remove the .gitkeep files from the specified path.
  -e, --empty         Create empty .gitkeep files. This will ignore any
                      message provided
  -m, --message TEXT  A message to be included in the .gitkeep file, ideally
                      used to explain why it's important to push the specified
                      directory to source control even if it's empty.
  -v, --verbose       Print out everything.
  --help              Show this message and exit.

ฉันหวังว่าคุณพบว่ามีประโยชน์.


13

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

มีคำพูดออกไปที่ไหนสักแห่งที่ฉันอ่านครั้งเดียว

ฉันพบRe: ล้างไดเรกทอรี ..แต่อาจมีอีกอันหนึ่ง

คุณต้องอยู่กับวิธีแก้ปัญหา ... โชคไม่ดี


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

1
คำตอบนี้ดูเหมือนว่าจะไม่สอดคล้องกันตั้งแต่ในโพสต์ต่อไปในหัวข้อที่อ้างถึง Linus Torvald กล่าวว่าเขาคาดหวังว่าพวกเขาจะต้องเพิ่มการติดตามไดเรกทอรี: markmail.org/message/libip4vpvvxhyqbl ในความเป็นจริงเขากล่าวว่าเขา "ยินดีต้อนรับแพทช์ที่ [เพิ่มการสนับสนุนสำหรับการติดตามไดเรกทอรีว่างเปล่า]"
Patrick M

แพทริคเขายังใช้คำว่า "งี่เง่า" ที่นั่น ฉันสงสัยว่าถ้อยคำของเขาติดกับผู้คนที่นี่ในหัวข้อนี้และดังนั้นฉันจึงคิดว่าเขาจะไม่นำสิ่งที่ "โง่" ไปสู่ ​​Git ด้วยตัวเอง
user2334883

10

เมื่อคุณเพิ่ม.gitignoreไฟล์หากคุณต้องการใส่เนื้อหาจำนวนหนึ่ง (คุณต้องการให้ Git เพิกเฉย) คุณอาจต้องการเพิ่มบรรทัดเดียวด้วยเครื่องหมายดอกจัน*เพื่อให้แน่ใจว่าคุณจะไม่เพิ่มเนื้อหาที่ถูกละเว้นโดยไม่ตั้งใจ .


9

ไม่มีวิธีที่จะทำให้ Git ติดตามไดเรกทอรีดังนั้นทางออกเดียวคือเพิ่มไฟล์ตัวแทนในไดเรกทอรีที่คุณต้องการให้ Git ติดตาม

ไฟล์สามารถตั้งชื่อและมีทุกอย่างที่คุณต้องการ แต่คนส่วนใหญ่ใช้ไฟล์เปล่าที่ชื่อ.gitkeep(แม้ว่าบางคนชอบ VCS-agnostic.keep )

คำนำหน้า .ทำเครื่องหมายว่าเป็นไฟล์ที่ซ่อนอยู่

อีกแนวคิดหนึ่งคือการเพิ่มREADMEไฟล์เพื่ออธิบายว่าจะใช้ไดเรกทอรีใด


8

ตามที่กล่าวถึงเป็นไปไม่ได้ที่จะเพิ่มไดเรกทอรีว่างเปล่า แต่นี่คือหนึ่งซับที่เพิ่มไฟล์. gitignore ที่ว่างเปล่าไปยังไดเรกทอรีทั้งหมด

ruby -e 'require "fileutils" ; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'

ฉันติดสิ่งนี้ใน Rakefile เพื่อให้เข้าถึงได้ง่าย


6
ฉันควรใช้find . -type d -empty -print0 | xargs --null bash -c 'for a; do { echo "*"; echo "!.gitignore"; } >>"$a/.gitignore"; done' --
Tino

8

วิธีการแก้ปัญหาของ Jamie Flournoy ใช้งานได้ดี นี่คือรุ่นปรับปรุงเล็กน้อยเพื่อให้.htaccess:

# Ignore everything in this directory
*
# Except this file
!.gitignore
!.htaccess

ด้วยวิธีนี้คุณสามารถที่จะกระทำโฟลเดอร์ที่ว่างเปล่าเช่น/log, /tmpหรือ/cacheและโฟลเดอร์จะอยู่ที่ว่างเปล่า


2
เขาต้องการเก็บไดเรกทอรีว่างไว้และไม่ใช่ไฟล์
gvsrepins

2
และฉันได้กล่าวว่ามันจะเก็บ. htaccess ด้วย ตัวอย่าง: หากซอฟต์แวร์มีไดเรกทอรีสำหรับไฟล์บันทึก (เช่น oxid eshop) ที่ไม่ควรเข้าถึงผ่านเว็บจะมี. htaccess อยู่ในไดเรกทอรี หากคุณใส่. gitignore ที่ระบุไว้ข้างต้นลงในโฟลเดอร์. htaccess จะไม่ถูกเว้นวรรคและโฟลเดอร์จะสามารถเข้าถึงได้ผ่านทางเว็บ
Roman

หากคุณมีไฟล์. htaccess ที่อยู่ภายใต้การควบคุมเวอร์ชันแสดงว่าคุณมีไดเรกทอรีที่มีไฟล์นั้นอยู่ภายใต้การควบคุมเวอร์ชันแล้ว ดังนั้นปัญหาได้รับการแก้ไขแล้ว - ไฟล์. gitignore ไม่เกี่ยวข้อง
Ponkadoodle

1
@ Walacoloo ที่เกี่ยวข้องกับคำถามที่คุณพูดถูกแต่ทว่าไฟล์นั้นมีประโยชน์ฉันจะใช้มันเป็นไดเรกทอรีอัพโหลดอย่างเช่นที่ไฟล์จะได้รับการปกป้องโดย. htaccess ตรงกันข้ามกับคำอธิบายของชาวโรมันไฟล์. htaccess จะได้รับการยอมรับเนื่องจากถูกแยกออกโดยไม่ใช้กฎ [กระทู้เก่า ๆ ฉันรู้]
ดาวิด

7

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

function check_page_custom_folder_structure () {
    if (!is_dir(TEMPLATEPATH."/page-customs"))
        mkdir(TEMPLATEPATH."/page-customs");    
    if (!is_dir(TEMPLATEPATH."/page-customs/css"))
        mkdir(TEMPLATEPATH."/page-customs/css");
    if (!is_dir(TEMPLATEPATH."/page-customs/js"))
        mkdir(TEMPLATEPATH."/page-customs/js");
}

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


2
เพียงแค่เราทุกคนอยู่ในหน้าเดียวกันฉันไม่ทำเช่นนี้อีกแล้ว มันเสียเวลา การ.gitkeepประชุมเป็นวิธีปฏิบัติที่ดีกว่ามาก
Mild Fuzz

ฉันไม่เห็นว่ามันจะเสียเวลาเปล่า เมื่อ TEMPLATEPATH ของคุณเป็นแบบไดนามิกคุณไม่สามารถใช้โซลูชัน. gitkeep ได้ และถึงแม้จะมีโครงสร้างโฟลเดอร์แบบ nondynamic คุณก็ควรเพิ่มสิ่งต่าง ๆ แทนการลบวิธีการตรวจสอบไดเรกทอรีที่ดีเช่นการตรวจสอบการอนุญาตและเปลี่ยนไฟล์ การเพิ่มวิธีการทำเครื่องหมายไดเรกทอรีภายใน. gignignore ทั่วโลกจะสมบูรณ์แบบสำหรับฉัน บางอย่างเช่น #keep / path / to / dir
Jochen Schultz

7

นี่คือแฮ็ค แต่มันตลกที่มันใช้งานได้ (Git 2.2.1) คล้ายกับสิ่งที่ @Teka แนะนำ แต่ง่ายต่อการจดจำ:

  • เพิ่ม submodule ไปยังที่เก็บใด ๆ (git submodule add path_to_repo )
  • จะเป็นการเพิ่มโฟลเดอร์และไฟล์ .submodulesนี้จะเพิ่มโฟลเดอร์และไฟล์กระทำการเปลี่ยนแปลง
  • ลบ.submodulesไฟล์และส่งมอบการเปลี่ยนแปลง

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

ร้ายแรง: ไม่ใช่ชื่อวัตถุที่ถูกต้อง b64338b90b4209263b50244d18278c0999867193

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


ใช้งานได้จริง แต่ฉันคิดว่าสับสน heck จาก IntelliJ ... : |
rogerdpack

ฉันได้สร้างวิธีแก้ปัญหาที่ดีกว่าโดยไม่มีข้อเสียเหล่านี้: stackoverflow.com/a/58543445/277882
ntninja

7

หลายคนตอบคำถามนี้ไปแล้ว เพียงเพิ่มรุ่น PowerShell ที่นี่

ค้นหาโฟลเดอร์ว่างทั้งหมดในไดเรกทอรี

เพิ่มไฟล์. gitkeep ที่ว่างเปล่าในนั้น

Get-ChildItem 'Path to your Folder' -Recurse -Directory | Where-Object {[System.IO.Directory]::GetFileSystemEntries($_.FullName).Count -eq 0} | ForEach-Object { New-Item ($_.FullName + "\.gitkeep") -ItemType file}

Nice.‌‌ ༼͡☉͜ʖ͡☉༽
FiringSquadWitness

6

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

/app/data/**/*.* !/app/data/**/*.md

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

คุณสามารถเติมไดเรกทอรีเหล่านี้ทั้งหมดด้วยไฟล์ xml / images หรืออะไรก็ได้และเพิ่มไดเรกทอรีเพิ่มเติมภายใต้ /app/data/เมื่อเวลาผ่านไปตามความต้องการที่เก็บข้อมูลสำหรับแอปของคุณพัฒนา (ด้วยไฟล์ README.md ที่ให้บริการเพื่อเขียนในรายละเอียดว่า ตรง)

ไม่จำเป็นต้องแก้ไข.gitignoreหรือกระจายอำนาจของคุณเพิ่มเติมโดยสร้างใหม่.gitignoreสำหรับแต่ละไดเรกทอรีใหม่ อาจไม่ใช่วิธีที่ฉลาดที่สุด แต่เป็นคำย่อที่ชาญฉลาดและเหมาะกับฉันเสมอ ดีและเรียบง่าย! ;)

ป้อนคำอธิบายรูปภาพที่นี่


6

วิธีง่ายๆในการทำเช่นนี้คือการเพิ่ม.gitkeepไฟล์ไปยังไดเรกทอรีที่คุณต้องการ (ในปัจจุบัน) ทำให้ว่างเปล่า

ดูคำตอบ SOFนี้สำหรับข้อมูลเพิ่มเติม - ซึ่งอธิบายได้ว่าทำไมบางคนถึงพบว่ารูปแบบการแข่งขันของการเพิ่มไฟล์. gitignore (ตามที่ระบุไว้ในคำตอบมากมายที่นี่) ทำให้เกิดความสับสน


4

เพิ่มอีกหนึ่งตัวเลือกในการต่อสู้

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

รูปแบบดังกล่าวคือ:

*
!.gitignore

ทีนี้ถ้าคุณต้องการวิธีที่จะทำสิ่งนี้ที่ command line, ในคราวเดียว, ในขณะที่อยู่ในไดเร็กตอรี่ที่คุณต้องการเพิ่ม, คุณสามารถรัน:

$ echo "*" > .gitignore && echo '!.gitignore' >> .gitignore && git add .gitignore

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

#!/bin/bash

dir=''

if [ "$1" != "" ]; then
    dir="$1/"
fi

echo "*" > $dir.gitignore && \
echo '!.gitignore' >> $dir.gitignore && \
git add $dir.gitignore

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

$ ignore_dir ./some/directory

ตัวเลือกอื่น (เพื่อตอบกลับความคิดเห็นโดย @GreenAsJade) หากคุณต้องการติดตามโฟลเดอร์ว่างที่MAYมีไฟล์ที่ถูกติดตามในอนาคต แต่จะว่างเปล่าในตอนนี้คุณสามารถ*ออกจาก.gitignoreไฟล์และตรวจสอบสิ่งต่อไปนี้ โดยพื้นฐานแล้วไฟล์ทั้งหมดที่พูดคือ "อย่าเพิกเฉยฉัน " แต่อย่างอื่นไดเรกทอรีนั้นว่างเปล่าและถูกติดตาม

.gitignoreไฟล์ของคุณจะมีลักษณะดังนี้:

!.gitignore

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

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


4

บางครั้งคุณต้องจัดการกับไลบรารีหรือซอฟต์แวร์ที่เขียนไม่ดีซึ่งต้องการไดเรกทอรีที่ว่างเปล่าและมีอยู่จริง วางแบบง่าย ๆ.gitignoreหรือ.keepอาจทำลายพวกเขาและทำให้เกิดข้อบกพร่อง ต่อไปนี้อาจช่วยได้ในกรณีเหล่านี้ แต่ไม่มีการรับประกัน ...

สร้างไดเรกทอรีที่ต้องการก่อน:

mkdir empty

จากนั้นคุณเพิ่มลิงก์สัญลักษณ์ที่เสียหายไปยังไดเรกทอรีนี้ (แต่ในกรณีอื่นนอกเหนือจากกรณีการใช้งานที่อธิบายไว้ด้านบนโปรดใช้ a READMEพร้อมคำอธิบาย):

ln -s .this.directory empty/.keep

ในการเพิกเฉยไฟล์ในไดเรกทอรีนี้คุณสามารถเพิ่มเข้าไปในรูทของคุณได้.gitignore:

echo "/empty" >> .gitignore

ในการเพิ่มไฟล์ที่ถูกละเว้นให้ใช้พารามิเตอร์เพื่อบังคับ:

git add -f empty/.keep

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

find empty -type f

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

$ php -r "var_export(glob('empty/.*'));"
array (
  0 => 'empty/.',
  1 => 'empty/..',
)

แต่ฉันขอแนะนำอย่างยิ่งให้ใช้โซลูชันนี้เฉพาะในกรณีพิเศษการเขียนที่ดีREADMEในไดเรกทอรีว่างมักเป็นวิธีที่ดีกว่า (และฉันไม่รู้ว่ามันใช้งานได้กับระบบไฟล์ windows ... )


4

การอ่านคำตอบของ@ofavreและ@ stanislav-bashkyrtsevโดยใช้การอ้างอิง submodule GIT ที่เสียเพื่อสร้างไดเรกทอรี GIT ฉันแปลกใจที่ไม่มีใครแนะนำเลยว่าการแก้ไขความคิดนี้ง่ายและปลอดภัยทั้งหมด:

แทนที่จะเจาะ submodule ปลอมเข้า GITเพียงเพิ่มจริงที่ว่างเปล่า

ป้อน: https://gitlab.com/empty-repo/empty.git

ที่เก็บ GIT ที่มีหนึ่งคอมมิชชัน:

commit e84d7b81f0033399e325b8037ed2b801a5c994e0
Author: Nobody <none>
Date: Thu Jan 1 00:00:00 1970 +0000

ไม่มีข้อความไม่มีไฟล์ที่คอมมิท

การใช้

ในการเพิ่มไดเรกทอรีว่างให้คุณ repo GIT:

git submodule add https://gitlab.com/empty-repo/empty.git path/to/dir

ในการแปลงไดเรกทอรีว่างที่มีอยู่ทั้งหมดเป็น submodules:

find . -type d -empty -delete -exec git submodule add -f https://gitlab.com/empty-repo/empty.git \{\} \;

Git จะเก็บแฮชคอมมิทล่าสุดเมื่อสร้างการอ้างอิง submodule ดังนั้นคุณไม่ต้องกังวลเกี่ยวกับตัวฉัน (หรือ GitLab) โดยใช้สิ่งนี้เพื่อฉีดไฟล์ที่เป็นอันตราย น่าเสียดายที่ฉันไม่พบวิธีบังคับให้ใช้รหัสยืนยันใด ๆ ในระหว่างการชำระเงินดังนั้นคุณจะต้องตรวจสอบด้วยตนเองว่าใช้รหัสยืนยันการe84d7b81f0033399e325b8037ed2b801a5c994e0ใช้งานด้วยตนเองgit submodule statusหลังจากเพิ่มธุรกรรมซื้อคืนแล้ว

ยังคงไม่ได้เป็นทางออกพื้นเมือง แต่ที่ดีที่สุดที่เราอาจจะมีใครสักคนโดยไม่ต้องได้รับในมือของพวกเขาจริงๆ , จริงๆสกปรกใน codebase GIT

ภาคผนวก: การสร้างความมุ่งมั่นนี้อีกครั้ง

คุณควรจะสามารถสร้างการกระทำที่แน่นอนนี้โดยใช้ (ในไดเรกทอรีว่าง):

# Initialize new GIT repository
git init

# Set author data (don't set it as part of the `git commit` command or your default data will be stored as “commit author”)
git config --local user.name "Nobody"
git config --local user.email "none"

# Set both the commit and the author date to the start of the Unix epoch (this cannot be done using `git commit` directly)
export GIT_AUTHOR_DATE="Thu Jan 1 00:00:00 1970 +0000"
export GIT_COMMITTER_DATE="Thu Jan 1 00:00:00 1970 +0000"

# Add root commit
git commit --allow-empty --allow-empty-message --no-edit

การสร้าง GIT ที่ทำซ้ำได้ยากมาก ...


3

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


60
ฉันประกวดมุมมองนี้ โครงสร้างคือเนื้อหาและทุกสิ่งที่คุณตั้งชื่อมีส่วนช่วยในเนื้อหา
ThomasH

20
ไฟล์เปล่าไม่ใช่ซอร์สโค้ดหรือเนื้อหา มันเป็นเพียงชื่อ แต่ Git จะติดตามไฟล์ที่ว่างเปล่าอย่างมีความสุข ฉันไม่คิดว่าเป็นการตัดสินใจออกแบบโดยเจตนาเพื่อให้ Git ปฏิเสธที่จะติดตามไดเรกทอรีที่ว่างเปล่า ฉันคิดว่าการติดตามไดเรกทอรีว่างเปล่าเป็นคุณสมบัติที่ไม่จำเป็นต้องใช้ 99% ของเวลาดังนั้นพวกเขาจึงไม่อยากทำงานพิเศษที่จำเป็นเพื่อให้มันทำงานได้อย่างถูกต้อง Git สามารถทำได้ถ้ามีคนต้องการคุณลักษณะที่ไม่ดีพอที่จะใช้มัน ฉันสงสัยว่าผู้ดูแลระบบ Git จะไม่เห็นด้วยกับโปรแกรมปะแก้หากทำอย่างถูกต้อง
Dan Molding

1
@TobyAllen ที่นี่เป็นลิงก์คำถามที่พบบ่อยที่ปรับปรุงแล้วคำตอบยอดนิยมคือสิ่งที่แนะนำโดย FAQ พร้อมคำแนะนำที่แม่นยำยิ่งขึ้น
Daniel Da Cunha

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

ไม่เห็นด้วยจริงๆ ฉันสามารถหาสาเหตุต่าง ๆ ได้ว่าทำไมฉันต้องการติดตามโฟลเดอร์ว่าง ตัวอย่างเช่นฉันกำลังพัฒนาเฟรมเวิร์ก PHP MVC ที่มีน้ำหนักเบามากสำหรับโครงการของฉัน ฉันมีโฟลเดอร์เฉพาะสำหรับวางแบบจำลองมุมมอง ฯลฯ เมื่อฉันสร้างไซต์ใหม่ตามกรอบงานของฉันโฟลเดอร์เหล่านั้นจะว่างเปล่าเนื่องจากไม่มีรุ่นหรือมุมมองตามค่าเริ่มต้น แต่ฉันต้องการโฟลเดอร์ที่มีอยู่มิฉะนั้นกรอบงานของฉันจะชนะ ไม่ทำงาน!
Gladen

2

คุณสามารถบันทึกรหัสนี้เป็น create_readme.php และเรียกใช้รหัสPHPจากไดเรกทอรีรากของโครงการ Git ของคุณ

> php create_readme.php

มันจะเพิ่มไฟล์ README ไปยังไดเรกทอรีทั้งหมดที่ว่างเปล่าดังนั้นไดเรกทอรีเหล่านั้นจะถูกเพิ่มไปยังดัชนี

<?php
    $path = realpath('.');
    $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),       RecursiveIteratorIterator::SELF_FIRST);
    foreach($objects as $name => $object){
        if ( is_dir($name) && ! is_empty_folder($name) ){
            echo "$name\n" ;
            exec("touch ".$name."/"."README");
        }
    }

    function is_empty_folder($folder) {
        $files = opendir($folder);
        while ($file = readdir($files)) {
            if ($file != '.' && $file != '..')
                return true; // Not empty
            }
        }
?>

จากนั้นทำ

git commit -m "message"
git push
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.