
Git là phần mềm dùng để quản lý và kiểm tra các phiên bản khác nhau trong quá trình phát triển mã nguồn. Tôi thường sử dụng Git để quản lý code cũng như để hoàn thành luận văn gần đây của mình. Trong bài viết này, tôi xin tổng hợp lại ghi chú các thao tác lệnh thường dùng trong Git.
Cơ chế của Git

- repository (nơi lưu thông tin quá khứ/cuối cùng của dự án, commit từ staging index).
- staging index (nơi lưu tạm dữ liệu trước khi commit).
- working directory (nơi lưu thông tin làm việc hiện hành)
- Con trỏ HEAD luôn trỏ vào thời điểm cuối cùng của nhánh hiện hành.
Quy trình làm việc nhóm với Git
# My work git checkout master git fetch git merge origin/master git checkout -b feedback_form git add feedback.html git commit -m "Add customer feedback form" git fetch git push-u origin feedback_form # Coworker git checkout master git fetch git merge origin/master git checkout -b feedback_form origin/feedback_form git log git show 8284abdq9 git commit -am "Add tour selector to feedback form" git fetch git push # My work git fetch git log -p feedback_form..origin/feedback_form git merge origin/feedback_form git checkout master git fetch git merge origin/master git merge feedback_form git push
Ta có thể thấy quy trình làm việc này khá công phu, nhưng theo thời gian ta sẽ hình thành được thói quen và cách làm việc nhóm hiệu quả hơn nhờ Git. Những thao tác này sẽ được trình bày với các nội dung bên dưới.
Thao tác commit
Sau mỗi lần thay đổi nội dung của file, ta thực hiện các lệnh sau
# đưa các file bị thay đổi vào staging index git add . # lưu vào repository kèm theo thông tin ghi chú git commit -m "Initial commit" # add và commit cùng lúc git commit -am "Initial commit" # thay đổi nội dung ghi chú hoặc ghi đè lên commit # gần nhất git commit --ammend "Ammend the commit"
Kinh nghiệm viết thông tin ghi chú
- Một dòng mô tả rõ ràng và ngắn gọn, khoảng 50 kí tự đổ xuống.
- Viết nội dung ở thì hiện tại, không phải ở thì quá khứ. (e.g. fix bug, fixes bug, not fixed bug)
- Có thể sử dụng tiếp đầu ngữ để quản lý (e.g. [css, js], bugfix:, #38405-)
Quan sát
Quan sát commit log
# liệt kê danh sách commit git log # liệt kê 2 commit gần nhất git log -n 2 git log -2 # liệt kê theo thời gian "kể từ" git log --since=2015-12-01 # liệt kê theo thời gian "tới khi" git log --until=2015-12-01 # liệt kê theo người commit git log --author="ongxuanhong" # tìm theo regular expression git log --grep="Init" # liệt kê theo định dạng một dòng đơn giản git log --oneline # liệt kê trong khoảng hai thời điểm git log 29910a..92ad92 # liệt kê trong khoảng đối với file xác định git log 09ua199.. index.html # liệt kê theo dạng đồ thị git log --oneline --graph --all --decorate # hiển thị nội dung commit git show # hiển thị nội dung remote branch origin/master git log --oneline origin/master

Quan sát những thay đổi
# so sánh sai biệt giữa working directory và repository git diff # so sánh sai biệt giữa staging index và repository git diff --staged # xem những thay đổi của một file xác định git diff first_file.txt # so sánh sai biệt giữa một thời điểm commit trong # quá khứ với repository git diff 9a98bc98 # xem những thay đổi của một file xác định tại một # thời điểm commit bất kì git diff 9a98bc98 first_file.txt # rút gọn hiển thị những thay đổi git diff --color-words first_file.txt # so sánh sai biệt giữa hai commit bất kì git diff 9a98bc98..1737vb8a72 # thống kê những thay đổi từ thời điểm bất kì trong # quá khứ cho đến thời điểm hiện tại git diff --stat --summary d54cf21..HEAD # so sánh hai branch git diff master..new_branch # so sánh branch new_feature với commit trước đó # của shorten_title branch git diff --color-words new_feature..shorten_title^ # so sánh local branch với tracking branch origin/master git diff master..origin/master
Thao tác với file
Loại bỏ deleted/untracking file
# xác nhận loại bỏ một file đã delete git rm file_to_delete1.txt # xác nhận loại bỏ một loạt file đã delete git ls-files --deleted -z | xargs -0 git rm # loại bỏ một file untrack git clean -f trunk_1.txt
Di chuyển hoặc đổi tên file
# đổi tên file git mv first_file.txt primary_file.txt # di chuyển và đổi tên file cùng lúc git mv second_file.txt source/secondary_file.txt
Git reset
Độ sâu sự can thiệp của Git reset bắt đầu từ repository
- soft: không thay đổi staging index và working directory
- mixed (default): thay đổi staging index khớp với repostitory nhưng không thay đổi working directory
- hard: thay đổi staging index và working directory khớp với repository
# quan sát SHA index mà HEAD đang trỏ vào cat .git/refs/heads/master # di chuyển con trỏ của repository đến một thời điểm # trong quá khứ git reset --soft da9u0388787
Undo những thay đổi
# mới thay đổi ở working directory, chưa add vào staging index, # ta checkout nội dung quá khứ từ repository về working # directory để undo những thay đổi. git checkout -- index.html # unstaged những thay đổi: đưa staging index về với trạng thái # quá khứ của repository git reset HEAD resources.html # truy vấn phiên bản tại một thời điểm commit trong quá khứ git checkout 83872763a776 -- resources.html # quay lại phiên bản trong quá khứ, đồng thời thực hiện # một commit mới kèm theo ghi chú git revert 83872763a776
Git ignore
Những file thường không cần track
- Compiled source code
- Packages và compressed files
- Logs và databases
- Những file phát sinh từ hệ điều hành
- User uploaded assets (images, PDFs, videos)
Branch

- Dùng để thử ý tưởng mới
- Cô lập tính năng mới với tính năng chính
- Linh hoạt chuyển đổi giữa các tính năng
- Chỉ dùng một working directory nhưng có thể lưu được nhiều pha làm việc cùng lúc.
Xem và tạo lập branch
# liệt kê danh sách các branch git branch # xem con trỏ HEAD đang ở branch nào cat .git/HEAD # xem có bao nhiêu branch trong head cat .git/refs/heads/ # head đang trỏ đến commit nào cat .git/refs/heads/master # tạo lập branch mới git branch new_branch
Switching
Để chuyển đổi qua lại giữa các branch, mọi thay đổi trong working directory phải được commit hoặc có thể tồn tại một số file untrack.
# chuyển qua branch new_branch git checkout new_branch # vừa tạo vừa chuyển qua new_branch cùng lúc git checkout -b new_branch
Trường hợp chuyển đổi nhưng bị vướng uncommit
# cách 1: undo những thay đổi git checkout -- index.html # cách 2: commit các thay đổi còn tồn tại git commit -am "Commit changes" # cách 3: lưu tạm vào stash (nơi lưu trữ bí mật) git stash save "changed mission page title"
Làm việc với stash
# hiển thị danh sách stash đã lưu git stash list # quan sát nội dung của stash cụ thể, index bắt đầu từ 0 git stash show stash@{0} # patch option: tương tự như show commit git stash show -p stash@{0} # lấy stash ra và đưa vào working directory # pop: xóa luôn khỏi thư mục stash # apply: chỉ copy từ thư mục stash git stash pop/apply stash@{0} # xóa stash git stash drop stash@{0} # xóa tất cả stash git stash clear
Thay đổi branch
# Đổi tên branch git branch -m/--move new_feature seo_title # Phải switch qua branch khác trước khi xoá. # Ta không thể xóa branch hiện hành. Tương tự như việc # chương trình đang đọc file thì chương trình khác không # được xóa. git branch -d/--delete branch_to_delete # Nếu branch muốn xóa không chứa nội dung nào, # thì ta chỉ cần tham số -d để xóa. Ngược lại, ta phải merge # nội dung trước khi xoá hoặc ta có thể dùng tham số -D # để chấp nhận xóa hoàn toàn git branch -D branch_to_delete
Thay đổi dấu nhắc lệnh của command line để quan sát branch hiện hành
# mở file .bashrc, sau đó thêm dòng lênh export PS1='\W$(__git_ps1 "(%s)") > ' # nạp lại .bashrc để thấy kết quả source .bashrc # kết quả thu được testing(new_branch) >
Merge branch
Fast-forward merge: di chuyển nội dung commit từ new_branch đưa trực tiếp lên timeline của master sau đó di chuyển con trỏ HEAD vào vị trí mới. Phương thức này không cần tạo commit mới.
Real merge: merge nội dung hai branch có nội dung khác nhau kèm theo một commit mới.
# chuyển qua branch chính (có thể branch khác ngoài master) git checkout master # merge branch git merge revise_navigation # ép Git không sử dụng fast-forward mà phải tạo một commit mới git merge --no-ff revise_navigation # nếu fast-forward được thì làm, không được thì thôi git merge --ff-only revise_navigation
Giải quyết merge conflict

Merge conflict xảy ra khi nội dung trên cùng một file có nhiều hơn một sự thay đổi diễn ra cùng lúc. Lúc này, Git sẽ không biết nên chọn nội dung nào để làm nội dung lưu lại cuối cùng.
Khi merge conflict, bên trong nội dung file bị conflict sẽ có các dòng đánh dấu như bên dưới
<<<<<<<<<< HEAD some content A ====== some content B >>>>>>>>>> text_edits
Lúc này ta có 3 cách giải quyết
# 1) không merge nữa git merge --abort # 2) lựa chọn và chỉnh sửa nội dung, sau đó commit. # default message của merge sẽ hiện ra git add . git commit # 3) sử dụng merge tool git mergetool 'git mergetool' will now attempt to use one of the following tools: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare emerge vimdiff # sau khi merge, ta có thể quan sát branch hiện hành # đã merge với những branch nào git branch --merged
Để hạn chế merge conflict
- chỉ nên thay đổi một vài dòng
- chỉ nên thay đổi trên một file
- chú ý các thay đổi như space, tab, line return
- thường xuyên merge (thay vì đợi conflict 50 file, ta hạn chế conflict còn 2-3 file).
Git remote
Git remote dùng để chia sẻ source code cho các thành viên trong nhóm cùng làm việc. Ba bước cơ bản thường dùng để thao tác với remote gồm push (upload source code), fetch (download source code), merge (đồng bộ hóa dữ liệu server và local). Trong đó, con trỏ orgin/master cũng chỉ là một branch để tracking luân phiên server và local.



Sau khi tạo một tài khoản trên Github hoặc Bitbucket ta có thể tiến hành tracking remote server.
Thêm/Xóa một remote
# liệt kê danh sách remote đang tracking (tương tự git branch # liệt kê danh sách các branch) git remote # liệt kê chi tiết thông tin fetch/push git remote -v # thêm một remote git remote add <alias> <url> git remote add origin https://github.com/username/project.git # nơi lưu thông tin remote cat .git/config # xóa một remote git remote rm origin
Tạo remote branch
# -u: upstream. pushing branch master lên remote origin git push -u origin master # nơi lưu thông tin origin/master cat .git/refs/remotes/origin/master # xem danh sách remote branch git branch -r # xem danh sách cả remote và local branch git branch -a # download thành một thư mục mới git clone https://github.com/username/project.git new_folder
Tracking remote branch
# cách 1: chỉnh config file git config branch.non_tracking.merge refs/heads/master git config branch.non_tracking.remote origin # cách 2: dùng --set-upstream (Git > 1.7) git branch --set-upstream non_tracking origin/master
Pushing > Fetching > Merging
# upload master branch lên remote origin git push origin master # full version (local_branch:remote_branch) git push origin master:master # phiên bản rút gọn: vì ta đang tracking origin # trên master branch git push # download source từ remote origin git fetch origin # phiên bản rút gọn: vì ta đang tracking origin # vài điểm lưu ý: fetch trước khi làm việc, fetch # trước khi push, fetch thường xuyên git fetch # đồng bộ local và remote git merge origin/master # pull thay thế hai bước fetch và merge, chỉ sử dụng # khi nắm vững hai cơ chế trên git pull
Checkout/Delete remote branch
Khi thư mục local chưa có branch trên remote, ta có thể checkout như sau
# checkout remote branch git branch non_tracking origin/non_tracking # cách khác: vừa tạo branch vừa switch branch git checkout -b non_tracking origin/non_tracking # delete branch trên remote server # (local vẫn còn non_tracking branch) # cơ chế: do không có branch nào được push # nên trên server tự động delete remote branch git push origin :non_tracking # cách khác: sử dụng --delete # non_tracking trên server và local đều được delete git push origin --delete non_tracking
Một số cách thiết lập alias (shortcut) cho những command hay sử dụng
git config --global alias.st status git config --global alias.co checkout git config --global alias.ci commit git config --global alias.br branch git config --global alias.df diff git config --global alias.dfs "diff --staged" git config --global alias.logg "log --graph --oneline --decorate --abbrev-commit --all"
Lần đầu tạo repository
Thiết lập thông số lần đầu làm việc
git config --global user.name "Hong Ong" git config --global user.email "my_email@email.com"
Thiết lập repository
Trường hợp chỉ muốn clone repository
git clone ssh://git@github.com:1234/abc/my_project.git
Trường hợp đã có sẵn source code và muốn upload lên repository
cd existing-project git init git add --all git commit -m "Initial Commit" git remote add origin ssh://git@github.com:1234/abc/my_project.git git push origin master
Trường hợp Git đã track source của bạn trong quá trình làm việc tại local
cd existing-project git remote set-url origin ssh://git@github.com:1234/abc/my_project.git git push origin master
Reblogged this on matnotes.
ThíchThích
cái này sử dụng trên hđh ubuntu đúng k ạ ?
ThíchThích