簡體   English   中英

Git fetch沒有解決git checkout上的pathspec錯誤 - *

[英]Git fetch does not resolve pathspec error on git checkout — *

在以前的項目中,我經常運行git checkout -- *來丟棄我工作目錄中的所有更改。

  1. 在我目前的項目中,我得到以下內容:

     $ git checkout -- * error: pathspec 'node_modules' did not match any file(s) known to git. 
  2. 然后我做了一個git status

     $ git status On branch <feature_branch> Your branch is ahead of 'origin/<feature_branch>' by 2 commits. (use "git push" to publish your local commits) Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: <relative_file_path_in_current_app_dir> no changes added to commit (use "git add" and/or "git commit -a") 
  3. 我讀了另一個StackOverflow 帖子 ,說git fetch可以解決這個pathspec錯誤。 我試過了,它從遠程推出了一個新的功能分支:

     $ git fetch remote: Counting objects: 67, done. remote: Compressing objects: 100% (67/67), done. remote: Total 67 (delta 55), reused 0 (delta 0) Unpacking objects: 100% (67/67), done. From https://bitbucket.org/<repo_name> b42b31e05..e7f3858ad <unrelated_bug_branch> -> origin/<unrelated_bug_branch> 36b2cd4e9..ac87583fd develop -> origin/develop 61945b8ef..22a63fd7e <unrelated_feature_1_branch> -> origin/<unrelated_feature_branch> 322a39980..1f8752f2c <unrelated_feature_2_branch> -> origin/<unrelated_feature_2_branch> * [new branch] <unrelated_feature_3_branch> -> origin/<unrelated_feature_3_branch> 5fe02b8b3..a27140571 <unrelated_feature_4_branch> -> origin/<unrelated_feature_4_branch> 
  4. 我做另一個git status ,它與上面的#2相同。

  5. 我可以定位特定文件,這將有效:

     $ git checkout -- <relative_file_path_in_current_app_dir> 
  6. git status現在顯示我有一個干凈的工作樹。

究竟是我的pathspec錯誤的根本原因是什么,我該如何解決? 我可以在此期間檢查特定文件,但我只是對此錯誤感到好奇。

我擔心鏈接的問題Git:無法簽出分支 - 錯誤:pathspec'...'與git已知的任何文件都不匹配是一個爛攤子:正如你所說,它有很多答案,並且很少解釋。 同時ElpieKay的評論有正確的答案: node_modules是你讓Git忽略的文件或目錄,所以當你要求你的Git更新它時,它說: 嗯? 現在更新什么?

詳細描述

問題的根源在於Git將太多東西塞進一個命令中。 git checkout命令可以:

  • 從一些現有的遠程跟蹤名稱(如origin/develop )自動創建一個新分支(例如,像develop一樣的新分支名稱 ); 要么
  • 檢查一個現有的分支(一個具有給定名稱的分支,如master ); 要么
  • 檢查現有的歷史提交(例如,通過標記名稱,例如v1.2 ,或通過原始哈希ID),從而導致Git調用分離的HEAD

所有這些動作都以某種方式改變了Git的HEAD概念。 特殊名稱HEAD (所有大寫字母 - 這通常在Linux系統上是必需的,而Windows用戶通常可以小寫打字head )是你的Git記得你在哪個分支,如果有的話 因此,以上三種git checkout改變你所在的分支 ,或者 - 對於可怕的聲音,但實際上內部非常正常, 1個獨立的HEAD情況,缺乏任何分支。


1 Git使用這種分離的頭的狀態,當你在一個沖突或互動變基,例如。 將它用於正常開發並不是一個好主意,但它適用於臨時工作或這些內部到Git狀態。 只要完成你的rebase,或任何導致暫時脫離HEAD的東西,Git將重新連接HEAD,你可以繼續走動,你的頭重新連接。 :-)


git checkout可以做更多的事情, 而不涉及改變你的HEAD ,這就是git checkout --的用途。 在這里,Git可以:

  • 索引中提取一個或多個文件到工作樹: git checkout -- filename(s) ,或
  • 從特定提交中提取一個或多個文件,首先將其寫入索引,然后寫入工作樹: git checkout commit-specifier -- filename(s)

--從文件名中分隔提交說明符,例如masterdevelop1f3a907或其他。 如果文件名為master則通常需要 -- git checkout master會將HEAD切換為master ,而不是檢出名為master文件 它有時是可選的:如果你有一個名為master的文件,但是你想從develop技巧中獲得副本,那么編寫git checkout develop master會讓Git明白這一點(即使它讓普通人感到困惑)。

git checkout可以做更多的事情,但讓我們停止這三組明顯非常不同的操作:(1) 將HEAD更改為不同的分支 ,(2) 將HEAD更改為在特定提交時分離 ,並且(3) 根本不改變HEAD,只需從索引或特定提交中獲取一個文件或多個文件

Git在git checkout文檔中用各種語法標記表達了這些不同的動作。 引用那個 - 我會引用整個可怕的七項清單 - 我們看到:

