我的每個拉取請求都作為對所有先前拉取請求的提交可見,這讓我大吃一驚,因為我希望每個 PR 只有其提交可見 請參見影像。
在這張圖片中,“testbranch2”、“testbranch3”和“update1”都是不同的分支。我不希望他們的提交在“testbranch3”拉取請求中可見......
我提交和推送的方式
git add .
git commit -m "update2"
git push --set-upstream origin "branchName"
//then I create new branch before I start working
git checkout -b "branchName2"
我究竟做錯了什么 ?
uj5u.com熱心網友回復:
我究竟做錯了什么 ?
相信樹枝。??
說真的,整個問題都與你認為Git 所做的事情與 Git實際所做的事情有關。在 Git 中,分支名稱并不重要。也就是說,它們對您(人類)很重要,但對 Git 無關。對 Git 來說重要的是commits。你需要把 Git 看作是關于提交的——不是分支,不是檔案,而是提交。
好的,但是:實際上,這意味著什么?現在是星期一早上(至少現在就在這里),那么你會做些什么不同的事情來讓 Git 為你作業呢?答案從運行git log --graph --decorate或開始git log --all --decorate --oneline --graph。另請參閱Pretty Git 分支圖(查看圖表的更多選項)。這種圖表不僅顯示了個人提交本身,還顯示了提交之間的關系,您將如何知道稍后會在拉取請求中顯示什么。
請記住,這只是幫助你想象你已經擁有的東西。 您還必須做一些其他不同的事情,以便您構建其他不同的東西,以便您看到的內容發生變化。但是如果你看不到它——如果你不能預覽你擁有的東西,在你提交給 GItHub 來做一個 Pull Request 之前,你只是在黑暗中摸索。 一旦你能看到你在做什么,那么就該改變你在做什么了。
不幸的是,分支在 Git 中是一個壞詞。從褻瀆的意義上說還不錯,但從某種意義上說,它有如此多的含義,以至于它沒有任何意義。分支確實存在,但是當有人說“分支”時,它們是什么意思? (另請參閱“分支”到底是什么意思?)要正確到達那里,我們必須從單個提交開始。
提交
一個 Git 提交:
有編號。它有一個唯一的數字,非常大且看起來很隨機,例如
dda7228a83e2e9ff584bf6adbf55910565b41e14. 這個大而丑陋的數字對人類來說太難處理了(我使用剪切和粘貼來獲取這個數字),這就是 Git 實際找到提交的方式。Git 確實需要該數字才能找到提交。是只讀的。這是相當神奇的編號系統所必需的。編號系統的神奇之處在于,宇宙中的每個Git 系統都同意該提交獲得該編號,即使沒有與其他 Git 軟體交談。當您進行新的提交時,它會獲得一個新的、唯一的編號,以前從未使用過,也不會再次使用。這在數學上是不可能的,總有一天 Git 會崩潰,但是數字空間的絕對大小讓我們希望永遠不會看到它(盡管另見新發現的 SHA-1 沖突如何影響 Git?);但要讓它在此之前作業,提交必須是只讀的。他們是。
存盤兩個東西:
直接地,每個提交都存盤一些元資料,或者關于提交本身的資訊。這包括提交作者的姓名和電子郵件地址,以及一些日期和時間戳。
間接地,每個檔案的完整快照。此快照采用特殊的壓縮格式,與任何提交的所有部分一樣是只讀的;但對于 Git 本身來說很重要的是,每個檔案的內容都經過重復資料洗掉。因此,當下一次提交中的完整快照主要是本次提交中完整快照的副本時,下一次提交不會占用太多空間,因為所有重復的檔案都不占用空間。同樣,此提交并沒有占用太多空間,因為它主要包含來自早期(或以后)提交的檔案的副本。
您通常不必非常關心這些細節,只要您記住每個提交都包含元資料和完整快照。但是您確實需要關心元資料的某些部分。 例如,您提供日志訊息,它應該是您和其他人稍后可以閱讀并找出您進行此提交的原因的內容。(你不必擔心提交的變化,因為Git可以比較相鄰的快照來找到變化。你需要解釋的是變化的原因。)
現在,對于 Git 自己的操作,每個提交的元資料中還有另外一件非常重要的事情。每個提交都有編號,每個提交在其元資料中包含一些早期提交的提交編號——哈希 ID 。 大多數提交只包含一個較早提交的哈希 ID。 我們將這樣的提交稱為普通提交,存盤的哈希 ID 是提交的父級。
這為普通提交提供了簡單的父/子關系。
了解提交如何形成分支
假設我們做了一個新的提交,它有一些看起來很丑的哈希 ID,我們H簡稱為 Hash。讓我們畫它,它漂浮在太空中,并帶有一個箭頭:
<-H
突出的箭頭表示存盤在的元資料中H的哈希 ID 。這個存盤的父哈希 ID 有效地指向的父提交。讓我們稱之為 commit ,并把它畫進去: H HG
<-G <-H
假設G也是一個普通的提交,它有一個像這樣伸出的箭頭,表示存盤在G其中的哈希 ID 指向G的 parent F:
... <-F <-G <-H
這一直重復到第一次提交。第一次提交的特別之處在于,作為第一個,它不會向后指向。這讓 Git 停止倒退。
對此有兩點需要注意:
首先,Git需要哈希 ID 來查找提交,但提交具有父/子關系,其中子節點向后指向父節點,因此 Git 可以自己找到哈希 ID。
其次,這適用于除最后一個之外的每個提交。沒有提交“最后一次”來查找最后一次提交。
為了解決這個問題,我們可以只記住哈希 ID,但這是一個令人不快的前景。誰想記住dda7228a83...或什么?但是,嘿,等一下,我們有一臺電腦。計算機擅長這種記憶。為什么我們不選擇一個名字,比如mainor master,然后用這個名字來存盤一個哈希 ID?
這正是我們所做的:
...--F--G--H <-- main
我們稱之為分支。或者,我們稱這個名字 main為branch。或者,我們稱別的東西為分支。我們稱很多東西為“分支”,以至于有人說“分支”或“分支”,如果沒有更多背景關系或資訊,我們不知道它們的實際含義。
分支名稱查找提交
現在,假設我們有一個現有的提交鏈——我們可以稱之為“分支”——在提交處結束,H如下所示:
...--G--H <-- main
讓我們創建一個新的分支名稱,例如develop. 我們必須選擇一個提交。我們應該選擇哪一個?怎么樣H,最新的?
...--G--H <-- main, develop
這是一個技巧問題:這些提交在哪個分支上?
讓我插入一些分支的圖片以幫助隱藏答案,同時您考慮一下。??

