Sự khác biệt giữa nhánh git, ngã ba, tìm nạp, hợp nhất, rebase và clone là gì?


502

Tôi muốn hiểu sự khác biệt giữa một nhánh, một ngã ba và một bản sao trong Git?

Tương tự như vậy, nó có nghĩa gì khi tôi làm git fetchtrái ngược với a git pull?

Ngoài ra, rebaseso với có nghĩa là mergegì?

Làm thế nào tôi có thể squash cá nhân cam kết với nhau?

Chúng được sử dụng như thế nào, tại sao chúng được sử dụng và chúng đại diện cho cái gì?

GitHub hình như thế nào?


19
bạn có thể thay đổi câu trả lời được chấp nhận thành câu trả lời của Michael Durrant không?
siride

11
Dĩ nhiên anh ta có thể , nhưng đây phải là sự lựa chọn của anh ta, và thật lòng mà nói, hầu hết những người đến đây (như tôi) đều muốn một cái gì đó súc tích hơn, chính xác như câu trả lời mà anh ta đã chọn, lúc này là của chính anh ta =)
user1271772

Câu trả lời:


366

Một bản sao chỉ đơn giản là một bản sao của một kho lưu trữ. Nhìn bề ngoài, kết quả của nó tương đương với svn checkout, nơi bạn tải mã nguồn từ một số kho lưu trữ khác. Sự khác biệt giữa các VCS tập trung như Subversion và DVCS như Git là trong Git, khi bạn sao chép, bạn thực sự sao chép toàn bộ kho lưu trữ nguồn, bao gồm tất cả lịch sử và các nhánh. Bây giờ bạn có một kho lưu trữ mới trên máy của mình và bất kỳ cam kết nào bạn thực hiện vào kho lưu trữ đó. Không ai sẽ thấy bất kỳ thay đổi nào cho đến khi bạn đẩy các cam kết đó sang kho lưu trữ khác (hoặc kho gốc) hoặc cho đến khi ai đó rút các cam kết từ kho lưu trữ của bạn, nếu nó có thể truy cập công khai.

Một nhánh là một cái gì đó trong một kho lưu trữ. Về mặt khái niệm, nó đại diện cho một chủ đề của sự phát triển. Bạn thường có một nhánh chính, nhưng bạn cũng có thể có một nhánh nơi bạn đang làm việc trên một số tính năng xyz và một nhánh khác để sửa lỗi abc. Khi bạn đã kiểm tra một chi nhánh, bất kỳ cam kết nào bạn thực hiện sẽ ở lại chi nhánh đó và không được chia sẻ với các chi nhánh khác cho đến khi bạn hợp nhất chúng với hoặc phản đối chúng lên chi nhánh. Tất nhiên, Git có vẻ hơi kỳ lạ khi nói đến các nhánh cho đến khi bạn nhìn vào mô hình cơ bản về cách các nhánh được thực hiện. Thay vì tự mình giải thích (tôi đã nói quá nhiều, methinks), tôi sẽ liên kết với lời giải thích "khoa học máy tính" về cách các mô hình và cam kết của Git, được lấy từ trang web của Git:

http://eagain.net/articles/git-for-computer-scientists/

Một ngã ba không thực sự là một khái niệm Git, nó là một ý tưởng chính trị / xã hội. Đó là, nếu một số người không hài lòng với cách thức thực hiện dự án, họ có thể lấy mã nguồn và tự làm việc với nó từ các nhà phát triển ban đầu. Đó sẽ được coi là một ngã ba. Git làm cho việc giả mạo trở nên dễ dàng vì mọi người đều đã có bản sao mã nguồn "chính" của riêng mình, do đó, nó đơn giản như cắt đứt quan hệ với các nhà phát triển dự án ban đầu và không yêu cầu xuất lịch sử từ kho lưu trữ chung như bạn có thể phải làm với SVN .

EDIT: vì tôi không biết định nghĩa hiện đại về "ngã ba" như được sử dụng bởi các trang web như GitHub, vui lòng xem các bình luận và câu trả lời của Michael Durrant bên dưới để biết thêm thông tin.


