avral
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Giới thiệu về Git. #### 0. Master branch Mặc định, các project được create trên git sẽ có một branch tên là **master** (protected branch). Protected branch được sinh ra để đảm bảo branch được an toàn và buộc các developer phải dùng merge requests để apply change, thường thì các branch được protect sẽ là các branch chứa source code để deploy lên môi trường thật, các nhánh có vai trò quan trọng (development). Do đó nên, protected branch có các đặc điểm sau: - Chỉ có user với quyền *Master* mới được tạo branch được protected - Chống push commit (trừ user với quyền *Master*) - Chống *tất cả mọi người* force push (không thay đổi history của các commit trước) - Chống *tất cả mọi người* xóa branch Thêm thông tin về [protected branch](http://172.16.20.9/help/user/project/protected_branches). ## 1. Commit change *TODO: Ảnh Local Operation.* Khi muốn thực hiện một commit lên local repo, hãy dùng các command sau: ``` # List những thay đổi > git status # Stagged changes > git add changed_file_1.cc > git add changed_file_2.cc # Nếu có file mà đã được stagged, tuy nhiên mình không muốn commit nữa, thì thực hiện discard. > git checkout changed_file_1.cc # Hoặc muốn reset working directory về một trạng thái ở commit nào đấy. > git reset --hard HEAD > git reset --hard HEAD~5 > git reset --hard 7b5cab5 > git reset 7b5cab5 # Commit to local repository. > git commit -m "Add code for feature 1" ``` Thi thoảng, mình đang code mà đến giờ về, và mình muốn commit lên local để cho chắc chắn. Sang hôm sau, mình lại code tiếp, vẫn content đấy và mình muốn commit thêm vào commit ngày hôm qua. Lúc này mình sẽ sử dụng tham số *--amend* của câu lệnh commit. ``` > git add changed_file_3.cc > git commit --amend # Ngoài ra có thể amend để thay đổi nội dung của message commit, author, email. > git commit --amend --author=="Author Name <email@address.com>" ``` **Note:** - Mỗi commit chỉ nên chứa change cho một tác vụ nhất định, không nên gộp 2 hoặc nhiều tác vụ vào một commit, vì sẽ rất khó để theo dõi cũng như sửa xóa sau này. Ex: Đầu tiên mình có một commit `Fix bug A, B`. Tuy nhiên sau đó, mình quyết định A không phải là bug nữa mà là tính năng, làm sao để bỏ changed ra khỏi commit? Vì thế nên mình nên tách ra thành 2 commit `Fix bug A` và `Fix bug B`. Khi không muốn sử dụng A nữa thì chỉ cần dùng `git revert` là xong. - Commit message nên mô tả được nội dung có thể hiểu được, đặc biệt cần tránh kiểu các message sau `small fix`, `minor fix`, `fix 1`, `fix 2`, `add changed_file.cc`, etc. Nếu commit message dài quá, mình có thể break xuống dòng, trên git sẽ hiển thị phần additional của message trong dấu `...` - Không commit **generated file** lên git để tránh việc nặng server và clone lâu không cần thiết. **Generated file** bao gồm: execution file, cmake file, node_modules, draft file, các file format như .vscode, etc. Có thể sử dụng `git ignore` để làm việc này một cách tự động. **Refer mục 9.** Nên có description để hướng dẫn build hoặc các lệnh cơ bản để chạy chương trình như: ``` > make > cmake > npm install ``` Trong trường hợp cần các thao tác phức tạp hơn để build hay để setup môi trường develop trên máy local, hãy cố gắng viết script (*bash* or *python*). ## 2. Tạo/xóa branch Idea là mỗi branch sẽ thực hiện develop cho một feature, một screen, hay cũng có thể là một hotfix. Mỗi người có thể thực hiện develop trên một branch khác nhau rồi sau đó merge vào branch chính, không nên để nhiều người develop trên cùng một branch, vì tránh conflict và khó quản lý. Để tạo branch: ``` > git branch feature_1 > git checkout feature_1 # Chuyển sang branch 'feature_1' # Hoặc có thể dùng lệnh sau: > git checkout -b feature_1 # Tạo và chuyển sang branch feature_1 ``` Để xóa branch: ``` # Xóa branch ở local > git branch -d feature_1 > git branch -D feature_1 # Xóa remote branch > git push origin --delete feature_1 > git push origin :feature_1 ``` ## 3. Check log, diff của các commit Các lệnh để check log và commit: ``` # Show log > git log > git log --oneline # Show change của commit: git show (COMMIT) > git show HEAD > git show HEAD~5 > git show 7b5cab5 # Show diff từ commit này đến commit kia: git diff (COMMIT_1) (COMMIT_2) > git diff HEAD~2 HEAD > git diff HEAD~2 HEAD ./test.cpp # Compare limit with file test.cpp > git diff HEAD~2 # Compare working directory với commit HEAD~2 # Compare 2 branches > git diff topic master > git diff topic..master ``` **Recommendation:** - Trước khi tạo merge request, bản thân developer nên review code của mình trước (bằng cách dùng lệnh diff hoặc dùng trực tiếp gitlab web) để tránh việc commit thừa, hoặc sửa những phần không cần thiết, code test, comment, etc. - Về nguyên tắc, không chỉ người có quyền master mới có quyền review, mà bất cứ ai cũng có thể review code nếu muốn. Khi tạo merge request, nếu có thể, nên invite developer khác vào review. Hoặc ít nhất tự mình review. - Để review, có thể dùng công cụ review sẵn có của gitlab. ## 4. Merge code Để merge code từ branch phụ sang branch chính (ex: `feature_1` -> `master`), thực hiện theo các bước sau: - Khi merge code từ feature, phải đảm bảo branch feature được update theo latest commit của branch master. A -> B -> C -> D master | - -> E -> F feature_1 Thì trước khi merge, phải update commit C, D vào branch `feature_1`, tất nhiên vị trí phải là trước commit E, F A -> B -> C -> D master | - -> E -> F feature_1 Sử dụng các câu lệnh sau: ``` # Update master để đảm bảo đây là latest code trên branch master > git checkout master > git pull # Chuyển sang branch feature_1 > git checkout feature_1 # Rebase (Đẩy các commit mới của branch) master với (xuống dưới các commit của branch) feature_1 > git rebase master # Push change lên remote repo > git push origin feature_1 ``` - Tạo merge request, và review nếu cần. Với những branch được tạo ra phục vụ việc hotfix, hay fix bug trong khi test, thì không cần phải tạo merge request mà có thể merge trực tiếp vào branch chính. Tuy nhiên với những update kiểu như feature, tính năng mới, thì nên tạo merge request và review cẩn thận. Thêm nữa, sau này nếu trong trường hợp muốn gỡ feature ra khỏi product thì chỉ cần `revert merge commit` là được. Để tạo merge request, vào `Repository` chọn branch `feature_1`, click `Create merge request` button, và làm theo hướng dẫn của Gitlab. - Review - Tiến hành rebase thêm lần nữa trước khi Accept merge request (trong trường hợp có thêm commit mới trên `master` trong thời gian review code). - Accept merge request. Có thể accept merge request bằng Gitlab web. Ngoài ra mình có thể merge thông qua command line như sau: ``` # Chuyển về branch master > git checkout master # Merge > git merge --no-ff feature_1 # No fast forward (recommend) > git merge feature_1 # Fast forward (not recommend) # Push update lên remote > git push origin master ``` **Note:** - Tham khảo thêm về `merge` và `rebase`: - [https://backlog.com/git-tutorial/vn/stepup/stepup1_4.html](https://backlog.com/git-tutorial/vn/stepup/stepup1_4.html) - [Why we should use --no-ff instead of --ff?](http://dev.bizo.com/2014/02/why-we-chose-not-to-git-fast-forward-merge.html) ## 5. Squash các commit trước khi merge Khi commit, mình nên commit theo các function, screen lớn, chứ không nên commit kiểu tủn mủn -> khó quản lý. Tuy nhiên, trong quá trình làm việc, mình có thể bị break bởi các task khác nhau và phải commit nhiều commit cho một function, như ví dụ sau: ``` > git log --oneline c21a5b4 (HEAD -> feature_1) Working on feature_1 end f48b837 Working on feature_1 day 2 801c650 Working on feature_1 day 1 2f4594c (origin/master) Fix bug A ``` Khi đó mình nên thực hiện thao tác squash 3 commit `c21a5b4`, `f48b837` và `801c650` lại với nhau trước khi push lên remote. Sử dụng lệnh sau: ``` > git rebase -i HEAD~2 pick c21a5b4 Working on feature_1 end pick f48b837 Working on feature_1 day 2 pick 801c650 Working on feature_1 day 1 # Rebase 801c650..c21a5b4 onto d286baa # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # ``` Sau khi edit và show log mình sẽ được kết quả như sau: ``` > git log --oneline d286baa (HEAD -> features_1) Implement feature 1 2f4594c (origin/master) Fix bug A ``` ## 6. Không được thay đổi history trên `master`, làm thế nào để bỏ một commit? Vì `master` là protected branch, nên mình không được phép `force push` (thay đổi history) trên `master`. Tuy nhiên trong một số trường hợp, mình muốn bỏ một commit thì hãy sử dụng `revert`. ``` > git log --oneline d286baa (HEAD -> master) Implement feature 1 51612a4 Fix bug A 5049f9f Update config file for notify error to Chatwork 97alos2 Correct interface between api and bpex_core # Mình muốn revert commit `Update config file for notify error to Chatwork` > git revert 5049f9f > git log --oneline f48b837 (HEAD -> master) Revert commit 5049f9f d286baa Implement feature 1 51612a4 Fix bug A 5049f9f Update config file for notify error to Chatwork 97alos2 Correct interface between api and bpex_core ``` ## 7. git stash Thi thoảng, khi đang làm việc trên một project, bạn muốn switch sang một branch khác để thực hiện một minor change. Tuy nhiên, vấn đề là bạn không muốn thực hiện commit vì minor change chỉ mất khoảng 20', sau đó bạn sẽ quay lại đây để thực hiện tiếp công việc. Trong trường hợp này hãy sử dụng `git stash`. ``` > git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: index.html # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # # modified: lib/simplegit.rb # > git stash Saved working directory and index state \ "WIP on master: 049d078 added the index file" HEAD is now at 049d078 added the index file (To restore them type "git stash apply") > git status # On branch master nothing to commit, working directory clean # Ngoài ra có thể thêm message để mô tả stash > git stash save “Your stash message”. ``` Để xem tất cả các stash được lưu trong stack ``` > git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size" stash@{2}: WIP on master: 21d80a5 added number to log ``` Lấy data ở trong stack đổ ra working directory. ``` # Lấy stash@{0} > git stash apply # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # # modified: index.html # modified: lib/simplegit.rb # # Nếu muốn apply stash@{2} > git stash apply stash@{2} # Drop stash ref ra khỏi stack > git stash drop stash@{2} # Pop = Apply + Drop > git stash pop stash@{2} ``` Show content của một stash ``` > git stash show stash@{0} ``` Clear all stash in repo. Becareful! It's impossilbe to revert. ``` > git stash clear ``` ## 8. git cherry-pick Lệnh này chỉ đơn giản là pick một commit apply vào current branch ``` # git cherry-pick (COMMIT) > git cherry-pick 51612a4 ``` ## 8. gitignore Để giải quyết vấn đề không commit generated file, git đã cung cấp cho ta công cụ `gitignore`. Khi add một file mới vào git, git sẽ kiểm tra nếu file nằm trong file `.gitignore` thì nó sẽ lờ file đấy đi. Chú ý là file phải không được cache nữa (git sẽ cache tất cả các file trong working directory để check change). Các pattern thường dùng: - Sử dụng `#` để comment và có thể cách dòng. - Khi ignore thư mục nên có ký tự `/` ở sau tên thư mục để phân biệt thư mục với file, symbolic link. - Dấu `!` nghĩa là phủ định: !folder_name/example.exe - Dấu `*` như trong linux: **.xml* nghĩa là tất cả các file có đuôi xml. - Dấu `**` để dùng trong trường hợp thư mục không cần định rõ tên: ***/foo.xml* nó chỉ có hiệu lực cho tất cả các file foo.xml ở tất cả mọi nơi trong working directory. Câu lệnh: ``` # Tạo file .gitignore ở root của working directory > touch .gitignore # Sample .gitignore file cho C++ project # # Prerequisites # *.d # # Compiled Object files # *.slo # *.lo # *.o # *.obj # # # Precompiled Headers # *.gch # *.pch # # # Compiled Dynamic libraries # *.so # *.dylib # *.dll # # # Fortran module files # *.mod # *.smod # # # Compiled Static libraries # *.lai # *.la # *.a # *.lib # # # Executables # *.exe # *.out # *.app # Remove cache đã được lưu từ trước > git rm -r --cached . ``` **Note:** Phạm vi ảnh hưởng của `gitignore` File .gitignore sẽ ảnh hưởng đến các file và thư mục anh em với nó hoặc là con cháu, chắt của nó. Thường thì project chỉ cần 1 file .gitignore ở ngoài cùng là đủ nhưng nếu project quá lớn ta có thể tách file .gitignore vào từng folder nhỏ để dễ quản lý.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully