[教學] git應用-如果硬推也推不上怎麼辦 - 討論區

[教學] git應用-如果硬推也推不上怎麼辦

文章瀏覽次數 737 文章回覆數 1

特種兵

特種兵圖像(預設)

2021-01-22 10:59:07

From:211.23.21.202

這次是在處理 NVDA 臺灣平臺遇到的狀況

這篇主要是過程,結局大概會讓人有點傻眼吧

如果有更好解法的麻煩分享

假設工作都完成了,因為本地端有 rebase 或 reset 之類的動作,導致一般 push 會失敗,所以就硬推:

$ git push origin master -f                                                     
 logo@nvda.org.tw's password:                                                    
 Enumerating objects: 28, done.                                                  
 Counting objects: 100% (28/28), done.                                           
 Delta compression using up to 6 threads                                         
 Compressing objects: 100% (20/20), done.                                        
 Writing objects: 100% (20/20), 87.25 KiB | 2.81 MiB/s, done.                    
 Total 20 (delta 10), reused 0 (delta 0), pack-reused 0                          
 remote: error: denying non-fast-forward refs/heads/master (you should pull first
 )                                                                               
 To nvda.org.tw:/xxx/yyyy                                                
  ! [remote rejected] master -> master (non-fast-forward)                        
 error: failed to push some refs to 'nvda.org.tw:/xxx/yyyy'              

# 沒想到硬推也推不上,訊息大概是說有比較大的異動,所以沒辦法 fast-forward
# 看狀態

$ git status

On branch master
Your branch and 'origin/master' have diverged,
and have 2 and 4 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean

# 注意到 2 和 4 這兩個關鍵數字
# 看一下最新的 3 個 log

$ git log -3
commit 511a86da14d94f27082883973ee4be7f61b5e58c
Author: Logo-Kuo <logo@forblind.org.tw>
Date:   Wed Jan 13 11:02:00 2021 +0800

    上傳十二月份收支公告

commit 4efc555ea5a20dfc106162ecf9563018ae8f6cce
Author: Logo-Kuo <logo@forblind.org.tw>
Date:   Thu Dec 24 09:14:41 2020 +0800

    上傳十一月份收支公告

commit 3dfb667a8b1aac624e1d01d12c8a02c73090ad1f
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Sat Dec 19 14:58:03 2020 +0800

    暫時取消自動展開所選教學區左側類別選單 (Because JS error)

# 再看一下遠端倉庫的最新 5 個 log

$ git log -5 origin/master
commit 2f3742583d7e38f669c9b72a2ac96b8eb37ed638
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Wed Dec 30 13:47:29 2020 +0800

    move storage/.gitignore to storage/IAE/

commit 10d3578ad22beb60e6b9a5e57529b77f2a7310d6
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Wed Dec 30 13:44:13 2020 +0800

    storage/ use .gitignore

commit 9280350f393a911159de13f4b79a425d9385b169
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Wed Dec 30 11:51:05 2020 +0800

    .gitignore 增加 vscode 忽略檔案

commit 5a48df45e67f77c8255d8737248c774dd48c2cbc
Author: Logo-Kuo <logo@forblind.org.tw>
Date:   Thu Dec 24 09:14:41 2020 +0800

    上傳十一月份收支公告

commit 3dfb667a8b1aac624e1d01d12c8a02c73090ad1f
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Sat Dec 19 14:58:03 2020 +0800

    暫時取消自動展開所選教學區左側類別選單 (Because JS error)

先分析一下 2 和 4 的狀況

現在本地有 2 個 commit 是遠端沒有的

其中一個雖然 commit 一樣但 id 已經不同

而遠端則是有 4 個本地端沒有的 commit

如果按照我們之前的邏輯與操作方式,本地應該會先退兩個版,然後再 pull 回來

但如果我們直接本地退版的話,原本遠端沒有的那兩個 commit 就會不見

沒關係,無論如何,我先開個分支,免得發生什麼意外

$ git branch new_master                                                         

$ git switch new_master
 Switched to branch 'new_master'                                                 

$ git status
On branch new_master
nothing to commit, working tree clean

$ git switch master

好,算是有個 new_master 分支備份,這樣我們就可以到 master 大膽操作了

所以,我還是先退兩個版,然後拉回遠端倉庫我所沒有的 commit

最後從 new_master 把那兩個本地新 commit cherry-pick 回來,然後硬推上去

那就先硬退版

$ git reset --hard HEAD~2                                                       
 HEAD is now at 3dfb667 暫時取消自動展開所選教學區左側類別選單 (Because JS error)

$ git status
 commit 3dfb667a8b1aac624e1d01d12c8a02c73090ad1f
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Sat Dec 19 14:58:03 2020 +0800

    暫時取消自動展開所選教學區左側類別選單 (Because JS error)

$ git status
On branch master
Your branch is behind 'origin/master' by 4 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean

退 2 個了,所以落後 4 個,拉回遠端我所沒有的 commit

$ git pull origin master
 From nvda.org.tw:/xxx/yyyy                                              
  * branch            master     -> FETCH_HEAD                                   
Updating 3dfb667..2f37425
Fast-forward
 .gitignore                                           |   2 ++
 app/Http/Controllers/Donation/DonationController.php |   4 ++++
 storage/IAE/.gitignore                               |   2 ++
 ...略
 storage/app/public/footer-logo/tpnic-logo.png        | Bin
 36 files changed, 8 insertions(+)

如果是在上一篇的話,因為沒有本地的新 commit 所以做到這邊硬推上去就收工了

那我們先 cherry-pick 一個來試看看

# 先查出 commit id
$ git log -2 new_master                                                         
 commit 511a86da14d94f27082883973ee4be7f61b5e58c (new_master)                    
 Author: Logo-Kuo <logo@forblind.org.tw>                                         
 Date:   Wed Jan 13 11:02:00 2021 +0800                                          

     上傳十二月份收支公告                                                        

 commit 4efc555ea5a20dfc106162ecf9563018ae8f6cce                                 
 Author: Logo-Kuo <logo@forblind.org.tw>                                         
 Date:   Thu Dec 24 09:14:41 2020 +0800                                          

     上傳十一月份收支公告                                                        

# 撿回我們要的 commit  

$ git cherry-pick 511a86da                                                      
 [master 642844b] 上傳十二月份收支公告                                           
  Date: Wed Jan 13 11:02:00 2021 +0800                                           
  2 files changed, 4 insertions(+)                                               
  create mode 100644 storage/IAE/202012.pdf                                      

# 檢查一下

$ git log -5
 commit 642844ba29f3ea9d4a728fe1f0cdd95260561ce4
Author: Logo-Kuo <logo@forblind.org.tw>
Date:   Wed Jan 13 11:02:00 2021 +0800

    上傳十二月份收支公告

commit 2f3742583d7e38f669c9b72a2ac96b8eb37ed638
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Wed Dec 30 13:47:29 2020 +0800

    move storage/.gitignore to storage/IAE/

commit 10d3578ad22beb60e6b9a5e57529b77f2a7310d6
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Wed Dec 30 13:44:13 2020 +0800

    storage/ use .gitignore

commit 9280350f393a911159de13f4b79a425d9385b169
Author: Kevin Lin <kevinlin@forblind.org.tw>
Date:   Wed Dec 30 11:51:05 2020 +0800

    .gitignore 增加 vscode 忽略檔案

commit 5a48df45e67f77c8255d8737248c774dd48c2cbc
Author: Logo-Kuo <logo@forblind.org.tw>
Date:   Thu Dec 24 09:14:41 2020 +0800

    上傳十一月份收支公告

看來很地正確,但很不幸的硬推還是推不上去,錯誤訊息是一樣的

當時,其實不要 cherry-pick 就推不上去了

如果我從 fast-forward 下手,也就是不要讓他用 fast-forward 的方式

那就是使用 rebase 把本地與遠端不同的 commit 直接修掉

然後把遠端拉回來後再推上去,還是失敗

最後,沒辦法了,反正我確定本地是最正確的,於是就把遠端倉庫整個砍掉

以我這邊為例,就是主機上的 /xxx/yyyy 整個倉庫資料夾刪掉

然後新增一個空的資料夾叫 abcd,進去該資料夾後重新初始化裸倉

git init --bare

所以這是新的 abcd 是空倉庫

然後修改本地端的.git/config

因為原本是推拉到 /xxx/yyyy 所以要改成 /xxx/abcd

[remote "origin"]
	url = logo@nvda.org.tw:/xxx/yyyy

# 改成

	url = logo@nvda.org.tw:/xxx/abcd

然後把專案、分支通通推上去,測試一下沒問題了

最後再把 abcd 改回 yyyy 這樣其他合作開發伙伴才不會出問題

記得自己本地端的設定也要改回去喔

好吧,雖然很粗魯,但問題解決了

留言

#1

特種兵

特種兵圖像(預設)

2021-01-29 10:38:27

From:211.23.21.202

我一直覺得使用 push -f 還會發生 non-fast-forward 的錯誤很奇怪
都用 -f 就是要解決推不上去的問題呀,怎麼還會這樣,那 -f 有什麼用?
同樣的動作,在公司的內部系統是可以用 -f 推上去的,這樣才正常
這時候,我認為一定是 git 設定的問題
查了很多文章,大家都是用 -f 或 pull merge 來解決這種問題,但我這邊就是推不上去
有幾篇文章提到要加 receive.denyNonFastForwards = false 的設定,但我在本機做實驗,加了還是推不上
最後開始翻 git manual 關於設定的原文來看才發現
他說在初始化倉庫的時候設定,所以我認為應該設定在倉庫,而不是本地端
到遠端倉庫使用 git config -l 檢查設定
果然這個參數被設定為 true
去確認公司內部系統的遠端倉庫,並沒有加入這個參數,可見預設就是 false
那就開啟 nvda 遠端倉庫的 config 把這個參數設定刪除即可