記一次使用commit提交大檔案無法推送到遠端庫解決問題過程及git rebase使用
阿新 • • 發佈:2020-07-30
**記一次使用commit提交大檔案無法推送到遠端庫解決問題過程及git rebase使用**
[toc]
解決這個問題並沒有特別的(刪除提交歷史中某個檔案,然後重新push),但是由於開始的使用失誤,中間有使用`git rebase`和`git reset`命令處理,所以特此記錄下
## 大檔案無法push到遠端倉庫
### 問題
首先,故事(事故)的起因是這樣的。
某次`git push`(類似測試使用,沒有分支)到遠端倉庫時發生如下無法提交大檔案的報錯(大檔案是一個pdf檔案)
```sh
$ git push
Enumerating objects: 204, done.
Counting objects: 100% (204/204), done.
Delta compression using up to 4 threads
Compressing objects: 100% (183/183), done.
Writing objects: 100% (187/187), 419.00 MiB | 2.21 MiB/s, done.
Total 187 (delta 21), reused 0 (delta 0)
remote: Resolving deltas: 100% (21/21), completed with 12 local objects.
remote: Powered by GITEE.COM [GNK-3.8]
remote: error: File: db501995ac30070d50bdc115a7708f9ba84332d3 403.57 MB, exceeds 100.00 MB.
remote: Use command below to see the filename:
remote: git rev-list --objects --all | grep db501995ac30070d50bdc115a7708f9ba84332d3
remote: Please remove the file from history and try again. (https://gitee.com/help/articles/4232)
To gitee.com:findmoon/xxxx.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to '[email protected]:findmoon/xxxx.git'
```
根據提示,如下檢視大檔案是哪個
![](https://img2020.cnblogs.com/blog/1108935/202007/1108935-20200729225703691-1518828864.png)
### commit的大檔案無法push到遠端庫解決辦法
首先說一下解決辦法,需要修改提交歷史,刪除已提交到本地倉庫的大檔案的提交記錄,
從commit的提交歷史中刪除指定檔案的命令為`git filter-branch --tree-filter 'rm -f 檔名' HEAD`
如下,刪除大檔案
```sh
$ git filter-branch --tree-filter 'rm -f "Electron/pdf/677969 xxxx xxx.pdf"' HEAD
Rewrite d1244f8fbc1f08b473bd498c023b09bd8ac3246b (12/12) (156 seconds passed, remaining 0 predicted)
Ref 'refs/heads/master' was rewritten
```
執行刪除成功會返回`Ref 'refs/heads/master' was rewritten`提示,如果返回`unchanged`則表示沒有任何更改。
**如果檔案路徑包含空格需要用引號將刪除檔案路徑包含起來**。
然後重新push推送成功。
整體操作如下:
![](https://img2020.cnblogs.com/blog/1108935/202007/1108935-20200729225703481-301296799.png)
### `git filter-branch`命令:
![](https://img2020.cnblogs.com/blog/1108935/202007/1108935-20200729225703152-1749779724.png)
參考自[git誤commit大檔案導致不能push問題解決](https://www.cnblogs.com/samwu/p/9760023.html)
## `git commit後的回滾`
撤銷已經提交的commit有兩種方法:
- 使用 `git reset --hard HEAD^`
- 使用 `git rebase -i HEAD~n`
### git reset --hard 丟棄最新的提交
程式碼提交後,需求發生變化導致之前提交的已經不合適,或者 程式碼提交後發現有嚴重bug,需要回滾可是使用這個命令:
`git reset --hard HEAD^`
> 1,`HEAD^` 表示 最新提交HEAD位置往回數一個提交, 幾個 ^ 就往回數幾個提交;
> 2,`HEAD~n` 表示 最新提交HEAD位置往回數n個提交
`reset` 命令只能回滾最新的提交。如果只想刪除指定的某個提交,而保留最新的一次或兩次commit,`reset`就無法做到了。
`reset`命令[git 刪除某次指定的提交](https://www.cnblogs.com/yiven/p/8533644.html)
### git rebase -i 丟棄指定提交
如果想撤銷中間某次commit的情況,可以使用如下的命令:
`git rebase -i HEAD~2`(列出最新的兩次提交,然後決定對應提交的操作)
> 1. `rebase -i`是 `rebase --interactive` 的縮寫;
>
> 2. `git rebase -i` 不僅可以刪除commit, 還可以修改commit。 具體的可以檢視`rebase`中提示的引數
如下執行`git rebase`檢視命令引數:
```s
$ git rebase -i HEAD~2
pick 71add05 20200225同步
pick 45d4805 測試刪除中間某次commit
# Rebase 36b460a..45d4805 onto 36b460a (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop = remove commit
# l, label