㈠ 如何將git倉庫裡面的代碼刪除
首先進行 Git 垃圾回收:
git gc --auto
其次查看 Git 倉庫佔用空間:
$ -hs .git/objects 45M .git/objects
然後找出歷史中超過一定大小的文件,最後在歷史中刪除並且提交。
㈡ 如何在Git中撤銷一切
任何一個版本控制系統中,最有用的特性之一莫過於 「撤銷(undo)」操作。在Git中,「撤銷」有很多種含義。
當你完成了一次新的提交(commit),Git會及時存儲當前時刻倉庫(repository)的快照(snapshot);你能夠使用Git將項目回退到任何之前的版本。
下文中,我將列舉幾個常見的、需要「撤銷」的場景,並且展示如何使用Git來完成這些操作。
一、撤銷一個公共修改 Undo a "public" change
場景:你剛剛用git push將本地修改推送到了GitHub,這時你意識到在提交中有一個錯誤。你想撤銷這次提交。
使用撤銷命令:git revert
發生了什麼:git revert將根據給定SHA的相反值,創建一個新的提交。如果舊提交是「matter」,那麼新的提交就是「anti-matter」——舊提交中所有已移除的東西將會被添加進到新提交中,舊提交中增加的東西將在新提交中移除。
這是Git最安全、也是最簡單的「撤銷」場景,因為這樣不會修改歷史記錄——你現在可以git push下剛剛revert之後的提交來糾正錯誤了。
二、修改最近一次的提交信息 Fix the last commit message
場景:你只是在最後的提交信息中敲錯了字,比如你敲了git commit -m "Fxies bug #42",而在執行git push之前你已經意識到你應該敲"Fixes bug #42"。
使用撤銷命令:git commit –amend或git commit --amend -m "Fixes bug #42"
發生了什麼:git commit –amend將使用一個包含了剛剛錯誤提交所有變更的新提交,來更新並替換這個錯誤提交。由於沒有staged的提交,所以實際上這個提交只是重寫了先前的提交信息。
三、撤銷本地更改 Undo "local" changes
場景:當你的貓爬過鍵盤時,你正在編輯的文件恰好被保存了,你的編輯器也恰在此時崩潰了。此時你並沒有提交過代碼。你期望撤銷這個文件中的所有修改——將這個文件回退到上次提交的狀態。
使用撤銷命令:git checkout --
發生了什麼:git checkout將工作目錄(working directory)里的文件修改成先前Git已知的狀態。你可以提供一個期待回退分支的名字或者一個確切的SHA碼,Git也會默認檢出HEAD——即:當前分支的上一次提交。
注意:用這種方法「撤銷」的修改都將真正的消失。它們永遠不會被提交。因此Git不能恢復它們。此時,一定要明確自己在做什麼!(或許可以用git diff來確定)
四、重置本地修改 Reset "local" changes
場景:你已經在本地做了一些提交(還沒push),但所有的東西都糟糕透了,你想撤銷最近的三次提交——就像它們從沒發生過一樣。
使用撤銷命令:git reset或git reset --hard
發生了什麼:git reset將你的倉庫紀錄一直回退到指定的最後一個SHA代表的提交,那些提交就像從未發生過一樣。默認情況下,git
reset會保留工作目錄(working
directory)。這些提交雖然消失了,但是內容還在磁碟上。這是最安全的做法,但通常情況是:你想使用一個命令來「撤銷」所有提交和本地修改——那
么請使用--hard參數吧。
五、撤銷本地後重做 Redo after undo "local"
場景:你已經提交了一些內容,並使用git reset –hard撤銷了這些更改(見上面),突然意識到:你想還原這些修改!
使用撤銷命令:git reflog和git reset, 或者git checkout
發生了什麼:git reflog是一個用來恢復項目歷史記錄的好辦法。你可以通過git reflog恢復幾乎任何已提交的內容。
你或許對git log命令比較熟悉,它能顯示提交列表。git reflog與之類似,只不過git reflog顯示的是HEAD變更次數的列表。
一些說明:
1. 只有HEAD會改變。當你切換分支時,用git commit提交變更時,或是用git
reset撤銷提交時,HEAD都會改變。但當你用git checkout --時,
HEAD不會發生改變。(就像上文提到的情形,那些更改根本就沒有提交,因此reflog就不能幫助我們進行恢復了)
2. git reflog不會永遠存在。Git將會定期清理那些「不可達(unreachable)」的對象。不要期望能夠在reflog里找到數月前的提交記錄。
3. reflog只是你個人的。你不能用你的reflog來恢復其他開發者未push的提交。
因此,怎樣合理使用reflog來找回之前「未完成」的提交呢?這要看你究竟要做什麼:
1. 如果你想恢復項目歷史到某次提交,那請使用git reset --hard
2. 如果你想在工作目錄(working direcotry)中恢復某次提交中的一個或多個文件,並且不改變提交歷史,那請使用git checkout--
3. 如果你想確切的回滾到某次提交,那麼請使用git cherry-pick。
六、與分支有關的那些事 Once more, with branching
場景:你提交了一些變更,然後你意識到你正在master分支上,但你期望的是在feature分支上執行這些提交。
使用撤銷命令:git branch feature, git reset --hard origin/master, 和 git checkout feature
發生了什麼:你可能用的是git checkout -b來建立新的分支,這是創建和檢出分支的便捷方法——但實際你並不想立刻切換分支。git
branch feature會建立一個叫feature的分支,這個分支指向你最近的提交,但是你還停留在master分支上。
git reset --hard將master回退至origin/master,並忽略所有新提交。別擔心,那些提交都還保留在feature上。
最後,git checkout將分支切換到feature,這個分支原封不動的保留了你最近的所有工作。
七、事半功倍處理分支 Branch in time saves nine
場景:你基於master新建了一個feature分支,但是master分支遠遠落後與origin/master。現在master分支與
origin/master同步了,你期望此刻能在feature下立刻commit代碼,並且不是在遠遠落後master的情況下。
使用撤銷命令:git checkout feature和git rebase master
發生了什麼:你也許已經敲了命令:git reset(但是沒用--hard,有意在磁碟上保存這些提交內容),然後敲了git checkout -b,之後重新提交更改,但是那樣的話,你將失去本地的提交記錄。不過,一個更好的方法:
使用git rebase master可以做到一些事情:
1.首先,它定位你當前檢出分支和master之間的共同祖先節點(common ancestor)。
2.然後,它將當前檢出的分支重置到祖先節點(ancestor),並將後來所有的提交都暫存起來。
3.最後,它將當前檢出分支推進至master末尾,同時在master最後一次提交之後,再次提交那些在暫存區的變更。
八、批量撤銷/找回 Mass undo/redo
場景:你開始朝一個既定目標開發功能,但是中途你感覺用另一個方法更好。你已經有十幾個提交,但是你只想要其中的某幾個,其他的都可以刪除不要。
使用撤銷命令:git rebase -i
發生了什麼:-i將rebases設置為「交互模式(interactive mode)」。rebase開始執行的操作就像上文討論的一樣,但是在重新執行某個提交時,它會暫停下來,讓你修改每一次提交。
rebase –i將會打開你的默認文本編輯器,然後列出正在執行的提交,就像這樣:
前兩列最關鍵:第一列是選擇命令,它會根據第二列中的SHA碼選擇相應的提交。默認情況下,rebase –i會認為每個更改都正通過pick命令被提交。
要撤銷一個提交,直接在編輯器刪除對應的行就可以了。如果在你的項目不再需要這些錯誤的提交,你可以直接刪除上圖中的第1行和3-4行。
如果你想保留提交但修改提交信息,你可以使用reword命令。即,將命令關鍵字pick換成reword(或者r)。你現在可能想立刻修改提交消
息,但這么做不會生效——rebase –i將忽略SHA列後的所有東西。現有的提交信息會幫助我們記住0835fe2代表什麼。當你敲完rebase
–i命令後,Git才開始提示你重寫那些新提交消息。
如果你需要將2個提交合並,你可以用squash或者fixup命令,如下圖:
squash和fixup都是「向上」結合的——那些用了這些合並命令(編者按:指squash、fixup)的提交,將會和它之前的提交合並:上圖中,0835fe2和6943e85將會合並成一個提交,而38f5e4e和af67f82將會合並成另一個提交。
當你用squash時,Git將會提示是否填寫新的提交消息;fixup則會給出列表中第一個提交的提交信息。在上圖中,af67f82是一個
「Ooops」信息,因為這個提交信息已經同38f5e4e一樣了。但是你可以為0835fe2和6943e85合並的新提交編寫提交信息。
當你保存並退出編輯器時,Git將會按照從上到下的順序執行你的提交。你可以在保存這些提交之前,修改提交的執行順序。如果有需要,你可以將af67f82和0835fe2合並,並且可以這樣排序:
九、修復早先的提交 Fix an earlier commit
場景:之前的提交里落下了一個文件,如果先前的提交能有你留下的東西就好了。你還沒有push,並且這個提交也不是最近的提交,因此你不能用commit –amend。
使用撤銷命令:git commit --squash和git rebase --autosquash -i
發生了什麼:git commit –squash將會創建一個新的提交,該提交信息可能像這樣「squash! Earlier commit」。(你也可以手寫這些提交信息,commit –squash只是省得讓你打字了)。
如果你不想為合並的提交編寫信息,也可以考慮使用命令git commit --fixup。這種情況下,你可能會使用commit --fixup,因為你僅希望在rebase中使用之前的提交信息。
rebase --autosquash –i將會啟動rebase交互編輯器,編輯器會列出任何已完成的squash!和fixup!提交,如下圖:
當使用--squash和–fixup時,你或許記不清你想修復的某個提交的SHA碼——只知道它可能在一個或五個提交之前。你或許可以使用Git
的^和~操作符手動找回。HEAD^表示HEAD的前一次提交。HEAD~4表示HEAD前的4次提交,加起來總共是前5次提交。
十、停止跟蹤一個已被跟蹤的文件 Stop tracking a tracked file
場景:你意外將application.log添加到倉庫中,現在你每次運行程序,Git都提示application.log中有unstaged的提交。你在.gitignore中寫上」*.log」,但仍舊沒用——怎樣告訴Git「撤銷」跟蹤這個文件的變化呢?
使用撤銷命令: git rm --cached application.log
發生了什麼:盡管.gitignore阻止Git跟蹤文件的變化,甚至是之前沒被跟蹤的文件是否存在,但是,一旦文件被add或者
commit,Git會開始持續跟蹤這個文件的變化。類似的,如果你用git add
–f來「強制」add,或者覆蓋.gitignore,Git還是會繼續監視變化。所以以後最好不要使用–f來add .gitignore文件。
如果你希望移除那些應當被忽略的文件,git rm –cached可以幫助你,並將這些文件保留在磁碟上。因為這個文件現在被忽略了,你將不會在git status中看到它,也不會再把這個文件commit了。
以上就是如何在Git上撤銷的方法。如果你想學習更多Git命令用法,可以移步下面相關的文檔:
checkout
commit
rebase
reflog
reset
revert
rm
㈢ git清除歷史紀錄
若我想刪除歷史記錄里比較考前的提交,而後面還有很多需要保留的提交,則:
1.2 如果要刪除的歷史記錄是分散的,則可以考慮 Interactive Rebase,自行挑揀/合並等。如git rebase -i <ref>
1.1 如果要刪除的歷史記錄是連續的,比如說從最開始到某一刻全部都刪除或者是中間一截可以刪除,則可以考慮 Onto Rebase,如 git rebase --onto <ONTO_BASE_ref> <START_ref> <END_ref>,其中 START 到 END 之間的是需要保留的部分,而 ONTO_BASE 則是最新的基點;換言之,從 ONTO_BASE 到 START 之間的歷史記錄會被幹掉。
若我要刪除的歷史記錄很多,要保留的則很少(比如說就保留最近的一個,以前都不想要了),那索性可以直接創建 Orphan Branch 來重建歷史記錄。如 git checkout --orphan new_start,這條命令會創建一個叫做 new_start 的分支,該分支沒有任何歷史記錄,但是所有的文件都會原封不動的存在,你可以據此開始重新提交。完成之後甚至可以把舊的分支直接廢棄。另外,也可以指定新分支的起點,默認當然是從 HEAD 開始了。
你還可以把歷史記錄分成兩份(或更多份),其中有的完整,有的則簡化等等,具體參見這篇關於 git replace 的文檔:http://git-scm.com/2010/03/17/replace.html
其實還有很多種場景可以說道,Git 的用法非常靈活,即使暫時用不到也值得細細過一遍知道它能做什麼樣的事情,然後遇到各種復雜的場景就可以自己推導出解決方案了。
㈣ git如何刪除歷史提交
你非要保留那次merge並且刪掉b而不是revert b么?不要輕易rebase -i歷史提交,尤其是本地倉儲是從伺服器上sync下來的時候,本地的自己開發的還好說。。而且你就算把b刪掉,歷史也變成了a<-c'<-d'<-e'<-f'(d'<-g'<-f'),commit id都變了的
真要這么搞就用這個,git rebase -p --onto a b
git help rebase里都有
㈤ 初學git,commit了多次才push到remote,怎麼刪除不想要的commit歷史
git add -A, git commit -m "你的日誌", git push最後提個醒,如果有改動最好還是直接push上去好,不然到最後累的是自己。
㈥ git怎樣回退到上一個
這些開發中很常見的問題,所以git的取消提交,回退甚至返回上一版本都是特別重要的.
大致分為下面2種情況:
1.沒有push
這種情況發生在你的本地代碼倉庫,可能你add ,commit 以後發現代碼有點問題,准備取消提交,用到下面命令
reset
git reset [--soft | --mixed | --hard
上面常見三種類型
--mixed
會保留源碼,只是將git commit和index 信息回退到了某個版本.
git reset 默認是 --mixed 模式
git reset --mixed 等價於 git reset
--soft
保留源碼,只回退到commit 信息到某個版本.不涉及index的回退,如果還需要提交,直接commit即可.
--hard
源碼也會回退到某個版本,commit和index 都回回退到某個版本.(注意,這種方式是改變本地代碼倉庫源碼)
當然有人在push代碼以後,也使用 reset --hard <commit...> 回退代碼到某個版本之前,但是這樣會有一個問題,你線上的代碼沒有變,線上commit,index都沒有變,當你把本地代碼修改完提交的時候你會發現權是沖突.....
所以,這種情況你要使用下面的方式
2.已經push
對於已經把代碼push到線上倉庫,你回退本地代碼其實也想同時回退線上代碼,回滾到某個指定的版本,線上,線下代碼保持一致.你要用到下面的命令
revert
git revert用於反轉提交,執行evert命令時要求工作樹必須是干凈的.
git revert用一個新提交來消除一個歷史提交所做的任何修改.
revert 之後你的本地代碼會回滾到指定的歷史版本,這時你再 git push 既可以把線上的代碼更新.(這里不會像reset造成沖突的問題)
revert 使用,需要先找到你想回滾版本唯一的commit標識代碼,可以用 git log 或者在adgit搭建的web環境歷史提交記錄里查看.
git revert
通常,前幾位即可
git revert c011eb3
git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit
看似達到的效果是一樣的,其實完全不同.
第一:
上面我們說的如果你已經push到線上代碼庫, reset 刪除指定commit以後,你git push可能導致一大堆沖突.但是revert 並不會.
第二:
如果在日後現有分支和歷史分支需要合並的時候,reset 恢復部分的代碼依然會出現在歷史分支里.但是revert 方向提交的commit 並不會出現在歷史分支里.
第三:
reset 是在正常的commit歷史中,刪除了指定的commit,這時 HEAD 是向後移動了,而 revert 是在正常的commit歷史中再commit一次,只不過是反向提交,他的 HEAD 是一直向前的.
㈦ 如何清除gitcommit的內容
你的意思是用git commit提交了一個更改,但是你又不需要這個更改了,想退回到上一個comiit ID上去,但是又想把你更改的代碼保留嗎?可以用git reset --soft commit-id (你運行gitcommit 之前的那個最新commit ID),然後敲git status看看,根據說明可以用相應的命令了
㈧ 如何從 git repository 中徹底刪除文件
當我們的
git
repository
提交大的數據文件之後,.git
目錄會很大,有時候有些數據我們已經不再需要,
這時候我們可以刪除,但是沒有徹底刪除,.git
中會保存的有歷史記錄,這時候,我們可以用一下方式徹底刪除。
git
filter-branch
--index-filter
\
'git
rm
-r
--cached
--ignore-unmatch
path/to/your/file'
\
head
git
push
origin
master
--force
rm
-rf
.git/refs/original/
git
reflog
expire
--expire=now
--all
git
gc
--prune=now
git
gc
--aggressive
--prune=now
㈨ git中怎麼刪除某個分支的所有記錄
下載安裝git管理工具
進入項目根目錄(含.git文件夾)使用bash運行git命令
> git checkout the_local_branch // 切換到本地分支
> git branch -dthe_local_branch // 刪除本地分支的所用記錄
>git branch -Dthe_local_branch // 上面執行有問題,需要-D強制刪除
> git push origin:the_remote_branch // 刪除遠程分支
至此該分支的所有記錄都被完全刪除了
㈩ 如何刪除git提交歷史中包含的大文件
文件在當前工作目錄已經刪除了,即使使用git log -p 刪除文件名稱 ,直接指定原來沒有刪除時文件的路徑和文件名,也不行的。