Tại sao tôi muốn giai đoạn trước khi cam kết trong Git?


102

Tôi mới sử dụng tính năng kiểm soát phiên bản và tôi hiểu rằng "cam kết" về cơ bản là tạo bản sao lưu trong khi cập nhật phiên bản 'hiện tại' mới của những gì bạn đang làm.

Điều tôi không hiểu là dàn dựng để làm gì, từ góc độ thực tế. Việc dàn dựng một thứ gì đó chỉ tồn tại dưới danh nghĩa hay nó phục vụ một mục đích? Khi bạn cam kết, nó sẽ cam kết mọi thứ, phải không?

Chỉnh sửa: Tôi nghĩ rằng tôi có thể đang nhầm lẫn giữa thuật ngữ. Tệp 'theo giai đoạn' có giống với tệp 'được theo dõi' không?


6
Không. Tệp được theo dõi là tệp đã được biết đến với kho lưu trữ (thường là từ một cam kết trước). Tệp theo giai đoạn là tệp đã được thêm vào chỉ mục, sau này sẽ được sử dụng để cam kết.
Mark Peters

Câu trả lời:


82

Khi bạn cam kết, nó sẽ chỉ cam kết các thay đổi trong chỉ mục (các tệp "theo giai đoạn"). Có rất nhiều cách sử dụng cho việc này, nhưng rõ ràng nhất là chia nhỏ các thay đổi trong công việc của bạn thành các phần nhỏ hơn, khép kín. Có lẽ bạn đã sửa một lỗi trong khi triển khai một tính năng. Bạn có thể git addchỉ tệp đó (hoặc git add -pchỉ thêm một phần của tệp!) Và sau đó cam kết sửa lỗi đó trước khi cam kết mọi thứ khác. Nếu bạn đang sử dụng git commit -athì bạn chỉ đang ép buộc addmọi thứ ngay trước khi cam kết. Không sử dụng -anếu bạn muốn tận dụng các tệp dàn.

Bạn cũng có thể coi các tệp theo giai đoạn như một bản sao làm việc trung gian với --cachednhiều lệnh. Ví dụ: git diff --cachedsẽ cho bạn thấy các giai đoạn khác nhau HEADnhư thế nào để bạn có thể thấy những gì bạn sắp cam kết mà không bị trộn lẫn trong các thay đổi hoạt động khác của bạn.


25
Việc sử dụng thực sự phổ biến khác là khi một số thay đổi của bạn không bao giờ được cam kết; ví dụ, bạn có thể phân loại nội dung tốt, cam kết, sau đó loại bỏ nội dung xấu bằng git reset --hard.
Cascabel

3
@BenJackson trong ví dụ của bạn, sự khác biệt giữa giai đoạn + cam kết và cam kết chọn lọc là gì? Tôi không thấy bất kỳ sự khác biệt nào.
Eugenio

9
Cá nhân tôi đã không thể nhận được câu trả lời thỏa mãn cho câu hỏi, "Mục đích của việc dàn dựng là gì?" câu hỏi. Thành thật mà nói, nó chỉ là không cần thiết. Tôi đã sử dụng một chi nhánh cục bộ, vì vậy không có nguy cơ phá vỡ bản dựng. Tôi sẽ không xuất bản và thực hiện yêu cầu kéo cho đến khi tôi hoàn toàn hài lòng với các thay đổi của mình. Tôi đã có thể phân chia các cam kết của mình một cách hợp lý. Chỉ không cần một bước trung gian. Như vậy, tôi không bao giờ sử dụng nó.
mrplainswalker

3
Tôi không nghĩ rằng bạn thực sự trả lời câu hỏi. "nhưng rõ ràng nhất là chia nhỏ những thay đổi trong công việc của bạn thành những phần nhỏ hơn, khép kín." Tại sao ai đó lại muốn chia nhỏ những thay đổi của họ thành những thay đổi nhỏ hơn? Nếu bạn định thêm và thực hiện một bản sửa lỗi duy nhất trước khi sửa mã mà bạn định thay đổi ban đầu, tại sao bạn không thực hiện việc sửa lỗi đó thay vì thêm nó và sau đó cam kết?
kiwicomb123

