Published on
-
7 mins read

Vài notes khi làm việc với git

Authors
  • avatar
    Name
    Tuan Anh Huynh (Leo)
    Twitter
    @hta218
Photo by Yancy Min on Unsplash
git-notes

Post này dành cho anh em thích làm việc với git qua command-line giống mình nhé

Git alias

Git aliases are a powerful workflow tool that create shortcuts to frequently used Git commands

git alias hiểu đơn giản là tạo shortcut (command ngắn hơn) cho những command dài để gõ cho nhanh

Syntax

$ git config --global alias.<shortcut> <original-command>

Chú ý flag --global để sử dụng ở tất cả project, nếu không thì alias sẽ chỉ work trên project hiện tại bạn đang làm việc cùng thôi nhé!

Sử dụng quotes (dấu nháy '' nếu original-command có chứa space (dấu cách))

Mình alias hầu hết các command mà mình thường xuyên làm việc

  • Git status

    Kiểm tra những thay đổi trước khi commit

    $ git config --global alias.st status
    # Now instead of `git status`, use `git st`
    $ git st
    On branch v2
    Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git restore <file>..." to discard changes in working directory)
    modified: components/Twemoji.js
    modified: css/tailwind.css
    modified: data/blog/git-notes.mdx
    no changes added to commit (use "git add" and/or "git commit -a")

    Tip: dùng git st với flag --short hay -s để xem short-format của những thay đổi và alias luôn command này

    $ git config --global alias.s 'status --short'
    # Now instead of `git st`, use `git s`
    $ git s
    M components/Image.js
    M data/blog/git-notes.mdx
    ?? public/static/images/force-with-lease.jpg

    Dễ xem hơn hẳn đúng không

  • Git commit

    $ git config --global alias.cm 'commit -m'

    Commit changes (chú ý add/stage changes trước)

    $ git cm "Initial commit"

    Tip: nếu chỉ sửa các file có sẵn mà không thêm mới hoặc xóa file thì có thể dùng flag --all hoặc -a để không phải add/stage changes trước khi commit

    $ git config --global alias.cam 'commit -am'
    # Now instead of 2 git commands
    $ git add style.css # `style.css` is already existed, not new file!
    $ git cm "Update style"
    # Use only 1 command
    $ git cam "Update style"
  • Git stash

    Stash the changes in a dirty working directory away

    Đúng như định nghĩa, dùng git stash khi muốn cất những thay đổi đi, trước khi pull code mới về

    # Ngắn quá rồi nên không cần `alias` nữa
    $ git stash

    Apply những thay đổi vừa cất sau khi pull

    $ git stash pop

    Alias command này

    $ git config --global alias.sp 'stash pop'
    # Now
    $ git sp
    # Is equal
    $ git stash pop
  • Git pull/push

    Luôn pull rebaseforce push để có 1 clean commit tree nhé anh em

    • pull rebase

      $ git config --global alias.prb 'pull origin --rebase'
      # Now
      $ git pull origin --rebase main
      # Is equal
      $ git prb main
      # Or
      $ git prb master
    • Nếu có conflict sau khi rebase ?

      • List toàn bộ các file conflict với git diff và alias command này

        $ git config --global alias.cf 'diff --name-only --diff-filter=U'
        # Now to list all conflict files use
        $ git cf
        # Reolve all conflict then stage changes
        $ git add .
        # Finish rebase with
        $ git rebase --continue
    • force push

      Vì sử dụng pull rebase nên sau khi resolve hết conflict (nếu có) thì chúng ta cần force push để đẩy thay đổi lên remote repo

      $ git config --global alias.pf 'push --force-with-lease'
      # Now after rebase
      $ git pf

      Tại sao không sử dụng --force?

      TL;DR

      force push sẽ overwrite remote repo với những thay đổi ở local mà không quan tâm đến những update có thể có sau khi bạn rebase, hành động này nguy hiểm khi 2 dev cùng làm việc trên 1 branch.
      --force-with-lease ngược lại, đảm bảo việc không có update upstream thì mới có thể force push

      force-with-lease
  • Git checkout

    $ git config --global alias.co 'checkout'
    # Eg
    $ git co main

    Tạo branch mới

    $ git config --global alias.cob 'checkout -b'
    # Eg
    $ git cob feature-x

    Tip: để quay lại nhánh cũ bạn có thể dùng git co -

    Ví dụ

    $ git branch
    dev
    * feature-x-y-z__ISSUE_ID
    main
    # The current branch is `feature-x-y-z__ISSUE_ID`
    # Checkout to `dev`
    $ git co dev
    # Do something
    # Commit ...
    # Now to come back to `feature-x-y-z__ISSUE_ID` use
    $ git co -
    # Instead of
    $ git checkout feature-x-y-z__ISSUE_ID
  • Git diff

    Kiểm tra sự thay đổi của file trước khi commit (mình thường dùng để remove những đoạn debug, hardcode, console.log ... quên chưa xóa)

    $ git config --global alias.d 'diff'
    # Eg
    $ git d style.css

Note

Tất cả alias vừa tạo đều có trong file ~/.gitconfig (MacOS). Bạn có thể mở thẳng file này và thêm/sửa/xóa bất kì alias nào

$ vim ~/.gitconfig
[alias]
s = status --short
st = status
cm = commit -m
# ...

Điều kiện bắt buộc: biết sử dụng vim

vim-meme

Git workflow

Workflow làm việc với git hằng ngày của mình (alias được giải thích hết ở trên)

# Stash changes
$ git stash
# Update changes from upstream
$ git prb main
# Apply stash changes
$ git sp
# Resolve conflict if existed
# Work
# Check working status
$ git s
# Check file changes (if needed)
$ git d # or git d file.ext
# Stage changes
$ git add .
# Commit
$ git cm "commit message"
# Or skip stage changes if no new file created/deleted
$ git cam "commit message"
# Update changes again
$ git prb main
# If there're conflicts, resolve all then
$ git add file.ext
$ git rebase --continue
# Force push
$ git pf
# Making pull request

Đây là flow hoản chỉnh nhưng chỉ các dòng được hightlight là thường xuyên sử dụng nhất thôi nhé

.gitignore.gitkeep

  • .gitignore

    Khái niệm mình không nhắc lại vì quá phổ biến rồi. Template chỉ việc lấy về xài xem ở repo này

    Tip: ignore tất cả file trong 1 directory chỉ giữ lại 1 file

    # Ignore all file in a directory
    homework/*
    # Keep only this file
    !homework/file-to-keep
  • .gitkeep

    Làm thế nào để đẩy 1 folder trống lên remote repo?

    Tạo 1 file .gitkeep đặt trong folder (trống) để đẩy folder đó lên remote repo

    Đây không phải là 1 feature của git! Chỉ là 1 convention của 1 ông dev nào đó nghĩ ra thôi nhé

    Giải thích: bản chất là làm cho folder không trống nữa (đã có file bên trong) nên sẽ có thể commit lên upstream, suy ra .gitkeep có thể là bất kì file nào bạn nghĩ ra (có hoặc không có nội dung đều được). Chọn .gitkeep vì nó dễ hiểu và dễ nhớ.

Kết bài

Trên đây là toàn bộ những note của mình về git, các bạn chia sẻ thêm use cases của mình ở dưới comment nhé!

Refs