Có phải dĩa Git thực sự là bản sao Git?


817

Tôi cứ nghe mọi người nói họ đang giả mạo mã trong Git. Git "fork" nghe có vẻ nghi ngờ như Git "clone" cộng với một số tâm lý (vô nghĩa) sẵn sàng từ bỏ sự hợp nhất trong tương lai. Không có lệnh fork trong Git, phải không?

GitHub làm cho dĩa thực hơn một chút bằng cách ghim thư tương ứng lên nó. Tức là bạn nhấn nút ngã ba và sau đó, khi bạn nhấn nút yêu cầu kéo, hệ thống đủ thông minh để gửi email cho chủ sở hữu. Do đó, đó là một chút nhảy múa xung quanh quyền sở hữu và quyền của kho lưu trữ.

Có không? Bất kỳ sự giận dữ nào đối với GitHub mở rộng Git theo hướng này? Hoặc bất kỳ tin đồn về Git hấp thụ các chức năng?


10
Vâng, nó chỉ là một loại bản sao được theo dõi bởi cơ sở dữ liệu github.
Paŭlo Ebermann

15
GitHub không làm điều gì đó đặc biệt để tránh nhân đôi yêu cầu lưu trữ (trên máy chủ của GitHub)?
Keith Thompson

18
Chưa được đề cập: Xóa một repo riêng sẽ xóa tất cả các nhánh của nó. Xóa một repo công khai giữ các dĩa nhưng thúc đẩy một ngã ba là repo cha mẹ mới. Nếu sếp của bạn đặt repo công khai của bạn ở chế độ riêng tư, nó sẽ phá vỡ tất cả các nhánh hiện có và bạn sẽ không thể thực hiện các yêu cầu kéo từ chúng sang repo riêng. help.github.com/articles/ từ
Plato

Tôi tin rằng (không có bằng chứng vì GitHub không cho chúng tôi thấy điều này) rằng cơ chế thực tế ở đây là "thay thế" của Git. Nói cách khác, ngã ba là một bản sao nhân bản --referenceđược sử dụng. Chính xác thì cách xử lý repos và xóa công khai hoàn toàn không rõ ràng (di chuyển thay thế cho repo được chọn ngẫu nhiên? Chỉ tất cả các nhánh cho một số thay thế chung không phải là một phần của ngã ba ban đầu?), Nhưng việc sử dụng thay thế giải thích các hành vi có thể quan sát được.

Câu trả lời:


925

Fork , trong bối cảnh GitHub, không mở rộng Git.
Nó chỉ cho phép nhân bản ở phía máy chủ.

Khi bạn sao chép kho lưu trữ GitHub trên máy trạm cục bộ, bạn không thể đóng góp trở lại kho lưu trữ ngược dòng trừ khi bạn được tuyên bố rõ ràng là "người đóng góp". Đó là bởi vì bản sao của bạn là một ví dụ riêng biệt của dự án đó. Nếu bạn muốn đóng góp cho dự án, bạn có thể sử dụng forking để thực hiện nó, theo cách sau:

  • sao chép kho lưu trữ GitHub trên tài khoản GitHub của bạn (đó là phần "fork" , một bản sao ở phía máy chủ)
  • đóng góp vào kho lưu trữ GitHub đó (nó nằm trong tài khoản GitHub của riêng bạn, vì vậy bạn có quyền đẩy vào nó)
  • báo hiệu mọi đóng góp thú vị trở lại kho lưu trữ GitHub ban đầu (đó là phần "yêu cầu kéo" bằng cách thay đổi bạn đã thực hiện trên kho lưu trữ GitHub của riêng bạn)

Kiểm tra thêm " Quy trình làm việc GitHub hợp tác ".

Nếu bạn muốn giữ một liên kết với kho lưu trữ ban đầu (còn được gọi là ngược dòng), bạn cần thêm một từ xa giới thiệu kho lưu trữ ban đầu đó.
Xem " Sự khác biệt giữa nguồn gốc và ngược dòng trên GitHub là gì? "

ngã ba và thượng nguồn

Và với Git 2.20 (Q4 2018) và hơn thế nữa, việc tìm nạp từ ngã ba sẽ hiệu quả hơn, với các đảo delta .


6
"Khi bạn đang nhân bản một repo GitHub trên máy trạm cục bộ của mình, bạn không thể đóng góp trở lại repo ngược dòng trừ khi bạn được tuyên bố rõ ràng là" người đóng góp "." --- Điều này có đúng với "forking" không? Vui lòng giải thích.
chharvey

