Sind Git-Gabeln tatsächlich Git-Klone?

817

Ich höre immer wieder Leute sagen, dass sie Code in Git geben. Git "Fork" klingt verdächtig nach Git "Clone" plus einer (bedeutungslosen) psychologischen Bereitschaft, auf zukünftige Zusammenschlüsse zu verzichten. Es gibt keinen Gabelbefehl in Git, oder?

GitHub macht Gabeln ein wenig realer, indem Korrespondenz darauf geheftet wird. Das heißt, Sie drücken die Gabel-Taste und später, wenn Sie die Pull-Anforderungs-Taste drücken, ist das System intelligent genug, um dem Eigentümer eine E-Mail zu senden. Daher ist es ein bisschen wie ein Tanz um Repository-Besitz und Berechtigungen.

Ja Nein? Haben Sie Angst, dass GitHub Git in diese Richtung erweitert? Oder Gerüchte, dass Git die Funktionalität absorbiert?

Brian
quelle
10
Ja, es ist nur eine Art Klon, der von der Github-Datenbank verfolgt wird.
Paŭlo Ebermann
15
Tut GitHub nicht etwas Besonderes, um eine Verdoppelung der Speicheranforderungen (auf GitHubs eigenen Servern) zu vermeiden?
Keith Thompson
18
Noch nicht erwähnt: Durch das Löschen eines privaten Repos werden alle Gabeln gelöscht. Durch das Löschen eines öffentlichen Repos bleiben die Gabeln erhalten, eine Gabel wird jedoch zum neuen übergeordneten Repo. Wenn Ihr Chef Ihr öffentliches Repo privat macht, werden alle vorhandenen Gabeln beschädigt, und Sie können keine Pull-Anfragen von ihnen an das private Repo senden. help.github.com/articles/…
Plato
Ich glaube (ohne Beweis, da GitHub uns dies nicht zeigt), dass der eigentliche Mechanismus hier Gits "Alternativen" sind. Mit anderen Worten, die Gabel ist ein Spiegelklon mit --referenceverwendet. Wie genau mit öffentlichen Repos und Löschungen umgegangen wird, ist überhaupt nicht klar (wechseln Sie die Alternativen zu zufällig ausgewählten, beworbenen Repo? Zeigen Sie alle Gabeln auf eine gemeinsame Alternative, die nicht Teil der ursprünglichen Gabel ist?), Aber die Verwendung von Alternativen erklärt verschiedene beobachtbare Verhaltensweisen.
Torek

Antworten:

925

Fork erweitert Git im GitHub-Kontext nicht.
Es ist nur das Klonen auf der Serverseite zulässig.

Wenn Sie ein GitHub-Repository auf Ihrer lokalen Workstation klonen, können Sie nur dann einen Beitrag zum Upstream-Repository leisten, wenn Sie ausdrücklich als "Mitwirkender" deklariert sind. Das liegt daran, dass Ihr Klon eine separate Instanz dieses Projekts ist. Wenn Sie einen Beitrag zum Projekt leisten möchten, können Sie dies auf folgende Weise mit Forking tun:

  • Klonen Sie das GitHub-Repository in Ihrem GitHub-Konto (das ist der "Fork" -Teil , ein Klon auf der Serverseite).
  • Commits zu diesem GitHub-Repository beitragen (es befindet sich in Ihrem eigenen GitHub-Konto, sodass Sie das Recht haben, darauf zuzugreifen)
  • signalisieren Sie jeden interessanten Beitrag zurück zum ursprünglichen GitHub-Repository (das ist der Teil "Pull Request" über die Änderungen, die Sie an Ihrem eigenen GitHub-Repository vorgenommen haben).

Überprüfen Sie auch " Collaborative GitHub Workflow ".

Wenn Sie eine Verbindung zum ursprünglichen Repository (auch Upstream genannt) beibehalten möchten, müssen Sie eine Fernbedienung hinzufügen, die auf dieses ursprüngliche Repository verweist.
Siehe " Was ist der Unterschied zwischen Ursprung und Upstream auf GitHub? "

Gabel und stromaufwärts

Und mit Git 2.20 (Q4 2018) und mehr ist das Abrufen von der Gabel mit Delta-Inseln effizienter .

