本文內容主要包括如下幾點,帶你們一塊兒看git的發展歷程git
發展歷史程序員
基本功能github
基本用法web
約定npm
命令詳解分佈式
· Commitpost
· Checkoutfetch
· Detached HEAD(匿名分支提交)spa
· Reset版本控制
· Merge
· Cherry Pick
· Rebase
技巧
2008年4月10日,GitHub正式上線。
2014年1月23日,聯合創始人湯姆·普雷斯頓-維爾納(Tom Preston-Werner)從另外一位聯合創始人克里斯·萬斯特拉斯(Chris Wanstrath)手中接過總裁職位,後者也將接過普雷斯頓-維爾納留下的CEO位置。
2018年6月4日晚,微軟宣佈,經過75億美圓的股票交易收購GitHub。 [2] 10月26日,微軟以75億美圓收購GitHub交易已完成。10月29日,微軟開發者服務副總裁奈特·弗裏德曼(Nat Friedman)將成爲GitHub的新一任CEO。 [3]
2020年3月17日,Github宣佈收購npm,GitHub如今已經保證npm將永遠免費。 [4]
做爲開源代碼庫以及版本控制系統,Github擁有超過900萬開發者用戶。隨着愈來愈多的應用程序轉移到了雲上,Github已經成爲了管理軟件開發以及發現已有代碼的首選方法。
如前所述,做爲一個分佈式的版本控制系統,在Git中並不存在主庫這樣的概念,每一份複製出的庫均可以獨立使用,任何兩個庫之間的不一致之處均可以進行合併。
GitHub能夠託管各類git庫,並提供一個web界面,但它與外國的SourceForge、Google Code或中國的coding的服務不一樣,GitHub的獨特賣點在於從另一個項目進行分支的簡易性。爲一個項目貢獻代碼很是簡單:首先點擊項目站點的「fork」的按鈕,而後將代碼檢出並將修改加入到剛纔分出的代碼庫中,最後經過內建的「pull request」機制向項目負責人申請代碼合併。已經有人將GitHub稱爲代碼玩家的MySpace。
在GitHub進行分支就像在Myspace(或Facebook…)進行交友同樣,在社會關係圖的節點中不斷的連線。
GitHub項目自己天然而然的也在GitHub上進行託管,只不過在一個私
有的,公共視圖不可見的庫中。開源項目能夠免費託管,但私有庫則並不如此。Chris Wanstrath,GitHub的開發者之一,確定了經過付費的私有庫來在財務上支持免費庫的託管這一計劃。
經過與客戶的接洽,開發FamSpam,甚至是開發GitHub自己,GitHub的私有庫已經被證實了物有所值。任何但願節省時間並但願和團隊其它成員同樣遠離頁面頻繁轉換之苦的人士都會從GitHub中得到他們真正想要的價值。
在GitHub,用戶能夠十分輕易地找到海量的開源代碼。
那在整理和了解了git的相關發展經歷和基本功能以後,對於程序員最重要的話題也是搜索最多的詞彙--用法就要出來了,那對於github,咱們有那些比較好的操做命令呢?做爲一個資深程序員,那確定想到了呀,來看一下吧
下面的四條命令在工做目錄、暫存目錄(也叫作索引)和倉庫之間複製文件。
· git add files 把當前文件放入暫存區域。
· git commit 給暫存區域生成快照並提交。
· git reset -- files 用來撤銷最後一次git add files,你也能夠用git reset 撤銷全部暫存區域文件。
· git checkout -- files 把文件從暫存區域複製到工做目錄,用來丟棄本地修改。
你能夠用 git reset -p, git checkout -p, or git add -p進入交互模式。
也能夠跳過暫存區域直接從倉庫取出文件或者直接提交代碼。
· git commit -a 至關於運行 git add 把全部當前目錄下的文件加入暫存區域再運行。git commit.
· git commit files 進行一次包含最後一次提交加上工做目錄中文件快照的提交。而且文件被添加到暫存區域。
· git checkout HEAD -- files 回滾到複製最後一次提交。
後文中如下面的形式使用圖片。
綠色的5位字符表示提交的ID,分別指向父節點。分支用橘色顯示,分別指向特定的提交。當前分支由附在其上的HEAD標識。 這張圖片裏顯示最後5次提交,ed489是最新提交。 master分支指向這次提交,另外一個maint分支指向祖父提交節點。
提交時,git用暫存區域的文件建立一個新的提交,並把此時的節點設爲父節點。而後把當前分支指向新的提交節點。下圖中,當前分支是master。 在運行命令以前,master指向ed489,提交後,master指向新的節點f0cec並以ed489做爲父節點。
即使當前分支是某次提交的祖父節點,git會一樣操做。下圖中,在master分支的祖父節點maint分支進行一次提交,生成了1800b。 這樣,maint分支就再也不是master分支的祖父節點。此時,合併 (或者 衍合) 是必須的。
若是想更改一次提交,使用 git commit --amend。git會使用與當前提交相同的父節點進行一次新提交,舊的提交會被取消。
checkout命令用於從歷史提交(或者暫存區域)中拷貝文件到工做目錄,也可用於切換分支。
當給定某個文件名(或者打開-p選項,或者文件名和-p選項同時打開)時,git會從指定的提交中拷貝文件到暫存區域和工做目錄。好比,git checkout HEAD~ foo.c會將提交節點HEAD~(即當前提交節點的父節點)中的foo.c複製到工做目錄而且加到暫存區域中。(若是命令中沒有指定提交節點,則會從暫存區域中拷貝內容。)注意當前分支不會發生變化。
當不指定文件名,而是給出一個(本地)分支時,那麼HEAD標識會移動到那個分支(也就是說,咱們「切換」到那個分支了),而後暫存區域和工做目錄中的內容會和HEAD對應的提交節點一致。新提交節點(下圖中的a47c3)中的全部文件都會被複制(到暫存區域和工做目錄中);只存在於老的提交節點(ed489)中的文件會被刪除;不屬於上述二者的文件會被忽略,不受影響。
若是既沒有指定文件名,也沒有指定分支名,而是一個標籤、遠程分支、SHA-1值或者是像master~3相似的東西,就獲得一個匿名分支,稱做detached HEAD(被分離的HEAD標識)。這樣能夠很方便地在歷史版本之間互相切換。好比說你想要編譯1.6.6.1版本的git,你能夠運行git checkout v1.6.6.1(這是一個標籤,而非分支名),編譯,安裝,而後切換回另外一個分支,好比說git checkout master。然而,當提交操做涉及到「分離的HEAD」時,其行爲會略有不一樣,詳情見在 下面。
當HEAD處於分離狀態(不依附於任一分支)時,提交操做能夠正常進行,可是不會更新任何已命名的分支。(你能夠認爲這是在更新一個匿名分支。)
一旦此後你切換到別的分支,好比說master,那麼這個提交節點(可能)不再會被引用到,而後就會被丟棄掉了。注意這個命令以後就不會有東西引用2eecb。
可是,若是你想保存這個狀態,能夠用命令git checkout -b name來建立一個新的分支。
reset命令把當前分支指向另外一個位置,而且有選擇的變更工做目錄和索引。也用來在從歷史倉庫中複製文件到索引,而不動工做目錄。
若是不給選項,那麼當前分支指向到那個提交。若是用--hard選項,那麼工做目錄也更新,若是用--soft選項,那麼都不變。
若是沒有給出提交點的版本號,那麼默認用HEAD。這樣,分支指向不變,可是索引會回滾到最後一次提交,若是用--hard選項,工做目錄也一樣。
若是給了文件名(或者 -p選項), 那麼工做效果和帶文件名的checkout差很少,除了索引被更新。
merge 命令把不一樣分支合併起來。合併前,索引必須和當前提交相同。若是另外一個分支是當前提交的祖父節點,那麼合併命令將什麼也不作。 另外一種狀況是若是當前提交是另外一個分支的祖父節點,就致使fast-forward合併。指向只是簡單的移動,並生成一個新的提交。
不然就是一次真正的合併。默認把當前提交(ed489 以下所示)和另外一個提交(33104)以及他們的共同祖父節點(b325c)進行一次三方合併。結果是先保存當前目錄和索引,而後和父節點33104一塊兒作一次新提交。
cherry-pick命令"複製"一個提交節點並在當前分支作一次徹底同樣的新提交。
衍合是合併命令的另外一種選擇。合併把兩個父分支合併進行一次提交,提交歷史不是線性的。衍合在當前分支上重演另外一個分支的歷史,提交歷史是線性的。 本質上,這是線性化的自動的 cherry-pick
上面的命令都在topic分支中進行,而不是master分支,在master分支上重演,而且把分支指向新的節點。注意舊提交沒有被引用,將被回收。
要限制回滾範圍,使用--onto選項。下面的命令在master分支上重演當前分支從169a6以來的最近幾個提交,即2c33a。
一樣有git rebase --interactive讓你更方便的完成一些複雜操做,好比丟棄、重排、修改、合併提交。沒有圖片體現這些,細節看這裏:git-rebase(1)
1. 在最後提交中更改Export(Export changes done in last commit )
這個命令一般會使用按期發送已更改的項目,以方便其餘人審查/集成。
gitarchive-o../updated.zipHEAD$(gitdiff--name-onlyHEAD^)
2. 在兩次提交之間更改Export文件(Export changed files between two commits)
一樣地,若是你須要在兩次提交之間更改文件,能夠選擇如下這段代碼。
gitarchive-o../latest.zipNEW_COMMIT_ID_HERE$(gitdiff--name-onlyOLD_COMMIT_ID_HERENEW_COMMIT_ID_HERE)
3. 克隆一個特定的遠程分支(Clone a specific remote branch)
若是你想從遠程資源庫中克隆一個特定的分支,而無需克隆整個資源庫分支,那麼下面的這段代碼將對你有用。
gitinit
gitremoteadd-tBRANCH_NAME_HERE-foriginREMOTE_REPO_URL_PATH_HERE
gitcheckoutBRANCH_NAME_HERE
4. 從不相關的本地資源庫中應用補丁(Apply patch from Unrelated local repository)
這裏有個快捷方式可幫助你實現。
git--git-dir=PATH_TO_OTHER_REPOSITORY_HERE/.gitformat-patch-k-1--stdoutCOMMIT_HASH_ID_HERE|gitam-3-k
5. 檢查分支是否在其它分支中遭到更改(Check if your Branch changes are part of Other branch)
cherry這個命令,可以檢查你的分支在其餘分支中是否被更改。它會在當前的分支上顯示變化,並註明+或-標識符。+表明不存在,-表示在現有的分支中存在。
gitcherry-vOTHER_BRANCH_NAME_HERE
#Forexample:tocheckwithmasterbranch
gitcherry-vmaster
6. 啓動一個無歷史記錄的新分支( Start a new Branch with No History)
有時,你想啓動一個新的分支,但並不想運行漫長的歷史記錄,例如,你想將代碼放置在一個公共的域中(開源),但又不想共享歷史。
gitcheckout--orphanNEW_BRANCH_NAME_HERE
7. 從其餘分支簽出文件但無需切換分支( Checkout File from Other Branch without Switching Branches )
這裏將教你如何獲取想要的文件。
gitcheckoutBRANCH_NAME_HERE--PATH_TO_FILE_IN_BRANCH_HERE
8. 忽略追蹤文件中的更改( Ignore Changes in a Tracked File )
若是你是在某個團隊中工做,他們都在使用同一個分支,也許你會頻繁使用提取/合併(fetch/merge),但這有時須要重置特定的配置文件,這就意味着在每次合併後你必須去作更改。如今,使用這個命令,你能夠要求Git忽略更改特定文件。
gitupdate-index--assume-unchangedPATH_TO_FILE_HERE
9. 檢查已提交部分是否在發佈的版本中遭到更改(Check if committed changes are part of a release)
name-rev這個命令能夠告訴你已提交到最新版本的某個位置。使用這個代碼可幫助你檢查,提交的部分是否在已發佈版本中遭到更改。
gitname-rev--name-onlyCOMMIT_HASH_HERE
10. 用復位替代合併(Pull with rebase instead of merge )
當某項特性分支被合併到主流中,此時該分支合併會在Git中以合併提交來進行記錄。可是當團隊中多個成員在同一個分支上工做時,常規的合併會致使多個合併消息在日誌中呈現混亂狀態。所以,你可使用復位(rebase)來保持歷史清晰,清除無用的合併消息。
gitpull--rebase
此外,你還能夠經過配置一個特定的分支來複位。
gitconfigbranch.BRANCH_NAME_HERE.rebasetrue
11. 保存http用戶/密碼,增長http上傳數據的大小
git config --global credential.helper store
git config --global http.postBuffer 524288000