61
@ TestSubject528491 không, với một ngã ba, điều đó có nghĩa là bạn đang nhân bản repo ngược dòng dưới dạng repo của riêng bạn ở phía máy chủ GitHub. Sau đó, bạn có thể sao chép cục bộ repo "ngã ba" mới đó trên máy tính của mình và tự do đẩy lùi nó, vì bạn là người tạo và chủ sở hữu của ngã ba đó.
VonC

9
Đối với tôi, điểm mấu chốt là bạn không thể gửi PR từ bản sao địa phương trừ khi bạn được tuyên bố là cộng tác viên . Tôi đã quá quen với việc gửi PR từ repo địa phương của mình, nhưng đó là vì tôi luôn được đánh dấu là người đóng góp. Nếu bạn nghĩ về nó, để gửi PR, bạn phải đẩy một nhánh đến repo từ xa và sau đó tạo PR. Tôi đoán nó có ý nghĩa nếu bạn không muốn những người ngẫu nhiên tạo chi nhánh trên repo của bạn. Và bạn muốn họ thay thế nó và gửi PR theo cách đó.
Adam Zerner

Tôi đã thấy cách tiếp cận từ xa "ngược dòng" thứ hai ở nơi khác, nhưng không đơn giản hơn khi kéo trực tiếp từ "GitHub - Bản gốc" sang "GitHub - Fork"? Cách tiếp cận từ xa thứ hai dường như không hoạt động trong thiết lập Eclipse và eGit của tôi, không chuyển sang repo "GitHub - Fork" của tôi (không có gì để đẩy).
William T. Mallard

Đừng bận tâm, liên kết thông tin ở đây đã cho tôi một cái nhìn sâu sắc. Là người đóng góp, nên kéo từ "GitHub - Bản gốc" sang "GitHub - Fork", sau đó từ "- Fork" sang máy cục bộ, nhưng nếu bạn là chủ sở hữu, bạn có thể muốn kéo trực tiếp từ "- Fork" của tôi đầu tiên để xem xét, chạy thử nghiệm, vv trước khi đẩy sang "- Bản gốc".
William T. Mallard

135

Tôi cứ nghe mọi người nói họ đang giả mạo mã trong git. Git "fork" nghe có vẻ nghi ngờ như git "clone" cộng với một số tâm lý (vô nghĩa) sẵn sàng từ bỏ sự hợp nhất trong tương lai. Không có lệnh fork trong git, phải không?

"Forking" là một khái niệm, không phải là một lệnh được hỗ trợ đặc biệt bởi bất kỳ hệ thống kiểm soát phiên bản nào.

Loại rèn đơn giản nhất đồng nghĩa với phân nhánh. Mỗi khi bạn tạo một chi nhánh, bất kể VCS của bạn, bạn đã "rẽ nhánh". Những dĩa này thường khá dễ dàng để hợp nhất lại với nhau.

Loại ngã ba mà bạn đang nói đến, trong đó một bên riêng biệt lấy một bản sao hoàn chỉnh của mã và bỏ đi, nhất thiết phải xảy ra bên ngoài VCS trong một hệ thống tập trung như Subversion. Một VCS phân tán như Git có hỗ trợ tốt hơn nhiều cho việc hủy toàn bộ cơ sở mã và bắt đầu một dự án mới một cách hiệu quả.

Git (không phải GitHub) thực sự hỗ trợ "forking" toàn bộ repo (nghĩa là nhân bản nó) theo một số cách:

  • Khi bạn sao chép, một điều khiển từ xa originđược tạo ra cho bạn
  • theo mặc định, tất cả các nhánh trong bản sao sẽ theo dõi chúng origin tương đương
  • tìm nạp và hợp nhất các thay đổi từ dự án ban đầu mà bạn rẽ nhánh rất dễ dàng

Git làm cho việc thay đổi đóng góp trở lại nguồn của ngã ba đơn giản như yêu cầu ai đó từ dự án ban đầu rút từ bạn hoặc yêu cầu quyền truy cập bằng văn bản để đẩy lùi các thay đổi. Đây là phần mà GitHub làm cho dễ dàng hơn và chuẩn hóa.

Bất kỳ angst trên Github mở rộng git theo hướng này? Hoặc bất kỳ tin đồn về git hấp thụ các chức năng?