VonC
quelle
6
"Wenn Sie ein GitHub-Repo auf Ihrer lokalen Workstation klonen, können Sie nur dann einen Beitrag zum Upstream-Repo leisten, wenn Sie ausdrücklich als" Mitwirkender "deklariert sind." --- Stimmt das nicht mit "Gabeln"? Bitte erkläre.
Chharvey
61
@ TestSubject528491 nein, mit einer Gabel bedeutet dies, dass Sie das Upstream-Repo als Ihr eigenes Repo auf der GitHub-Serverseite klonen . Dann können Sie das neue "Gabel" -Repo lokal auf Ihren Computer klonen und es frei zurückschieben, da Sie der Schöpfer und Eigentümer dieser Gabel sind.
VonC
9
Für mich ist der entscheidende Punkt, dass Sie keine PR von Ihrer lokalen Kopie einreichen können, es sei denn, Sie sind als Mitwirkender deklariert . Ich bin es so gewohnt, PRs von meinem lokalen Repo einzureichen, aber das liegt daran, dass ich immer als Mitwirkender markiert bin. Wenn Sie darüber nachdenken, müssen Sie zum Einreichen einer PR einen Zweig an das Remote-Repo senden und dann die PR erstellen. Ich denke, es ist sinnvoll, wenn Sie nicht möchten, dass zufällige Personen Zweige in Ihrem Repo erstellen. Und dass Sie es vorziehen würden, wenn sie es teilen und stattdessen PRs auf diese Weise einreichen.
Adam Zerner
Ich habe den zweiten "Upstream" -Remote-Ansatz an anderer Stelle gesehen, aber ist es nicht einfacher, direkt von "GitHub - Original" zu "GitHub - Fork" zu wechseln? Der zweite Remote-Ansatz schien in meinem Eclipse- und eGit-Setup nicht zu funktionieren und konnte nicht auf mein Repo "GitHub - Fork" übertragen werden (nichts zu pushen).
William T. Mallard
Egal, der Link hier gibt mir einen Einblick. Als Mitwirkender ist es sinnvoll, von "GitHub - Original" zu "GitHub - Fork" und dann von "- Fork" zu einem lokalen Computer zu wechseln. Wenn Sie jedoch der Eigentümer sind, möchten Sie wahrscheinlich direkt von meinem "- Fork" ziehen. Überprüfen Sie zuerst, führen Sie Tests usw. aus, bevor Sie auf "- Original" klicken.
William T. Mallard
135

Ich höre immer wieder Leute sagen, dass sie Code in Git geben. Git "Fork" klingt verdächtig nach Git "Clone" plus einer (bedeutungslosen) psychologischen Bereitschaft, auf zukünftige Zusammenschlüsse zu verzichten. Es gibt keinen Gabelbefehl in Git, oder?

"Forking" ist ein Konzept, kein Befehl, der von einem Versionskontrollsystem speziell unterstützt wird.

Die einfachste Art des Gabelns ist gleichbedeutend mit Verzweigen. Jedes Mal, wenn Sie einen Zweig erstellen, unabhängig von Ihrem VCS, haben Sie "gegabelt". Diese Gabeln lassen sich normalerweise leicht wieder zusammenführen.

Die Art von Gabelung, von der Sie sprechen, bei der eine separate Partei eine vollständige Kopie des Codes nimmt und weggeht, geschieht notwendigerweise außerhalb des VCS in einem zentralisierten System wie Subversion. Ein verteiltes VCS wie Git bietet eine viel bessere Unterstützung für das Verzweigen der gesamten Codebasis und das effektive Starten eines neuen Projekts.

Git (nicht GitHub) unterstützt nativ das "Gabeln" eines gesamten Repos (dh das Klonen) auf verschiedene Arten:

  • Wenn Sie klonen, wird eine entfernte Fernbedienung originfür Sie erstellt
  • Standardmäßig verfolgen alle Zweige im Klon ihre originEntsprechungen
  • Das Abrufen und Zusammenführen von Änderungen aus dem ursprünglichen Projekt, aus dem Sie gegabelt haben, ist trivial einfach

Git macht es einfach, Änderungen an der Quelle des Forks zurückzugeben, indem Sie jemanden aus dem ursprünglichen Projekt bitten, von Ihnen zu ziehen, oder Schreibzugriff anfordern, um Änderungen selbst zurückzuschieben. Dies ist der Teil, den GitHub einfacher macht und standardisiert.

Irgendeine Angst vor Github, der sich in diese Richtung erstreckt? Oder irgendwelche Gerüchte, dass Git die Funktionalität absorbiert?

Es gibt keine Angst, weil Ihre Annahme falsch ist. GitHub "erweitert" die Forking-Funktionalität von Git mit einer schönen GUI und einer standardisierten Methode zum Ausgeben von Pull-Anfragen, fügt Git jedoch nicht die Funktionalität hinzu. Das Konzept des Full-Repo-Forkings ist auf einer fundamentalen Ebene direkt in die verteilte Versionskontrolle eingebunden. Sie können GitHub jederzeit verlassen und weiterhin Projekte pushen / ziehen, die Sie "gegabelt" haben.

meagar
quelle
6
Vielen Dank für Ihre hervorragende Antwort. Ich möchte nur klarstellen, das heißt, außerhalb des Github-Kontexts könnte ich einige X projectauf meinen Computer klonen . Wenn ich Änderungen in meinem lokalen Bereich vornehme und keinen Schreibzugriff auf den Ursprung habe, sende ich dem Autor des Projekts eine E-Mail, um einen Pull anzufordern. Er wird eine Fernbedienung namens Gideon erstellen, die eine URL zu meinem lokalen Klon sein wird, und er kann ziehen, richtig?
Gideon
1
Wenn Sie Ihre Änderungen in ein Projekt einbringen möchten, können Sie sie entweder in Dateien speichern, z. B. mithilfe des Git-Format-Patches, und sie an eine E-Mail an jemanden anhängen, der über diesen Schreibzugriff verfügt, oder Sie können Ihr eigenes Hosting erhalten und senden Sie die URL in einer E-Mail, z. B. mit dem Befehl git request-pull. Repos auf Workstations sind normalerweise nicht direkt online verfügbar.
BDSL
Aber ja, wenn Ihre Workstation für den Autor des Projekts über das Internet zugänglich ist, können Sie einfach die URL an ihn senden und er kann sie als Fernbedienung hinzufügen und daraus ziehen.
BDSL
1
Re: angst, das einzige für mich ist, dass es keinen Link oder Button zum Klicken gibt, um einen Pull-from-my-Repo-Perspektiv-Button zu erstellen, bei dem GitHub Ihnen sagt, dass Sie 50 Commits hinter sich haben. Kein Problem, jetzt wo ich weiß, dass sie den Begriff "Pull Request" verwenden, um auch Anfragen zum Ziehen vom Upstream zu Ihrer GitHub-Gabel einzuschließen. Git ist schwer.
William T. Mallard
80

Ja, Gabel ist ein Klon. Es ist entstanden, weil Sie nicht ohne deren Erlaubnis auf die Kopien anderer pushen können . Sie machen eine Kopie davon für Sie ( Gabel ), wo Sie auch eine Schreibgenehmigung haben.

Wenn der tatsächliche Eigentümer oder andere Benutzer mit einer Verzweigung Ihre Änderungen mögen, können sie diese in Zukunft in ihr eigenes Repository zurückziehen. Alternativ können Sie ihnen eine "Pull-Anfrage" senden.

ssapkota
quelle
Kann ich das Repository einfach auf meinen lokalen Computer klonen, einen Zweig erstellen und dann eine Pull-Anfrage an den ursprünglichen Eigentümer senden? Es scheint überflüssig zu sein, mehrere Kopien von Repos auf GitHub zu hosten, nur um Code-Updates zu ermöglichen.
Casey
4
@Casey Sie können eine Pull-Anfrage nur über GitHub von GitHub selbst senden, und Sie können eine GitHub-Pull-Anfrage nur von einem Zweig senden, der auf GitHub vorhanden ist. Wenn Sie kein Mitarbeiter des betreffenden Repositorys sind, können Sie keinen Zweig erstellen, von dem aus Sie eine GitHub-Pull-Anforderung initiieren können. Nichts hindert Sie daran, dies auf altmodische Weise per E-Mail zu tun, aber GitHub spielt dabei keine Rolle.
Beau Simensen
2
@Casey, ein Grund dafür ist, dass andere normalerweise keinen URL-Zugriff auf Ihre Workstation haben. Der GitHub forkbedeutet, dass sich auf dem GitHub-Server eine Kopie Ihrer Arbeit befindet, auf die Sie pushzugreifen können und auf die andere URL-Zugriff haben, damit sie dies können pull. Dies pull requestist nur eine Standardmethode, um die URL für Ihre Kopie (auf GitHub) zu ihnen zu bringen, damit sie sie einfach in ihr Repository ziehen können.
Jesse Chisholm
Dies sollte die richtige / akzeptierte Antwort sein, glaube ich. Stellen Sie sich ein Durcheinander in einer Szene vor, in der ein Team von 15 bis 20 Entwicklern Zweige erstellt und zum Ursprung drängt, während 15 bis 20 Entwickler ihre eigene Kopie desselben Repositorys haben und so viele Zweige wie möglich vornehmen, Änderungen vornehmen und zurückschieben. Dann kann der Autor des ursprünglichen Repositorys nur die gewünschten Änderungen vornehmen.
Kishor Pawar
37

