it-swarm-eu.dev

Wie kann ich Git dazu bringen, Symlinks zu folgen?

Ist mein Bestes, ein Shell-Skript zu sein, das Symlinks durch Kopien ersetzt, oder gibt es eine andere Möglichkeit, Git mitzuteilen, Symlinks zu folgen?

PS: Ich weiß, dass es nicht sehr sicher ist, aber ich möchte es nur in bestimmten Fällen tun.

174
Matt

HINWEIS: Dieser Hinweis ist seit Git 1.6.1 per Kommentar überholt. Git hat sich früher so verhalten und tut es nicht mehr.


Git versucht standardmäßig, Symlinks zu speichern, anstatt ihnen zu folgen (für die Kompaktheit, und das ist in der Regel das, was die Leute wollen).

Es gelang mir jedoch aus Versehen, Dateien über den Symlink hinaus hinzuzufügen, wenn der Symlink ein Verzeichnis ist.

I.e .:

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

zu tun

 git add /bar/foo/baz

es schien zu funktionieren, als ich es versuchte. Dieses Verhalten war jedoch zu dem Zeitpunkt von mir nicht erwünscht, so dass ich Ihnen keine weiteren Informationen geben kann.

37
Kent Fredric

Was ich hinzugefügt habe, um die Dateien innerhalb eines Symlinks in Git zu bekommen (ich habe keinen Symlink verwendet, aber):

Sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Führen Sie diesen Befehl im von Git verwalteten Verzeichnis aus. TARGETDIRECTORY muss erstellt werden, bevor die SOURCEDIRECTORY eingebunden wird.

Es funktioniert gut unter Linux, aber nicht unter OS X! Dieser Trick hat mir auch bei Subversion geholfen. Ich verwende es, um Dateien aus einem Dropbox-Konto einzuschließen, wo ein Webdesigner seine/ihre Sachen macht.

124
user252400

Warum nicht gleich Symlinks erstellen? Das heißt, anstatt vom Git-Repository aus mit dem Anwendungsverzeichnis zu verknüpfen, verlinken Sie einfach in die andere Richtung.

Nehmen wir beispielsweise an, ich stelle eine in ~/application installierte Anwendung ein, die eine Konfigurationsdatei config.conf benötigt:

  • Ich füge config.conf zu meinem Git-Repository hinzu, zum Beispiel bei ~/repos/application/config.conf.
  • Dann erstelle ich aus ~/application einen Symlink, indem ich ln -s ~/repos/application/config.conf ausführt.

Dieser Ansatz funktioniert möglicherweise nicht immer, aber bisher hat er gut funktioniert.

65
spier

Verwenden Sie stattdessen feste Links. Dies unterscheidet sich von einer weichen (symbolischen) Verbindung. Alle Programme, einschließlich git, behandeln die Datei als reguläre Datei. Beachten Sie, dass der Inhalt durch Ändern von entweder der Quelle oder des Ziels geändert werden kann.

Auf macOS (vor 10.13 High Sierra)

Wenn Sie git und Xcode bereits installiert haben, installieren Sie hardlink . Es ist ein mikroskopisches Werkzeug zum Erstellen von harten Links

Um den Hardlink zu erstellen, einfach:

hln source destination

macOS High Sierra-Update

Unterstützt Apple File System feste Links für Verzeichnisse?

Feste Verzeichnisverknüpfungen werden von Apple File System nicht unterstützt. Alle Hardlinks für Verzeichnisse werden in symbolische Links oder Aliase konvertiert, wenn Sie unter Mac OS von HFS + in APFS-Volumenformate konvertieren.

From APFS FAQ auf developer.Apple.com

Folgen Sie https://github.com/selkhateeb/hardlink/issues/31 für zukünftige Alternativen.

Unter Linux und anderen Unix-Varianten

Der Befehl ln kann feste Verknüpfungen herstellen:

ln source destination

Unter Windows (Vista, 7, 8,…)

Jemand schlug vor, mklink unter Windows eine Junction zu erstellen, aber ich habe es nicht ausprobiert:

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

Dies ist ein Pre-Commit-Hook , der die Symlink-Blobs im Index durch den Inhalt dieser Symlinks ersetzt.

Fügen Sie dies in .git/hooks/pre-commit ein und machen Sie es ausführbar:

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

Anmerkungen

Wir verwenden so oft wie möglich POSIX-kompatible Funktionen. diff -a ist jedoch nicht POSIX-kompatibel, möglicherweise unter anderem.

In diesem Code können Fehler enthalten sein, auch wenn er etwas getestet wurde.

16
Abbafei

Ich habe seit geraumer Zeit Dateien über Symlinks hinaus hinzugefügt. Früher funktionierte das einwandfrei, ohne besondere Vorkehrungen zu treffen. Seit ich auf Git 1.6.1 aktualisiert habe, funktioniert das nicht mehr.

Möglicherweise können Sie zu Git 1.6.0 wechseln, damit dies funktioniert. Ich hoffe, dass eine zukünftige Version von Git git-add mit einem Flag versehen wird, damit es Symlinks erneut folgen kann.

12
Erik Schnetter

Bei Git 2.3.2+ (Q1 2015) gibt es einen weiteren Fall, in dem Git not nicht mehr dem Symlink folgt: siehe commit e0d201b von Junio ​​C Hamano (gitster) (Main Git Maintainer) )

apply: Berühren Sie eine Datei nicht außerhalb eines symbolischen Links

Da Git symbolische Links als symbolische Links verfolgt, kann ein Pfad, der einen symbolischen Link in seinem führenden Teil hat (z. B. path/to/dir/file, wobei path/to/dir ein symbolischer Link zu einer anderen Stelle ist, sei es innerhalb oder außerhalb des Arbeitsbaums) niemals in einem Patch so erscheinen gültig gültig, es sei denn, derselbe Patch entfernt zuerst den symbolischen Link, damit dort ein Verzeichnis erstellt werden kann.

Erkennen und verwerfen Sie einen solchen Patch.

Wenn eine Eingabe einen symbolischen Link path/to/dir erstellt und dann eine Datei path/to/dir/file erstellt, müssen wir sie als Fehler markieren, ohne tatsächlich einen path/to/dir symbolischen Link im Dateisystem zu erstellen.

Stattdessen überprüfen wir für jeden Patch in der Eingabe, der einen Pfad (dh keine Löschung) im Ergebnis hinterlässt, alle führenden Pfade anhand der sich ergebenden Baumstruktur, die der Patch erstellen würde, indem wir alle Patches in der Eingabe und dann das Patch-Ziel untersuchen Anwendung (entweder der Index oder der Arbeitsbaum).

Auf diese Weise:

  • einen Unfug oder Fehler begehen, um gleichzeitig einen symbolischen Link path/to/dir und eine Datei path/to/dir/file hinzuzufügen, 
  • erlaubt ein gültiges Patch, das einen symbolischen link path/to/dir entfernt und dann eine Datei path/to/dir/file hinzufügt.

Das bedeutet, dass in diesem Fall die Fehlermeldung nicht generisch ist wie "%s: patch does not apply", sondern eine spezifischere:

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

Ich war müde von jeder Lösung, die entweder hier veraltet ist oder root benötigt, also Ich habe eine LD_PRELOAD-basierte Lösung erstellt (nur Linux).

Es hakt sich in Gits Interna ein und überschreibt das "Ist das ein Symlink?" Funktion, so dass Symlinks als ihr Inhalt behandelt werden. Standardmäßig sind alle Links außerhalb des Repos eingebettet. Siehe den Link für Details.

5
Alcaro

Hmmm, mount --bind scheint bei Darwin nicht zu funktionieren.

Hat jemand einen Trick, der das tut?

[bearbeitet]

OK, ich fand die Antwort unter Mac OS X, einen Hardlink zu machen. Abgesehen davon, dass diese API nicht über ln verfügbar gemacht wird, müssen Sie dazu Ihr eigenes kleines Programm verwenden. Hier ist ein Link zu diesem Programm:

Feste Verzeichnisverknüpfungen in Mac OS X erstellen

Genießen!

4
J Chris A

Ich verwende Git 1.5.4.3 und es folgt dem übergebenen Symlink, wenn es einen nachgestellten Schrägstrich hat. Z.B.

# Adds the symlink itself
$ git add symlink

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

Verwenden Sie bei MacOSbindfs

brew install bindfs

cd /path/to/git_controlled_dir 

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

Es wurde durch andere Kommentare angedeutet, aber in anderen Antworten nicht eindeutig angegeben. Hoffentlich spart dies jemandem etwas Zeit. 

0
ijoseph

Die Konvertierung von Symlinks kann hilfreich sein. Link in einem Git-Ordner statt eines Symlinks durch ein Skript .

0
Yurij73