125
Một ngã ba không nhất thiết có nghĩa là nhà phát triển không hài lòng với repo chính. Thông thường, nó có nghĩa là một nhà phát triển khác đã đọc, nhưng không viết, truy cập vào repo đó. Nhà phát triển có thể phân nhánh repo, thực hiện thay đổi nhưng vì anh ta không thể viết thư cho repo chính nên anh ta phải gửi các thay đổi của mình dưới dạng bản vá. Vì vậy, forking cũng là một phương tiện khuyến khích sự hợp tác mà không cấp quyền truy cập ghi.
brycemcd

5
Tôi cho rằng đó là sự thật. Tôi chỉ từng thấy "ngã ba" được sử dụng trong bối cảnh tạo ra một phiên bản mới, có khả năng cạnh tranh của một dự án.
siride

32
Bạn có thể nói rằng một ngã ba là một nhánh dự kiến ​​sẽ không được sáp nhập ngược dòng
masonk

6
Git hub sử dụng "fork" như ý nghĩa của fork. Đó là một kho lưu trữ mới được lưu trữ trên github, tách biệt với bản gốc. Tuy nhiên, github cũng làm cho nó rất đơn giản để thực hiện các yêu cầu kéo. Yêu cầu kéo về cơ bản yêu cầu chủ sở hữu của kho lưu trữ ban đầu "kéo" các thay đổi từ ngã ba của repo trở lại nguồn gốc. Bằng cách đó, mọi người đều có thể sử dụng kiểm soát nguồn và có lịch sử của tất cả các thay đổi, bao gồm cả thay đổi của họ, nhưng không phải ai cũng cần quyền truy cập ghi vào repo gốc.
mklauber

4
Tôi đã cập nhật câu trả lời của mình để bảo mọi người nhìn vào câu trả lời của Michael Durrant để biết thêm về mô hình của github.
siride 17/03 '

531

Git

Câu trả lời này bao gồm GitHub vì nhiều người cũng đã hỏi về điều đó.

Kho lưu trữ cục bộ

Git (cục bộ) có một thư mục ( .git) mà bạn cam kết các tệp của mình và đây là 'kho lưu trữ cục bộ' của bạn. Điều này khác với các hệ thống như SVN nơi bạn thêm và cam kết vào kho lưu trữ từ xa ngay lập tức.

Git lưu trữ từng phiên bản của một tệp thay đổi bằng cách lưu toàn bộ tệp. Nó cũng khác với SVN về mặt này vì bạn có thể đi đến bất kỳ phiên bản riêng lẻ nào mà không cần 'tái tạo' nó thông qua các thay đổi delta.

Git hoàn toàn không 'khóa' các tệp và do đó tránh được chức năng 'khóa độc quyền' để chỉnh sửa (các hệ thống cũ hơn như pvcs xuất hiện), vì vậy tất cả các tệp luôn có thể được chỉnh sửa, ngay cả khi ngoại tuyến. Nó thực sự làm một công việc tuyệt vời là hợp nhất các thay đổi tệp (trong cùng một tệp!) Trong quá trình kéo hoặc tìm nạp / đẩy đến một kho lưu trữ từ xa như GitHub. Lần duy nhất bạn cần thực hiện các thay đổi thủ công (thực sự chỉnh sửa một tệp) là nếu hai thay đổi liên quan đến cùng một dòng mã.


Chi nhánh

Các nhánh cho phép bạn giữ mã chính (nhánh 'chính'), tạo một bản sao (một nhánh mới) và sau đó làm việc trong nhánh mới đó. Nếu công việc mất một thời gian hoặc chủ nhân nhận được rất nhiều cập nhật kể từ khi chi nhánh được thực hiện thì việc hợp nhất hoặc nổi loạn (thường được ưu tiên cho lịch sử tốt hơn và dễ dàng giải quyết xung đột hơn) đối với chi nhánh chính nên được thực hiện. Khi bạn hoàn thành, bạn hợp nhất các thay đổi được thực hiện trong nhánh trở lại vào kho lưu trữ chính. Nhiều tổ chức sử dụng các nhánh cho từng phần công việc cho dù đó là một tính năng, lỗi hoặc mục vặt. Các tổ chức khác chỉ sử dụng các chi nhánh cho các thay đổi lớn như nâng cấp phiên bản.

Ngã ba: Với một nhánh bạn kiểm soát và quản lý chi nhánh, trong khi với một ngã ba, người khác điều khiển chấp nhận mã trở lại.