1
@ kiwicomb123 Thường là vì bạn đã tìm thấy lỗi đó khi đang làm việc khác và bạn muốn sửa lỗi đó trong bản cam kết của riêng nó với thông báo nhật ký của chính nó và sự linh hoạt khi hợp nhất / cherry-pick / rebase để sửa ở một nơi khác.
Ben Jackson

26
  • Khu vực dàn cung cấp quyền kiểm soát để làm cho cam kết nhỏ hơn. Chỉ cần thực hiện một thay đổi hợp lý trong mã, thêm các tệp đã thay đổi vào khu vực tổ chức và cuối cùng nếu các thay đổi không tốt thì hãy chuyển sang cam kết trước đó hoặc cam kết thay đổi. những thay đổi. Với khu vực dàn dựng, việc tập trung trong các tác vụ nhỏ trở nên dễ dàng hơn.
  • Nó cũng cung cấp cho bạn lời đề nghị nghỉ ngơi và quên đi những công việc bạn đã làm trước khi nghỉ. Giả sử bạn cần thay đổi ba tệp để thực hiện một thay đổi hợp lý và bạn đã thay đổi tệp đầu tiên và cần một thời gian nghỉ dài cho đến khi bạn bắt đầu thực hiện các thay đổi khác. Tại thời điểm này, bạn không thể cam kết và bạn muốn theo dõi những tệp nào bạn đã hoàn thành để sau khi quay lại, bạn không cần phải cố gắng nhớ lại bao nhiêu công việc đã được thực hiện. Vì vậy, thêm tệp vào vùng dàn và nó sẽ lưu công việc của bạn. Khi bạn quay lại, chỉ cần thực hiện git diff --stagedvà kiểm tra xem bạn đã thay đổi tệp nào, ở đâu và bắt đầu thực hiện các thay đổi khác.

13

Một mục đích thực tế của việc dàn dựng là phân tách hợp lý các cam kết tệp.

Vì phân đoạn cho phép bạn tiếp tục chỉnh sửa tệp / thư mục làm việc và thực hiện cam kết trong các phần khi bạn nghĩ rằng mọi thứ đã sẵn sàng, bạn có thể sử dụng các giai đoạn riêng biệt cho các chỉnh sửa không liên quan về mặt logic.

Giả sử bạn có 4 file fileA.html, fileB.html, fileC.htmlfileD.html. Bạn thực hiện thay đổi đối với tất cả 4 tệp và sẵn sàng cam kết nhưng các thay đổi trong fileA.htmlfileB.htmlcó liên quan về mặt logic (ví dụ: cùng một triển khai tính năng mới trong cả hai tệp) trong khi các thay đổi trong fileC.htmlfileD.htmltách biệt và không liên quan về mặt logic với tệp trước đó. Bạn có thể đầu tiên tập tin stage fileA.htmlfileB.htmlvà cam kết những.

git add fileA.html
git add fileB.html
git commit -m "Implemented new feature XYZ"

Sau đó, trong bước tiếp theo, bạn thực hiện và cam kết các thay đổi đối với hai tệp còn lại.

git add fileC.html
git add fileD.html
git commit -m "Implemented another feature EFG"

6
Trong ví dụ này, tôi không chắc liệu việc dàn dựng có thực sự cần thiết hay không. Sau khi chỉnh sửa cả 4 tệp, nếu tôi chỉ muốn commit fileA.html và fileB.html, tôi vẫn có thể commit mà không cần dàn dựng. Lệnh: git commit -m "Implemented new feature XYZ" fileA.html fileB.html sẽ hoạt động tốt mà không cần lệnh git add. Tôi đến từ lật đổ thế giới mà dàn không phải là một khái niệm, vì vậy, tôi không thuyết phục về tính hữu dàn git
Pavan

5

Sẽ dễ hiểu hơn việc sử dụng các lệnh git addcommitnếu bạn tưởng tượng một tệp nhật ký đang được duy trì trong kho lưu trữ của bạn trên Github. Tệp nhật ký của một dự án điển hình đối với tôi có thể trông giống như sau:

---------------- Day 1 --------------------
Message: Complete Task A
Index of files changed: File1, File2

Message: Complete Task B
Index of files changed: File2, File3
-------------------------------------------

---------------- Day 2 --------------------
Message: Correct typos
Index of files changed: File3, File1
-------------------------------------------
...
...
...and so on

Tôi thường bắt đầu một ngày của mình với một git pullyêu cầu và kết thúc nó bằng một git pushyêu cầu. Vì vậy, mọi thứ bên trong bản ghi của một ngày tương ứng với những gì xảy ra giữa chúng. Trong mỗi ngày, có một hoặc nhiều nhiệm vụ hợp lý mà tôi hoàn thành, yêu cầu thay đổi một vài tệp. Các tệp được chỉnh sửa trong tác vụ đó được liệt kê trong một chỉ mục.

Mỗi nhiệm vụ phụ này (Nhiệm vụ A và Nhiệm vụ B ở đây) là các cam kết riêng. Các git addlệnh bổ sung thêm file vào danh sách 'Index của tập tin đã thay đổi'. Quá trình này còn được gọi là quá trình dàn dựng. Các git commithồ sơ lệnh / để hoàn tất những thay đổi và danh sách chỉ số tương ứng cùng với một thông báo tùy chỉnh.

Hãy nhớ rằng bạn vẫn chỉ thay đổi bản sao cục bộ của kho lưu trữ của mình chứ không phải bản sao trên Github. Sau đó, chỉ khi bạn thực hiện 'git push' thì tất cả các thay đổi đã ghi này, cùng với các tệp chỉ mục của bạn cho mỗi lần cam kết, mới được đăng nhập vào kho lưu trữ chính (trên Github).

Ví dụ, để có được mục nhập thứ hai trong tệp nhật ký tưởng tượng đó, tôi đã thực hiện:

git pull
# Make changes to these files
git add File3 File4
# Verify changes, run tests etc..
git commit -m 'Correct typos'
git push

Tóm lại, git addgit commitcho phép bạn chia nhỏ thay đổi đối với kho lưu trữ chính thành các thay đổi phụ hợp lý có hệ thống. Như các câu trả lời và nhận xét khác đã chỉ ra, tất nhiên chúng còn có nhiều công dụng hơn nữa. Tuy nhiên, đây là một trong những cách sử dụng phổ biến nhất và nguyên tắc lái xe đằng sau Git là một hệ thống kiểm soát sửa đổi nhiều giai đoạn không giống như những hệ thống phổ biến khác như Svn.


2

Khu vực tổ chức giúp chúng tôi tạo ra các cam kết một cách linh hoạt hơn. Bằng cách tạo, tôi có nghĩa là chia nhỏ các cam kết thành các đơn vị hợp lý. Điều này rất quan trọng nếu bạn muốn có một phần mềm có thể bảo trì. Cách rõ ràng nhất mà bạn có thể đạt được:

Bạn có thể làm việc trên nhiều tính năng / lỗi trong một thư mục làm việc duy nhất và vẫn tạo ra các cam kết có ý nghĩa. Có một thư mục làm việc duy nhất chứa tất cả công việc đang hoạt động của chúng tôi cũng rất thuận tiện. (Điều này có thể được thực hiện mà không cần khu vực tổ chức, chỉ miễn là các thay đổi không bao giờ chồng chéo lên tệp. Và bạn cũng có thêm trách nhiệm theo dõi thủ công xem chúng có chồng chéo hay không)

Bạn có thể tìm thêm ví dụ tại đây: Công dụng của Index

Và phần tốt nhất là, những lợi thế không dừng lại với danh sách quy trình công việc này. Nếu một quy trình làm việc duy nhất xuất hiện, bạn có thể gần như chắc chắn rằng khu vực tổ chức sẽ giúp bạn.


2

Để mở rộng câu trả lời của Ben Jackson, câu trả lời nào tốt, chúng ta hãy xem xét kỹ câu hỏi ban đầu. (Xem câu trả lời của anh ấy để biết lý do tại sao phải nhập các câu hỏi; đây là thông tin thêm về những gì đang xảy ra .)

Tôi mới sử dụng tính năng kiểm soát phiên bản và tôi hiểu rằng "cam kết" về cơ bản là tạo bản sao lưu trong khi cập nhật phiên bản 'hiện tại' mới của những gì bạn đang làm.

Điều này không hoàn toàn đúng. Sao lưu và kiểm soát phiên bản chắc chắn có liên quan - chính xác mức độ phụ thuộc vào một số thứ ở một mức độ nào đó là vấn đề quan điểm - nhưng chắc chắn có một số khác biệt, nếu chỉ về mục đích: Bản sao lưu thường được thiết kế để phục hồi sau thảm họa (máy bị lỗi, hỏa hoạn phá hủy toàn bộ tòa nhà bao gồm tất cả các phương tiện lưu trữ, v.v.). Kiểm soát phiên bản thường được thiết kế cho các tương tác chi tiết hơn và cung cấp các tính năng mà bản sao lưu không có. Các bản sao lưu thường được lưu trữ trong một thời gian, sau đó bị loại bỏ là "quá cũ": một bản sao lưu mới hơn là tất cả những gì quan trọng. Kiểm soát phiên bản thường lưu mọi phiên bản đã cam kết mãi mãi.

Điều tôi không hiểu là dàn dựng để làm gì, từ góc độ thực tế. Việc dàn dựng một thứ gì đó chỉ tồn tại dưới danh nghĩa hay nó phục vụ một mục đích? Khi bạn cam kết, nó sẽ cam kết mọi thứ, phải không?

Có và không. Thiết kế của Git ở đây hơi đặc biệt. Có những hệ thống kiểm soát phiên bản tồn tại không yêu cầu một bước dàn dựng riêng biệt. Ví dụ, Mercurial, rất giống Git về cách sử dụng, không yêu cầu một hg addbước riêng biệt , ngoài bước đầu tiên giới thiệu một tệp hoàn toàn mới. Với Mercurial, bạn sử dụng hglệnh để chọn một số cam kết, sau đó bạn thực hiện công việc của mình, sau đó bạn chạy hg commitvà hoàn thành. Với Git, bạn sử dụng git checkout, 1 sau đó bạn làm công việc của mình, sau đó bạn chạy git add, và sau đó git commit. Tại sao phải thêm git addbước?

Bí mật ở đây là những gì Git gọi, khác nhau, chỉ mục hoặc khu vực tổ chức , hoặc đôi khi — hiếm khi ngày nay — bộ nhớ cache . Đây là tất cả các tên cho cùng một thứ.

Chỉnh sửa: Tôi nghĩ rằng tôi có thể đang nhầm lẫn giữa thuật ngữ. Tệp 'theo giai đoạn' có giống với tệp 'được theo dõi' không?

Không, nhưng chúng có liên quan. Một theo dõi tập tin là một trong những tồn tại trong chỉ số của Git. Để hiểu đúng về chỉ mục, tốt hơn là bạn nên bắt đầu với việc hiểu các cam kết.


Kể từ phiên bản Git 2.23, bạn có thể sử dụng git switchthay thế git checkout. Đối với trường hợp cụ thể này, hai lệnh này thực hiện chính xác cùng một việc. Lệnh mới tồn tại bởi vì git checkoutquá nhiều thứ; chúng được chia thành hai lệnh riêng biệt git switchgit restoređể giúp việc sử dụng Git dễ dàng và an toàn hơn.


Cam kết

Trong Git, một cam kết lưu toàn bộ ảnh chụp nhanh của mọi tệp mà Git biết. (Git biết về những tệp nào? Chúng ta sẽ xem điều đó trong phần tiếp theo.) Những ảnh chụp nhanh này được lưu trữ ở dạng đặc biệt, chỉ đọc, chỉ Git, được nén và khử trùng lặp, nói chung chỉ bản thân Git mới có thể đọc . (Có nhiều thứ trong mỗi cam kết hơn chỉ là ảnh chụp nhanh này, nhưng đó là tất cả những gì chúng ta sẽ đề cập ở đây.)