Không có angst vì giả định của bạn là sai. GitHub "mở rộng" chức năng giả mạo của Git với GUI đẹp và cách phát hành yêu cầu kéo được tiêu chuẩn hóa, nhưng nó không thêm chức năng vào Git. Khái niệm về repo đầy đủ được đưa vào kiểm soát phiên bản phân tán ở cấp độ cơ bản. Bạn có thể từ bỏ GitHub bất cứ lúc nào và vẫn tiếp tục đẩy / kéo các dự án mà bạn đã "rẽ nhánh".


6
Cảm ơn câu trả lời tuyệt vời của bạn. Tôi chỉ muốn làm rõ, điều này có nghĩa là, bên ngoài bối cảnh của github tôi có thể sao chép một số X projecttrên máy của mình. Nếu tôi thực hiện thay đổi tại địa phương của mình và không có quyền truy cập bằng văn bản, tôi sẽ gửi email cho tác giả của dự án để yêu cầu kéo. Anh ta sẽ tạo ra một điều khiển từ xa được gọi là gideon sẽ là một url cho bản sao địa phương của tôi, và anh ta có thể kéo, phải không?
gideon

1
Nếu bạn muốn đóng góp các thay đổi của mình cho một dự án, bạn có thể lưu chúng vào các tệp, ví dụ như sử dụng bản vá định dạng git và đính kèm chúng vào email cho ai đó có quyền truy cập ghi hoặc bạn có thể có được lưu trữ của riêng mình, đẩy công việc của bạn đến đó và gửi URL trong email, ví dụ: sử dụng lệnh git request-pull. Repos trên máy trạm thường không được truy cập trực tuyến.
bdsl

Nhưng có, nếu máy trạm của bạn tình cờ có thể truy cập qua internet cho tác giả của dự án thì bạn chỉ cần gửi URL cho họ và họ có thể thêm nó dưới dạng từ xa và lấy từ đó.
bds

1
Re: angst, điều duy nhất đối với tôi là không có liên kết hoặc nút nào để nhấp để tạo nút kéo từ góc nhìn của tôi, trong đó GitHub nói với bạn rằng bạn 50 cam kết phía sau. Bây giờ tôi không biết rằng họ đang sử dụng thuật ngữ "Yêu cầu kéo" để bao gồm cả các yêu cầu kéo từ thượng nguồn đến ngã ba GitHub của bạn. Git thật khó.
William T. Mallard

80

Vâng, ngã ba là một bản sao. Nó nổi lên bởi vì, bạn không thể đẩy sang bản sao của người khác mà không có sự cho phép của họ . Họ tạo một bản sao của nó cho bạn ( ngã ba ), nơi bạn cũng sẽ có quyền viết.

Trong tương lai nếu chủ sở hữu thực tế hoặc người dùng khác có một ngã ba như các thay đổi của bạn, họ có thể kéo nó trở lại kho lưu trữ của riêng họ. Ngoài ra, bạn có thể gửi cho họ một "yêu cầu kéo".


Tôi có thể chỉ cần sao chép kho lưu trữ vào máy cục bộ của mình, tạo một nhánh, sau đó gửi yêu cầu kéo cho chủ sở hữu ban đầu không? Dường như có nhiều bản sao của các repos được lưu trữ trên toàn GitHub, chỉ để tạo điều kiện cập nhật mã.
Casey

4
@Casey Bạn chỉ có thể gửi yêu cầu kéo qua GitHub từ chính GitHub và bạn chỉ có thể gửi yêu cầu kéo GitHub từ một nhánh tồn tại trên GitHub. Nếu bạn không phải là cộng tác viên trên Kho lưu trữ được đề cập, không có cách nào để bạn tạo một nhánh mà từ đó bạn có thể bắt đầu yêu cầu kéo GitHub. Không có gì ngăn bạn làm điều đó qua email theo cách cũ, nhưng GitHub không đóng vai trò nào trong đó.
Beau Simensen

2
@Casey, một lý do là thông thường những người khác không có quyền truy cập URL vào máy trạm của bạn. GitHub forkcó nghĩa là có một bản sao công việc của bạn trên máy chủ GitHub, mà bạn có thể pushvà những người khác có quyền truy cập URL để họ có thể pull. Đây pull requestchỉ là một cách tiêu chuẩn để nhận URL cho bản sao của bạn (trên GitHub) cho họ để họ có thể dễ dàng kéo nó vào kho lưu trữ của họ.
Jesse Chisholm