Nói rộng ra, có hai cách tiếp cận chính để làm chi nhánh. Đầu tiên là giữ hầu hết các thay đổi trên nhánh chính, chỉ sử dụng các nhánh cho những thứ lớn hơn và chạy dài hơn như thay đổi phiên bản mà bạn muốn có hai nhánh có sẵn cho các nhu cầu khác nhau. Thứ hai là về cơ bản bạn tạo một nhánh cho mọi yêu cầu tính năng, sửa lỗi hoặc xử lý và sau đó tự quyết định khi nào thực sự hợp nhất các nhánh đó vào nhánh chính. Mặc dù điều này nghe có vẻ tẻ nhạt, nhưng đây là một cách tiếp cận phổ biến và là cách tiếp cận mà tôi hiện đang sử dụng và khuyên dùng vì điều này giữ cho nhánh chính sạch hơn và đó là chủ mà chúng tôi quảng bá để sản xuất, vì vậy chúng tôi chỉ muốn hoàn thành, đã kiểm tra mã, thông qua việc nổi loạn và sáp nhập các chi nhánh.

Cách tiêu chuẩn để đưa một nhánh 'vào' thành chủ là làm a merge. Các chi nhánh cũng có thể được "khởi động lại" để 'dọn dẹp' lịch sử. Nó không ảnh hưởng đến trạng thái hiện tại và được thực hiện để đưa ra lịch sử 'sạch hơn'.

Về cơ bản, ý tưởng là bạn phân nhánh từ một điểm nhất định (thường là từ chủ). Vì bạn đã phân nhánh, bản thân 'chủ nhân' đã di chuyển về phía trước từ điểm phân nhánh đó. Sẽ là 'sạch hơn' (dễ giải quyết vấn đề hơn và lịch sử sẽ dễ hiểu hơn) nếu tất cả các thay đổi bạn đã thực hiện trong một nhánh được chơi với trạng thái hiện tại của chủ nhân với tất cả các thay đổi mới nhất của nó. Vì vậy, quá trình là: lưu các thay đổi; lấy chủ nhân 'mới', và sau đó áp dụng lại (đây là phần rebase) các thay đổi một lần nữa chống lại điều đó. Xin lưu ý rằng rebase, giống như hợp nhất, có thể dẫn đến xung đột mà bạn phải giải quyết thủ công (nghĩa là chỉnh sửa và khắc phục).

Một hướng dẫn cần lưu ý:
Chỉ rebase nếu chi nhánh là cục bộ và bạn chưa đẩy nó đến điều khiển từ xa!
Điều này chủ yếu là vì việc nổi loạn có thể làm thay đổi lịch sử mà những người khác nhìn thấy có thể bao gồm các cam kết của chính họ.

Theo dõi chi nhánh

Đây là những nhánh được đặt tên origin/branch_name(trái ngược với chỉ branch_name). Khi bạn đang đẩy và kéo mã đến / từ các kho lưu trữ từ xa thì đây thực sự là cơ chế mà qua đó xảy ra. Ví dụ, khi bạn git pushgọi một nhánh building_groups, nhánh của bạn sẽ đi trước origin/building_groupsvà sau đó đến kho lưu trữ từ xa. Tương tự, nếu bạn làm một git fetch building_groups, tập tin được lấy sẽ được đặt trong origin/building_groupsnhánh của bạn . Sau đó, bạn có thể chọn hợp nhất chi nhánh này vào bản sao cục bộ của mình. Thực tiễn của chúng tôi là luôn luôn thực hiện một git fetchvà hợp nhất thủ công chứ không chỉ là một git pull(thực hiện cả hai điều trên trong một bước).

Lấy các nhánh mới.

Bắt các nhánh mới: Tại điểm ban đầu của một bản sao, bạn sẽ có tất cả các nhánh. Tuy nhiên, nếu các nhà phát triển khác thêm các nhánh và đẩy chúng vào điều khiển từ xa thì cần phải có một cách để 'biết' về các nhánh đó và tên của chúng để có thể kéo chúng xuống cục bộ. Điều này được thực hiện thông qua git fetchviệc sẽ đưa tất cả các nhánh mới và thay đổi vào kho lưu trữ cục bộ bằng cách sử dụng các nhánh theo dõi (ví dụ origin/:). Khi fetched, người ta có thể git branch --remoteliệt kê các nhánh theo dõi và git checkout [branch]thực sự chuyển sang bất kỳ nhánh nào.

