簡體   English   中英

在倉庫更新過程中如何解釋git錯誤?

[英]How to interpret git error during repo update?

我正在嘗試更新我的Github存儲庫。

操作系統/配置 :在MacBook Air上使用OS X 10.10.5(Yosemite)

完成以下命令后:

$ git init
$ git add
$ git commit -m "added new stuff"
$ git remote add origin https://github.com/user/repo.git
$ git push -u origin master

我收到此錯誤:

To https://github.com/user/repo.git>
! [rejected]        master -> master (fetch first)
error: failed to push some refs to
'https://github.com/user/repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

然后我嘗試了...

$ git pull --commit https://github.com/user/repo.git

我知道了

Merge https://github.com/user/repo
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

這些錯誤在英語中是什么意思? 接下來我該怎么辦?

有沒有一種方法可以僅“轉儲”隊列中的所有內容(而無需嘗試“拉出”),這樣我就可以繼續進行新的提交了? 我對下一步該怎么辦感到很困惑。

首先,讓我建議您閱讀Pro Git書 ,因為git隨附的大多數文檔都非常糟糕,尤其是對於新手。 (與5年前相比有所改進,但仍然有很多不足之處。)

就是說,讓我在這里嘗試快速介紹“您需要知道的內容”。

介紹性的東西

  1. 當與其他人一起工作時(包括在這里被稱為“其他人”的github),您的git會通過互聯網電話調出他們的git並進行工作。 這些其他人都是同齡人 ,也就是說,他們具有與您所做的新工作完全相同的能力,至少在一般情況下(github本身不會獨自完成新工作)。 這意味着在交換期間,您可能擁有“他們”(無論他們是什么)所沒有的東西,但是他們也可能擁有您所沒有的東西。
  2. Git與單個提交交換工作。 1確切地說,哪個提交以及如何提交變得更加復雜,所以讓我們暫緩一下。
  3. git push的反義不是git pull ,實際上是git fetch 我認為您收到的錯誤消息不應直接引用git pull ; 我們也會對此進行詳細介紹。
  4. Git通過其“真實名稱” SHA-1 ID來在內部跟蹤提交,例如,這是您在git log輸出中看到的長40個字符的十六進制內容。 每個提交都有一組由SHA-1 ID標識的“父”提交。 您可以自己使用SHA-1 ID,但是它們對人類非常不友好,您永遠不會記住應該以f13c9ab還是0e1d227或其他任何f13c9ab 0e1d227 (這些都是縮寫 ID!)。
  5. 因此,git因此為用戶提供了分支名稱,例如master 分支名稱只是您告訴git用來跟蹤在該分支上所做的最新提交的名稱。
  6. 最新的提交具有作為其父級的“過去是最新的”提交,其父級具有甚至更老的“最新”的提交,依此類推。 (git實現此目的的方法非常簡單:當您進行新的提交時,其父節點為“當前提交”,並且一旦將提交安全地存儲在存儲庫中,git就會用的ID替換分支中存儲的ID。新的提交。)

給定最后三項,讓我們繪制一個提交圖片段:

... <- 1f3a33c <- 98ab102   <-- branch

在這里,分支的尖端是commit 98ab102 ,其父節點是1f3a33c 我們可以說名稱branch “指向” 98ab102 ,它指向其父級,依此類推。

當您創建一個新的存儲庫( git init ,假設實際上是2 )時,它完全沒有提交,因此第一個提交沒有父級。 它是第二個和第三個提交,以此類推,它指向以前的提交。

當您進行“合並”時,您告訴git接受兩個(或三個,但現在僅說兩個)現有的提交,並通過合並來自某些提交的所有更改來進行一個新的提交,將兩者作為父提交共同點。 合並不是那么復雜,但是您通常應該在故意將工作划分為不同的開發線之后進行合並。

現在,返回以獲取,推動和拉動

您已經創建了一個新的存儲庫( git init ),至少放入了一個提交( git commit ),並添加了一個“遠程”( git remote add origin ... )。 最后一步說:“我有一個對等git,我想稱其為origin ,所以請記住該名稱下的URL。”

然后,您要求您的git調用“ origin”( git push ... origin ),並根據您的分支名稱“ master”( git push ... master )找到您提交的提交。 這是有點棘手的地方。 當你的git的會談,他混帳,應他的混帳使用什么名字? 簡短的答案是, 他的 git也將使用master名稱。 這是可變的,但是更改不是您想要的。

(您還通過-u標志要求讓git在您的git配置中記錄此交換。我們暫時將其保留。)

當您的git調用自己的git時,您的git會說“在這里,查看這些閃亮的新提交”(然后他做了),然后您的git說道:“為什么不將這些新提交完全按原樣添加到您的存儲庫中, 4和使您的master指向這些承諾中最重要的一個?” 他的回答是:“嗯,我做到這一點,但我會失去一些提交沒有。” 在這里您可以看到被rejected消息。

也許您希望他們到目前為止忘記他們的東西。 如果是這樣,您可以要求“強制推送”,即使您的git“丟失”了某些提交,您也可以讓他們的git告訴他們設置master 是否執行此操作仍由他們決定,但通常不是您想要的。

也許您想拿起他們擁有的東西並將其添加到您的收藏夾中,或者拿起他們擁有的東西並拋棄自己的工作。 這是您要git fetch