Việc khử trùng lặp giúp tiết kiệm không gian: chúng tôi thường chỉ thay đổi một vài tệp, sau đó thực hiện một cam kết mới. Vì vậy, hầu hết các tệp trong một cam kết hầu hết giống với các tệp trong cam kết trước đó. Bằng cách đơn giản sử dụng lại các tệp đó trực tiếp, Git tiết kiệm rất nhiều dung lượng: nếu chúng ta chỉ chạm vào một tệp, bản cam kết mới chỉ chiếm dung lượng cho một bản sao mới. Ngay cả sau đó nó được nén - đôi khi rất nén, mặc dù điều này thực sự xảy ra sau đó - để một .gitthư mục thực sự có thể nhỏ hơn các tệp mà nó chứa, sau khi chúng được mở rộng thành các tệp bình thường hàng ngày. Việc khử trùng lặp là an toàn vì các tệp đã cam kết luôn được đóng băng. Không ai có thể thay đổi một, vì vậy sẽ an toàn cho các cam kết phụ thuộc vào các bản sao của nhau.

Tuy nhiên, vì các tệp được lưu trữ ở định dạng Git đặc biệt, được đóng băng mọi lúc, nên Git phải mở rộng từng tệp thành một bản sao thông thường hàng ngày. Bản sao thông thường này không phải bản sao của Git : nó là bản sao của bạn , bạn có thể làm theo ý muốn. Git sẽ chỉ viết thư cho những thứ này khi bạn yêu cầu nó làm như vậy, để bạn có các bản sao của mình để làm việc. Những bản sao có thể sử dụng được ở bạn cây lao động hoặc công việc cây .

Điều này có nghĩa là khi bạn kiểm tra một số cam kết cụ thể, sẽ tự động có hai bản sao của mỗi tệp:

  • Git có một bản sao Git-ified được đóng băng mọi lúc, mọi nơi trong cam kết hiện tại . Bạn không thể thay đổi bản sao này (mặc dù tất nhiên bạn có thể chọn một cam kết khác hoặc tạo một cam kết mới).

  • Bạn có một bản sao định dạng bình thường trong cây công việc của mình. Bạn có thể làm bất cứ điều gì bạn muốn bằng cách sử dụng bất kỳ lệnh nào trên máy tính của bạn.

Các hệ thống điều khiển phiên bản khác (bao gồm cả Mercurial như đã đề cập ở trên) dừng ở đây, với hai bản sao này. Bạn chỉ cần sửa đổi bản sao cây công việc của mình, sau đó cam kết. Git ... không.

Chỉ số

Ở giữa hai bản sao này, Git lưu trữ bản sao thứ ba 2 của mọi tệp. Bản sao thứ ba này ở định dạng cố định , nhưng không giống như bản sao cố định trong cam kết, bạn có thể thay đổi nó. Để thay đổi nó, bạn sử dụng git add.

Các git addphương tiện lệnh làm cho các bản sao chỉ số của tập tin phù hợp với bản sao công việc cây . Có nghĩa là, bạn đang nói với Git: Hãy thay thế bản sao có định dạng cố định, loại bỏ trùng lặp có trong chỉ mục ngay bây giờ, bằng cách nén bản sao cây công việc đã cập nhật của tôi, khử trùng lặp nó và chuẩn bị đóng băng thành một cam kết mới. Nếu bạn không sử dụng git add, chỉ mục vẫn giữ bản sao định dạng cố định từ cam kết hiện tại.

Khi bạn chạy git commit, Git đóng gói bất cứ thứ gì có trong chỉ mục ngay lúc đó để sử dụng làm ảnh chụp nhanh mới. Vì nó đã ở định dạng cố định và đã được khử trùng lặp trước, nên Git không phải làm thêm nhiều việc.