Sáp nhập

Sáp nhập là quá trình kết hợp các thay đổi mã từ các nhánh khác nhau hoặc từ các phiên bản khác nhau của cùng một nhánh (ví dụ: khi một nhánh cục bộ và điều khiển từ xa không đồng bộ). Nếu một người đã phát triển công việc trong một chi nhánh và công việc đã hoàn thành, sẵn sàng và được thử nghiệm, thì nó có thể được sáp nhập vào masterchi nhánh. Điều này được thực hiện bằng cách git checkout masterchuyển sang masterchi nhánh, sau đó git merge your_branch. Việc hợp nhất sẽ mang tất cả các tệp khác nhau và thậm chí các thay đổi khác nhau vào cùng một tệp . Điều này có nghĩa là nó thực sự sẽ thay đổi mã bên trong các tệp để hợp nhất tất cả các thay đổi.

Khi thực hiện checkoutcủa masternó cũng khuyến khích để làm một git pull origin masterđể có được phiên bản mới nhất của các bậc thầy từ xa sáp nhập vào tổng thể địa phương của bạn. Nếu chủ từ xa thay đổi, tức là moved forward, bạn sẽ thấy thông tin phản ánh điều đó trong thời gian đó git pull. Nếu đó là trường hợp (chủ đã thay đổi), bạn nên làm chủ git checkout your_branchvà sau đó rebasenên làm chủ để các thay đổi của bạn thực sự được 'phát lại' trên đầu trang của chủ 'mới'. Sau đó, bạn sẽ tiếp tục với việc cập nhật tổng thể như được hiển thị trong đoạn tiếp theo.

Nếu không có xung đột, thì master sẽ có các thay đổi mới được thêm vào. Nếu có xung đột, điều này có nghĩa là các tệp tương tự có các thay đổi xung quanh các dòng mã tương tự mà nó không thể tự động hợp nhất. Trong trường hợp git merge new_branchnày sẽ báo cáo rằng có (các) xung đột để giải quyết. Bạn 'giải quyết' chúng bằng cách chỉnh sửa các tệp (sẽ có cả hai thay đổi trong đó), chọn các thay đổi bạn muốn, xóa theo nghĩa đen của các thay đổi bạn không muốn và sau đó lưu tệp. Các thay đổi được đánh dấu bằng các dấu phân cách như ========<<<<<<<<.

Khi bạn đã giải quyết bất kỳ xung đột nào, bạn sẽ một lần nữa git addgit commitnhững thay đổi đó để tiếp tục hợp nhất (bạn sẽ nhận được phản hồi từ git trong quá trình này để hướng dẫn bạn).

Khi quá trình không hoạt động tốt, bạn sẽ thấy git merge --abortrất thuận tiện để thiết lập lại mọi thứ.

Tương tác nổi loạn và đè bẹp / sắp xếp lại / xóa cam kết

Nếu bạn đã thực hiện công việc theo nhiều bước nhỏ, ví dụ: bạn cam kết mã là 'công việc đang tiến hành' mỗi ngày, bạn có thể muốn 'ép' nhiều cam kết nhỏ đó thành một vài cam kết lớn hơn. Điều này có thể đặc biệt hữu ích khi bạn muốn thực hiện đánh giá mã với các đồng nghiệp. Bạn không muốn phát lại tất cả các 'bước' bạn đã thực hiện (thông qua các cam kết), bạn muốn nói rằng đây là hiệu ứng kết thúc (khác biệt) của tất cả các thay đổi của tôi cho công việc này trong một lần cam kết.

Yếu tố quan trọng để đánh giá khi xem xét liệu có nên làm điều này hay không là nhiều lần xác nhận đối với cùng một tệp hoặc nhiều tệp hơn một lần (tốt hơn để xóa các cam kết trong trường hợp đó). Điều này được thực hiện với công cụ rebasing tương tác. Công cụ này cho phép bạn xóa các xác nhận, xóa các xác nhận, gửi lại tin nhắn, v.v. Ví dụ: git rebase -i HEAD~10( lưu ý: đó là a ~, không phải a- ) đưa ra các điều sau:

nổi loạn tương tác trong Git

Hãy cẩn thận và sử dụng công cụ này 'cẩn thận'. Thực hiện một squash / xóa / sắp xếp lại tại một thời điểm, thoát và lưu cam kết đó, sau đó nhập lại công cụ. Nếu các xác nhận không liền kề, bạn có thể sắp xếp lại chúng (và sau đó ép nếu cần). Bạn thực sự có thể xóa các cam kết ở đây, nhưng bạn thực sự cần chắc chắn về những gì bạn đang làm khi bạn làm điều đó!

Nĩa

Có hai cách tiếp cận chính để hợp tác trong kho Git. Đầu tiên, chi tiết ở trên, trực tiếp thông qua các nhánh mà mọi người kéo và đẩy từ / đến. Những cộng tác viên này có các khóa SSH được đăng ký với kho lưu trữ từ xa. Điều này sẽ cho phép họ đẩy trực tiếp đến kho lưu trữ đó. Nhược điểm là bạn phải duy trì danh sách người dùng. Cách tiếp cận khác - forking - cho phép bất kỳ ai 'fork' kho lưu trữ, về cơ bản tạo một bản sao cục bộ trong tài khoản kho lưu trữ Git của riêng họ. Sau đó, họ có thể thực hiện các thay đổi và khi hoàn tất gửi 'yêu cầu kéo' (thực sự đó là một 'cú hích' từ họ và yêu cầu 'kéo' cho người duy trì kho lưu trữ thực tế) để mã được chấp nhận.

Phương pháp thứ hai này, sử dụng dĩa, không yêu cầu ai đó duy trì danh sách người dùng cho kho lưu trữ.


GitHub

GitHub (kho lưu trữ từ xa) là một nguồn từ xa mà bạn thường đẩy và kéo những thay đổi đã cam kết đến nếu bạn có (hoặc được thêm vào) một kho lưu trữ như vậy, vì vậy cục bộ và từ xa thực sự khá khác biệt. Một cách khác để nghĩ về một kho lưu trữ từ xa là nó là một .gitcấu trúc thư mục sống trên một máy chủ từ xa.

Khi bạn 'ngã ba' - trong GitHub GUI trình duyệt web mà bạn có thể nhấp vào nút này Hình ảnh của nút ngã ba- bạn tạo một bản sao ( 'bản sao') của các mã trong của bạn tài khoản GitHub. Lần đầu tiên bạn có thể tinh tế một chút, vì vậy hãy đảm bảo rằng bạn nhìn vào kho lưu trữ mà một cơ sở mã được liệt kê bên dưới - chủ sở hữu ban đầu hoặc 'rẽ nhánh từ' và bạn, ví dụ như thế này:

Hình ảnh tên của kho lưu trữ rẽ nhánh

Khi bạn có bản sao cục bộ, bạn có thể thay đổi theo ý muốn (bằng cách kéo và đẩy chúng vào máy cục bộ). Khi bạn đã hoàn tất, sau đó bạn gửi một 'yêu cầu kéo' cho chủ sở hữu / quản trị kho lưu trữ ban đầu (nghe có vẻ lạ mắt nhưng thực ra bạn chỉ cần nhấp vào đây Hình ảnh của nút yêu cầu kéo:) và họ 'kéo' nó vào.

Phổ biến hơn cho một nhóm làm việc về mã cùng nhau là 'sao chép' kho lưu trữ (nhấp vào biểu tượng 'sao chép' trên màn hình chính của kho lưu trữ). Sau đó, gõ địa phương git clonevà dán. Điều này sẽ thiết lập cho bạn cục bộ và bạn cũng có thể đẩy và kéo đến vị trí GitHub (được chia sẻ).

Bản sao

Như đã chỉ ra trong phần trên GitHub, bản sao là bản sao của kho lưu trữ. Khi bạn có một kho lưu trữ từ xa, bạn đưa ra git clonelệnh chống lại URL của nó và sau đó bạn kết thúc bằng một bản sao cục bộ hoặc bản sao của kho lưu trữ. Bản sao này có tất cả mọi thứ , các tệp, nhánh chính, các nhánh khác, tất cả các cam kết hiện có, toàn bộ shebang. Đây là bản sao mà bạn thực hiện thêm và cam kết và sau đó chính kho lưu trữ từ xa là thứ bạn đẩy những cam kết đó. Chính khái niệm cục bộ / từ xa này đã biến Git (và các hệ thống tương tự như Mercurial) thành DVCS ( Hệ thống kiểm soát phiên bản phân tán ) trái ngược với các CVS ​​truyền thống (Hệ thống phiên bản mã) như SVN, PVCS, CVS, v.v. bạn cam kết trực tiếp đến kho lưu trữ từ xa.

