Nhảy tới nội dung

Một bài viết được gắn thẻ "git"

Xem tất cả Thẻ

· Một phút để đọc
ManhPT

Post-git là một module Powershell cho phép tích hợp Git với Powershell hỗ trợ git autocomplete. Posh-git có vài tính năng quan trọng như:

  • Cung cấp thông tin cơ bản về repository hiện tại trên dòng lệnh
  • Tự động gợi ý khi gõ lệnh (git autocomplete)

Giao diện Powershell sau khi tích hợp posh-git:

demo-posh-git-on-powershell

Trong một bài viết trước, mình có hướng dẫn cách cài đặt và tích hợp oh-my-posh cho Powershell để cải thiện trải nghiệm làm việc. Trong bài viết này mình sẽ giới thiệu posh-git.

1. Cài đặt posh-git

Trước khi cài đặt thì bạn cũng nên xem qua yêu cầu của posh-git trước tại đây.

Cài đặt qua Powershell

Install-Module posh-git -Scope CurrentUser

Cài đặt qua Chocolatey

choco install poshgit

Cài đặt qua Scoop

scoop install posh-git

2. Tích hợp post-git để sử dụng tính năng git autocomplete

Để tích hợp posh-git vào Powershell thì ta cần phải thực hiện bước Import-Module. Cách nhanh nhất để làm việc này chỉ là một dòng lệnh:

Add-PoshGitToProfile

Giao diện posh-git trên Powershell cơ bản:

powershell-post-git

Nếu thành công thì chỉ cần mở lại Powershell là đã có thể sử dụng posh-git với Powershell rồi. Nếu lệnh trên báo lỗi thì ta có thể làm thủ công bằng cách:

notepad $PROFILE

Cập nhật nội dung của $PROFILEfile và thêm dòngImport-Module posh-gitvào.

Nội dung file$PROFILE (C:\Users\$env:USERNAME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1) của bạn có thể sẽ như sau:

Import-Module oh-my-posh Import-Module posh-git Set-PoshPrompt -Theme honukai

Lưu lại và khởi động lại Powershell để hưởng thụ thành quả nhé.

Giao diện posh-git và oh-my-posh trên Powershell:

powershell-posh-git-oh-my-posh

Để nhận được gợi ý khi gõ lệnh với git thì bạn chỉ cần nhấn phím "Tab" là được.

· Một phút để đọc
ManhPT

TL;DR

Bài viết hướng dẫn cách cài đặt Oh-My-Posh vào Powershell.

Là một developer thì chắc hẳn bạn đã sử dụng shell/bash trên linux hay macos. Mà đã sử dụng shell/bash thì chắc cũng sẽ biết đến Oh My Zsh - một công cụ huyền thoại cho những ai yêu dòng lệnh (command line).

Một developer xuất thân MacOS như mình khi chuyển môi trường sang Windows đã luôn cảm thấy CMD hay Powershell rất tù khi phải làm việc chéo cánh với các server Linux. Ngoài ra khi làm việc với git command thì mình cũng bị phụ thuộc vào Git Bash để nhận được gợi ý khi gõ lệnh.

Sau một thời giản dài sống chung với lũ hồi tìm hiểu thì cuối cùng cũng tìm ra được chân ái - Oh My Posh. Oh My Posh giúp powershell trở nên đầy màu sắc đi kèm với những thông tin hữu ích liên quan đến project hiện tại và cả git nữa, quá ngon rồi 😁 mlem mlem...

powershell-ohmyposh-screenshot

Giao diện powershell sau khi được cài đặt OhMyPosh và danh sách themes để bạn chọn

1. Cài đặt Oh-My-Posh

Tài liệu chính chủ của Oh My Posh cũng đã có hướng dẫn rất đầy đủ rồi nhưng mình vẫn tóm tắt lại theo các bước cài đặt bằng Powershell cho tiện. Để cài đặt thì bạn mở Powershell với quyền Admin lên và:

Set-ExecutionPolicy RemoteSigned
Install-Module oh-my-posh -Scope CurrentUser

2. Sử dụng Oh-My-Posh

Để bắt đầu sử dụng Oh My Posh ngay trong powershell thì ta chỉ cần gõ lệnh sau:

Set-PoshPrompt -Theme honukai

Nhưng mỗi lần muốn sử dụng lại phải gõ lệnh thì bất tiện vl 🙄. Để đảm bảo mỗi lần mở Powershell lên mà Oh My Posh cũng sẵn sàng vào việc luôn thì cần sửa powershell profile (giống như cách ta update ~/.bash_profile ở linux/macos vậy):

notepad $PROFILE
# hoặc
notepad C:\Users\$env:USERNAME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Kết quả của lệnh trên là để cập nhật nội dung file Microsoft.PowerShell_profile.ps1, ta chỉ cần thêm nội dung như sau vào:

Set-PoshPrompt -Theme honukai

Xong bước này thì chỉ cần khởi động lại Powershell là bạn đã có thể sử dụng Oh My Posh rồi, nhưng nhìn nó sẽ sai sai như thế này:

oh-my-posh-with-out-nerd-fonts

3. Cài đặt font hỗ trợ Oh-My-Posh

Cái "sai sai" ở đây là lỗi font chữ nên bạn có thể nhìn thấy khá nhiều ký tự ⍰. Tài liệu của Oh My Posh có hướng dẫn rất rõ ràng là các bạn nên sử dụng Nerd Fonts (tham khảo), và họ khuyến khích sử dụng font Meslo LGM NF (tải về tại đây).

Bạn chỉ cần tải Meslo.zip về rồi giải nén ra rồi cài đặt.

cai-dat-meslo-font-oh-my-posh

Chưa xong, cần phải thay font cho Powershell nữa, click chuột phải vào thanh menu của cửa sổ Powershell > Properties > tab Fonts.

choose-font-meslo-oh-my-posh

Chọn font MesloLGM NF như ảnh trên rồi click OK. Thế là xong rồi, khởi động lại Powershell để hưởng thụ thành quả thôi. Max xịn sò 😎.

4. Thay đổi giao diện cho Oh-My-Posh (Optional)

Nếu bạn để ý một chút khi dùng Oh My Zsh thì nó sử dụng theme mặc định là robbyrussel. Đương nhiên là Oh My Zsh cũng cung cấp lựa chọn này cho bạn nếu bạn muốn có được cảm nhận tương đồng nhất có thể như với khi sử dụng bash trên linux/macos.

Như ở bước 2 mình có đặt sẵn câu lệnh Set-PoshPrompt -Theme honukai, có nghĩa là mình chọn sẵn theme honukai - theme này thì text không có màu nền nên khi mình sử dụng Powershell với VScode hay Jetbrains IDEs đều cho cảm giác dễ chịu.

Bạn có thể dùng lệnh Get-PoshThemes để liệt kê và chọn trong danh sách các themes có sẵn.

Get-PoshThemes

· Một phút để đọc
ManhPT

Lịch sử git thiếu nhất quán

Hầu hết developer chúng ta đều biết đến git - nếu chưa biết thì phải tìm hiểu và sử dụng ngay - một công cụ quá tuyệt vời để quản lý source code. Và giống như việc đặt tên biến trong code, commit messages cũng là một thứ gì đó thực sự gây đau đầu.

Trong một team, có anh em sẽ chỉ đặt một message ngắn ngủn cho xong, một số cẩn thận sẽ viết rõ những thay đổi trong đó và chèn thêm cả JIRA ticket number. Như thế sẽ tạo ra sự thiếu nhất quán trong lịch sử commit vốn đã rất phức tạp. Điều này khiến mình nghĩ đến việc chuẩn hóa commit trong project hiện tại.

Lựa chọn công cụ

Để có một commit có đầy đủ ý nghĩa với: loại commit (feature, fix bug, refactor...), JIRA ticket number, description. Sau thời gian ngâm cứu trên mạng thì mình đã tìm ra Commitizen và quyết định sử dụng nó để áp chuẩn cho việc commit.

Commitizen là công cụ dạng command line (dòng lệnh) hỗ trợ tự động format commit messages bằng cách hỏi bạn một vài câu hỏi, bạn nhập câu trả lời và commitizen sẽ tạo commit theo chuẩn dựa trên các thông tin được nhập. Bạn có thể cài đặt commitizen global với:

npm install commitizen -g