Điều này cũng giải thích tất cả các tệp không được kiểm soát. Tệp chưa được kiểm soát là tệp nằm trong cây công việc của bạn nhưng không có trong chỉ mục của Git ngay bây giờ . Nó không quan trọng bằng cách nào tệp được lưu trữ trong trạng thái này. Có thể bạn đã sao chép nó từ một số nơi khác trên máy tính của mình vào cây công việc của bạn. Có thể bạn đã tạo nó mới ở đây. Có thể có được một bản sao trong chỉ số Git, nhưng bạn loại bỏ bản sao đó với git rm --cached. Bằng cách này hay cách khác, có một bản sao ở đây trong cây công việc của bạn, nhưng không có bản sao trong chỉ mục của Git. Nếu bạn thực hiện một cam kết mới ngay bây giờ, tệp đó sẽ không có trong cam kết mới.

Lưu ý rằng git checkoutban đầu điền vào chỉ mục của Git từ cam kết mà bạn kiểm tra. Vì vậy, chỉ mục bắt đầu khớp với cam kết. Git cũng điền vào cây công việc của bạn từ cùng một nguồn này. Vì vậy, ban đầu, cả ba đều hợp nhau. Khi bạn thay đổi các tệp trong cây công việc và git addchúng, bây giờ chỉ mục và cây công việc của bạn khớp với nhau. Sau đó, bạn chạy git commitvà Git thực hiện một cam kết mới từ chỉ mục và bây giờ cả ba đều khớp lại.

Vì Git thực hiện các cam kết mới từ chỉ mục, chúng ta có thể đặt mọi thứ theo cách này: Chỉ mục của Git giữ cam kết tiếp theo mà bạn dự định thực hiện. Điều này bỏ qua vai trò mở rộng mà chỉ mục của Git đảm nhận trong quá trình hợp nhất xung đột, nhưng dù sao thì bây giờ chúng tôi cũng muốn bỏ qua điều đó. :-)

Đó là tất cả những gì cần làm — nhưng nó vẫn còn khá phức tạp! Nó đặc biệt phức tạp vì không có cách nào dễ dàng để xem chính xác những gì có trong chỉ mục của Git. 3 Nhưng có một lệnh Git cho bạn biết những gì đang xảy ra, trong một cách đó là khá hữu ích, và lệnh đó là git status.


2 Về mặt kỹ thuật, đây thực sự không phải là một bản sao . Thay vào đó, nó là một tham chiếu đến tệp Git-ified, đã được khử trùng lặp trước và mọi thứ. Ngoài ra còn có nhiều thứ khác ở đây, chẳng hạn như chế độ, tên tệp, số tổ chức và một số dữ liệu bộ nhớ cache để làm cho Git hoạt động nhanh. Nhưng trừ khi bạn bắt đầu làm việc với một số lệnh cấp thấp của Git - git ls-files --stagegit update-indexcụ thể là - bạn chỉ có thể coi nó như một bản sao.

3 Các git ls-files --stagelệnh sẽ cho bạn thấy tên và số dàn của mỗi tập tin trong chỉ số Git, nhưng thường đây không phải là anyway rất hữu ích.


git status

Các git statuslệnh thực sự hoạt động bằng cách chạy hai riêng biệt git difflệnh cho bạn (và cũng có thể làm một số công cụ hữu ích khác, chẳng hạn như nói cho bạn mà chi nhánh bạn đang ở trên).

Đầu tiên git diffso sánh cam kết hiện tại - mà, hãy nhớ rằng, bị đóng băng mọi lúc - với bất kỳ cam kết nào trong chỉ mục của Git. Đối với các tệp giống nhau , Git sẽ không nói gì cả. Đối với các tệp khác nhau , Git sẽ cho bạn biết rằng tệp này được sắp xếp để cam kết . Điều này bao gồm hoàn toàn mới file-nếu cam kết không có sub.pytrong nó, nhưng chỉ số khôngsub.pytrong nó, sau đó tập tin này được bổ sung và bất kỳ tập tin bị loại bỏ, đó là (và đang) trong cam kết nhưng không trong chỉ số bất kỳ nữa ( git rm, có lẽ).

