Git 2.5 đề xuất kể từ tháng 7 năm 2015 thay thế cho contrib/workdir/git-new-workdir
: git worktree
Xem cam kết 68a2e6a của Junio C Hamano ( gitster
) .
Các phiên bản lưu ý đề cập đến :
Một sự thay thế cho contrib/workdir/git-new-workdir
điều đó không dựa vào các liên kết tượng trưng và làm cho việc chia sẻ các đối tượng và giới thiệu an toàn hơn bằng cách làm cho người vay và người vay biết về nhau.
Xem cam kết 799767cc9 (Git 2.5rc2)
Điều đó có nghĩa là bây giờ bạn có thể làm mộtgit worktree add <path> [<branch>]
Tạo <path>
và kiểm tra <branch>
vào nó. Thư mục làm việc mới được liên kết với kho lưu trữ hiện tại, chia sẻ mọi thứ trừ các tệp cụ thể của thư mục làm việc như HEAD, index, v.v. Phần git worktree
này thêm:
Kho git có thể hỗ trợ nhiều cây làm việc , cho phép bạn kiểm tra nhiều nhánh cùng một lúc.
Với git worktree add
, một cây làm việc mới được liên kết với kho lưu trữ.
Cây làm việc mới này được gọi là "cây làm việc được liên kết" trái ngược với "cây làm việc chính" được chuẩn bị bởi " git init
" hoặc " git clone
" .
Kho lưu trữ có một cây làm việc chính (nếu đó không phải là kho lưu trữ trần) và không hoặc nhiều cây làm việc được liên kết.
chi tiết:
Mỗi cây làm việc được liên kết có một thư mục con riêng trong thư mục của kho lưu trữ
$GIT_DIR/worktrees
.
Tên của thư mục con riêng thường là tên cơ sở của đường dẫn của cây làm việc được liên kết, có thể được thêm vào một số để làm cho nó là duy nhất.
Ví dụ: khi $GIT_DIR=/path/main/.git
lệnh git worktree add /path/other/test-next next
tạo:
- cây làm việc được liên kết trong
/path/other/test-next
và
- cũng tạo một
$GIT_DIR/worktrees/test-next
thư mục (hoặc $GIT_DIR/worktrees/test-next1
nếu test-next
đã được thực hiện).
Trong một cây làm việc được liên kết:
$GIT_DIR
được đặt để trỏ đến thư mục riêng này (ví dụ /path/main/.git/worktrees/test-next
trong ví dụ) và
$GIT_COMMON_DIR
được đặt để quay trở lại cây làm việc chính $GIT_DIR
(ví dụ /path/main/.git
).
Các cài đặt này được thực hiện trong một .git
tệp nằm ở thư mục trên cùng của cây làm việc được liên kết.
Khi bạn hoàn thành với một cây làm việc được liên kết, bạn có thể chỉ cần xóa nó.
Các tệp quản trị của cây làm việc trong kho lưu trữ cuối cùng sẽ tự động bị xóa (xem gc.pruneworktreesexpire
trong git config
) hoặc bạn có thể chạy git worktree prune
trong cây chính hoặc bất kỳ cây làm việc được liên kết nào để dọn sạch mọi tệp quản trị cũ.
Cảnh báo: vẫn còn một phần git worktree
"BUG" để nhận biết.
Sự hỗ trợ cho các mô hình con là không đầy đủ .
KHÔNG nên thực hiện nhiều kiểm tra của một siêu dự án.
Lưu ý: với git 2.7rc1 (tháng 11 năm 2015), bạn có thể liệt kê bảng công việc của mình.
Xem cam kết bb9c03b , cam kết 92718b7 , cam 5.193.490 , cam kết 1ceb7f9 , cam kết 1ceb7f9 , cam 5.193.490 , cam kết 1ceb7f9 , cam kết 1ceb7f9 (ngày 08 Tháng 10 2015), cam kết 92718b7 , cam 5.193.490 , cam kết 1ceb7f9 , cam kết 1ceb7f9 (ngày 08 Tháng 10 2015), cam kết 5.193.490 , cam kết 1ceb7f9 (ngày 08 tháng 10 năm 2015), cam kết 1ceb7f9 (ngày 08 tháng 10 năm 2015) và cam kết ac6c561(02 tháng 10 năm 2015) bởi Michael Rappazzo ( rappazzo
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết a46dcfb , ngày 26 tháng 10 năm 2015)
worktree
: thêm list
lệnh ''
' git worktree list
' lặp đi lặp lại thông qua danh sách bàn làm việc và đưa ra chi tiết của bàn làm việc bao gồm đường dẫn đến bàn làm việc, bản sửa đổi và chi nhánh hiện đang được kiểm tra và nếu cây công việc trống.
$ git worktree list
/path/to/bare-source (bare)
/path/to/linked-worktree abcd1234 [master]
/path/to/other-linked-worktree 1234abc (detached HEAD)
Ngoài ra còn có tùy chọn định dạng sứ có sẵn.
Các định dạng sứ có một dòng trên mỗi thuộc tính.
- Các thuộc tính được liệt kê với một nhãn và giá trị được phân tách bằng một khoảng trắng.
- Các thuộc tính Boolean (như 'trần' và 'tách rời') chỉ được liệt kê dưới dạng nhãn và chỉ xuất hiện khi và chỉ khi giá trị là đúng.
- Một dòng trống cho biết sự kết thúc của một bàn làm việc
Ví dụ:
$ 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
Lưu ý: nếu bạn di chuyển thư mục worktree, bạn cần cập nhật thủ cônggitdir
tệp.
Xem cam kết 618244e (ngày 22 tháng 1 năm 2016) và cam kết d4cddd6 (ngày 18 tháng 1 năm 2016) của Nguyễn Thái Ngọc Duy ( pclouds
) .
Được giúp đỡ: Eric Sunshine ( sunshineco
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết d0a1cbc , ngày 10 tháng 2 năm 2016)
Tài liệu mới trong git 2.8 (tháng 3 năm 2016) sẽ bao gồm:
Nếu bạn di chuyển cây làm việc được liên kết, bạn cần cập nhật gitdir
tệp '' trong thư mục của mục nhập.
Ví dụ: nếu một cây làm việc được liên kết được chuyển đến /newpath/test-next
và .git
tệp của nó trỏ tới /path/main/.git/worktrees/test-next
, thì hãy cập nhật
/path/main/.git/worktrees/test-next/gitdir
để tham chiếu /newpath/test-next
thay thế.
Hãy cẩn thận khi xóa một nhánh: trước git 2.9 (tháng 6 năm 2016), bạn có thể xóa một nhánh đang sử dụng trong một cây làm việc khác .
Khi git worktree
tính năng "" được sử dụng ", git branch -d
" cho phép xóa một nhánh được kiểm tra trong một bàn làm việc khác.
Xem cam kết f292244 (29 tháng 3 năm 2016) của Kazuki Yamaguchi ( rhenium
) .
Được giúp đỡ: Eric Sunshine ( sunshineco
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 4fca4e3 , ngày 13 tháng 4 năm 2016)
branch -d
: từ chối xóa một chi nhánh hiện đang được kiểm tra
Khi một nhánh được kiểm tra bởi cây làm việc hiện tại, việc xóa nhánh bị cấm.
Tuy nhiên, khi chi nhánh chỉ được kiểm tra bởi các cây làm việc khác, xóa thành công không chính xác.
Sử dụng find_shared_symref()
để kiểm tra xem nhánh đang được sử dụng, không chỉ so sánh với ĐẦU của cây làm việc hiện tại.
Tương tự, trước git 2.9 (tháng 6 năm 2016), việc đổi tên một chi nhánh đã được kiểm tra trong một worktree khác đã không điều chỉnh ĐẦU tượng trưng trong các worktree khác đã nói.
Xem cam kết 18eb3a9 (08 tháng 4 năm 2016) và cam kết 70999e9 , cam kết 2233066 (27 tháng 3 năm 2016) của Kazuki Yamaguchi ( rhenium
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 741a694 , ngày 18 tháng 4 năm 2016)
branch -m
: cập nhật tất cả các tiêu đề trên mỗi công việc
Khi đổi tên một nhánh, hiện tại chỉ có đầu của cây làm việc hiện tại được cập nhật, nhưng nó phải cập nhật các đầu của tất cả các cây làm việc chỉ vào nhánh cũ.
Đây là hành vi hiện tại, / path / to / wt's HEAD không được cập nhật:
% 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]
Bản vá này khắc phục vấn đề này bằng cách cập nhật tất cả các tiêu đề công việc có liên quan khi đổi tên chi nhánh.
Cơ chế khóa được hỗ trợ chính thức với git 2.10 (quý 3 năm 2016)
Xem cam kết 080739b , cam kết 6d30862 , cam kết 58142c0 , cam kết 346ef53 , cam kết 346ef53 , cam kết 58142c0 , cam kết 346ef53 , cam kết 346ef53 (13 tháng 6 năm 2016), và cam kết 984ad9e , cam 6.835.314 (ngày 03 tháng 6 năm 2016) do Nguyễn Thái Ngọc Duy ( pclouds
) .
Gợi ý: Eric Sunshine ( sunshineco
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 2c608e0 , ngày 28 tháng 7 năm 2016)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
Nếu cây làm việc được liên kết được lưu trữ trên thiết bị di động hoặc chia sẻ mạng không phải lúc nào cũng được gắn kết, bạn có thể ngăn các tệp quản trị của nó bị cắt xén bằng cách ban hành git worktree lock
lệnh, tùy chọn chỉ định --reason
để giải thích tại sao cây làm việc bị khóa.
<worktree>
: Nếu các thành phần đường dẫn cuối cùng trong đường dẫn của cây làm việc là duy nhất trong số các cây làm việc, thì nó có thể được sử dụng để xác định các bàn làm việc.
Ví dụ: nếu bạn chỉ phải làm việc với cây tại " /abc/def/ghi
" và " /abc/def/ggg
", thì " ghi
" hoặc " def/ghi
" là đủ để trỏ đến cây làm việc trước đây.
Git 2.13 (quý 2 năm 2017) thêm lock
tùy chọn trong cam kết 507e6e9 (ngày 12 tháng 4 năm 2017) của Nguyễn Thái Ngọc Duy ( pclouds
) .
Gợi ý: David Taylor ( dt
) .
Giúp đỡ: Jeff King ( peff
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết e311597 , ngày 26 tháng 4 năm 2017)
Cho phép khóa một bàn làm việc ngay sau khi nó được tạo.
Điều này giúp ngăn chặn cuộc đua giữa " git worktree add; git worktree lock
" và " git worktree prune
".
Như vậy git worktree add' --lock
là tương đương với git worktree lock
sau git worktree add
, nhưng không có điều kiện chủng tộc.
Git 2.17+ (quý 2 năm 2018) thêm git worktree move
/ git worktree remove
: xem câu trả lời này .
Git 2.19 (Q3 2018) thêm --quiet
tùy chọn "" để làm cho " git worktree add
" ít dài dòng hơn.
Xem cam kết 371979c (15 tháng 8 năm 2018) của Elia Pinto ( devzero2000
) .
Được giúp đỡ: Martin gren, Duy Nguyễn ( pclouds
) và Eric Sunshine ( sunshineco
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết a988ce9 , ngày 27 tháng 8 năm 2018)
worktree
: thêm --quiet
tùy chọn
Thêm --quiet
tùy chọn '' vào git worktree
, như đối với các git
lệnh khác .
' add
' là lệnh duy nhất bị ảnh hưởng bởi nó vì tất cả các lệnh khác, ngoại trừ ' list
', hiện đang im lặng theo mặc định.
Lưu ý rằng " git worktree add
" được sử dụng để thực hiện "tìm tên có sẵn bằng stat và sau đó mkdir
", dễ bị đua.
Điều này đã được khắc phục với Git 2.22 (quý 2 năm 2019) bằng cách sử dụng mkdir
và phản ứng EEXIST
trong một vòng lặp.
Xem cam kết 7af01f2 (20 tháng 2 năm 2019) của Michal suchanek ( hramrach
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 20fe798 , ngày 09 tháng 4 năm 2019)
worktree
: sửa worktree add
cuộc đua
Git chạy một vòng lặp stat để tìm một tên công việc có sẵn và sau đó thực hiện mkdir
trên tên tìm thấy.
Biến nó thành mkdir
vòng lặp để tránh một lệnh gọi khác của worktree thêm tìm cùng tên miễn phí và tạo thư mục trước.
Git 2.22 (Q2 2019) sửa lỗi logic để biết liệu kho lưu trữ Git có cây làm việc bảo vệ " git branch -D
" khỏi việc xóa nhánh hiện đang được kiểm tra do nhầm lẫn hay không.
Việc triển khai logic này đã bị phá vỡ đối với các kho lưu trữ có tên khác thường, điều không may là tiêu chuẩn cho các mô hình con ngày nay.
Xem cam kết f3534c9 (19 tháng 4 năm 2019) của Jonathan Tan ( jhowtan
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết ec2642a , ngày 08 tháng 5 năm 2019)
Yêu cầu kéo mã 178 Thông tin chi tiết
worktree
: cập nhật is_bare
heuristic
Khi " git branch -D <name>
" được chạy, Git thường kiểm tra trước nếu nhánh đó hiện đang được kiểm tra.
Nhưng kiểm tra này không được thực hiện nếu thư mục Git của kho lưu trữ đó không ở " <repo>/.git
", đó là trường hợp nếu kho lưu trữ đó là một mô hình con có thư mục Git được lưu trữ dưới dạng " super/.git/modules/<repo>
", chẳng hạn.
Điều này dẫn đến việc chi nhánh bị xóa ngay cả khi nó được kiểm tra.
Điều này là do get_main_worktree()
trong worktree.c
các tập hợp is_bare
trên một worktree chỉ sử dụng heuristic rằng một repo trống nếu đường dẫn của worktree không kết thúc bằng " /.git
", và không phải là trần.
Đây is_bare
mã đã được giới thiệu trong 92718b7 ( " worktree
: add chi tiết để các struct worktree", 2015/10/08, Git v2.7.0-RC0), sau một pre-core.bare
heuristic.
Bản vá này thực hiện 2 điều:
- Thay vào đó, hãy dạy
get_main_worktree()
cách sử dụng is_bare_repository()
, được giới thiệu trong 7d1864c ("Giới thiệu biến cấu hình is_bare_Vposeective () và core.bare", 2007-01-07, Git v1.5.0-rc1) và cập nhật trong e90fdc3 ("Dọn dẹp xử lý cây công việc", 2007 -08-01, Git v1.5.3-RC4).
Điều này giải quyết git branch -D <name>
vấn đề "" được mô tả ở trên.
Tuy nhiên ... Nếu một kho lưu trữ có core.bare=1
nhưng git
lệnh "" đang được chạy từ một trong các worktrees thứ cấp của nó, is_bare_repository()
trả về false (điều này là tốt, vì có sẵn một worktree).
Và, coi công việc chính là không trần khi nó trần gây ra các vấn đề:
Ví dụ, thất bại trong việc xóa một nhánh từ một bàn làm việc phụ được đề cập bởi TRỤ của người làm việc chính, ngay cả khi bàn làm việc chính đó trống.
Để tránh điều đó, cũng kiểm tra core.bare
khi cài đặt is_bare
.
Nếu core.bare=1
, tin tưởng nó, và nếu không, sử dụng is_bare_repository()
.
git-new-workdir
sẽ được thay thế bằnggit checkout --to=<path>
trong Git 2.5. Xem câu trả lời của tôi dưới đây