Git 2.5 เสนอมาตั้งแต่เดือนกรกฎาคม 2558 แทนcontrib/workdir/git-new-workdir
: git worktree
ดูกระทำ 68a2e6aโดยJunio C Hamano (gitster
)
เอกสารเผยแพร่ระบุว่า :
การแทนที่contrib/workdir/git-new-workdir
สิ่งที่ไม่ต้องพึ่งพาลิงก์สัญลักษณ์และทำให้การแบ่งปันวัตถุและการอ้างอิงปลอดภัยยิ่งขึ้นโดยทำให้ผู้ยืมและผู้ยืมได้รับรู้ซึ่งกันและกัน
ดูคอมมิชชัน 799767cc9 (Git 2.5rc2)
นั่นหมายความว่าคุณสามารถทำได้git worktree add <path> [<branch>]
สร้าง<path>
และชำระเงิน<branch>
เป็นมัน ไดเร็กทอรีการทำงานใหม่เชื่อมโยงกับที่เก็บปัจจุบันแชร์ทุกอย่างยกเว้นไฟล์เฉพาะไดเรกทอรีทำงานเช่น HEAD, index ฯลฯgit worktree
ส่วนเพิ่ม:
ที่เก็บ git สามารถรองรับต้นไม้ทำงานได้หลายต้นช่วยให้คุณสามารถตรวจสอบได้มากกว่าหนึ่งสาขาในเวลาเดียวกัน
ด้วยแผนผังgit worktree add
การทำงานใหม่จะเชื่อมโยงกับที่เก็บ
ต้นไม้ต้นนี้การทำงานใหม่ที่เรียกว่า "การเชื่อมโยงต้นไม้ทำงาน" เมื่อเทียบกับ "ต้นการทำงานหลัก" จัดทำโดย " git init
" หรือ "git clone
"
ที่เก็บมีต้นไม้การทำงานหลักหนึ่งต้น (ถ้าไม่ใช่ที่เก็บเปลือย) และมีต้นไม้การทำงานเชื่อมโยงเป็นศูนย์หรือมากกว่า
รายละเอียด:
ต้นไม้แต่ละต้นการทำงานที่เชื่อมโยงมีไดเรกทอรีย่อยในพื้นที่เก็บข้อมูลส่วนตัวของ
$GIT_DIR/worktrees
ไดเรกทอรี
ชื่อของไดเรกทอรีย่อยส่วนตัวมักจะเป็นชื่อพื้นฐานของเส้นทางของแผนผังการทำงานที่เชื่อมโยงซึ่งอาจผนวกเข้ากับตัวเลขเพื่อทำให้เป็นเอกลักษณ์
ตัวอย่างเช่นเมื่อ$GIT_DIR=/path/main/.git
คำสั่งgit worktree add /path/other/test-next next
สร้าง:
- แผนผังการทำงานที่เชื่อมโยงใน
/path/other/test-next
และ
- สร้าง
$GIT_DIR/worktrees/test-next
ไดเรกทอรีด้วย (หรือ$GIT_DIR/worktrees/test-next1
ถ้าtest-next
ถ่ายไปแล้ว)
ภายในแผนผังการทำงานที่เชื่อมโยง:
$GIT_DIR
ถูกตั้งค่าให้ชี้ไปที่ไดเรกทอรีส่วนตัวนี้ (เช่น/path/main/.git/worktrees/test-next
ในตัวอย่าง) และ
$GIT_COMMON_DIR
ถูกตั้งค่าให้ชี้กลับไปที่แผนผังการทำงานหลัก$GIT_DIR
(เช่น/path/main/.git
)
การตั้งค่าเหล่านี้จะทำใน.git
ไฟล์ที่อยู่ในไดเรกทอรีด้านบนของแผนผังการทำงานที่เชื่อมโยง
เมื่อคุณทำแผนผังการทำงานที่เชื่อมโยงแล้วคุณสามารถลบมันได้
ไฟล์การดูแลระบบของแผนผังการทำงานในที่เก็บในที่สุดจะถูกลบออกโดยอัตโนมัติ (ดูgc.pruneworktreesexpire
ในgit config
) หรือคุณสามารถเรียกใช้git worktree prune
ในแผนผังการทำงานหลักหรือแผนผังที่เชื่อมโยงเพื่อล้างไฟล์การดูแลระบบที่เก่าเกินไป
คำเตือน: ยังมีส่วนgit worktree
"BUGS"ที่ต้องระวัง
การสนับสนุนสำหรับsubmodulesไม่สมบูรณ์
ไม่แนะนำให้ทำการเช็คเอาต์หลายรายการของ Superproject
หมายเหตุ: ด้วย git 2.7rc1 (พ.ย. 2558) คุณสามารถแสดงรายการ worktrees ของคุณ
ดูกระทำ bb9c03b , กระทำ 92718b7 , กระทำ 5193490 , กระทำ 1ceb7f9 , กระทำ 1ceb7f9 , กระทำ 5193490 , กระทำ 1ceb7f9 , กระทำ 1ceb7f9 (8 ตุลาคม 2015) กระทำ 92718b7 , กระทำ 5193490 , กระทำ 1ceb7f9 , กระทำ 1ceb7f9 (8 ตุลาคม 2015) กระทำ 5193490 , คอมมิชชัน 1ceb7f9 (08 ต.ค. 2558), คอมมิท 1ceb7f9 (08 ต.ค. 2558), และกระทำ ac6c561(2 ตุลาคม 2015) โดยไมเคิล Rappazzo (rappazzo
)
(รวมโดยJunio C Hamano - gitster
-ในการกระทำ a46dcfb , 26 ตุลาคม 2015)
worktree
: เพิ่มlist
คำสั่ง ''
' git worktree list
' วนซ้ำผ่านรายการ worktree และแสดงรายละเอียดของ worktree รวมถึงเส้นทางไปยัง worktree การตรวจสอบการแก้ไขและสาขาในปัจจุบันและถ้าต้นไม้ว่างเปล่า
$ git worktree list
/path/to/bare-source (bare)
/path/to/linked-worktree abcd1234 [master]
/path/to/other-linked-worktree 1234abc (detached HEAD)
นอกจากนี้ยังมีตัวเลือกรูปแบบพอร์ซเลน
รูปแบบ Porcelain มีบรรทัดต่อแอตทริบิวต์
- แอ็ตทริบิวต์ถูกลิสต์ด้วยเลเบลและค่าคั่นด้วยช่องว่างเดียว
- แอตทริบิวต์บูลีน (เช่น 'bare' และ 'แฝด') จะแสดงรายการเป็นป้ายกำกับเท่านั้นและจะปรากฏต่อเมื่อค่านั้นเป็นจริงเท่านั้น
- บรรทัดว่างหมายถึงจุดสิ้นสุดของ worktree
ตัวอย่างเช่น
$ git worktree list --porcelain
worktree /path/to/bare-source
bare
worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master
worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached
หมายเหตุ: หากคุณย้ายโฟลเดอร์ worktree คุณต้องอัปเดตไฟล์ด้วยตนเองgitdir
ดูกระทำ 618244e (22 มกราคม 2016) และกระทำ d4cddd6 (18 มกราคม 2016) โดยNguyễnTháiNgọc Duy (pclouds
)
ช่วยโดย: เอริคซันไชน์ (sunshineco
)
(รวมโดยJunio C Hamano - gitster
-ในการกระทำ d0a1cbc , 10 กุมภาพันธ์ 2016)
เอกสารใหม่ใน git 2.8 (มีนาคม 2016) จะรวมถึง:
หากคุณย้ายแผนผังการทำงานที่เชื่อมโยงคุณต้องอัปเดตgitdir
ไฟล์ '' ในไดเรกทอรีของรายการ
ตัวอย่างเช่นหากย้ายแผนผังการทำงานที่เชื่อมโยงไปยัง/newpath/test-next
และ.git
ไฟล์ชี้ไปที่ให้/path/main/.git/worktrees/test-next
อัปเดต
/path/main/.git/worktrees/test-next/gitdir
เป็นข้อมูลอ้างอิง/newpath/test-next
แทน
ระวังเมื่อทำการลบสาขา: ก่อนที่จะคอมไพล์ 2.9 (มิถุนายน 2559) คุณสามารถลบสาขาที่ใช้งานในแผนผังการทำงานอื่นได้
เมื่อgit worktree
มีการใช้งานฟีเจอร์ " git branch -d
" จะอนุญาตให้ลบสาขาที่เช็คเอาท์ใน worktree อื่น
ดูกระทำ f292244 (29 มีนาคม 2016) โดยKazuki ยามากูชิ (rhenium
)
ช่วยโดย: เอริคซันไชน์ (sunshineco
)
(รวมโดยJunio C Hamano - gitster
-ในการกระทำ 4fca4e3 , 13 เมษายน 2016)
branch -d
: ปฏิเสธการลบสาขาที่ชำระเงินแล้วในปัจจุบัน
เมื่อสาขาถูกเช็คเอาท์โดยแผนผังการทำงานปัจจุบันการลบสาขาจะถูกห้าม
อย่างไรก็ตามเมื่อสาขาถูกเช็กเอาต์ด้วยต้นไม้ทำงานอื่นการลบจะไม่สำเร็จ
ใช้find_shared_symref()
เพื่อตรวจสอบว่ามีการใช้งานสาขาหรือไม่ไม่ใช่แค่เปรียบเทียบกับ HEAD ของแผนผังการทำงานปัจจุบัน
ในทำนองเดียวกันก่อนที่จะคอมไพล์ 2.9 (มิถุนายน 2559) การเปลี่ยนชื่อสาขาที่เช็คเอาท์ใน worktree อื่นไม่ได้ปรับ HEAD เป็นสัญลักษณ์ใน worktree อื่นที่กล่าวมา
ดูกระทำ 18eb3a9 (8 เมษายน 2016) และกระทำ 70999e9 , กระทำ 2233066 (27 มีนาคม 2016) โดยKazuki ยามากูชิ (rhenium
)
(ผสานโดยJunio C Hamano - gitster
-ในการกระทำ 741a694 , 18 เมษายน 2016)
branch -m
: อัปเดตหัวต่อ worktree ทั้งหมด
เมื่อเปลี่ยนชื่อสาขาปัจจุบันเฉพาะ HEAD ของแผนผังการทำงานปัจจุบันเท่านั้นที่ได้รับการอัปเดต แต่ต้องอัปเดต HEADs ของแผนผังการทำงานทั้งหมดซึ่งชี้ไปที่สาขาเก่า
นี่คือพฤติกรรมปัจจุบัน / HEAD / path / to / wt ไม่ได้รับการอัพเดต:
% git worktree list
/path/to 2c3c5f2 [master]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m master master2
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m oldname newname
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 0000000 [oldname]
โปรแกรมแก้ไขนี้แก้ไขปัญหานี้ได้โดยการอัปเดต worktree HEADs ที่เกี่ยวข้องทั้งหมดเมื่อเปลี่ยนชื่อสาขา
กลไกการล็อครองรับอย่างเป็นทางการกับ git 2.10 (ไตรมาส 3 ปี 2559)
ดูกระทำ 080739b , กระทำ 6d30862 , กระทำ 58142c0 , กระทำ 346ef53 , กระทำ 346ef53 , กระทำ 58142c0 , กระทำ 346ef53 , กระทำ 346ef53 (13 มิถุนายน 2016) และกระทำ 984ad9e , กระทำ 6835314 (3 มิถุนายน 2016) โดยNguyễnTháiNgọc Duy (pclouds
)
แนะนำโดย: เอริคซันไชน์ (sunshineco
)
(รวมโดยJunio C Hamano - gitster
-ในการกระทำ 2c608e0 , 28 กรกฎาคม 2016)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
หากแผนผังการทำงานที่เชื่อมโยงถูกจัดเก็บไว้ในอุปกรณ์พกพาหรือเครือข่ายที่ไม่ได้ติดตั้งอยู่ตลอดเวลาคุณสามารถป้องกันไม่ให้ไฟล์การดูแลระบบถูกตัดโดยการออกgit worktree lock
คำสั่งหรือระบุทางเลือก--reason
เพื่ออธิบายว่าทำไมแผนผังการทำงานถูกล็อก
<worktree>
: หากส่วนประกอบของเส้นทางสุดท้ายในเส้นทางของต้นไม้ทำงานไม่ซ้ำกันในหมู่ต้นไม้ทำงานมันสามารถใช้เพื่อระบุ worktrees
ตัวอย่างเช่นหากคุณต้องทำงานต้นไม้ที่ " /abc/def/ghi
" และ " /abc/def/ggg
" ดังนั้น " ghi
" หรือ " def/ghi
" ก็เพียงพอที่จะชี้ไปยังต้นไม้ทำงานเดิมได้
Git 2.13 (Q2 2017) เพิ่มlock
ตัวเลือกในการกระทำ 507e6e9 (12 เมษายน 2017) โดยNguyễnTháiNgọc Duy (pclouds
)
แนะนำโดย: เดวิดเทย์เลอร์ (dt
)
ช่วยโดย: เจฟฟ์คิง (peff
)
(ผสานโดยJunio C Hamano - gitster
- in e311597 , 26 Apr 2017)
อนุญาตให้ล็อค worktree ทันทีหลังจากที่สร้างขึ้น
ซึ่งจะช่วยป้องกันการแข่งขันระหว่าง " git worktree add; git worktree lock
" และ " git worktree prune
"
ดังนั้นจึงgit worktree add' --lock
เทียบเท่ากับgit worktree lock
หลังจากgit worktree add
แต่ไม่มีเงื่อนไขการแข่งขัน
Git 2.17+ (Q2 2018) เพิ่มgit worktree move
/ git worktree remove
: ดูคำตอบนี้
Git 2.19 (ไตรมาสที่ 3 ปี 2018) เพิ่ม--quiet
ตัวเลือก "" เพื่อให้git worktree add
verbose น้อยลง ""
ดูกระทำ 371979c (15 สิงหาคม 2018) โดยเอเลียปินโต (devzero2000
)
ช่วยโดย: มาร์ติน Agren, Duy เหงียน ( pclouds
)และเอริคซันไชน์ (sunshineco
)
(รวมโดยJunio C Hamano - gitster
-ในการกระทำ a988ce9 , 27 สิงหาคม 2018)
worktree
: เพิ่ม--quiet
ตัวเลือก
เพิ่ม--quiet
ตัวเลือก '' ลงgit worktree
ในเช่นเดียวกับgit
คำสั่งอื่น ๆ
' add
' เป็นคำสั่งเดียวที่ได้รับผลกระทบเนื่องจากคำสั่งอื่น ๆ ทั้งหมดยกเว้น ' list
' จะเงียบโดยปริยาย
โปรดทราบว่า " git worktree add
" เคยทำ "ค้นหาชื่อที่มีสถานะเป็น stat แล้วmkdir
" ซึ่งเป็นไปได้ยาก
สิ่งนี้ได้รับการแก้ไขด้วย Git 2.22 (Q2 2019) โดยการใช้mkdir
และการตอบสนองEEXIST
ในการวนซ้ำ
ดูกระทำ 7af01f2 (20 กุมภาพันธ์ 2019) โดยคาล Suchanek (hramrach
)
(ผสานโดยJunio C Hamano - gitster
-ในการกระทำ 20fe798 , 09 Apr 2019)
worktree
: แก้ไขworktree add
การแข่งขัน
Git ใช้การวนรอบสถิติเพื่อค้นหาชื่อ worktree ที่พร้อมใช้งานจากนั้นใช้mkdir
กับชื่อที่พบ
เปลี่ยนเป็นmkdir
วนซ้ำเพื่อหลีกเลี่ยงการเรียกใช้ worktree เพิ่มการค้นหาชื่อฟรีเดียวกันและสร้างไดเรกทอรีก่อน
Git 2.22 (Q2 2019) แก้ไขลอจิกเพื่อบอกว่าที่เก็บ Git มีแผนผังการทำงานปกป้อง " git branch -D
" จากการลบสาขาที่เช็คเอาท์โดยไม่ได้ตั้งใจในขณะนี้
การดำเนินการตามตรรกะนี้ใช้งานไม่ได้กับที่เก็บที่มีชื่อผิดปกติ
ดูกระทำ f3534c9 (19 เมษายน 2019) โดยโจนาธานตาล (jhowtan
)
(ผสานโดยJunio C Hamano - gitster
- in ec2642a , 08 พฤษภาคม 2019)
คำขอให้ดึงรหัส 178 ข้อมูลเชิงลึก
worktree
: อัพเดตis_bare
ฮิวริสติก
เมื่อgit branch -D <name>
เรียกใช้" " Git มักจะตรวจสอบก่อนว่าสาขานั้นเช็คเอาท์อยู่หรือไม่
แต่การตรวจสอบนี้จะไม่ดำเนินการหากไดเรกทอรี Git ของที่เก็บนั้นไม่อยู่ที่ " <repo>/.git
" ซึ่งเป็นกรณีที่ที่เก็บนั้นเป็น submodule ที่มีไดเรกทอรี Git จัดเก็บเป็น " super/.git/modules/<repo>
"
ซึ่งส่งผลให้สาขาถูกลบแม้ว่าจะเช็คเอาท์
นี่เป็นเพราะget_main_worktree()
ในworktree.c
ชุดis_bare
บน worktree ใช้ฮิวริสติกเท่านั้นที่ repo จะว่างถ้าเส้นทางของ worktree ไม่ได้ลงท้ายด้วย " /.git
" และไม่เปลือยเปล่า รหัส
นี้is_bare
ถูกนำมาใช้ใน92718b7 (" worktree
: เพิ่มรายละเอียดให้กับโครงสร้าง worktree", 2015-10-08, Git v2.7.0-rc0) ตามด้วยการpre-core.bare
แก้ปัญหา
แพทช์นี้ทำ 2 สิ่ง:
- สอน
get_main_worktree()
ให้ใช้is_bare_repository()
แทนแนะนำใน7d1864c ("แนะนำ is_bare_repository () และตัวแปรการตั้งค่า core.bare", 2007-01-07, Git v1.5.0-rc1) และอัพเดทในe90fdc3 ("ทำความสะอาดการจัดการต้นไม้ทำงาน", 2007 -08-01, Git v1.5.3-rc4)
วิธีนี้จะช่วยแก้git branch -D <name>
ปัญหาที่อธิบายไว้ข้างต้น
อย่างไรก็ตาม ... หากที่เก็บมีcore.bare=1
แต่git
คำสั่ง "" กำลังถูกเรียกใช้จากหนึ่งใน worktrees รองของมันis_bare_repository()
ส่งกลับเท็จ (ซึ่งเป็นเรื่องปกติเนื่องจากมี worktree พร้อมใช้งาน)
และการรักษา worktree หลักเป็น non-bare เมื่อมันเปลือยทำให้เกิดปัญหา:
ตัวอย่างเช่นความล้มเหลวในการลบสาขาจาก worktree รองที่ถูกอ้างถึงโดย HEAD ของ worktree หลักแม้ว่า worktree หลักนั้นจะว่างเปล่า
เพื่อหลีกเลี่ยงปัญหานี้ให้ตรวจสอบcore.bare
การตั้งค่าis_bare
ด้วย
หากcore.bare=1
เชื่อถือและใช้is_bare_repository()
อย่างอื่น
git-new-workdir
จะถูกแทนที่ด้วยgit checkout --to=<path>
ใน Git 2.5 ดูคำตอบของฉันด้านล่าง