什么git fetch呢,去復雜盡可能,5是調用通過互聯網,手機同行,並找出他們有什么, 不知道。 它帶來了所有這些提交(記住,交換是通過提交進行的),並將它們(類似於Borg)添加到您的存儲庫中。 然后,這是至關重要的部分,它將更改分支名稱,以便它們不會干擾您的分支名稱。

git fetch用於與您的同級同步的名稱稱為“遠程跟蹤分支”,有時也稱為“遠程分支”。 關於“遠程分支機構”的一件奇怪的事是它們實際上不在遠程! 它們保存在您自己的存儲庫中。 原因很簡單:它們是git上次與該遠程通話時的遠程快照。 在兩個git掛斷Internet電話后,可以更改遙控器。 (當然,遠程實際更改的速度取決於遠程git的繁忙程度。)

此處的重命名模式很簡單:以遙控器的分支名稱(如master )並在前面添加遙控器的名稱( origin ):您的origin/master “跟蹤” originmaster (有一種全名表格,如果您意外地命名了自己的純本地,非遠程跟蹤分支或origin/oops分支的話,則可以使用,但最好的選擇是一開始就不要這樣做。 )

等一下, git pull從哪里來?

注意,到目前為止,都是git pushgit fetch 但是,假設您已經完成了git fetch並完成了他們的工作? 現在你有一個有點問題:你有你的工作,你有自己的工作,而這兩個有分歧。

如果你們都是從一個共同的基礎開始,我們可以這樣繪制您的提交圖:

... base <- yours   <-- HEAD -> master
         \
           theirs   <-- origin/master

這次我放入HEAD ->以顯示您所在的分支(運行git status ,您應該在其輸出中看到“ on branch master”)。

將這兩個不同的工作聯系在一起的一種簡單方法是使用git merge 如果你想這樣做,你只要運行git merge origin/master (注意斜線:你希望你的git找到你的 origin/master ,它在拿起git fetch和合並到這一點你的master ,使一個新的提交在您的master )。 結果看起來像這樣:

... base <- yours <- merge  <-- HEAD -> master
         \         /
           theirs      <-- origin/master

處理此問題的另一種方法(實際上通常是更好的方法)是使用git rebase ,我在這里不做詳細介紹。 關於使用rebase ,有很多StackOverflow答案。 但是,如果這樣做,您將獲得:

... base <- theirs <- yours   <-- HEAD -> master
                  \
                   .......... <-- origin/master

(請注意,在所有情況下, origin/master仍然指向最尖端的“其”提交。)

現在要牢記的主要一點是,無論您做什么,如果想讓他們的git接受您的提交而不必強行按下,則需要使您的工作成為他們的附加內容,以便您新的提交“指向”他們的。 push過程並不重要,您的工作是將其作為合並提交的“第二父級”,還是直接在其提交上進行構建; 它只需要通過提交ID指向其提交即可。 (但同樣,重新設置通常比合並好!)

所以, git pull (finally!)...

簡化的git pull所做的只是運行git fetch然后git merge 簡而言之,它是一個方便腳本:您總是先獲取然后合並,因此我們將為您提供一個先獲取然后合並的腳本。

當然, git merge通常是錯誤的。 默認情況下,它確實應該使用git rebase

您可以使 git pull使用git rebase 6,但是我認為至少(或者特別是對新手)使用兩個單獨的步驟是明智的,部分原因是如果出現問題,從中恢復的方式會有所不同兩種不同的動作。 要擺脫失敗的合並,請使用git merge --abort 要擺脫失敗的rebase,可以使用git rebase --abort (這些曾經更加不同,現在只是“中止一切失敗”,這是一個很大的改進。但是您需要知道該怎么做,如果您從git mergegit rebase開始,這將變得非常清楚。)

底線

最后,您需要在此處執行的操作取決於您要執行的操作以及遙控器允許您執行的操作。 如果您想放下它們的東西,請使用git push -f (強制),要知道您正在以這種方式使他們(無論他們為誰)感到痛苦,並且他們可能會完全禁止這樣做。 如果要保留它們的內容,請先使用git fetch ,然后按自己的意願保留它們的內容(合並,變基,重做等)。


1或帶有補丁,您可以通過電子郵件與同行交換。 也可以“捆綁”提交並通過其他方法轉移它們。 但是在這種情況下,我們正在通過Internet電話進行基於提交的交換。

2您可以在現有存儲庫中安全地運行git init 它的作用很小,但就我們的目的而言,它基本上什么也沒做,因此需要說“假設它確實能做到”。

3 Git將此稱為“章魚”合並,即使只有3個或4個父級而不是8個。

4 Git通常只會添加“更多內容”。 我喜歡將其稱為“ Git Borg” ,其中git在其現有系列中增加了您的技術獨特性。

5 git的一個共同主題是“這是不太你想要什么?沒關系,我們會保持現有的東西, 但要更復雜 ,所以你可以做想做什么呢!”

6見腳注5。

這樣的答案表明:

git fetch --all
git reset --hard origin/master

但是我還沒有嘗試過,所以不能確定它是否可以解決問題。 但這至少是一個嘗試的方向。

GIT告訴您先獲取。 您可以在日志中看到

$ git fetch -all

可能其他人已經推動精通,而您的承諾落伍了。 因此,您必須獲取,合並更改集,然后才能再次推送。

如果顯示遙控器上有更改,請執行“ Pull”操作,這將更新您的工作目錄。

$ git pull

然后您將更改推送到遙控器

$ git push -u origin master

我希望這會幫助您將更改推向大師

暫無
暫無

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

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