這種操做失誤,比較常見。通常這樣解決:git
git rm --cached filename
echo filename >> .gitignore
複製代碼
先解釋第二步,本地須要,遠程倉庫不須要,確定是要把那個文件寫入 .gitignore
文件裏面。 不然之後還要刪除。程序員
第一步則是把該文件從 git 的暫存區域中刪除。暫存區域,就是 index 區域。github
見一下親人:bash
git 三個區,git rm filename
, 會把文件從工做區 Working Directory 和暫存區域 Staging Area 中刪除。本地還要用,就不能這麼搞。ui
git rm --cached filename
, 則把文件從暫存區域 Staging Area 刪除,保留工做區的,咱們通常編輯見到的。spa
這種狀況就是已經 commit 了,生成快照,文件進了版本庫 Commit History,而後 push, 遠程庫與本地庫同步一下。設計
這個時候,直接 push 到遠程,無效。由於沒有新的快照,也就是沒有新的 commit id. 本地與遠程的歷史 log 是一致的。 修改文件,add 再 commit, push 提交過去,就會生效。指針
git stash
git pull
git stash pop
複製代碼
操做就是把本身修改的代碼隱藏,而後把遠程倉庫的代碼拉下來,而後把本身隱藏的修改的代碼釋放出來,讓 git 自動合併。接着找 <<<<<<<
, 哪裏衝突哪裏改。code
git reset --hard commit id
git pull
複製代碼
前面兩招挺管用的,場景就是合做的遠程倉庫上,別人作了一些改動,我沒有 commit , 而後把別人的 commit 拉下來。cdn
剛進入公司的時候,沒辦法,我也常常這麼作
場景就是合做的遠程倉庫上,別人作了一些改動,我在本地也作了一些 commit , 而後把別人的 commit 拉下來,再把個人更改添加上去。接着找 <<<<<<<
, 哪裏衝突哪裏改。
這個時候,先檢查一下個人本地倉庫與合做的遠程倉庫的最近的一個共同 commit id.
git reset commit id
git stash
git pull
git stash pop
複製代碼
git reset commit id
的做用是取消暫存文件。將 HEAD 的指針指向 commit id,修改了暫存區域 Staging Area 和版本庫 Commit History,工做區沙盒 Working Directory 保持原樣。
親人來了,看圖加深一下理解:
git reset commit id
就是 git reset -mixed commit id
,移動 HEAD,更新索引,即更新 staging area。移動 HEAD 分支的指向,使索引看起來像 HEAD。效果上看,就是取消了 commit id 之後的,add 和 commit .
git reset --soft commit id
,就是移動 HEAD。移動 HEAD 分支的指向,本質上是撤銷了上一次 git commit 命令。
當你在運行 git commit 時,Git 會建立一個新的提交,並移動 HEAD 所指向的分支來使其指向該提交。
當你將它 reset 回 HEAD~(HEAD 的父結點)時,其實就是把該分支移動回原來的位置,而不會改變索引和工做目錄。
git reset --hard commit id
, 移動 HEAD,更新索引,更新工做目錄。三件事情,全作了。前兩件事情,已經說了。更新工做目錄,讓工做目錄看起來像索引。從效果上看,就是撤銷一切修改,本地文件狀態同 commit id 的那時候。git rebase
, 不用 git merge
?git rebase
和 git merge
均可以用於合併分支,從 feature 分支上,取得新的提交 commits , 而後運用到 master 分支上(固然運用到其餘分支上也行)。
可是路子不一樣
merge 是合併,rebase 是變基
看圖可知: git rebase
有一個移動 base , 改變合併基準的操做
直觀的理解: git rebase
作的事情,就是先移指針,再移結點。
在 feature 分支上 git rebase master
,就把 feature 分支的基準 base 移動到 master 分支最新的 commit id 上。
合併分支前:
A <- B <- C [master]
^
\
D <- E [branch]
複製代碼
根結點是 A, 最初是 A , 在 A 狀態,分出去了分支 branch
git merge
是這樣合併的:
A <- B <- C
^ ^
\ \
D <- E <- F
複製代碼
提交到 C 的 master 分支和提交到 E 的 branch 分支,直接合並,通常是合併到 master, 有衝突解決衝突。
看圖可知: 採用 git merge
,不改變原來的 commit id, 會產生新的提交 commit id
項目協做成員比較多,通常須要使用 git rebase
, 固然也能夠這樣git merge
, git merge --squash feeature
若是使用 git merge
,極可能這樣,
這樣看,就很不舒服。須要採用 git rebase
修改歷史:
git rebase
是這樣合併的:
A <- B <- C <- `D` <- `E`
複製代碼
把 feature 分支( 例子中是 branch 分支)的提交 commits ,移動到 master 分支的頂端。
使用 rebase, 看起來更加 nice, 更加直觀,歷史就是一條直線嘛,沒什麼枝枝岔岔的。
看圖可知: 使用 rebase 後,把 feature 分支上 commit 拿來後,commit id 改掉了。而且沒有建立合併的公共節點 commit id
有的團隊採用 git rebase
工做流,有的採用 git merge
工做流,git rebase
工做流要求對 git 的理解深一些,商用多一些, feature 作好了,用 git rebase
合併。
這樣加 feature 怎麼加的,看 log 比較明朗。不然看 log, 上一條 feature A, 下一條 feature B , 不是很職業程序員。
git rebase
工做流,通常這麼實操, 在 feature 分支上 git rebase master
, 切到 master 分支上後, git merge feature
, 這時候 merge 也沒作什麼事情,就是把 master 分支的 HEAD 結點,移動到 feature 的 HEAD 結點, 兩個分支這時候狀態同步了。
git merge
工做流民用挺合適的,他的設計很是符合直覺,玩 github 開源,比較合適。由於多人寫做,git flow 工做流,不是很好統一
若是你採用 git rebase
工做流,你團隊其餘人不知道,你這麼搞,commit id 修改了,與他們本地庫的對不上,大家對你的意見可能會比較大
畢竟 git 採用分支,就是不冒犯別人代碼的意思