"Gabel" bedeutet in diesem Zusammenhang "Kopie des Codes erstellen, damit ich meine eigenen Änderungen hinzufügen kann". Sonst gibt es nicht viel zu sagen. Jeder Klon ist im Wesentlichen eine Gabel, und es ist Sache des Originals, zu entscheiden, ob die Änderungen von der Gabel gezogen werden sollen.

Daenyth
quelle
2
Im Einzelnen: "Machen Sie eine Kopie ihres Codes, on the GitHub serverdamit ich meine eigenen Änderungen hinzufügen kann and others can have URL access to my version". Die meisten lokalen Workstations bieten keinen URL-Zugriff, damit jemand darauf zugreifen kann. Wenn Sie jedoch auf dem Server auf Ihre Abzweigung drücken, können diese die URL für den Pull haben.
Jesse Chisholm
Die Frage bezieht sich nicht auf das Gabeln im Allgemeinen, sondern auf das GitHub-Gabeln im Speziellen.
Reinierpost
26

Beim Klonen wird eine Kopie des Git-Repositorys auf einen lokalen Computer erstellt, während beim Forken das Repository in ein anderes Repository geklont wird. Das Klonen ist nur für den persönlichen Gebrauch bestimmt (obwohl zukünftige Zusammenführungen auftreten können), aber mit Forking kopieren Sie und öffnen einen neuen möglichen Projektpfad

Sam Johnson
quelle
11

Das Gabeln erfolgt, wenn Sie sich entscheiden, zu einem Projekt beizutragen. Sie würden eine Kopie des gesamten Projekts zusammen mit den Verlaufsprotokollen erstellen. Diese Kopie wird vollständig in Ihrem Repository erstellt. Sobald Sie diese Änderungen vorgenommen haben, geben Sie eine Pull-Anforderung aus. Jetzt ist es Sache des Eigentümers der Quelle, Ihre Pull-Anfrage zu akzeptieren und die Änderungen in den Originalcode aufzunehmen.

Git-Klon ist ein tatsächlicher Befehl, mit dem Benutzer eine Kopie der Quelle erhalten können. Git-Klon [URL] Hiermit sollte eine Kopie von [URL] in Ihrem eigenen lokalen Repository erstellt werden.

aliasav
quelle
10

Ich denke, Fork ist eine Kopie eines anderen Repositorys, aber mit Ihrer Kontoänderung. Wenn Sie beispielsweise ein anderes Repository direkt lokal klonen, verwendet der Remote-Objektursprung weiterhin das Konto, von dem Sie klonen. Sie können Ihren Code nicht festschreiben und beitragen. Es ist nur eine reine Kopie von Codes. Andernfalls klont das Repository, wenn Sie ein Repository aufteilen, mit der Aktualisierung Ihrer Kontoeinstellung in Ihrem Github-Konto. Wenn Sie dann das Repo im Kontext Ihres Kontos klonen, können Sie Ihre Codes festschreiben.

Daniel Shen
quelle
10

Hier gibt es ein Missverständnis darüber, was eine "Gabel" ist. Eine Gabelung ist in der Tat nichts anderes als eine Reihe von Zweigen pro Benutzer. Wenn Sie zu einem Fork pushen, pushen Sie tatsächlich zum ursprünglichen Repository, da dies das EINZIGE Repository ist.

Sie können dies ausprobieren, indem Sie auf einen Fork drücken, das Commit notieren und dann zum ursprünglichen Repository wechseln und die Commit-ID verwenden. Sie werden feststellen, dass sich das Commit "im" ursprünglichen Repository befindet.

Das macht sehr viel Sinn, ist aber alles andere als offensichtlich (ich habe dies erst kürzlich zufällig entdeckt).

Wenn John das Repository SuperProject teilt, scheint es tatsächlich so zu sein, dass alle Zweige im Quell-Repository mit einem Namen wie "John.master", "John.new_gui_project" usw. repliziert werden.