如果分支是真實的東西,這將不是一個棘手的問題,但 Git 中的分支畢竟不是很真實,而且確實如此。訣竅是所有提交都在兩個分支上。在我們之前develop,所有的提交都只在一個分支上。如果我們現在創建第三個分支名稱,所有提交都在三個分支上。
在Git 中,分支名稱僅定位分支上的最后一次提交。其實分支名的定義就是它指向的commit 是分支上的最后一個commit!因此,如果我們決定創建一個指向 commit 的名稱G:
...--G <-- foobranch
\
H <-- main, develop
然后突然之間,直到并包括在內的每個提交G都在所有三個分支上,并且通過并包括在內的提交H都在兩個分支上。CommitG是branch 上的最后一次foobranch提交。
請記住,所有這些提交都是完全只讀的。當我們創建和銷毀分支名稱時,提交本身沒有任何變化。該名稱僅用于指向一個特定的提交。通過指向那個提交,它可以讓 Git(和我們)快速找到那個特定的提交——然后 Git 可以從那個點向后作業,但不能向前作業。
就是這樣:這是分支名稱的主要目的。它找到一個提交,它找到的一個提交被定義為分支的尖端提交。但是為了使這項作業順利進行,還有另一個特殊功能。
分支名稱移動
讓我們再次像這樣繪制我們的存盤庫:
...--G--H <-- main
并添加一個新的分支名稱:
...--G--H <-- main, develop
然后進行新的提交。新提交將獲得一些看起來隨機的哈希 ID;我們就叫它吧I。新提交I將向后指向現有提交H,原因我稍后會解釋,我們將擁有:
...--G--H
\
I
我們的兩個分支名稱之一應該更新為指向I. 但是哪一個?
這就是在樹枝上的意義所在。如果git status說on branch main,我們將得到:
...--G--H <-- develop
\
I <-- main
這可能不是我們想要的。我們可能希望成為“on”分支develop,以便我們得到:
...--G--H <-- main
\
I <-- develop
為了幫助顯示我們“啟用”了哪個分支名稱(例如,git status會說該分支的名稱),讓我們將特殊名稱附加HEAD到一個分支名稱上,如下所示:
...--G--H <-- main (HEAD), develop
哎呀!我們“在”錯誤的分支。我們跑:
git switch develop # or git checkout develop
我們得到:
...--G--H <-- main, develop (HEAD)
除了附件之外沒有其他任何變化,HEAD因為兩個H名稱現在都選擇提交。但隨后我們進行更改 and git add,git commit我們得到:
...--G--H <-- main
\
I <-- develop (HEAD)
這就是我們想要的。請注意如何HEAD仍然“附加”到名稱develop。
如果我們現在這樣git switch做main,Git 這次會做得更多。特別是 Git 將洗掉檔案的I提交版本,并切換回H檔案的提交版本。
Git 可以安全地執行此操作,因為提交的檔案(間接)存盤在 commit中,安全地只讀并保存,只要提交存在(通常“永遠”,盡管有“丟失”提交的方法)。如果 Git不能安全地做到這一點——如果你開始作業,然后意識到你在錯誤的分支上,有時會發生這種情況——git switch命令會告訴你,并拒絕切換分支。(我們不會在這里擔心如何解決該問題,但可以解決。)
(我們也沒有在這里介紹 Git 實際如何制作快照的復雜性。這令人驚訝,至少對于那些習慣于其他版本控制系統的人來說。)
回到你原來的問題
git add . git commit -m "update2" git push --set-upstream origin "branchName"
這部分沒問題,盡管“update2”是一個糟糕的提交訊息,因為它沒有說明為什么你改變了你改變了什么。git push出于篇幅原因,我們現在也將跳過所有復雜性。
但是,我們應該繪制您創建的提交的圖片:
...--G--H <-- main
\
I <-- branchName (HEAD)
您當前正在I通過附加的分支名稱“branchName進行”提交HEAD。
//then I create new branch before I start working git checkout -b "branchName2"
旁白:考慮從 移動git checkout到git switch。對于簡單的情況,這兩個命令做的事情完全相同(除了你需要這里-c而不是-b這里)。對于復雜的情況,git switch更安全,因為它不會將所有git restore代碼捆綁到同一個命令中。1
該-b選項告訴git checkout(或-c告訴git switch)此時創建一??個新的分支名稱。新分支名稱將指向當前提交,也就是您的新提交I。最后,命令切換到新的分支名稱,因此結果如下所示:
...--G--H <-- main
\
I <-- branchName, branchName2 (HEAD)
如果您現在進行另一個新的提交,結果如下所示:
...--G--H <-- main
\
I <-- branchName
\
J <-- branchName2 (HEAD)
這不是你想要的。 您想要一個看起來更像這樣的結果:
J <-- branchName2 (HEAD)
/
...--G--H <-- main
\
I <-- branchName
也就是說,您將希望 commitJ獨立于commit I,以便它不包括您在其中所做的任何作業,并I使其連接回 commitH作為其父級,而不是I作為其父級 commit。
那是因為稍后,當您提出拉取請求時,Git Hub(不是 Git 本身,而是 GitHub)將使用提交H作為“基礎”提交。GitHub(不是 Git)對 Pull Requests 有“基礎分支”的概念。請注意,拉取請求是 GitHub 特定的專案:它們不是 Git 的一部分。他們使用 Git 的提交,他們使用分支名稱,但他們為這些分支名稱賦予了比 Git 更多的含義。
因為這就是你想要的,你的命令序列應該看起來更像:
git switch main
git switch -c branchName2
(或git checkout main然后git checkout -b branchName2)。這里main可能是master或develop其他名稱,具體取決于您和您的團隊決定使用什么,但一般的想法是您將首先切換回您想要用作新提交的父提交的提交打算馬上做。為此,您將使用找到該提交的任何分支名稱。
請注意,如果您愿意,可以“提前計劃”。假設你還沒有做branchName,只是有:
...--G--H <-- main (HEAD)
您現在可以運行:
git branch branchName
git branch branchName2
并得到:
...--G--H <-- main (HEAD), branchName, branchName2
也就是說,此時所有三個名稱都存在,并且它們都選擇 commit H,您的起點提交。您現在git switch可以使用任何名稱并開始進行新的提交。
(不過,我通常會在自己切換到分支名稱時創建分支名稱:舊的git checkout -b或新奇的git switch -c。)
1該git checkout命令較舊,可同時進行切換和恢復。該git switch命令是“安全的”,因為它不會破壞未提交的作業;該git restore命令是“不安全的”,因為它假設如果你給它的引數意味著破壞我未提交的作業,你就是那個意思。Git 新手不知道哪些引數git checkout在“安全”(切換)模式下運行,哪些在“不安全”(恢復)模式下運行。因此,如果您使用兩個單獨的命令,您只需要在運行時格外小心git restore,而不是在每個分支開關上。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/510510.html
標籤:混帐github