Hình dung

Hình dung của các khái niệm cốt lõi có thể được nhìn thấy tại
http://marklodato.github.com/visual-git-guide/index-en.html
http://ndpsoftware.com/git-chcoateet.html#loc=index

Nếu bạn muốn hiển thị trực quan về cách các thay đổi đang hoạt động, bạn không thể đánh bại công cụ trực quan gitg( gitxdành cho macOS) bằng GUI mà tôi gọi là 'bản đồ tàu điện ngầm' (đặc biệt là Tàu điện ngầm Luân Đôn), tuyệt vời để hiển thị ai đã làm gì, làm thế nào mọi thứ thay đổi, chuyển hướng và sáp nhập, vv

Bạn cũng có thể sử dụng nó để thêm, cam kết và quản lý các thay đổi của mình!

Hình ảnh của giao diện gitg / gitx

Mặc dù gitg / gitx khá tối thiểu, số lượng công cụ GUI vẫn tiếp tục mở rộng. Nhiều người dùng Mac sử dụng ngã ba gitx của Brotherbard và cho Linux, một tùy chọn tuyệt vời là git thông minh với giao diện trực quan nhưng mạnh mẽ:

Hình ảnh của GUI thông minh git

Lưu ý rằng ngay cả với một công cụ GUI, bạn có thể sẽ thực hiện rất nhiều lệnh tại dòng lệnh.

Đối với điều này, tôi có các bí danh sau trong ~/.bash_aliasestệp của mình (được gọi từ ~/.bashrctệp của tôi cho mỗi phiên cuối):

# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git push '

VÀ tôi có "bí danh git" trong ~/.gitconfigtệp của mình - tại sao lại có những thứ này?
Vì vậy, việc hoàn thành chi nhánh (với khóa TAB) hoạt động!

Vì vậy, đây là:

[alias]
  co = checkout
  cob = checkout -b

Sử dụng ví dụ: git co [branch]<- hoàn thành tab cho các chi nhánh sẽ hoạt động.

Công cụ học tập GUI

Bạn có thể thấy https://learngitbranching.js.org/ hữu ích trong việc tìm hiểu một số khái niệm cơ bản. Ảnh chụp màn hình: Video: https://youtu.be/23JqqcLPss0nhập mô tả hình ảnh ở đây

Cuối cùng, 7 phao cứu sinh quan trọng!

  1. Bạn thực hiện thay đổi, thêm và cam kết chúng (nhưng không đẩy) và sau đó oh! bạn nhận ra bạn đang làm chủ

    git reset [filename(s)]
    git checkout -b [name_for_a_new_branch]
    git add [file(s)]
    git commit -m "A useful message"
    
    Voila!  You've moved that 'master' commit to its own branch !
  2. Bạn làm hỏng một số tệp trong khi làm việc trong một chi nhánh địa phương và chỉ muốn quay lại những gì bạn đã có lần cuối cùng bạn đã làm git pull:

    git reset --hard origin/master  # You will need to be comfortable doing this!
  3. Bạn bắt đầu thực hiện các thay đổi cục bộ, bạn chỉnh sửa một nửa tá tệp và sau đó, ôi thôi, bạn vẫn ở trong nhánh chính (hoặc khác):

    git checkout -b new_branch_name  # just create a new branch
    git add .                      # add the changes files
    git commit -m"your message"    # and commit them
  4. Bạn làm rối một tệp cụ thể trong nhánh hiện tại của mình và về cơ bản muốn 'đặt lại' tệp đó (mất các thay đổi) về lần cuối cùng bạn lấy nó từ kho lưu trữ từ xa:

    git checkout your/directories/filename

    Điều này thực sự đặt lại tệp (giống như nhiều lệnh Git, nó không được đặt tên tốt cho những gì nó đang làm ở đây).

  5. Bạn thực hiện một số thay đổi cục bộ, bạn muốn đảm bảo rằng bạn không mất chúng trong khi bạn thực hiện git resethoặc rebase: Tôi thường tạo một bản sao thủ công của toàn bộ dự án ( cp -r ../my_project ~/) khi tôi không chắc chắn liệu mình có thể gây rối trong Git hay mất quan trọng thay đổi.

  6. Bạn đang nổi loạn nhưng mọi thứ bị rối tung:

    git rebase --abort # To abandon interactive rebase and merge issues
  7. Thêm chi nhánh Git của bạn vào PS1lời nhắc của bạn (xem https://unix.stackexchange.com/a/127800/10043 ), ví dụ:

    Hình ảnh nhắc nhở

    Chi nhánh là selenium_rspec_conversion.


1
20/2/12 Đã thêm thông tin về hợp nhất so với rebase
Michael Durrant

1
16/12/12 Đã thêm phần trên bản sao để làm cho nó hoàn thiện hơn.
Michael Durrant

4
Rất nhiều văn bản !! Tôi sẽ tuân theo Subversion đơn giản của tôi :-)
Jonny