GitHub "versteckt" den "John". von uns und gibt uns die Illusion, wir hätten unsere eigene "Kopie" des Repositorys auf GitHub, aber wir tun es nicht und es wird auch keine benötigt.

Der Zweig meiner Gabel "master" heißt also eigentlich "Korporal.master", aber die GitHub-Benutzeroberfläche zeigt dies nie und zeigt mir nur "master".

Das ist so ziemlich das, was ich denke, geht sowieso unter der Haube vor, basierend auf Sachen, die ich in letzter Zeit gemacht habe, und wenn man darüber nachdenkt, ist es sehr gutes Design.

Aus diesem Grund denke ich, dass es für Microsoft sehr einfach wäre, Git-Gabeln in ihrem Visual Studio Team Services-Angebot zu implementieren.

Hugh
quelle
Lieber Hugh, die Hälfte Ihrer Antwort ist tatsächlich falsch - ein Fork ist ein Klon eines gesamten Repositorys von einem Benutzerkonto zu einem anderen Benutzerkonto, zusammen mit allen Zweigen und dem Verlauf. Wenn Sie sich für die Verzweigung festlegen, ändert sich im ursprünglichen Repository, aus dem Sie die Verzweigung vorgenommen haben, nichts. Abgesehen von diesen wenigen Missverständnissen, die Sie hinsichtlich der Bedeutung einer "Gabel" haben, gibt es jetzt einige gute Neuigkeiten: Die Visual Studio Team-Dienste enthalten jetzt eine "Gabel" -Funktionalität. ;)
Sorin Postelnicu
1
@ SorinPostelnicu Quelle? Ich neige dazu, Hugh hier zu glauben, weil ich persönlich erlebt habe, wie sich Gabeln so verhalten, dass sie nicht mit einem einfachen Klon des Repositorys übereinstimmen. Wenn beispielsweise Upstream gelöscht wird, werden Gabeln gelöscht (wie in einem Kommentar zur Frage von OP erwähnt), und manchmal hat Upstream beim Akzeptieren einer Pull-Anfrage Dinge in Zweigen meiner Gabeln zusammengeführt, ohne dass ich etwas unternehme.
Kartoffel
Dies scheint tatsächlich der Fall zu sein. Schließlich wäre es für GitHub unglaublich dumm, git clonejedes Mal, wenn jemand den "Gabel" -Knopf drückt , buchstäblich ein ganz neues Repository (sogar ein "nacktes") zu erstellen - das wäre eine unglaubliche Verschwendung von Speicher und wahrscheinlich auch ein Angriffsvektor .
Greg A. Woods
7

Abgesehen von der Tatsache, dass das Klonen vom Server auf Ihren Computer erfolgt und das Forking eine Kopie auf dem Server selbst erstellt, besteht ein wichtiger Unterschied darin, dass wir beim Klonen tatsächlich alle Zweige, Beschriftungen usw. erhalten.

Aber wenn wir uns teilen, bekommen wir tatsächlich nur die aktuellen Dateien im Hauptzweig, nichts anderes. Dies bedeutet, dass wir die anderen Zweige usw. nicht bekommen.

Wenn Sie also etwas wieder mit dem ursprünglichen Repository zusammenführen müssen, handelt es sich um eine Zusammenführung zwischen Repositorys, für die auf jeden Fall höhere Berechtigungen erforderlich sind.

Fork ist kein Befehl in Git; Es ist nur ein Konzept, das GitHub implementiert. Denken Sie daran, dass Git für die Arbeit in einer Peer-to-Peer-Umgebung entwickelt wurde, ohne dass Inhalte mit einer Masterkopie synchronisiert werden müssen. Der Server ist nur ein weiterer Peer, aber wir betrachten ihn als Masterkopie.

Deepak GM
quelle
7
Huh? Eine Gabel bekommt alle Äste, obwohl man wissen muss, wo man suchen muss (Hinweis :) git branch -a.
Tripleee
3

In einfachsten Worten,

Wenn Sie sagen, dass Sie ein Repository forken , erstellen Sie im Grunde genommen eine Kopie des ursprünglichen Repositorys unter Ihrer GitHub-ID in Ihrem GitHub-Konto.

und

Wenn Sie sagen, dass Sie ein Repository klonen , erstellen Sie direkt eine lokale Kopie des ursprünglichen Repositorys in Ihrem System (PC / Laptop), ohne eine Kopie in Ihrem GitHub-Konto zu haben.

anoNewb
quelle