Git khả thi tối thiểu để phát triển dựa trên Trunk
Ít hơn là nhiều hơn khi nói đến một công cụ mạnh mẽ — và quá phức tạp — như Git
Eli là đồng sáng lập và đồng giám đốc điều hành của trunk.io . Anh ấy đã giữ các vị trí lãnh đạo kỹ thuật tại Microsoft, Uber và Google (đã mua lại công ty khởi nghiệp mà anh ấy đồng sáng lập). Trọng tâm chính của anh ấy là giúp các nhóm xây dựng phần mềm tốt hơn, nhanh hơn.
Phát triển trong môi trường hợp tác là một hoạt động phức tạp liên quan đến việc theo dõi và điều phối công việc từ nhiều nhà phát triển. Nhiều người trong chúng ta sử dụng Git để kiểm soát phiên bản để xử lý tất cả những thay đổi này. Nhưng theo cách nói của Linus , Git là “trình quản lý thông tin đến từ địa ngục”. Nó cung cấp rất nhiều tùy chọn và trạng thái kỳ lạ, bạn có thể dễ dàng thấy mình ở một nơi tồi tệ đến mức phải sao chép lại từ đầu — ngay cả khi bạn không làm gì sai.
Nhiều người trong chúng ta biết rằng một nhà phát triển đã nghiên cứu Git refspec và cây Merkle cơ bản mà nó dựa trên, nhưng việc trở thành một người am hiểu về Git có thể không có trong bản mô tả công việc của bạn. Tôi có thể lái một chiếc ô tô hoàn toàn bình thường mà không cần hiểu cách thức hoạt động của hộp số và suy cho cùng, Git chỉ là một phương tiện để đạt được mục đích.
Để tận dụng tối đa Git, bạn phải sử dụng nó với số lượng ít nhất có thể khi phát triển dựa trên thân cây. Giới hạn các lệnh bạn sử dụng, luôn cập nhật nhánh tính năng của bạn đúng cách và chuẩn hóa việc sử dụng theo nhóm. Cá nhân, bạn có thể tận hưởng sự tự do để làm bất cứ điều gì bạn muốn. Nhưng với tư cách là một đội, cái giá cho sự tự do phải trả bằng sự xích mích.
Giới hạn hành động Git của bạn
Cách dễ nhất để thực hiện để đạt hiệu quả Git cao nhất là tuân theo một tập hợp con các lệnh. Git có thể làm được nhiều việc, nhưng phần lớn sức mạnh của nó chỉ tồn tại để giúp bạn thoát khỏi những tình huống khủng khiếp. Số lệnh mà Git cho phép so với số lệnh bạn thực sự nên gọi là hoàn toàn khác nhau.
Tôi đã từng được một CTO yêu cầu cung cấp một lớp học về git nâng cao cho nhóm kỹ sư của anh ấy. Câu trả lời của tôi rất đơn giản:
vào thời điểm bạn cần git nâng cao - bánh xe đã rời khỏi ô tô. thay vào đó, hãy tập trung vào việc sử dụng git lõi một cách chính xác.
Dưới đây là 10 lệnh git tôi sử dụng để hoàn thành công việc của mình đồng thời giảm thiểu số lần tôi rơi vào địa ngục Git:
Quản lý chi nhánh
git checkout -t -b {branch-name}
Tạo một nhánh, đặt ngược dòng cho nhánh hiện tại và chuyển sang nhánh đó. Bạn cũng có thể thực hiện việc này thông qua lệnh `git branch` nhưng phải thực hiện nhiều lệnh. Vì tôi luôn muốn chuyển sang một nhánh khi tôi tạo nó, nên lệnh này ngắn gọn hơn. Tạo và kiểm tra chi nhánh trong một cú trượt ngã. Tôi thường đặt tên cho tất cả các nhánh của mình eli/{work-being-done}.
git checkout {branch-name}
Chuyển sang một chi nhánh.
git branch -vvXem các nhánh hiện tại của bạn và ngược dòng của chúng.
git branch -D {branch-name}Xóa một nhánh cục bộ, thường là để dọn sạch các nhánh cũ/được hợp nhất thành nhánh chính.
đẩy & kéo
git fetch origin main:main
Kéo điều khiển từ xa mainvào địa phương của bạn main, ngay cả khi bạn hiện không ở mainchi nhánh! Đó là ; rất hữu ích khi bạn đang cố hợp nhất cái mới nhất mainvào một nhánh PR.
git push origin
Đẩy mã của tôi vào điều khiển từ xa; có khả năng quay rất nhiều máy trong CI để kiểm tra công việc của tôi.
git pull
Cập nhật chi nhánh địa phương của tôi bằng điều khiển từ xa cùng tên.
cam kết
git add -A .
Thêm mọi thứ tôi đang làm (tệp mới và tệp đã chỉnh sửa).
git commit -am "work"Xem ở đây để đi sâu vào suy nghĩ của tôi về các thông điệp cam kết cục bộ
git merge main
Nhiều hơn nữa về điều này dưới đây. Tôi là người thực dụng và không phải là người thích nổi loạn và rất vui khi làm vấy bẩn chi nhánh địa phương của mình bằng các hoạt động từ main.
Giữ cho nhánh tính năng của bạn được cập nhật đúng cách
Trong phần cuối cùng của tôi , tôi đã thảo luận về cách quản lý mã đích trên main. Nhưng thông thường trong quá trình phát triển và chắc chắn là trước khi hợp nhất, bạn cần cập nhật những thay đổi mới nhất mainvì:
- Bạn cần một số tính năng phù
mainhợp để thực hiện công việc tính năng của mình. - Có thứ gì đó
mainđã thay đổi và nếu bạn không nhặt nó lên, bạn sẽ làm hỏng nó khi cố gắng nhập mã của mình. - Bạn chỉ muốn luôn tươi mới vì bạn là một kỹ sư và yêu thích những thứ mới mẻ.
Cửa 1: hợp nhất git
Đây là chiến lược hợp nhất của tôi. Nó đơn giản, đáng tin cậy và không rườm rà. Cơ bản git mergelấy tất cả các thay đổi đã xảy ra mainvà hợp nhất chúng lại với nhau dưới dạng cam kết cùng với các thay đổi của bạn. Bạn có thể đọc quảng cáo buồn nôn về những nhược điểm của giải pháp không rườm rà này, nhưng thành thật mà nói, tôi chỉ nhún vai và nói “Tôi không quan tâm đến điều đó.” Nếu bạn hợp nhất các nhánh công việc của mình vào mainthì tất cả những điều vô nghĩa về ô nhiễm git-log sẽ trở thành như vậy.
Thực sự không quan trọng bằng cách nào/tại sao/điều gì đã đến với nhánh công việc của tôi. Điều quan trọng là - nó có được xây dựng không, nó có hoạt động không và mã có làm những gì tôi muốn nó làm không? Phần còn lại là học thuật.
Trong thực tế, và tôi là một kỹ sư rất thực tế, git mergecho phép bạn xử lý các xung đột hợp nhất một cách rõ ràng và quay lại xây dựng. Bạn giải quyết mọi xung đột hợp nhất một lần — và bạn đã sẵn sàng để bắt đầu. Đây là tùy chọn tốt nhất cho người mới bắt đầu, người dùng nâng cao bận rộn và những người không mơ mộng trở thành chuyên gia về Git.
Cửa 2: git rebase
Đây là lựa chọn tồi tệ nhất cho đến nay. Tôi biết rồi; thực tế có cả một thế hệ xem rebase so với hợp nhất thứ gì đó như tab so với khoảng trắng. Nhưng trong các dự án “thực tế”, trong đó một hoặc nhiều nhóm hợp nhất vào một kho lưu trữ hàng ngày, việc rebase yêu cầu giải quyết n xung đột hợp nhất thay vì một xung đột với một cuộc nổi dậy hợp nhất hoặc nén (thêm về điều đó bên dưới).
Ngoài ra, bất kỳ lần khởi động lại nào cũng ghi lại lịch sử Git và điều đó có nghĩa là nếu chi nhánh của bạn có một đối tác từ xa, bạn cần ghi git push --forcelại lịch sử của nó bằng lịch sử khởi động lại mới của chi nhánh. Điều này là tốt về mặt lý thuyết nhưng có khả năng vô tình xóa tác phẩm trước đó của bạn theo cách cực kỳ khó khôi phục. Nó đơn giản là nguy hiểm hơn nhiều so với việc hợp nhất và thực sự khiến tôi đau đầu khi nghĩ về nó.
Với mục đích của bài viết này, tôi đã cố gắng khởi động lại chỉ để nhắc nhở bản thân rằng tôi không thích quy trình làm việc này đến mức nào. Hãy xem những gì một lệnh rebase đơn giản phun vào thiết bị đầu cuối của tôi:
Có quá nhiều sai lầm với thiết bị đầu cuối đó. Tôi nhận được ghi chú về băm cam kết - không muốn xem chúng. Tôi nhận được bốn dòng gợi ý màu vàng để nhắc tôi cách thức hoạt động của toàn bộ điều này. Và tôi hiện đang trong một số quy trình công việc chỉ để lấy mã từ mainchi nhánh của mình. Cây quyết định rất phức tạp; git rebase --skip- đó là gì?! Tại sao có thể bỏ qua một cam kết? Bạn biết gì? Đừng nói với tôi vì tôi có việc phải làm.
Cửa 3: git squash rebase
Bạn chắc chắn không muốn những gì đằng sau cánh cửa số 2, nhưng một số người là những kẻ cực đoan. Đồng sáng lập của tôi, đồng Giám đốc điều hành David Apirian, đã chỉ cho tôi lối vào hậu trường bí mật của anh ấy để nổi loạn và điều đó thật tuyệt vời. Chúng tôi sẽ gọi đây là cuộc nổi loạn bí đao .
Tôi đã nhắc lại tầm quan trọng của tính đơn giản của Git, nhưng với cách tiếp cận này, bạn có thể rebase và ăn nó luôn. Bạn có được lớp phép thuật của một cuộc nổi loạn mà không có sự điên rồ của quy trình nổi loạn tiêu chuẩn. Với một cuộc nổi loạn bí đao, bạn có thể:
- Xem sự khác biệt về các cam kết cục bộ của bạn trước khi chuyển sang GitHub.
- Dễ dàng hoàn tác cam kết cuối cùng của bạn.
- Tránh làm ô nhiễm quan điểm của GitHub về yêu cầu kéo của bạn với rất nhiều cam kết cục bộ nhỏ.
Bước 1 - xóa tất cả các cam kết cục bộ của bạn:
git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message
git rebase main
Bạn có thể kết hợp tất cả những thứ này lại thành một lệnh uber duy nhất để kéo chính mới nhất, xóa tất cả các cam kết của bạn và khởi động lại trên chính mới nhất:
git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message &&
git fetch origin main:main &&
git rebase main
[alias]
smartcommit = !git add -A . && git commit -am "" --allow-empty-message
squash = !git reset --soft $(git merge-base HEAD main) && git commit -am "" --allow-empty-message
squashrebase = !git squash && git fetch origin main:main && git rebase main
smart = !git smartcommit && git squashrebase
Một trong những khía cạnh thú vị của việc luôn xóa bỏ các cam kết cục bộ của bạn là ở trên cùng của bạn git loglà tất cả công việc bạn đã thực hiện trong chi nhánh. Công việc tại địa phương của bạn bây giờ gần giống với PR được sáp nhập của squash sẽ trông như thế nào khi nó hạ cánh ở main.
Tại bất kỳ thời điểm nào, bạn có thể bật lần xác nhận cuối cùng của HEAD với chi nhánh địa phương của mình và xem tất cả công việc bạn đã thực hiện từ main. Điều này tương tự như chế độ xem chi tiết mà GitHub cung cấp cho bạn về những gì đã thay đổi, nhưng cho phép bạn ở lại thiết bị đầu cuối của mình và tránh chuyển đổi nhầm lẫn giữa hai giao diện người dùng khác nhau.
Tôi phải thừa nhận rằng lần đầu tiên David cho tôi xem quy trình làm việc này, tôi đã rất ấn tượng. Anh ấy đã giết gần hết rebasecon rồng và khả năng xem cục bộ tất cả các tệp bạn đã thay đổi trong nhánh của mình thật tuyệt vời.
Mặc dù việc khởi động lại squash giúp bạn duy trì trạng thái dòng chảy tốt hơn, nhưng phần lớn các nhà phát triển tốt hơn hết là chỉ hợp nhất. Sử dụng rebase hoặc squash rebase không chính xác dẫn đến ma sát làm giảm năng suất.
Cạm bẫy của trợ giúp chi nhánh GitHub
GitHub cung cấp cài đặt này ☝️ để đề xuất maintự động hợp nhất vào chi nhánh của bạn nếu nó đã lỗi thời. Cài đặt này thường phản tác dụng. Tôi muốn chi nhánh địa phương của mình là nguồn trung thực duy nhất cho PR của tôi và không ai khác (kể cả GitHub) nên thúc đẩy điều đó. Làm việc với GitHub trên chi nhánh cá nhân của tôi phải là con đường một chiều. Tôi viết mã cục bộ và đẩy.
Nếu bạn định cấu hình GitHub để bắt đầu đẩy các bản cập nhật tới nhánh công việc của mình, bạn đang yêu cầu lưu lượng truy cập bắt đầu đi sai hướng. Và đó là một công thức cho nỗi đau.
Vấn đề này cũng phát sinh khi người đánh giá mã để lại cho bạn các đề xuất cam kết nhỏ về yêu cầu kéo của bạn và bạn vô tình áp dụng chúng. Sau đó, nếu bạn thực hiện bất kỳ công việc nào trên chi nhánh địa phương của mình trước khi thực hiện những thay đổi đó… thì bạn đã mở một túi nhỏ bị tổn thương.
Tôi thường phát hiện ra rằng tôi đã vô tình làm điều này với chính mình khi tôi cố gắng đẩy các bản cập nhật của mình trở lại điều khiển từ xa và git cho tôi biết rằng tôi không đồng bộ hóa. Tại thời điểm đó, tôi có hai lựa chọn:
git push --forcevà thổi bay mọi thứ trên điều khiển từ xa không phải trên nhánh địa phương của bạn. Nói chung, bất cứ điều gì với từ lực lượng là phá hoại và nản lòng.git merge origin/{my-work-branch}để hợp nhất các thay đổi từ xa vào chế độ xem cục bộ của chi nhánh.
Cài đặt GitHub này ️☝️ yêu cầu các PR phải được cập nhật maintrước khi hợp nhất vào đó. Điều này thường “giải quyết” khả năng bị hỏng main; tuy nhiên, nó chỉ hoạt động với các repos tốc độ rất thấp. Khi một số ít nhà phát triển cố gắng hợp nhất nhiều PR mỗi ngày, họ sẽ rơi vào cuộc chạy đua để hợp nhất main- hoặc nếu không, họ sẽ liên tục thực hiện hợp nhất/rebase mainvào nhánh của họ để được "cập nhật" lại và về cơ bản là chạy đua với đồng nghiệp của họ là người đầu tiên hợp nhất. Đau đớn. Thông thường, nếu bạn muốn tính năng này nhưng bạn không phải là nhà phát triển đơn lẻ, thì bạn có thể muốn có một hàng đợi hợp nhất thay vào đó — đây là cách có thể mở rộng để đạt được mục tiêu chính không bị hỏng. Đây là điều mà chúng tôi cảm thấy đủ quan trọng để sản xuất với Trunk Merge .
Giảm thiểu Git cho giá trị tối đa
Bằng cách giữ cho việc sử dụng Git của bạn đơn giản nhất có thể, bạn sẽ cung cấp cho các nhà phát triển ít dây buộc hơn và có nhiều thời gian hơn để thực hiện công việc phát triển thực sự quan trọng. Làm cho Git đóng vai phụ chứ không phải nhân vật chính. Để duy trì một môi trường phát triển lành mạnh và hợp tác, hãy nhớ:
- Chọn diện tích bề mặt nhỏ nhất của Git để sử dụng và gắn bó với nó.
- Luôn quản lý các thay đổi ngược dòng của bạn theo cùng một cách.
- Tiêu chuẩn hóa các hoạt động trong nhóm của bạn để các đồng nghiệp của bạn cũng không đi chệch hướng.

![Dù sao thì một danh sách được liên kết là gì? [Phần 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