Thứ hai git diffso sánh tất cả các tệp trong chỉ mục của Git với các tệp trong cây công việc của bạn. Đối với các tệp giống nhau , Git không nói gì cả. Đối với các tệp khác nhau , Git sẽ cho bạn biết rằng tệp này không được sắp xếp để cam kết . Không giống như khác biệt đầu tiên, danh sách cụ thể này không bao gồm các tệp hoàn toàn mới: nếu tệp untrackedtồn tại trong cây công việc của bạn, nhưng không có trong chỉ mục của Git, Git chỉ thêm nó vào danh sách các tệp chưa được theo dõi . 4

Cuối cùng, sau khi tích lũy được những tập tin này untracked trong một danh sách, git statussẽ công bố những tên file quá, nhưng có một ngoại lệ đặc biệt: nếu tên của một tập tin được liệt kê trong một .gitignoretập tin, mà ngăn chặn danh sách cuối cùng này. Lưu ý rằng việc liệt kê một tệp được theo dõi — tệp nằm trong chỉ mục của Git — ở .gitignoređây không có tác dụng gì : tệp nằm trong chỉ mục, vì vậy nó được so sánh và được cam kết, ngay cả khi nó được liệt kê trong .gitignore. Tệp bỏ qua chỉ ngăn chặn các khiếu nại "tệp không được theo dõi". 5


4 Khi sử dụng phiên bản ngắn của git status- git status -s—các tệp không được theo dõi không được tách biệt như nhau, nhưng nguyên tắc thì giống nhau. Việc tích lũy các tệp như thế này cũng cho phép git statustóm tắt một loạt các tên tệp không được theo dõi bằng cách in tên thư mục, đôi khi. Để có được danh sách đầy đủ, hãy sử dụng git status -uallhoặc git status -u.

5 Liệt kê một tệp cũng làm cho việc thêm nhiều thao tác với tệp như git add .hoặc git add *bỏ qua tệp không được theo dõi. Phần này phức tạp hơn một chút, vì bạn có thể sử dụng git add --forceđể thêm một tệp thường bị bỏ qua. Có một số trường hợp đặc biệt thường nhỏ khác, tất cả đều cộng thêm vào điều này: tệp .gitignorecó thể được gọi đúng cách hơn .git-do-not-complain-about-these-untracked-files-and-do-not-auto-add-themhoặc một cái gì đó khó sử dụng tương tự. Nhưng điều đó quá vô lý, vì vậy .gitignorenó là.


git add -u,, git commit -av.v.

Có một số phím tắt tiện dụng cần biết ở đây:

  • git add .sẽ thêm tất cả các tệp cập nhật trong thư mục hiện tại và bất kỳ thư mục con nào. Điều này tôn trọng .gitignore, vì vậy nếu một tệp hiện chưa được theo dõi không bị khiếu nại git status, nó sẽ không được thêm tự động.

  • git add -usẽ tự động thêm tất cả các tệp cập nhật ở bất kỳ đâu trong cây công việc của bạn . 6 Điều này chỉ ảnh hưởng đến các tệp được theo dõi . Lưu ý rằng nếu bạn đã xóa bản sao cây công việc, điều này cũng sẽ xóa bản sao chỉ mục ( git addđiều này có phải là một phần của nó làm cho chỉ mục khớp với thứ cây công việc).

  • git add -Agiống như chạy git add .từ cấp cao nhất của cây công việc của bạn (nhưng hãy xem chú thích 6).

Bên cạnh đó, bạn có thể chạy git commit -a, tương đương với chạy 7git add -u và sau đó git commit. Đó là, điều này giúp bạn có những hành vi tương tự thuận tiện trong Mercurial.

Nói chung, tôi khuyên bạn không nên sử dụng git commit -amô hình này: Tôi thấy rằng tốt hơn nên sử dụng git statusthường xuyên, xem xét kỹ đầu ra và nếu trạng thái không như bạn mong đợi, hãy tìm hiểu lý do tại sao lại như vậy. Khi sử dụng git commit -a, quá dễ dàng để vô tình sửa đổi một tệp và thực hiện một thay đổi mà bạn không định thực hiện. Nhưng đây chủ yếu là vấn đề về sở thích / quan điểm.