git checkout [ -q ] [ -f ] [ -m ] [ <branch> ]
git checkout [ -q ] [ -f ] [ -m ] --detach [ <branch> ]
git checkout [ -q ] [ -f ] [ -m ] [ --detach ] <commit>
git checkout [ -q ] [ -f ] [ -m ] [[ -b | -B | --orphan ] <new_branch> [ <start_point> ]
git checkout [ -f | --ours | --theirs -m | --conflict=<style> ] [ <tree-ish> ] [ -- ] <paths>...
git checkout [ <tree-ish> ] [ -- ] <pathspec>...
git checkout-p | --patch )[ <tree-ish> ] [ -- ] [ <paths>... ]

其中三個是我們在這個答案中討論的操作(其他四個是git checkout可以做的更多事情,其中​​一些可能應該是不同的Git命令)。 我們來看看吧。

按名稱簽出分支(或簽出提交並分離HEAD)

從第一行開始:

git checkout [ <branch> ]

(我省略了簡化它的選項)。 這顯示了分支名稱在尖括號,這意味着你應該填寫1英寸它在方括號中為好,這樣你就可以離開它,但如果離開它,它的意思是“留在目前的分支”,這是有點傻事。 字當頭branch在尖括號狀,這標志着它作為一些人所謂一元變量 ,即,你應該填寫,與元變量告訴你什么樣的事情何去何從的名字 :分支名稱!

這是切換到某個現有分支,或從某些現有遠程跟蹤名稱操作創建新分支 您提供的分支名稱是要切換到或自動創建的分支名稱。 Git會查找與該名稱的現有的分支,如果不能找到一個,會看穿你的所有遠程跟蹤名字,你的origin/masterorigin/develop ,等等,看是否這些名字的人能擁有origin/ removed,是您要求的名稱。

(第二個引用的行與第一行相似,但是插入了--detach 。第三行與前兩行相似,但是<branch>而不是<commit> 。在第二個命令行中,-- --detach是必需的,在第三個,它是可選的。 <commit>元變量意味着你可以使用命名提交的任何東西,而不僅僅是分支名稱。這些是產生分離的HEAD的變體:它們檢查提交切換分支的方式相同,但是它們會在過程中關閉你的HEAD,這樣你就沒有分支了。基本上,如果你給git checkout一個命名提交但不是分支名稱的參數,Git只是假設你的意思 --detach 。如果你想在使用分支名稱時分離,你必須添加--detach 。這最后一件事不是大多數人想做的事情,但手冊頁無論如何都要覆蓋它。)

鏈接的問題及其答案主要是關於從遠程跟蹤名稱創建新分支 也就是說,他們回答了這個問題:

如果我說git checkout feature-X我得到一個錯誤,但后來我運行git fetch ,再次執行git checkout feature-X ,它就可以了。 為什么?

這里的答案是你第一次運行git checkout develop ,你沒有 origin/feature-X ,但是在git fetch完成之后,你確實有了一個origin/feature-X 這反過來,是因為git fetch創造了它,因為其他人創建feature-X上的origin ,一段時間相對較晚。 git fetch讓你的Git在origin調用Git並獲得所有分支和提交的列表。 您的Git會加載您尚未擁有的所有新提交,並創建或更新所有origin/*名稱,現在您擁有origin/feature-X

查看特定文件

倒數第二個引用的語法行:

git checkout [ <tree-ish> ] [ -- ] <pathspec>...

顯示了兩個元變量。 第一個是拼寫<tree-ish> ,它是Git的簡寫: 你可以在這里使用分支名稱,或者提交哈希,或者我可以用來查找我稱之為樹對象的任何東西。 Git有很多方法來指定提交哈希ID,這意味着要涵蓋所有這些,以及一些你不太可能遇到的奇怪的極端情況。 第一個元變量是可選的,如果你把它遺漏掉,Git會從Git的索引中檢查文件(我們這里沒有真正描述過,我不會詳細介紹,因為這已經很長了)。

第二個元變量是<pathspec> 請注意,它不是可選的! 這是Git-speak的簡寫文件名,或帶有*的模式,或許多其他很長的東西都不能在這里進行說明。 ...部分表示您可以列出多個。 這些pathspecs命名您希望Git在<tree-ish>找到的特定文件 (您指定的提交,如果您命名了一個)。

一切都出錯了

當你寫:

git checkout -- *

你的殼大概bash -expands的*所有的文件匹配當前工作目錄。 2因此,如果你有文件READMEhello以及node_modules等,那么Git看到的是:

git checkout -- README hello node_modules ...

沒有<tree-ish> ,因此Git會在索引中查找名為READMEhellonode_modules等的文件。

如果找不到其中一個 - 並且找不到node_modules -Git抱怨:

 error: pathspec 'node_modules' did not match any file(s) known to git. 

什么都不做

如果你改用. ,你的shell運行:

git checkout -- .

和Git看到了. 作為<pathspec>參數。 這意味着“當前目錄中Git已知的所有文件”,這樣就可以完成您想要的操作。 你也可以這樣寫:

git checkout -- '*'

它使用引號來保護*免受bash (或你正在使用的任何shell)。 然后Git會看到*Git*擴展為“當前目錄中Git已知的所有文件”。 但寫作. 更容易。


2請注意,在Windows上,CMD.EXE 不會擴展* ,而是將其傳遞給Git,讓Git擴展* ,這個錯誤永遠不會發生!

暫無
暫無

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

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