Đây phải là câu trả lời đúng / được chấp nhận mà tôi tin. Hãy tưởng tượng một mớ hỗn độn trong một cảnh trong đó một nhóm 15-20 nhà phát triển tạo ra các nhánh và đẩy về nguồn gốc so với 15-20 nhà phát triển có bản sao của cùng một kho lưu trữ và tạo ra nhiều nhánh và thực hiện các thay đổi và đẩy nó trở lại. Sau đó, Tác giả của kho lưu trữ ban đầu chỉ có thể lấy những thay đổi mà anh ấy / cô ấy muốn.
Kishor Pawar

37

"Fork" trong ngữ cảnh này có nghĩa là "Tạo một bản sao mã của họ để tôi có thể thêm các sửa đổi của riêng mình". Không có nhiều điều để nói. Mỗi bản sao về cơ bản là một ngã ba, và tùy thuộc vào bản gốc để quyết định có nên lấy các thay đổi từ ngã ba hay không.


2
Cụ thể: "Tạo một bản sao mã của họ on the GitHub serverđể tôi có thể thêm các sửa đổi của riêng mình and others can have URL access to my version". Hầu hết các máy trạm cục bộ không cung cấp quyền truy cập URL cho bất kỳ ai có thể kéo. Nhưng nếu bạn đẩy đến ngã ba của bạn trên máy chủ, thì họ có thể có URL để kéo.
Jesse Chisholm

Câu hỏi không phải là về việc giả mạo nói chung, mà là về việc giả mạo GitHub cụ thể.
Revierpost

26

Nhân bản liên quan đến việc tạo một bản sao của kho git vào một máy cục bộ, trong khi việc giả mạo là nhân bản kho lưu trữ vào một kho lưu trữ khác. Nhân bản chỉ dành cho sử dụng cá nhân (mặc dù có thể xảy ra sự hợp nhất trong tương lai), nhưng với việc bạn đang sao chép và mở một đường dẫn dự án mới có thể


11

Ngã ba được thực hiện khi bạn quyết định đóng góp cho một số dự án. Bạn sẽ tạo một bản sao của toàn bộ dự án cùng với nhật ký lịch sử của nó. Bản sao này được tạo hoàn toàn trong kho lưu trữ của bạn và một khi bạn thực hiện những thay đổi này, bạn sẽ đưa ra yêu cầu kéo. Bây giờ, chủ sở hữu nguồn phải chấp nhận yêu cầu kéo của bạn và kết hợp các thay đổi vào mã gốc.

Git clone là một lệnh thực tế cho phép người dùng lấy bản sao của nguồn. git clone [URL] Điều này sẽ tạo một bản sao của [URL] trong kho lưu trữ cục bộ của riêng bạn.


10

Tôi nghĩ rằng fork là một bản sao của kho lưu trữ khác nhưng với sửa đổi tài khoản của bạn. ví dụ: nếu bạn trực tiếp sao chép kho lưu trữ khác cục bộ, nguồn gốc đối tượng từ xa vẫn đang sử dụng tài khoản mà bạn sao chép. Bạn không thể cam kết và đóng góp mã của bạn. Nó chỉ là một bản sao thuần túy của mã. Mặt khác, nếu bạn rẽ nhánh một kho lưu trữ, nó sẽ sao chép repo với bản cập nhật cài đặt tài khoản của bạn trong tài khoản github của bạn. Và sau đó nhân bản repo trong ngữ cảnh tài khoản của bạn, bạn có thể cam kết mã của mình.


10

Có một sự hiểu lầm ở đây liên quan đến "ngã ba" là gì. Một ngã ba trên thực tế không có gì khác ngoài một tập hợp các nhánh trên mỗi người dùng. Khi bạn đẩy đến một ngã ba, bạn thực sự đẩy đến kho lưu trữ ban đầu, bởi vì đó là kho lưu trữ DUY NHẤT.

Bạn có thể thử điều này bằng cách đẩy tới một ngã ba, lưu ý đến cam kết và sau đó đến kho lưu trữ ban đầu và sử dụng ID cam kết, bạn sẽ thấy rằng cam kết đó là "trong" kho lưu trữ ban đầu.

Điều này rất có ý nghĩa, nhưng nó không rõ ràng (tôi chỉ phát hiện ra điều này một cách tình cờ gần đây).

Khi John giả mạo kho lưu trữ SuperProject, điều dường như thực sự xảy ra là tất cả các nhánh trong kho lưu trữ nguồn được sao chép với một tên như "John.master", "John.new_gui_project", v.v.

