- 特色
- 分散式
- 每個人都有完整的 repo
- 開發時不一定要網路,同步時才要
- 非線性開發
- 不一定只能依靠上一個版本
- 分散式
- repo 目錄結構
- working directory
- working directory 中的檔案在 add 後會進入 staging area
- staging area
- staging area 中的檔案在 commit 後會進入 repository
- repository
- repository 中的檔案在 checkout 後會進入 working directory
- working directory
初始化
git init
設定自己的資料
git config --global user.name "Cychih" git config --global user.email "[email protected]"
把一個 repo 複製到 local 端
git clone {URI}
查看 commit history
git log
把所有檔案加入 staging area
git add -A
查看 staging area 和 working directory 的差異
git status
git diff
正式 commit
git commit
若不慎 add 了太多檔案,但只想要 commit 特定檔案
git commit file1 file2 ...
追蹤檔案
列出追蹤中的檔案
git ls-files
設定不要被追蹤的檔案
永久性
.gitignore
- 有敏感資訊的檔案一定要加入
.gitignore
一次性 (只有這次需要暫時 unstage)
git reset {filename}
刪除追蹤中的檔案 (會真的把檔案刪掉)
git rm {filename}
- 建議不要手動
rm
,不然 tracking list 中仍然會存在該檔名,導致 repo dirty
- 建議不要手動
重新命名追蹤中的檔案
git mv {name1} {name2}
- 建議不要手動
mv
,不然 tracking list 中仍然在存在該檔名,導致 repo dirty
- 建議不要手動
回到最新的 commit 的狀態
git reset --hard HEAD
把單一檔案還原到先前的版本
git checkout {commit} -- {filename}
stash 是一個 stack,可以把未 commit 的內容暫存起來,避免因正在修改某些檔案而導致無法做其他操作,如切換 branch 等等
把未 commit 的更動暫存起來
git stash
- 同時會把檔案內容復原成 branch 的最新狀態
把暫存的更動放回原檔
git stash apply
列出最新 stash 的改動
git stash show
放棄一個 stash
git stash drop
submodule 讓一個 repo 可以使用其他 repo,且每個 repo 可以是不同版本
為 repo 加入一個 submodule
git submodule add {URI}
把一個含有 submodule 的 repo clone 下來
git clone {URI}
cd {repo}
git submodule init
git submodule update
更新 repo 內的 submodule
cd {submodule}
git pull origin master
cd ..
git add {submodule}
git commit -m "Update submodule"
git push origin
- 其他 main repo 也需要更新
git pull origin
git submodule update
bare repo 可以讓你不架設 git server,卻又可以 push/pull
建立方式
新增一個目錄,暫時叫
bare_repo
cd bare_repo
git init --bare
在所有其他需要 push/pull 的 repo 中,加上 remote
git remote add origin {username}@{host}:{bare-repo-path}
只加入檔案部份的更動
以 patch 的方式
git add -p {filename}
編輯每行改動
git add -e
- 每行的開頭必須是以下字元其中一個
- 空白字元,代表不改動
-
字元,代表刪除+
字元,代表增加
- 每行的開頭必須是以下字元其中一個
忽略特定檔案未來的所有改動
git update-index --assume-unchanged {filename}
移動一串 commits
狀況
o---o master \ o---o---o feature1 \ o---o---o feature2 A B C
期望達成效果
o---o master |\ | o---o---o feature1 | o---o---o feature2 A B C
指令
使用 Cherry-pick(一步一步複製)
git checkout master
o---o master* \ o---o---o feature1 \ o---o---o feature2 A B C
git checkout -b tmp
o---o master tmp* \ o---o---o feature1 \ o---o---o feature2 A B C
git cherry-pick A B C
o---o master |\ | o---o---o feature1 | \ | o---o---o feature2 | A B C | o---o---o tmp* A B C
- 或是
git cherry-pick feature1..feature2
- 或是
git branch -D feature2
git checkout -b feature2
git branch -D tmp
o---o master |\ | o---o---o feature1 | o---o---o feature2* A B C
使用 rebase(直接剪下來拔過去)
git rebase --onto master feature1 feature2
較簡單的狀況:Local repo 在 master branch 上與遠端的 master conflict 了,希望把 Local repo 新增的改動 append 在遠端 master 之上
- 先
git fetch
抓下遠端的 master branch - 再使用
git rebase origin/master
,更改 Local 的 master
- 先
壓縮 (squash) 一串 commits
git rebase -i {after-and-not-include-this-commit}
列出 branch
git branch
創造一個 branch
git branch {name}
跳到另一個 branch
git checkout {name}
回到某個 commit 的狀態
git reset {hash}
把一個 branch push 到 github 上
git push origin {branch_name}
git push origin master
把一個 remote branch pull 下來而不 merge
git fetch origin {remote branch name}:{local branch name}
有時會失敗的方法
git checkout --track origin/{branch_name}
避免把 branch 上的所有 history 都 merge 進 master
git checkout master
git merge --edit --no-ff {branch_name}
刪除 remote branch
git push origin --delete {branch_name}
更新 branch database
git fetch -p
git pull
設定目的地
git remote add origin {URI}
git remote add origin http://github.com/{username}/{}.git
- 有設定 ssh key 的話,可用 ssh
git remote add origin [email protected]:{username}/{}.git
add
可改成set-url
在 github 上隱藏前一個 commit
git push -f origin HEAD^:master
假設該 project 名稱為 A
- 在 github 上 fork A, A 會複製一份到自己的帳號底下 (稱為 B)
git clone B
git remote add upstream A
git fetch upstream
- 修改 repo 內的東西
git push origin master
(或是其他想要 push 合併回原 repo 的 branch)- 在 github 上的 A 頁面發出 pull request
列出所有 option
$ git help -c