it-swarm-id.com

Bagaimana saya bisa membuat Git mengikuti symlink?

Apakah yang terbaik adalah skrip Shell yang menggantikan symlink dengan salinan, atau adakah cara lain untuk memberitahu Git untuk mengikuti symlink?

PS: Saya tahu itu tidak terlalu aman, tetapi saya hanya ingin melakukannya dalam beberapa kasus tertentu.

174
Matt

CATATAN: Saran ini sekarang kedaluwarsa sesuai komentar sejak Git 1.6.1. Git dulu berperilaku seperti ini, dan tidak lagi melakukannya.


Git secara default mencoba untuk menyimpan symlink alih-alih mengikutinya (untuk kekompakan, dan umumnya yang diinginkan orang).

Namun, saya tidak sengaja berhasil menambahkan file di luar symlink ketika symlink adalah direktori.

Yaitu.:

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

dengan melakukan

 git add /bar/foo/baz

tampaknya berfungsi ketika saya mencobanya. Namun perilaku itu tidak diinginkan oleh saya pada saat itu, jadi saya tidak dapat memberi Anda informasi lebih dari itu.

37
Kent Fredric

Apa yang saya lakukan untuk menambahkan agar file dalam symlink ke Git (saya tidak menggunakan symlink tetapi):

Sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Lakukan perintah ini di direktori yang dikelola Git. TARGETDIRECTORY harus dibuat sebelum SOURCEDIRECTORY dipasang ke dalamnya.

Ini berfungsi dengan baik di Linux, tetapi tidak pada OS X! Trik itu membantu saya dengan Subversi juga. Saya menggunakannya untuk memasukkan file dari akun Dropbox, tempat webdesigner melakukan tugasnya.

124
user252400

Mengapa tidak membuat symlink sebaliknya? Berarti alih-alih menautkan dari repositori Git ke direktori aplikasi, tautkan sebaliknya.

Misalnya, katakanlah saya sedang menyiapkan aplikasi yang terpasang di ~/application yang membutuhkan file konfigurasi config.conf:

  • Saya menambahkan config.conf ke repositori Git saya, misalnya, di ~/repos/application/config.conf.
  • Lalu saya membuat symlink dari ~/application dengan menjalankan ln -s ~/repos/application/config.conf.

Pendekatan ini mungkin tidak selalu berhasil, tetapi sejauh ini berhasil bagi saya.

65
spier

Gunakan tautan keras sebagai gantinya. Ini berbeda dari tautan lunak (simbolik). Semua program, termasuk git akan memperlakukan file sebagai file biasa. Perhatikan bahwa konten dapat dimodifikasi dengan mengubah salah satu sumber atau tujuan.

Di macOS (sebelum 10.13 Sierra Tinggi)

Jika Anda sudah menginstal git dan Xcode, instal hardlink . Ini adalah alat mikroskopis untuk membuat tautan keras

Untuk membuat tautan keras, cukup:

hln source destination

macOS pembaruan Sierra Tinggi

Apakah Apple File System mendukung tautan keras direktori?

Tautan keras direktori tidak didukung oleh Apple File System. Semua tautan keras direktori dikonversi ke tautan simbolis atau alias ketika Anda mengonversi dari format volume HFS + ke APFS di macOS.

Dari APFS FAQ di developer.Apple.com

Ikuti https://github.com/selkhateeb/hardlink/issues/31 untuk alternatif di masa mendatang.

Di Linux dan rasa Unix lainnya

Perintah ln dapat membuat tautan keras:

ln source destination

Di Windows (Vista, 7, 8, ...)

Seseorang menyarankan untuk menggunakan mklink membuat persimpangan pada Windows, tetapi saya belum mencobanya:

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

Ini adalah kait pra-komit yang menggantikan gumpalan symlink dalam indeks, dengan konten dari symlink tersebut.

Letakkan ini di .git/hooks/pre-commit, dan buat itu bisa dieksekusi:

#!/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

Catatan

Kami menggunakan fungsionalitas yang sesuai dengan POSIX sebanyak mungkin; namun, diff -a tidak sesuai dengan POSIX, mungkin antara lain.

Mungkin ada beberapa kesalahan/kesalahan dalam kode ini, meskipun agak diuji.

16
Abbafei

Saya dulu menambahkan file di luar symlink untuk beberapa waktu sekarang. Ini digunakan untuk bekerja dengan baik, tanpa membuat pengaturan khusus. Karena saya memperbarui ke Git 1.6.1, ini tidak berfungsi lagi.

Anda mungkin bisa beralih ke Git 1.6.0 untuk membuat ini berfungsi. Saya berharap bahwa versi Git di masa depan akan memiliki bendera untuk git-add yang memungkinkannya untuk mengikuti symlink lagi.

12
Erik Schnetter

Dengan Gitp4 (Q1 2015), ada satu kasus lain di mana Git akan tidak mengikuti symlink lagi: lihat commit e0d201b oleh Junio ​​C Hamano (gitster) (pengelola utama Git )

apply: jangan menyentuh file di luar tautan simbolik

Karena Git melacak tautan simbolik sebagai tautan simbolik, jalur yang memiliki tautan simbolik di bagian terdepan (mis. path/to/dir/file, di mana path/to/dir adalah tautan simbolis ke tempat lain, baik di dalam atau di luar pohon yang bekerja) tidak pernah dapat muncul dalam tambalan berlaku secara sah, kecuali tambalan yang sama terlebih dahulu menghapus tautan simbolik untuk memungkinkan direktori dibuat di sana.

Mendeteksi dan menolak tambalan seperti itu.

Demikian pula, ketika input membuat tautan simbolik path/to/dir dan kemudian membuat file path/to/dir/file, kita perlu menandainya sebagai kesalahan tanpa benar-benar membuat tautan simbolik path/to/dir di sistem file.

Alih-alih, untuk setiap tambalan di input yang meninggalkan jalur (yaitu non-penghapusan) di hasilnya, kami memeriksa semua jalur utama terhadap pohon yang dihasilkan yang akan dibuat oleh tambalan dengan memeriksa semua tambalan di input dan kemudian target tambalan aplikasi (baik indeks atau pohon kerja).

Dengan cara ini, kami:

  • menangkap kerusakan atau kesalahan untuk menambahkan tautan simbolis path/to/dir dan file path/to/dir/file pada saat yang sama, 
  • sambil memungkinkan tambalan yang valid yang menghapus link path/to/dir simbolik dan kemudian menambahkan file path/to/dir/file.

Itu berarti, dalam hal ini, pesan kesalahan tidak akan menjadi pesan umum seperti "%s: patch does not apply", tetapi pesan yang lebih spesifik:

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

Saya bosan dengan setiap solusi di sini baik yang sudah usang atau membutuhkan root, jadi Saya membuat solusi berbasis LD_PRELOAD (hanya Linux).

Itu menghubungkan ke internal Git, mengesampingkan 'apakah ini symlink?' berfungsi, memungkinkan symlink diperlakukan sebagai kontennya. Secara default, semua tautan ke luar repo diuraikan; lihat tautan untuk detailnya.

5
Alcaro

Hmmm, mount --bind sepertinya tidak berfungsi di Darwin.

Adakah yang punya trik itu?

[diedit]

OK, saya menemukan jawabannya di Mac OS X adalah membuat hardlink. Kecuali bahwa API tidak diekspos melalui ln, jadi Anda harus menggunakan program kecil Anda sendiri untuk melakukan ini. Berikut ini tautan ke program itu:

Membuat tautan keras direktori di Mac OS X

Nikmati!

4
J Chris A

Saya menggunakan Git 1.5.4.3 dan ini mengikuti symlink yang diteruskan jika memiliki garis miring. Misalnya.

# Adds the symlink itself
$ git add symlink

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

Pada MacOS, gunakan bindfs

brew install bindfs

cd /path/to/git_controlled_dir 

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

Sudah diisyaratkan oleh komentar lain, tetapi tidak jelas disediakan dalam jawaban lain. Semoga ini menghemat waktu seseorang. 

0
ijoseph

Konversi dari symlink dapat bermanfaat. Tautkan dalam folder Git alih-alih symlink oleh skrip .

0
Yurij73