it-swarm-vi.tech

Làm cách nào để Git theo liên kết tượng trưng?

Là tốt nhất của tôi sẽ là một kịch bản Shell thay thế các liên kết tượng trưng bằng các bản sao, hoặc có một cách khác để nói với Git theo các liên kết tượng trưng?

Tái bút: Tôi biết nó không an toàn lắm, nhưng tôi chỉ muốn làm điều đó trong một vài trường hợp cụ thể.

174
Matt

LƯU Ý: Lời khuyên này hiện đã lỗi thời theo nhận xét kể từ Git 1.6.1. Git đã từng cư xử theo cách này, và không còn như vậy nữa.


Git theo mặc định cố gắng lưu trữ các liên kết tượng trưng thay vì theo dõi chúng (cho gọn, và đó thường là những gì mọi người muốn).

Tuy nhiên, tôi đã vô tình quản lý để có được nó để thêm các tập tin ngoài symlink khi symlink là một thư mục.

I E.:

  /foo/
  /foo/baz
  /bar/foo --> /foo
  /bar/foo/baz

bằng cách làm

 git add /bar/foo/baz

nó xuất hiện để làm việc khi tôi thử nó. Tuy nhiên, hành vi đó là không mong muốn của tôi vào thời điểm đó, vì vậy tôi không thể cung cấp cho bạn thông tin ngoài điều đó.

37
Kent Fredric

Tôi đã làm gì để thêm các tệp trong liên kết tượng trưng vào Git (Tôi không sử dụng liên kết tượng trưng nhưng):

Sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Thực hiện lệnh này trong thư mục do Git quản lý. TARGETDIRECTORY phải được tạo trước khi SOURCEDIRECTORY được gắn vào nó.

Nó hoạt động tốt trên Linux, nhưng không phải trên OS X! Thủ thuật đó cũng giúp tôi với Subversion. Tôi sử dụng nó để bao gồm các tệp từ tài khoản Dropbox, trong đó một thiết kế web thực hiện công cụ của mình.

124
user252400

Tại sao không tạo symlink theo cách khác? Ý nghĩa thay vì liên kết từ kho Git đến thư mục ứng dụng, chỉ cần liên kết theo cách khác.

Ví dụ: giả sử, tôi nói rằng tôi đang thiết lập một ứng dụng được cài đặt trong ~/application cần tệp cấu hình config.conf:

  • Tôi thêm config.conf vào kho Git của tôi, ví dụ, tại ~/repos/application/config.conf.
  • Sau đó, tôi tạo một liên kết tượng trưng từ ~/application bằng cách chạy ln -s ~/repos/application/config.conf.

Cách tiếp cận này có thể không phải lúc nào cũng hiệu quả, nhưng nó đã làm việc tốt cho tôi cho đến nay.

65
spier

Sử dụng liên kết cứng thay thế. Điều này khác với một liên kết mềm (tượng trưng). Tất cả các chương trình, bao gồm git sẽ coi tệp là một tệp thông thường. Lưu ý rằng nội dung có thể được sửa đổi bằng cách thay đổi hoặc nguồn hoặc đích.

Trên macOS (trước 10.13 High Sierra)

Nếu bạn đã cài đặt git và Xcode, cài đặt liên kết cứng . Đây là một công cụ hiển vi để tạo liên kết cứng

Để tạo liên kết cứng, chỉ cần:

hln source destination

cập nhật macOS High Sierra

Apple File System có hỗ trợ thư mục liên kết cứng không?

Thư mục liên kết cứng không được Apple File System hỗ trợ. Tất cả các liên kết cứng thư mục được chuyển đổi thành liên kết tượng trưng hoặc bí danh khi bạn chuyển đổi từ định dạng khối lượng HFS + sang APFS trên macOS.

Từ APFS FAQ trên developer.Apple.com

Theo dõi https://github.com/selkhateeb/hardlink/issues/31 cho các lựa chọn thay thế trong tương lai.

Trên Linux và các hương vị Unix khác

Lệnh ln có thể tạo liên kết cứng:

ln source destination

Trên Windows (Vista, 7, 8, ')

Ai đó đã đề xuất sử dụng mklink tạo một đường nối trên Windows, nhưng tôi chưa thử:

mklink /j "source" "destination"
41
bfred.it

Đây là một hook pre-commit thay thế các đốm liên kết tượng trưng trong chỉ mục, với nội dung của các liên kết tượng trưng đó.

Đặt cái này trong .git/hooks/pre-commit và làm cho nó có thể thực thi được:

#!/bin/sh
# (replace "find ." with "find ./<path>" below, to work with only specific paths)

# (these lines are really all one line, on multiple lines for clarity)
# ...find symlinks which do not dereference to directories...
find . -type l -exec test '!' -d {} ';' -print -exec sh -c \
# ...remove the symlink blob, and add the content diff, to the index/cache
    'git rm --cached "$1"; diff -au /dev/null "$1" | git apply --cached -p1 -' \
# ...and call out to "sh".
    "process_links_to_nondir" {} ';'

# the end

Ghi chú

Chúng tôi sử dụng chức năng tuân thủ POSIX càng nhiều càng tốt; tuy nhiên, diff -a không tuân thủ POSIX, có thể trong số những thứ khác.

Có thể có một số lỗi/lỗi trong mã này, mặc dù nó đã được thử nghiệm phần nào.

16
Abbafei

Tôi đã sử dụng để thêm các tập tin ngoài symlink trong một thời gian khá lâu. Điều này được sử dụng để làm việc tốt, mà không thực hiện bất kỳ sắp xếp đặc biệt. Vì tôi đã cập nhật lên Git 1.6.1, nên nó không hoạt động nữa.

Bạn có thể chuyển sang Git 1.6.0 để thực hiện công việc này. Tôi hy vọng rằng một phiên bản Git trong tương lai sẽ có cờ là git-add cho phép nó theo dõi các liên kết tượng trưng một lần nữa.

12
Erik Schnetter

Với Git 2.3.2+ (Q1 2015), có một trường hợp khác trong đó Git sẽ không theo symlink nữa: see commit e0d201b by Junio ​​C Hamano (gitster) (người duy trì Git chính )

apply: không chạm vào tệp ngoài liên kết tượng trưng

Vì Git theo dõi các liên kết tượng trưng dưới dạng liên kết tượng trưng, ​​nên một đường dẫn có liên kết tượng trưng trong phần đầu của nó (ví dụ path/to/dir/file, trong đó path/to/dir là một liên kết tượng trưng đến một nơi khác, không thể ở bên trong hoặc bên ngoài cây hoạt động) áp dụng hợp lệ, trừ khi bản vá tương tự trước tiên loại bỏ liên kết tượng trưng để cho phép một thư mục được tạo ở đó.

Phát hiện và từ chối một bản vá như vậy.

Tương tự, khi một đầu vào tạo một liên kết tượng trưng path/to/dir và sau đó tạo một tệp path/to/dir/file, chúng ta cần gắn cờ đó là một lỗi mà không thực sự tạo liên kết tượng trưng path/to/dir trong hệ thống tệp.

Thay vào đó, đối với bất kỳ bản vá nào trong đầu vào để lại một đường dẫn (nghĩa là không xóa) trong kết quả, chúng tôi kiểm tra tất cả các đường dẫn đối với cây kết quả mà bản vá sẽ tạo bằng cách kiểm tra tất cả các bản vá trong đầu vào và sau đó là mục tiêu của bản vá ứng dụng (chỉ mục hoặc cây làm việc).

Bằng cách này, chúng tôi:

  • bắt một trò nghịch ngợm hoặc một lỗi để thêm một liên kết tượng trưng path/to/dir và một tệp path/to/dir/file cùng một lúc, 
  • trong khi cho phép một bản vá hợp lệ loại bỏ link path/to/dir tượng trưng và sau đó thêm tệp path/to/dir/file.

Điều đó có nghĩa là, trong trường hợp đó, thông báo lỗi sẽ không phải là một thông báo chung như "%s: patch does not apply", mà là một thông báo cụ thể hơn:

affected file '%s' is beyond a symbolic link
6
VonC

Tôi cảm thấy mệt mỏi với mọi giải pháp ở đây hoặc đã lỗi thời hoặc yêu cầu root, vì vậy Tôi đã thực hiện một giải pháp dựa trên LD_PRELOAD (chỉ dành cho Linux).

Nó móc vào nội bộ của Git, ghi đè lên 'đây có phải là một liên kết tượng trưng không?' chức năng, cho phép các liên kết tượng trưng được coi là nội dung của chúng. Theo mặc định, tất cả các liên kết đến bên ngoài repo được nội tuyến; xem liên kết để biết chi tiết.

5
Alcaro

Hmmm, mount --bind dường như không hoạt động trên Darwin.

Có ai có một mẹo mà không?

[chỉnh sửa]

OK, tôi đã tìm thấy câu trả lời trên Mac OS X là tạo một liên kết cứng. Ngoại trừ việc API đó không được hiển thị thông qua ln, vì vậy bạn phải sử dụng chương trình nhỏ của riêng mình để thực hiện việc này. Đây là một liên kết đến chương trình đó:

Tạo liên kết cứng thư mục trong Mac OS X

Thưởng thức!

4
J Chris A

Tôi đang sử dụng Git 1.5.4.3 và nó đi theo liên kết tượng trưng đã qua nếu nó có dấu gạch chéo. Ví dụ.

# Adds the symlink itself
$ git add symlink

# Follows symlink and adds the denoted directory's contents
$ git add symlink/
1
artistoex

Trên MacOS, sử dụng bindfs

brew install bindfs

cd /path/to/git_controlled_dir 

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

Nó đã được gợi ý bởi các bình luận khác, nhưng không được cung cấp rõ ràng trong các câu trả lời khác. Hy vọng điều này sẽ giúp ai đó tiết kiệm thời gian. 

0
ijoseph

Chuyển đổi từ symlink có thể hữu ích. Liên kết trong thư mục Git thay vì liên kết tượng trưng theo tập lệnh .

0
Yurij73