簡體   English   中英

Git Pull Force 覆蓋本地文件

[英]Git Pull Force to overwrite local files

Git Pull Force ”、“ git reset branch to origin ”,或者換句話說,拉一個遠程分支來覆蓋一個本地分支,似乎是一個被廣泛搜索的功能,盡管本地下降很少,但它的興趣越來越大。

對於不斷增長的團隊和不斷增加的開發人員數量,這絕對是有意義的。

在此處輸入圖像描述

目前,最短的工作解決方案非常冗長,需要了解分支

git reset --hard origin/<branch_name>

編輯:有一個更方便的變體git reset --hard @{u}
請給予應有的評論 更多快捷方式在這里

這是不幸的,因為輸入以下內容要快得多

git pull

然而,這也帶來了自己的挑戰。 不同的歷史,合並沖突等......


我們確實有這樣的速記

git push origin HEAD -u --force

它將本地分支<branch_name>推送到源,覆蓋具有相同名稱<branch_name>的遠程分支並將其設置為它自己的上游分支。

但是,沒有這樣的--force / reset替代git pull


將此功能添加到git的最佳方法是什么?


如何強制“git pull”覆蓋本地文件? 660 萬次觀看
將本地存儲庫分支重置為就像遠程存儲庫 HEAD 4.7m 視圖一樣
如何強制 git pull 在每次拉動時覆蓋所有內容? 37 萬次觀看
從 Git 遠程 240k 視圖中提取時使用遠程更改解決沖突
執行 git pull 時如何強制更新? 9 萬次觀看
在不提交的情況下強制 GIT Pull
用 git 強制拉動
帶有隱式變基的 git force pull
清理一個 fork 並從上游重新啟動它
拉動時強制 git 更新我的本地倉庫
將本地 repo 的所有分支重置為與遠程相同
Github - 放棄所有更改

我要強調的是,雖然您肯定提到了每天都會出現的需求,但在沒有警告的情況下強行刪除您的工作的git命令也是問題的來源,會產生更多的破壞性后果(尋找“我在git reset --hard后丟失了我的工作/ git checkout . ,我可以取回它嗎?”問題)。

以您的pull -f示例為例,當您使用遙控器提取時,您不知道將從遙控器中得到什么,這一事實會放大這一點。

根據我卑微的經驗,我強烈建議養成不使用git pull而只使用git fetch的習慣。

然后檢查與origin/branchname的差異,然后選擇是否要重置或變基或...


有一個命令說“移至該提交並丟棄所有更改”會很好,我將在這里重復我在對@VonC 的回答的評論中建議的內容:

#!/bin/bash

target=$1
if [ -z "$target" ]; then
    target=HEAD
fi

set -e  # avoid going forward if one command fails ...

git stash
git restore -SW -s "$target" -- .
git reset "$target"

(我沒有一個好的別名: git goto ?)

它將為git reset提供一個相當安全的替代方案; 主要的警告是:磁盤上的一個文件,在開始提交中沒有被跟蹤,但在$target中被跟蹤,將被覆蓋而不被保存。

您還需要一個更復雜的git stash變體來保存這些文件。


[更新] 我想我找到了一個腳本,可以隱藏受影響的文件(並且只有那些):

#!/bin/bash

target=$1
if [ -z "$target" ]; then
    target=HEAD
fi

set -e  # avoid going forward if one command fails ...

list_impacted_files () {
   local target=$1

   # tracked files in the working tree that have a diff
   git diff --no-renames --name-only HEAD

   # untracked files that will be clobbered when restoring $target :
   #   * files that are present in $target but not in HEAD
   #   * and that currently exist on disk (use 'ls' to keep only those)
   # add '|| true' to ignore error code returned by 'ls' on non existing files
   git diff --no-renames --name-only --diff-filter=A HEAD "$target" |\
     xargs -r ls 2> /dev/null || true 
}

# list files as described above, and feed this list to `git stash -u`
# 'xargs -r <cmd>' avoids running <cmd> at all if stdin is empty
# in our case: don't run 'git stash -u' if no files are to be stashed ...
list_impacted_files "$target" | xargs -r git stash -u --

git restore -SW -s "$target" -- .
git reset "$target"

要將您的存儲庫恢復到原來的狀態:

  • 恢復到初始提交(使用git reset或上面的腳本......)
  • git stash list中找到要恢復的stash@{xx}
  • 運行git stash apply --index stash@{xx}

您至少需要三個命令:

  • 獲取,更新遠程跟蹤分支
  • 使用@{u}@{upstream}后綴重置上游分支
  • 清理以確保沒有多余的文件留下

那是:

git fetch
git reset --hard @{u}
git clean -nd

(在git clean中將-nd選項替換為-fd以實際刪除文件:我總是喜歡先預覽git clean 會做什么,然后再實際刪除任何內容)

您必須將它們分組為別名或腳本( git-pullreset ),然后您可以調用它們。


LeGEC評論中建議:

git stash
git restore -SW -s @{u} -- .
git reset @{u}

那會:

  • 保留完全未跟蹤的文件(例如:在 HEAD 和@{u}中未跟蹤的文件) untouched ,並且
  • 將提供一種方法,使仍然有一些東西可以恢復到“以前的樣子”。

我將采取不同的方法,挑戰問題的前提。 如果您發現自己必須調整本地分支以匹配遠程分支,這表明您永遠不應該有一個本地分支以.

相反,以這樣一種方式工作,即您使用的分支遠程跟蹤分支,因此無需調整。

以我為例。 我整天都在靈活地制作小功能分支,並推動它們形成合並到主的拉取請求。 但我自己沒有 main 我需要它做什么? 沒有什么!

  • 要啟動一個功能分支,我從 origin/main 開始獲取並創建分支。
  • 為了研究遠程 main 的狀態,我獲取然后檢查 origin/main,分離。
  • 為了審查一個拉取請求,我獲取然后檢查 origin/yourbranch,分離。 如果在審查期間,作者將更多提交推送到拉取請求分支,我會再次獲取並檢查 origin/yourbranch,分離。

所以我唯一擁有的本地分支是我自己的特性分支——它們沒有上游並且不能被拉取(也不需要,因為它們中唯一的進一步提交將來自我)。

簡而言之,我的建議是,如果人們確實想知道如何“拉出遠程分支以覆蓋本地分支”作為他們常規工作流程的一部分,那么這僅僅表明他們一開始就錯誤地使用了 Git。 除非:

  • 您將向它添加提交並推送它,或者
  • 您將在本地合並到它,這在當今的拉取請求世界中通常不是這種情況,或者
  • 它純粹是本地的和實驗性的,即您只是在開發功能時嘗試一種可能的方法。

這些場景都不會涉及相應的遠程跟蹤分支,因此問題中提出的情況永遠不會出現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM