主頁 > .NET開發 > Gitreset不會更新遠程服務器上的更改

Gitreset不會更新遠程服務器上的更改

2021-11-09 01:10:51 .NET開發

我目前正在學習 GitHub Actions。我的目標是為一個小型私有網路專案(網站)構建一個部署管道。除此之外,我注意到了一些我不明白的事情。

最好我用一個例子來解釋它。但首先我的設定:

  • 遠程存盤庫“Project_X”在 GitHub 上
  • GH Action 會在每次推送時啟動到遠程服務器的 SSH 連接以初始化git pull那里。
  • 完畢!

到目前為止,這作業正常。

現在我測驗了如果我的最后一次推送包含錯誤并且我想撤消它會發生什么。以便頁面繼續運行,我可以進行錯誤修復。所以我輸入了 local: git reset --hard hash_from_prev_commit在本地,提交被重置。隨著git push -f遠程存盤庫也進行了更新。但是在遠程服務器上它沒有被重置。GitHub 操作輸出:

out: /www/htdocs/w019db06
out: On branch master
out: Your branch is up-to-date with 'origin/master'.
out: nothing to commit, working directory clean
err: From github.com:Project-X/git-workflow-test
err:   ffd263c...e5a9ec8 master -> origin/master (forced update)
out: Already up-to-date.
==============================================
? Successfully executed commands to all host.

為什么會這樣,我必須做什么才能使更改在遠程服務器上生效?

uj5u.com熱心網友回復:

TL; 博士

您需要運行第三個存盤庫,git fetch然后是git reset --hard,如下所示:

git fetch origin
git reset --hard origin/master

如果您愿意在master此處對名稱進行硬編碼

讓我在這里總結一下,有三個存盤庫。讓我們給他們起個名字:阿爾弗雷德、芭芭拉和貓女。存盤庫 A (Alfred) 位于您的筆記本電腦上。存盤庫 B (Barbara) 在 GitHub 上。存盤庫 C 位于您的服務器上,無論它是什么。

為簡單起見,由于您在筆記本電腦上運行某些命令而運行的某個 Git 行程A執行的操作是“Git A”;那些在 B(在 GitHub 上)是“Git B”,那些出現在 C 上的是“Git C”。這應該有助于保持在每個存盤庫中每臺機器上發生的事情。git whatever

這一行,加上下一行,我還不會參考:

  ffd263c...e5a9ec8 master -> origin/master (forced update)

由 Git C 列印,因為 Git C 正在運行git pull. 但是git pull意味著:運行git fetch,然后運行第二個 Git 命令

背景(有點長,如果你喜歡可以略過)

現在,在我們繼續之前,我們需要再做一些說明:

  1. Git 是關于commits 的這與分支名稱或檔案無關:分支名稱幫助某些 Git 存盤庫查找提交,并且提交包含檔案,但我們真正關心的是提交

  2. 提交是共享的:如果存盤庫 A、B 和 C 相互交叉連接,它們最終都會以相同的提交結束。

  3. 提交被編號,帶有丑陋的哈希 ID。通常我喜歡使用單個大寫字母來代替這些,只要我從字母表中開始更深入地開始(A、B 和 C 是各種機器上的存盤庫,所以我想避免使用那些字母)。

  4. 每個提交包含,作為其元資料的一部分,一些先前提交或提交的原始哈希 ID 大多數提交只有一個先前的哈希 ID,它將提交形成為向后看的鏈:

    ... <-F <-G <-H
    

    whereH代表鏈中最新提交的哈希 ID 提交H最新款,是結束鏈:有這點后,沒有更多的提交。

  5. 如第 1 條所述,Git 存盤庫將使用分支名稱來幫助它查找提交。但是分支名稱不共享:每個 Git 存盤庫都有自己的分支名稱。

現在,有點懶惰,我傾向于像這樣繪制提交:

...--F--G--H   <-- master (HEAD)

Here we see how the current branch name—in this case master—points to the last commit in the chain. The process of making a new commit is done, in Git, by checking out some commit (H), using some branch name (master), which makes that branch the current branch and that particular commit the current commit. Then we act on the files in our working tree, use git add to "stage" them, and run git commit, and Git builds a new commit I, that points back to the current commit:

...--F--G--H   <-- master (HEAD)
            \
             I

As the last step of git commit, Git writes I's actual hash ID—some big ugly hexadecimal number—into the name master:

...--F--G--H
            \
             I   <-- master (HEAD)

and now the chain of commits ends not at H but at I.

When we use git push or git fetch, our Git calls up some other Git and either sends them our new commits (git push) or gets any new commits from them (git fetch). This is how the commits get shared. But after that, things get a little weirder: if we're using git fetch, our Git updates, not a branch name, but rather a remote-tracking name. For instance, if we got a new commit J from their Git, we would now have:

...--F--G--H--I   <-- master (HEAD)
               \
                J   <-- origin/master

We can now add commit J to our branch (our master, which is independent of their master) using various Git operations, to get:

...--F--G--H--I--J   <-- master (HEAD), origin/master

For various reasons, git push is different: after we send our new commit to some other repository, we ask them (politely) if they will please, if it's OK, set their branch name to some particular commit. For instance, if they have only commits up through H, we can send them commit I, or commits I-J, that add on to their H like this, and then ask them to set their master.

The problem

Let's review what kicks all this off. You, on your laptop—on Git A—are going to run:

git reset --hard HEAD~

or equivalent. This moves your branch name master back one commit. But we don't get there all at once.

Let's say you started with:

...--G--H   <-- master (HEAD), origin/master

You then added commit I in your repository A:

...--G--H   <-- origin/master
         \
          I   <-- master (HEAD)

You then ran git push origin master. That sent new commit I to repo B, and then asked them to make their master point to I, which they did:

...--G--H--I   <-- master (HEAD), origin/master

You then had repo B tickle repo C, which ran git pull origin master or just git pull (both do the same thing). Repo C called up repo B and got what to repo C was new: commit I:

...--G--H   <-- master (HEAD)
         \
          I   <-- origin/master

The second command that your git pull ran on C was git merge. This discovered that there was no need for a true merge, so it just added commit I to its master:

...--G--H--I   <-- master (HEAD), origin/master

So now, repos A and C match (down to both having an origin/master name pointing to commit I, as copied from repo B and renamed). Repo B has its master pointing to commit I.

And now we reset commit I away on repo A. (Whew, finally.) Let's draw that:

...--G--H   <-- master (HEAD)
         \
          I   <-- origin/master

Repo A still remembers that repo B is using commit I as repo B's master. That's true!

You might now run git push origin master from A and get an error about it not being a fast-forward:

! rejected ... (non-fast-forward)

That's because your Git talked with their Git, found that you had no commits to send, and ended with a polite request that they set their master to point to H. That's a polite request that they forget commit I, and they say no.

So you resort to git push -f or equivalent. This changes the final step of git push from a polite request, please set your master to point to H, to a forceful command: Set your master to point to H! If they obey, this happens in repo B:

...--G--H   <-- master (HEAD)
         \
          I   ???

Note that repo B has no name for commit I any more. You can still access it by raw hash ID (GitHub allow you to do this with their APIs and web interface), but you have to know the hash ID.

Now, this git push onto GitHub triggers Repo A to do a git pull, which—again—is just git fetch followed by a second Git command, in this case, git merge. Repo C currently has this:

...--G--H--I   <-- master (HEAD), origin/master

They run git fetch origin and see that, in repo B (on GitHub), master selects commit H. This means that they can make their origin/master point to commit H, but only by doing a forced update: it's a "non-fast-forward", in Git jargon.

So, they do that. Now they have this:

...--G--H   <-- origin/master
         \
          I   <-- master (HEAD)

That is, Repo C still has commit I. It's right there at the end of their master.

Their Git now runs its second step for git pull, which is to run git merge origin/master (more or less—it actually works off the raw hash ID at this point, internally). That tells them to add commit H into their chain that ends at commit I. Commit H is already in this chain, so they print:

Already up-to-date.

and then do nothing.

What's wrong is now obvious (well, as clear as things get in Git)

The problem here is that git merge—the default second command of git pull—is just wrong. You don't want to merge new commits in, on repo C. You want to switch to the latest commit on some branch on repo B. That's recorded in origin/master, in the case of repo B's master.

The git pull command can be told to run a different second command: instead of git merge, you can have it use git rebase. But that's equally wrong, or maybe even "wronger" (if that's a thing). You don't want either of those.

Git isn't a deployment tool

The ultimate problem here is that you're treating Git as a deployment tool, and it just isn't one. It can be used as one, much as a screwdriver can be used as a chisel, or a drill press can be used to tighten screws. It's just an abuse of the tool, to some extent. You need to be sure you know exactly what you're doing.

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/352842.html

標籤:混帐 github 部署 github-actions

上一篇:用于匯出的git存檔的替代方法

下一篇:將檔案推送到Github/Gitlab而不將其添加到.git?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more