git fetch 做了些什么
git fetch 完成了僅有的但是很重要的兩步:
- 從遠程倉庫下載本地倉庫中缺失的提交記錄
- 更新遠程分支指針(假設(shè)為 o/master)
git fetch 實際上將本地倉庫中的遠程分支更新成了遠程倉庫相應(yīng)分支最新的狀態(tài):

git fetch 通常通過互聯(lián)網(wǎng)(使用 http:// 或 git:// 協(xié)議) 與遠程倉庫通信。
git fetch 不會做的事
git fetch 并不會改變你本地倉庫的狀態(tài)。它不會更新你的 master 分支,也不會修改你磁盤上的文件。
理解這一點很重要,因為許多開發(fā)人員誤以為執(zhí)行了 git fetch 以后,他們本地倉庫就與遠程倉庫同步了。它可能已經(jīng)將進行這一操作所需的所有數(shù)據(jù)都下載了下來,但是并沒有修改你本地的文件。
所以,你可以將 git fetch 的理解為單純的下載操作。
合并遠程分支
當遠程分支中有新的提交時,你可以像合并本地分支那樣來合并遠程分支。也就是說就是你可以執(zhí)行以下命令:
git cherry-pick o/mastergit rebase o/mastergit merge o/master- 等等
實際上,由于先抓取更新再合并到本地分支這個流程很常用,因此 Git 提供了一個專門的命令來完成這兩個操作,它就是 git pull。
git pull
git pull 就是 git fetch + git merge o/master。
當你想要 push 你的新提交時,發(fā)現(xiàn)遠程倉庫在你上次拉取以后已經(jīng)又有了改變,也就是說你的新 commit 是基于舊提交的修改,這種情況下 Git 是不允許你進行 push 操作的,你需要使自己的工作基于遠程的提交,這個過程可以用以下命令:
git fetch; git merge o/mastergit fetch; git rebase o/master- 最簡單的當然還是
git pull -r(git pull --rebase的縮寫)
然后再 git push 就沒問題了。
在開發(fā)社區(qū)里,有許多關(guān)于 merge 與 rebase 的討論。以下是關(guān)于 rebase 的優(yōu)缺點:
- 優(yōu)點:rebase 使你的提交樹變得很干凈, 所有的提交都在一條線上
- 缺點:rebase 修改了提交樹的歷史。比如,提交 C1 可以被 rebase 到 C3 之后。這看起來 C1 中的工作是在 C3 之后進行的,但實際上是在 C3 之前。
一些開發(fā)人員喜歡保留提交歷史,因此更偏愛 merge。而其他人可能更喜歡干凈的提交樹,于是偏愛 rebase。仁者見仁,智者見智。
git push
git push 負責將你的變更上傳到指定的遠程倉庫。遠程倉庫中的 master 分支被更新,我們的遠程分支(o/master)也同樣會被更新。
未指定參數(shù)時,Git 是通過當前檢出分支的屬性來確定遠程倉庫以及要 push 的目的地的。我們可以為 push 指定參數(shù),語法是 git push <remote> <place>。這句話的含義是:切到本地倉庫中的 <place> 分支,獲取所有的提交,再到遠程倉庫 <remote> 中找到 <place> 分支,將遠程倉庫中沒有的提交記錄都添加上去,搞定之后告訴我。
如果不指定參數(shù),且 HEAD 沒有跟蹤任何分支,git push 不會有任何響應(yīng):

要同時為源和目的地指定 <place> 的話,只需要用冒號將二者連起來就可以了 git push origin <src>:<dst>。
注意如果 <src> 傳了個空值過去,會刪除該遠程分支。
從遠程庫刪除某些文件但保留本地的文件
有時我們會誤把一些不必要的文件(如目標文件、log 日志等)提交并推送到了遠程庫,現(xiàn)在希望從遠程庫刪除這些文件但保留本地的文件,可以像這樣 執(zhí)行:
git rm -r --cached dir1
git rm --cached dir2/*.pyc
git commit -m "remove irrelated files"
git push origin branch1