The Basics 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 $ git init $ git status $ git add <file> $ git commit $ git log $ git log --oneline $ git log --oneline <file_name> $ git log --graph --abbrev-commit --decorate --date =relative --all $ git config --global user.name "<name>" $ git config --global user.email <email>
Undoing Changes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ git checkout <commit-id | tag-name> $ git checkout master $ git tag -a <tag-name> -m "<description>" $ git tag $ git revert <commit-id> $ git reset --hard $ git clean -f
需要注意 git reset --hard
+ git clean -f
的使用,是在 working directory 上生效,並不是在 commit snapshot 上,因此一旦 undo 之後,所有尚未 commit 的變更都會完全消失且無法追溯,請確定真的不要這些變更之後,再執行這兩個指令
Branches 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 $ git branch $ git branch <branch-name> $ git checkout <branch-name> $ git merge <branch-name> $ git branch -d <branch-name> $ git branch -D <branch-name> $ git rm <file> $ git mv <old-filename> <new-filename> $ git commit -a -m "<message>"
以下 master branch 合併 css branch 的狀況稱為 fast-forward merge
:
因為 css branch 是從 master branch 中最新的 commit snapshot 所延伸出來,所以 master branch 合併 css branch 是不需要做什麼額外的判斷處理
使用 branch 的基本原則:
為每一個主要的新增功能,都使用 branch 的方式來完成
若無法為 branch 取一個實際的名稱(無法定義修改的內容為何),就不要使用 branch
!3-way merge](http://rypress.com/tutorials/git/media/4-1.png )
3-way merge 在當要合併兩個擁有不同 commit snapshot 時會發生,此時 Git 會額外建立一個 merge commit snapshot,並同時指向兩個不同的 branch(如上圖中的 After ,紅色圈圈表示這個 commit snapshot 同時來自 crazy & master 兩個 branch)
fast-forward merge 不會在 project history 中看到,這是與 3-way merge 不同的地方
Rebasing 當整個 git 專案越來越多 branch 時,可以透過 rebase 的方式來整理 branch,避免過於凌亂;此外,rebase 也有在不進行 merge 的情況下,取得最新版 master 的效果。
透過 rebase 可以把 branch 指向指定 branch 的最新 commit snapshot;舉例來說,可將多餘的 branch 重新 rebase 後指向 master 最新的 commit snapshot,如此一來後續進行 merge 時就會變成 fast-forward merge ,相關的 commit snapshot 都變成了 linear history,這樣在後續檢視上會更為直覺。
rebase 雖然可以讓整體專案的 branch 更為簡潔易讀,但在某些 rebase 操作上會移除(or 修改)某些 commit snapshot,因此後續就會無法還原當初 commit snapshot 的全貌,這也是 rebase 功能有所爭議的地方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $ git log <branch-feature>..<branch-dev> $ git rebase <new-base> $ git rebase -i <new-base> $ git commit --amend $ git rebase --continue git rebase --abort git merge --no-ff <branch-name>
以下用圖說明執行 git merge
指令時有無加上 --no-ff
參數所產生的效果:
Rewriting History 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ git reflog $ git reset --mixed HEAD~<n> $ git reset --hard HEAD~<n> $ git log <since>..<until > $ git log --stat
Remotes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $ git clone <remote-path> $ git remote $ git remote add <remote-name> <remote-path> $ git fetch <remote-name> $ git merge <remote-name>/<branch-name> $ git branch -r $ git push <remote-name> <branch-name> $ git push <remote-name> <tag-name>
Centralized Workflows 1 2 3 4 5 $ git init --bare <repository-name> $ git remote rm <remote-name>
Patch Workflows
1 2 3 4 5 6 $ git format-patch <branch-name> Create a patch for each commit contained in the current branch but not in <branch-name>. You can also specify a commit ID instead of <branch-name>. $ git am < <patch-file>
Tips & Tricks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 $ git archive <branch-name> --format=zip --output=<file> $ git bundle create <file> <branch-name> $ git clone repo.bundle <repo-dir> -b <branch-name> $ git stash $ git stash apply $ git diff <commit-id>..<commit-id> $ git diff $ git diff --cached $ git reset HEAD <file> Unstage a file, but don’t alter the working directory or move the current branch. $ git checkout <commit-id> <file> $ git config --global alias .<alias-name> <git-command>
git reset :
git checkout :
Plumbing 1 2 $ git cat-file <type > <object-id>
1 2 3 4 5 6 7 8 9 10 11 12 13 $ git cat-file -t <object-id> $ git ls-tree <tree-id> 040000 tree 5aa02e7f90df11621262d7fe91a9357bb44494aa about 100644 blob 4838a99c7bb4cc75941ff0a5e3a05fe4889570f9 blue.html ....... 100644 blob c9d942d8aadb84617d78455f8e2da25866c079a2 style.css 100644 blob e9d1781fd949fd41d2439ae3824a293531bc38a5 yellow.html $ git cat-file blob e9d178
1 2 3 4 5 6 7 8 9 10 11 12 $ git gc $ git update-index [--add] <file> Stage the specified file, using the optional --add flag to denote a new untracked file. $ git write-tree $ git commit-tree <tree-id> -p <parent-id>
References