Không thích cài global thì có thể cài vào dev dependencies của package.json cũng ok:

npm install commitizen --save-dev

Giờ thì thay vì commit bằng lệnh:

git commit

Ta dùng:

git cz

Cấu hình commitizen

Để bắt đầu làm việc với commitizen, chúng ta cần cài đặt thêm một vài cấu hình có sẵn trong package.json gọi là adapter. Những adapter này sẽ định nghĩa những câu hỏi khi commit. Bạn có thể chọn một adapter từ đây.

Trong bài viết này mình chọn cz-conventional-changelog để bắt đầu, bạn cũng nên cài nó vào dev dependencies.

npm install cz-conventional-changelog --save-dev

Tiếp tục cấu hình adapter với lệnh sau:

commitizen init cz-conventional-changelog --save-dev

cz-conventional-changelog sẽ ép commit message theo chuẩn như sau:

type(scope): JIRA-Ticket - Short description

Sau khi gõ lệnh "git cz", dòng lệnh sẽ đưa ra những câu hỏi về: type, scope, short description, long description, breaking changes - vui lòng đọc kỹ các câu hỏi trước khi chọn hoặc trả lời, việc này khá dễ dàng và sẽ rất nhanh quen thôi.

Cấu hình validate commit message

Adapter cz-conventional-changelog không yêu cầu nhập JIRA ticket number nên chúng ta cần kiểm tra dòng đầu của commit message để chắc chắn nó có chưa JIRA ticket number. Ta có thể làm điều này với Huskyvalidate-commit-message. Để bắt đầu thì cũng cài 2 tool này dạng dev dependencies:

npm install husky --save-dev
npm install validate-commit-msg --save-dev

Husky là một tool cho phép ta có thể chạy kèm lệnh bất kỳ với git hooks, còn validate-commit-message thì sử dụng regex kiểm tra string. Để cấu hình 2 tool này thì chúng ta cần thêm thủ công đoạn config sau vào bên dưới "config" trong package.json:

"validate-commit-msg": {
"types": [
"feat",
"fix",
"docs",
"style",
"refactor",
"perf",
"test",
"chore",
"revert"
],
"warnOnFail": false,
"maxSubjectLength": 72,
"subjectPattern": "^[A-Z]+-[0-9]+ - .*",
"subjectPatternErrorMsg": "Subject must be in format 'CMS-123 - Commit message'",
"helpMessage": ""
}

Commit theo chuẩn không chỉ cho đẹp

Ngoài cải thiện tính dễ dễ hiểu của commit messages. Việc commit theo chuẩn chung như trên còn có rất nhiều lợi ích khác:

  • Quan trọng nhất phải kể đến đó là có thể đánh version phần mềm dựa trên commit (theo https://semver.org/)
  • Trigger thay đổi trên các tool dự án (JIRA)
  • CICD support
  • ...

Tận hưởng kết quả

Done rồi, commitizen đã sẵn sàng để bảo vệ sự trong sáng và nhất quán trong lịch sử git của bạn. Bài viết dựa trên kinh nghiệm cá nhân và có sự tham khảo + dịch lại từ: https://dev.bleacherreport.com/how-we-use-commitizen-to-clean-up-commit-messages-a16790dcd2fd.

· Một phút để đọc
ManhPT

Vấn đề là...

Nếu bạn đã từng sử dụng git trên "cửa sổ dòng lệnh" (terminal) của windows, linux hay macOS, bạn sẽ thấy rằng mật khẩu git của chúng ta được lưu lại tự động. Sau đó, chúng ta chỉ cần fetch - push - pull bình thường. Không cần nhập lại username và password của git nữa.

Hơi tiếc là Ubuntu nói riêng và linux nói chung không có tính năng này. Dĩ nhiên chúng ta có thể cài đặt thêm phần mềm bên thứ 3 để có được tính năng tương tự. Mmình chưa thử và cũng ko tin tưởng để thử... lol.

Giải pháp

Sau đây là một thủ thuật nhỏ và cực kỳ đơn giản để bạn có thể quên đi việc bị hỏi username và password liên tục mỗi khi git fetch. Đó là sử dụng git credential storage chỉ với một câu lệnh duy nhất.

git config --global credential.helper store
  • store mode: chế độ này lưu thông tin đăng nhập của bạn dưới dạng plain-text mặc định trong file ~/.my-credentials. Bạn sẽ chỉ phải nhập lại mật khẩu khi bạn đã thay đổi mật khẩu trên git server. Cách này không được bảo mật cho lắm vì mật khẩu được lưu cứng dưới dạng không mã hoá. Do đó, ít nhất các bạn cũng nên sử dụng personal access token thay cho mật khẩu, ví dụ: github personal access token, gitlab personal access token... (lúc nào mà nhỡ có bị lộ thì revoke cái là xong).
git config --global credential.helper cache
git config --global credential.helper cache '--timeout 30000'
  • cache mode: chế độ này thì an toàn hơn do mật khẩu của bạn sẽ được lưu trong RAM thay vì file cứng và dĩ nhiên là có timeout - mặc định là 15 phút (900 giây). Bạn có thể tuỳ ý thay đổi thời gian timeout sao cho phù hợp với nhu cầu. Mình khuyến cáo nên sử dụng cách này.

Kết luận

Trong thực tế, việc sử dụng private key vẫn tối ưu và bảo mật hơn so với trực tiếp lưu trữ mật khẩu, nhưng việc setup không đơn giản như trên. Các đồng dâm tuỳ ý chọn lựa nhé.

· Một phút để đọc
ManhPT

Bạn có bao giờ tự hỏi

  1. Git còn gì ngoài git commit, git pushgit pull? Thỉnh thoảng dùng thêm git merge, còn gì nữa không?
  2. git mergegit rebase khác gì nhau, nên dùng cái nào?
  3. Ở vị trí team leader bạn sẽ vận hành git ra sao để kết hợp với process của team (agile) và giải quyết các conflict trong quá trình code?
  4. Lịch sử git có giá trị như thế nào? Hay bạn chẳng bao giờ để ý đến nó?

Nếu bạn là 1 git command line master thì mọi thứ đều có thể được giải quyết dưới local bằng dòng lệnh. Nhưng khi làm việc trong một nhóm đông thành viên, làm thế nào để xử lý các vấn đề conflict code, release ra sao, thêm feature mới như thế nào, hotfix ra làm sao một cách trơn tru và hiệu quả, giảm thiểu tối đa các bước thủ công, tiến dần đến một git workflow tự động hoàn toàn (devops).

Luôn luôn tạo ra linear history

Git Workflow được giới thiệu sau đây luôn giữ một tư duy cực kỳ nhất quán về git history luôn luôn là linear history (có thể hiểu là history trên một đường thẳng). Nhìn trong hình đủ thấy linear history dễ hiểu hơn rất nhiều so với non-linear history, đủ dễ để nhìn vào graph là có thể thấy được thứ tự của các commit và sự khác nhau giữa các version được release.

Tham khảo

  1. http://www.bitsnbites.eu/a-tidy-linear-git-history/

git mergegit rebase đúng lúc đúng chỗ

Nguyên tắc tiên quyết

  1. Để update code mới nhất, không merge trên local, hãy dùng rebase
  2. merge tự động bằng merge (pull) request (cần cấu hình để khi merge sẽ sinh ra một empty commit nhằm đánh dấu vị trí merge)

Một ví dụ thực tế về linear history

· Một phút để đọc
ManhPT

Vấn đề là...

Trong quá trình code chắc hẳn bạn thường xuyên tạo ra những dumb commit để tránh mất code, hoặc nhiều commit trùng tên nhau. Bạn có bao giờ nghĩ đến việc gộp các commit (squash commit) đó lại thành một commit có ý nghĩa hơn chưa?

Squash commit (gộp commit) là một việc nên làm nhưng không phải ai cũng nghĩ đến. Thậm chí có nghĩ đến thì đa số cũng không muốn làm bởi sợ rằng có thể gây ra mất code. Xin được khẳng định luôn là code một khi đã được commit thì không mất đi đâu được, vô tư đi.

Để squash commit, chúng ta sẽ sử dụng câu lệnh git rebase -i hoặc git rebase --interactive. Trong nội dung bài viết này tôi sẽ không giải thích về rebase. Các bạn có thể tham khảo thêm các bài viết sau để hiểu rõ ràng hơn:

  1. https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase
  2. https://www.atlassian.com/git/tutorials/merging-vs-rebasing

Bài viết này nằm trong series về Git Workflow. Các bạn có thể tham khảo bài viết giới thiệu tại đây.

Trước khi squash

  • Bạn nên kiểm tra lại lịch sử của mình trước để xác nhận lại lần cuối những commit mà mình cần squash.
  • Copy hash id của commit nằm ngay trước những commit cần squash

Ví dụ trong ảnh trên, chúng ta có tới 4 commit giống nhau, cùng là update readme.md. 4 commit này làm chung một nhiệm vụ là update readme nên có thể gộp lại thành 1 commit, tránh tạo rác trong git history. Để squash được bạn cần có hash id của commit nằm trước tất cả các commit cần squash, VD trong ảnh sẽ là dbd01be2.

Bắt đầu squash commit

Tổng hợp các commit

  • $ git rebase -i dbd01be2 vào terminal tại root của project.
  • Màn hình VIM editor sẽ hiện lên như hình sau, đôi khi vim không phải editor mặc định của git mà có thể là nano hay một editor nào đó khác do bạn thiết lập sẵn hoặc mặc định của hệ điều hành mà bạn dùng. Không cần quá lo lắng, mục đích chỉ là edit nội dung và cũng chỉ toàn là text mà thôi.

Trong màn hình này, bạn sẽ nhìn thấy 4 commit mà bạn chọn để squash sẽ nằm ở trên cùng, mỗi commit nằm trên 1 dòng với nội dung gồm 3 phần: pick 7424f7c update readme.md

  1. pick là command, mặc định pick là giữ lại commit đó sau quá trình rebase và không thay đổi gì.
  2. 7424f7c là hash id của commit
  3. update readme.md là commit message

Để ý một chút bạn sẽ thấy các hướng dẫn rebase ở phía bên dưới (nằm trong vùng comment) nói chi tiết hơn về các action mà bạn có thể sử dụng khi rebase, hiện tại chúng ta chỉ quan tâm đến action squash mà thôi. Nếu bạn rebase lần đầu thì hãy đọc kỹ để hiểu rõ hơn về rebase.

Đổi action của các commit cần squash

Tiếp tục squash:

  • Nhấn i để có thể edit content
  • Trừ commit trên cùng, sửa command của 3 commit sau từ pick thành squash

Chú ý: Ở màn hình này bạn cần đặc biệt cẩn thận với việc edit thông tin. Squash luôn là gộp với commit trước đó nên commit đầu tiên không thể là squash. VD như màn hình trên thì 3 commit sau sẽ được gộp vào commit đầu tiên và tạo ra 1 commit mới. Đừng xóa bất cứ dòng nào không phải commit #. Nếu bạn xóa 1 dòng thì commit tại dòng đó sẽ bị mất.

  • Nhấn Esc để thoải khỏi INSERT mode
  • :wq để write nội dung và quit ra khỏi VIM editor

Cập nhật commit message của commit mới (commit sau khi gộp)

Bạn tiếp tục được chuyển tới một màn hình VIM editor mới. Nhiệm vụ lần này là để update commit message cho commit mới - là kết quả gộp của 4 commit trước đó. Git đơn giản tổng hợp lại 4 commit message trước đó để bạn có thể chọn hoặc sửa để thay thế mới.

  • Xóa bớt và chỉ giữ lại những gì bạn thấy cần.
  • Comment có thể bỏ qua vì sẽ không được đưa vào commit message thực tế
  • :wq để write và quit

Kết quả trên command line sẽ là:

Sau khi squash commit

Lịch sử git mới mà bạn nhận được sẽ là:

Có thể thấy commit được gộp lại là commit mới hoàn toàn vì có hash khác. Trong trường hợp bạn muốn undo việc squash, chỉ cần kiểm tra với git reflog:

Ở bên trái bạn sẽ thấy các commit hash id cũ. Để undo bạn chỉ cần copy hash id của commit cuối cùng (trong 4 commit được gộp là 71e40e0) sau đó nhập vào terminal: $ git reset --hard 71e40e0 Kiểm tra lịch sử, mọi thứ như chưa từng xảy ra. Tuyệt cmn vời!

Bonus

Sau thời điểm reset bạn có muốn thử kiểm tra git reflog xem điều gì đã xảy ra không? Magic... :))

· Một phút để đọc
ManhPT

Giới thiệu Gitlab và Gitlab Flow

Gitlab là một công cụ rất hay và có self-hosted (on-premise) plan cho phép bất cứ ai, công ty hay tổ chức nào cũng có thể cài đặt một Git Platform của riêng mình.

  • Một điểm cộng của Gitlab đó là tính năng Gitlab Board, giúp bạn tổ chức và sắp xếp các issue thành các board giống như Trello, khá tiện lợi cho việc quản lý theo quy trình (VD: Agile).
  • Gitlab còn cho phép bạn tạo các Merge Request (Pull Request, theo cách nói của Github) dựa trên các issue đã có, đồng thời tạo luôn cả source branch giúp bạn.
  • Bên cạnh đó, Gitlab cung cấp Gitlab CI cho phép bạn apply CI/CD vào bất cứ project nào. Với tôi thì đây là một tính năng không thể thiếu khi lựa chọn một công cụ devops.

Trước khi bắt đầu thực hành hoặc đọc tiếp, bạn nên tạo một repo trống để thử nghiệm.

Tại sao cần Gitlab Flow

Thực tế, gitlab flow hay git workflow không phải một khái niệm mới. Do git không hề dễ học cho người mới nên các workflow của nó thường bị bỏ qua, ngoài ra các nhà cung cấp công cụ devops cũng thường đưa ra những git workflow riêng để phù hợp với luồng devops trên công cụ của họ. Bạn có thể tham khảo thêm:

Bắt đầu tạo một issue

Vào Issues > List và chọn New issue. Hoặc bạn có thể chọn Import CSV để import list task có sẵn từ các nguồn khác như Jira, Redmine...

Click New issue như hình minh họa bên dưới.

Điền đầy đủ thông tin tùy theo yêu cầu từng team sau đó Submit issue.

Tạo merge request từ issue

Sau khi đã có issue, ta có thể tạo merge request từ issue đó rất nhanh chỉ cần click Create merge request.

Bạn có thể tạo bao nhiêu merge request tùy ý nhưng thường chỉ nên tạo 1 merge request cho mỗi 1 issue.

Branch đã được tạo sẵn

Sau khi tạo merge request thì Gitlab cũng tạo luôn branch cho bạn.

Sau đó chọn copy câu lệnh checkout mà Gitlab cung cấp sẵn, paste vào terminal/shell của bạn (sau khi đã clone repo) để bắt đầu code.

Đây là các step đơn giản đầu tiên để làm việc với Gitlab Flow. Mọi task như tạo feature mới, fix bug, refactor... đều cần được quy hoạch về step cơ bản này.

· Một phút để đọc
ManhPT

Vấn đề là...

Không ít lần project có cấu hình eslint gặp lỗi Expected linebreaks to be 'LF' but found 'CRLF'. Lỗi này thực sự dẫn đến sự bế tắc khi lần đầu gặp phải. Tại sao lập trình trên windows cứ hay gặp mấy vấn đề dễ gây bối rối như vậy? Shit… chê tí thôi chứ dùng MacOS hay Linux thì đừng mơ chơi đc PUBG Mobile giả lập.

git config --global core.autocrlf false
git config --global core.eol lf

Gõ 2 dòng lệnh trên vào bất cứ CLI tool nào bạn có (powershell, cmd, terminal…). Done!

Giải ngố 1 chút

  • core.autocrlf là để tự động sử dụng CRLF cho các file mới được tạo hoặc sau khi git add
  • core.eol là để set mặc định kiểu xuống dòng cho Git
  • --global thì bạn sẽ setup cấu hình Git trên toàn hệ thống
  • Còn nếu muốn apply setting đặc dị này cho từng project thì có thể dùng file .gitattributes

Tham khảo

  1. https://help.github.com/en/articles/dealing-with-line-endings
  2. https://stackoverflow.com/questions/37826449/expected-linebreaks-to-be-lf-but-found-crlf-linebreak-style
  3. https://stackoverflow.com/questions/1552749/difference-between-cr-lf-lf-and-cr-line-break-types