6
Huh? Một người dùng lật đổ cũng có thể viết một cuốn sách về việc sử dụng lật đổ. Theo ý kiến ​​của tôi, lật đổ là một công nghệ cũ hơn với ít chức năng hơn. Cá nhân tôi thấy git rất dễ sử dụng. ymmv
Michael Durrant

3
Ái chà, Micheal! SO là tất cả về chia sẻ kiến ​​thức. Cảm ơn vì công việc tuyệt vời, chắc chắn +1
Michiel

143

Dưới đây là hình ảnh của Oliver Steele về cách tất cả khớp với nhau:

nhập mô tả hình ảnh ở đây


6
Hình ảnh này có thể được cập nhật để thêm "git clone" mà tôi chắc chắn rằng hầu hết mọi người đều quen thuộc trong mọi trường hợp.
Contango

3
@Gravitas, tôi thực sự thích đồ họa này, nhưng nó không cho tôi biết khi nào các tập tin bị ghi đè và khi nào chúng được hợp nhất. Bạn có thể cho tôi biết đó là cái nào cho các lệnh này không? Có lẽ các lệnh ghi đè trên đầu và các lệnh hợp nhất bên dưới các ổ đĩa? Cảm ơn.
zylstra

Theo những gì tôi hiểu, git pull sẽ kéo xuống từ xa bất cứ điều gì bạn yêu cầu (vì vậy, bất cứ thân cây nào bạn yêu cầu) và ngay lập tức hợp nhất nó vào nhánh bạn đang ở khi bạn thực hiện yêu cầu. Pull là một yêu cầu cấp cao chạy 'tìm nạp' sau đó là 'hợp nhất' theo mặc định hoặc rebase với 'siêu cơ sở'. Bạn có thể làm mà không cần nó, nó chỉ là một tiện lợi.
Contango

Chính xác thì git clone sẽ đi đâu trong sơ đồ này? Còn git hợp nhất? Tôi rất mới với git nhưng tôi thích hình ảnh này.
Mishelle 7/07/2015

2
Tôi sẽ xem liệu tôi có thể làm một phiên bản cập nhật của sơ đồ không.
Contango 7/07/2015

8

Ngã ba Vs. Clone - hai từ có nghĩa là sao chép