6 Nếu phiên bản Git của bạn có trước Git 2.0, hãy cẩn thận ở đây: git add -uchỉ hoạt động trên thư mục hiện tại và các thư mục con, vì vậy trước tiên bạn phải leo lên cấp cao nhất của cây công việc của mình. Các git add -Atùy chọn có vấn đề tương tự.

7 Tôi nói gần như tương đươnggit commit -athực sự hoạt động bằng cách tạo thêm một chỉ mục và sử dụng chỉ mục khác đó để thực hiện cam kết. Nếu cam kết hoạt động , bạn sẽ có được hiệu quả tương tự như khi thực hiện git add -u && git commit. Nếu cam kết không hoạt động — nếu bạn làm cho Git bỏ qua cam kết theo bất kỳ cách nào trong số nhiều cách bạn có thể làm điều đó — thì sau đó không có tệp nào được git add-ed vì Git ném ra chỉ mục bổ sung tạm thời và quay lại sử dụng chỉ mục chính .

Có thêm các biến chứng đi kèm nếu bạn sử dụng git commit --onlyở đây. Trong trường hợp này, Git tạo ra một chỉ mục thứ ba và mọi thứ trở nên rất phức tạp, đặc biệt nếu bạn sử dụng các móc cam kết trước. Đây là một lý do khác để sử dụng các git addhoạt động riêng biệt .


1

Tôi thấy quan điểm về việc sử dụng sân khấu để làm cho cam kết nhỏ hơn như được đề cập bởi @Ben Jackson và @Tapashee Tabassum Urmi và đôi khi tôi sử dụng nó cho mục đích đó, nhưng tôi chủ yếu sử dụng nó để làm cho cam kết của mình lớn hơn! đây là quan điểm của tôi:

Giả sử tôi muốn thêm một tính năng nhỏ yêu cầu một số bước nhỏ hơn. Tôi không thấy có điểm nào khi có một cam kết riêng cho các bước nhỏ hơn và làm ngập dòng thời gian của mình. Tuy nhiên, tôi muốn lưu từng bước và quay lại nếu cần,

Tôi chỉ đơn giản là xếp các bước nhỏ hơn chồng lên nhau và khi tôi cảm thấy nó xứng đáng để thực hiện, tôi cam kết. Bằng cách này, tôi loại bỏ các cam kết không cần thiết khỏi dòng thời gian nhưng không thể hoàn tác (thanh toán) bước cuối cùng.

Tôi thấy các cách khác để thực hiện việc này (đơn giản hóa lịch sử git) mà bạn có thể sử dụng tùy thuộc vào sở thích của mình:

  1. sửa đổi git (thay đổi cam kết cuối cùng của bạn) không phải là thứ bạn muốn cho mục đích cụ thể này (tôi thấy nó chủ yếu là thực hiện một cam kết xấu và sau đó sửa nó)
  2. git rebase, là một suy nghĩ sau và có thể gây ra các vấn đề nghiêm trọng cho bạn và những người khác sử dụng kho lưu trữ của bạn.
  3. tạo một nhánh tạm thời, hợp nhất và sau đó xóa nó sau đó (đây cũng là một lựa chọn tốt, yêu cầu nhiều bước hơn nhưng cho phép bạn kiểm soát nhiều hơn)

0

Nó giống như một hộp kiểm cung cấp khả năng chọn những tệp để cam kết.

ví dụ: nếu tôi đã chỉnh sửa fileA.txtfileB.txt. Nhưng tôi chỉ muốn cam kết các thay đổi fileA.txt. bởi vì tôi vẫn chưa kết thúc với fileB.txt.

Tôi có thể chỉ cần sử dụng git add fileA.txtvà cam kết sử dụng git commit -m "changed fileA.txt"và tiếp tục làm việc fileB.txtvà sau khi kết thúc, tôi có thể cam kết fileB.txtdễ dàng

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.