GitHub "giấu" "John." từ chúng tôi và cho chúng tôi ảo tưởng rằng chúng tôi có "bản sao" của kho lưu trữ trên GitHub, nhưng chúng tôi không và thậm chí không cần thiết.

Vì vậy, nhánh "nhánh" của nhánh của tôi thực sự được đặt tên là "Korporal.master", nhưng Giao diện người dùng GitHub không bao giờ tiết lộ điều này, chỉ hiển thị cho tôi "chủ".

Đây là khá nhiều những gì tôi nghĩ vẫn diễn ra dưới mui xe dựa trên những thứ tôi đã làm gần đây và khi bạn suy ngẫm về nó, đó là thiết kế rất tốt.

Vì lý do này, tôi nghĩ rằng Microsoft sẽ rất dễ dàng triển khai các nhánh Git trong dịch vụ Nhóm Visual Studio của họ.


Hugh thân mến, một nửa phản hồi của bạn thực sự không chính xác - một ngã ba là một bản sao của toàn bộ kho lưu trữ từ tài khoản người dùng này sang tài khoản người dùng khác, cùng với tất cả các chi nhánh và lịch sử. Khi bạn cam kết với ngã ba, không có gì thay đổi trong kho lưu trữ ban đầu mà bạn đã rẽ nhánh. Nhưng bên cạnh một số hiểu lầm từ phía bạn về "ngã ba" là gì, giờ đây có một tin tốt: Các dịch vụ của Visual Studio Team bao gồm chức năng "Fork". ;)
Sorin Postelnicu

1
@SorinPostelnicu nguồn? Tôi có xu hướng tin Hugh ở đây do kinh nghiệm cá nhân của các dĩa hành xử theo cách không phù hợp với họ là một bản sao đơn giản của kho lưu trữ. Ví dụ, khi ngược dòng bị xóa, các dĩa sẽ bị xóa (như đã được đề cập trong một nhận xét về câu hỏi của OP) và đôi khi ngược dòng đã kết hợp mọi thứ vào nhánh của dĩa của tôi khi chấp nhận yêu cầu kéo, mà tôi không làm gì cả.
khoai tây

Quả thực điều này dường như là trường hợp. Rốt cuộc, GitHub sẽ cực kỳ ngu ngốc khi nghĩa đen là git clonemột kho lưu trữ hoàn toàn mới (thậm chí là "trần") mỗi khi ai đó nhấn nút "ngã ba" - đó sẽ là một sự lãng phí đáng kinh ngạc về lưu trữ và cũng có thể là một vectơ tấn công .
Greg A. Woods

7

Ngoài thực tế là nhân bản từ máy chủ sang máy của bạn và forking đang tạo một bản sao trên chính máy chủ, một sự khác biệt quan trọng là khi chúng tôi nhân bản, chúng tôi thực sự có được tất cả các chi nhánh, nhãn, v.v.

Nhưng khi chúng ta rẽ nhánh, chúng ta thực sự chỉ nhận được các tệp hiện tại trong nhánh chính, không có gì khác. Điều này có nghĩa là chúng tôi không có được các chi nhánh khác, v.v.

Do đó, nếu bạn phải hợp nhất một cái gì đó trở lại kho lưu trữ ban đầu, thì đó là một sự hợp nhất giữa các kho lưu trữ và chắc chắn sẽ cần các đặc quyền cao hơn.

Fork không phải là một lệnh trong Git; nó chỉ là một khái niệm mà GitHub thực hiện. Hãy nhớ rằng Git được thiết kế để hoạt động trong môi trường ngang hàng mà không cần phải đồng bộ hóa nội dung với bất kỳ bản sao chính nào. Máy chủ chỉ là một máy ngang hàng khác, nhưng chúng tôi xem nó như một bản sao chính.


7
Huh? Một ngã ba có được tất cả các nhánh, mặc dù bạn phải biết nơi để tìm (gợi ý git branch -a:).
tripleee

3

Nói một cách đơn giản nhất,

Khi bạn nói bạn đang giả mạo một kho lưu trữ, cơ bản bạn đang tạo ra một bản sao của kho lưu trữ ban đầu dưới GitHub ID của bạn trong tài khoản GitHub của bạn.

Khi bạn nói rằng bạn đang nhân bản một kho lưu trữ, bạn đang tạo một bản sao cục bộ của kho lưu trữ ban đầu trong hệ thống của bạn (PC / máy tính xách tay) mà không có một bản sao trong tài khoản GitHub của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.