Xin vui lòng xem sơ đồ này . (Nguyên văn từ http://www.dataschool.io/content/images/2014/Mar/github1.png ).

.-------------------------.     1. Fork     .-------------------------.
| Your GitHub repo        | <-------------- | Joe's GitHub repo       |
| github.com/you/coolgame |                 | github.com/joe/coolgame |
| ----------------------- | 7. Pull Request | ----------------------- |
| master -> c224ff7       | --------------> | master -> c224ff7 (c)   |
| anidea -> 884faa1 (a)   |                 | anidea -> 884faa1 (b)   |
'-------------------------'                 '-------------------------'
    |                 ^
    | 2. Clone        |
    |                 |
    |                 |
    |                 |
    |                 |
    |                 | 6. Push (anidea => origin/anidea)
    v                 |
.-------------------------.
| Your computer           |  3. Create branch 'anidea'
| $HOME/coolgame          |
| ----------------------- |  4. Update a file
| master -> c224ff7       |
| anidea -> 884faa1       |  5. Commit (to 'anidea')
'-------------------------'

(a) - after you have pushed it
(b) - after Joe has accepted it
(c) - eventually Joe might merge 'anidea' (make 'master -> 884faa1')

Cái nĩa

  • Một bản sao để repo từ xa (đám mây) liên kết nó với Joe's
  • Sau đó, một bản sao bạn có thể sao chép vào repo cục bộ của mình và F *% $ - lên
  • Khi bạn đã hoàn tất, bạn có thể đẩy trở lại từ xa của bạn
  • Sau đó, bạn có thể hỏi Joe nếu anh ta muốn sử dụng nó trong dự án của mình bằng cách nhấp vào yêu cầu kéo

Bản sao

  • một bản sao để repo địa phương của bạn (ổ cứng)

Lưu ý rằng lợi thế DVCS thực sự là bạn không cần bất kỳ quyền truy cập cụ thể nào vào repo của Joe để làm điều này. Nếu Joe muốn bạn đóng góp thường xuyên hơn, anh ta có thể cấp cho bạn quyền truy cập: họ có thể đẩy anideangay tới repo của anh ta và tiết kiệm cho bạn các công việc để giữ cho ngã ba của bạn được cập nhật. OTOH nếu bạn sẽ không đạt được thỏa thuận với Joe, bạn có thể tiếp tục phát triển và sử dụng ngã ba của mình (và xem liệu bạn có thể khiến anh ấy thay đổi ý định sau này không).
Alois Mahdal

6

Chỉ cần thêm vào những người khác, một lưu ý cụ thể để rèn.

Thật tốt khi nhận ra rằng về mặt kỹ thuật, nhân bản repo và từ bỏ repo là điều tương tự. Làm:

git clone $some_other_repo

và bạn có thể chạm vào lưng mình --- bạn vừa rẽ một số repo khác.

Git, với tư cách là một VCS, trên thực tế tất cả là về nhân bản giả mạo. Ngoài việc "chỉ duyệt" bằng giao diện người dùng từ xa như cgit, có rất ít việc phải làm với git repo không liên quan đến việc giả mạo nhân bản repo tại một số điểm.

Tuy nhiên,

  • Khi ai đó nói rằng tôi đã rẽ nhánh repo X , họ có nghĩa là họ đã tạo ra một bản sao của repo ở một nơi khác với ý định phơi bày nó cho người khác, ví dụ như để hiển thị một số thử nghiệm hoặc áp dụng cơ chế kiểm soát truy cập khác (ví dụ: cho phép mọi người không có Truy cập Github nhưng có tài khoản nội bộ của công ty để cộng tác).

    Sự thật rằng: repo có lẽ được tạo ra bằng lệnh khác hơn git clonelà nó có thể được lưu trữ ở đâu đó trên máy chủ trái ngược với máy tính xách tay của ai đó và hầu hết có thể có định dạng hơi khác (nghĩa là "repo trần", tức là không có cây hoạt động) tất cả chỉ là chi tiết kỹ thuật.

    Thực tế là nó có thể sẽ chứa tập hợp các nhánh, thẻ hoặc cam kết khác nhau có lẽ là lý do tại sao họ đã làm điều đó ngay từ đầu.

    (Những gì Github làm khi bạn nhấp vào "ngã ba", chỉ là nhân bản với đường được thêm vào: nó nhân bản repo cho bạn, đặt nó dưới tài khoản của bạn, ghi lại "ngã ba từ" ở đâu đó, thêm từ xa có tên "ngược dòng" và quan trọng nhất là chơi hoạt hình đẹp.)

  • Khi ai đó nói rằng tôi đã nhân bản repo X , họ có nghĩa là họ đã tạo một bản sao của repo cục bộ trên máy tính xách tay hoặc máy tính để bàn của họ với ý định nghiên cứu nó, chơi với nó, đóng góp cho nó hoặc xây dựng một cái gì đó từ mã nguồn trong đó.

Cái hay của Git là nó làm cho tất cả hoàn toàn khớp với nhau: tất cả các repos này đều có chung một phần của chuỗi cam kết khối để có thể an toàn (xem ghi chú bên dưới) hợp nhất các thay đổi qua lại giữa tất cả các repos này khi bạn thấy phù hợp.


Lưu ý: "an toàn" miễn là bạn không viết lại phần chung của chuỗi và miễn là các thay đổi không xung đột.

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.