1. Git的概述:
什么是Git?
--> 是用C語言開發(fā)的分布式版本控制系統(tǒng)。
--> 版本控制系統(tǒng)可以保留一個文件集合的歷史記錄,并能回滾文件集合到另一個狀態(tài)(歷史記錄狀態(tài))。另一個狀態(tài)可以是不同的文件,也可以是不同的文件內(nèi)容。->舉個例子,你可以將文件集合轉換到兩天之前的狀態(tài),或者你可以在生產(chǎn)代碼和實驗性質的代碼之間進行切換。文件集合往往被稱作是“源代碼”。在一個分布版本控制系統(tǒng)中,每個人都有一份完整的源代碼(包括源代碼所有的歷史記錄信息),而且可以對這個本地的數(shù)據(jù)進行操作。分布版本控制系統(tǒng)不需要一個集中式的代碼倉庫。
使用Git的功能:
當你對本地的源代碼進行了修改,你可以標注它們和下一個版本相關(將他們加入到stage的暫存區(qū)中 -- add
),然后提交到分支的本地倉庫中去( commit
)。git 保存了所有的版本信息,所以可以轉換源代碼到任何的歷史版本。你可以對本地的倉庫進行代碼的提交,然后與其他的遠程或本地倉庫進行同步。你可以使用 git 來進行倉庫的克隆(clone),完整的復制一個已有的遠程倉庫。倉庫的所有者可以進行push操作(推送變更到別處倉庫)或pull操作(從別處倉庫拉取變更)來同步變更。
2. Git的安裝
在終端輸入: git 。可以查看是否安裝了Git.如果已經(jīng)安裝了Git,可通過在終端輸入:"gitk"就啟動了,打開圖形工具,用來輔助管理Git;可以查看日志、注釋、分支等信息。
>>方法1: 通過安裝Homebrew,然后在安裝Git。
第一步:打開終端,在終端輸入如下命令安裝Homebrew;
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
然后-輸入密碼,“return”,"brew help"一步步在終端中操作;安裝Homebrew。
第二步:Homebrew安裝好之后,就可以通過brew安裝 Git了
brew install git
>>方法2: 直接去Git官網(wǎng)下載Git安裝。 ttp://git-scm.com/downloads/
>>方法3:可以使用Xcode的集成環(huán)境進行安裝git。
3. Git的重要術語:
4. 使用git (即本地操作)
通常使用git創(chuàng)建版本庫又叫倉庫。英文名 repository
, 可以簡單理解成一個目錄,這個目錄里面的所有文件都可以被 git 管理起來,每個文件的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”。
> 4.1 添加入文件或進行某些代碼更改操作,通過git先操作 add
到倉庫暫存區(qū),然后在 commit
到該分支的本地倉庫。
下面是從新建文件夾 --> 初始化git倉庫 --> 添加新建文件 實現(xiàn)git功能 :
第一步:在合適的地方創(chuàng)建一個目錄。(不一定需要在空目錄下創(chuàng)建Git倉庫,選擇已有東西的目錄也是可以的)
$ cd 拖入某個文件夾即可進入這個目錄
$ mkdir firstgit -- 新建firstgit文件夾
$ cd firstgit -- 進入firstgit文件夾
第二步:用 git init 命令將這個目錄變成可以使用git管理的倉庫。
$ git init
//這樣空的倉庫,就建立好了,可以發(fā)現(xiàn)當前目錄下多了一個 `.git` 的文件夾(.git默認為隱藏文件夾,需要開啟顯示隱藏文件夾功能),這個文件夾中是Git用來跟蹤管理版本庫的,千萬不要手動修改這個目錄里面的文件,不然改亂了,就把Git倉庫給破壞了。 //終端執(zhí)行 ls -a/ls -ah 會發(fā)現(xiàn)目錄里多.git文件(隱藏文件),這個就是git用來跟蹤管理的文件。
第三步:在這個目錄下創(chuàng)建個文件,并輸入一些內(nèi)容。
$ vi readme.txt
然后回車就可以進入剛剛創(chuàng)建的文件中;在鍵盤上敲擊 i 鍵 進入編輯狀態(tài);輸入完成后通過 esc鍵 退出編輯; 輸入 “:wq” 進行保存
** 在進行接下來的步驟之前可以先查看某個倉庫緩存區(qū)的狀態(tài)以及相關文件:git status **
第四步:也同樣可以把外部文件拖入剛剛創(chuàng)建的倉庫,然后在加入到暫存區(qū)和倉庫中區(qū)。用命令git add告訴Git,把文件添加到倉庫
$ git add readme.txt/git add ./git add *.txt
//add: 將修改從工作區(qū)(就是電腦能看到的目錄)提交到stage(或index)的暫存區(qū);這時查看git status 看到添加文件是綠色還未commite
第五步:用命令git commit把文件提交到版本庫
$ git commit -m "第一次提交"
//commit:將修改從stage(或index)的暫存區(qū)提交到 master 分支的版本庫中。
*至此我們已經(jīng)成功地添加并提交了一個文件到本地倉庫。為什么會有add、commit呢?因為commit可以一次提交很多文件,所以你可以多次add不同的文件。如:$git add file1 $git add file2 $git commit -m"2file"
第六步: 如果該本地倉庫鏈接了 `remote`遠程倉庫并且也在本地添加了遠程倉庫的 `remote`地址 接下來可以把本地倉庫傳到github/gitlab上去,在此之前可能需要設置 `username`和 `email`,因為github/gitlab每次commit都會記錄他們。
** 設置本地git中所有git倉庫 uers.name/user.email:
$ git config --global user.name "your name" //給自己起個用戶名
$ git config --global user.email "your_email@youremail.com" //填寫自己的郵箱
** 設置當前git倉庫的 `user.name` + `user.email`
$ git config --user.name "your name" //此用戶名可以和push的倉庫對應。
$ git config --user.email "your_email@youremail.com" //填寫remote倉庫地址郵箱--以便可以做github/gitlab 做相應的配置。
> 4.2 在倉庫中的文件被提交修改
當修改了倉庫中的某個文件中的內(nèi)容時,先使用
git status
查看狀態(tài)顯示綠色的文件已修改的狀態(tài),出現(xiàn)modified: ...
并且顯各個文件為紅色顯示等。接著可以使用命令:
git diff HEAD -- ...
查看修改的內(nèi)容(查看的是工作區(qū)與版本庫最新版本區(qū)別)然后使用命令
git add .
加入到stage(或index)的暫存區(qū),然后git commit -m "倉庫修改本次commit內(nèi)容記錄"
提交到當前分支的本地倉庫。顯示提交完成后,可使用git status
查看是否提交完成,是否文件沒有add或者commit。
> 4.3 撤銷各種場景的修改
場景1:當你改亂了
工作區(qū)
某個文件的內(nèi)容,想直接丟棄工作區(qū)的修改時,用命令git checkout -- "this file"
場景2:當你不但改亂了
工作區(qū)
某個文件的內(nèi)容,還添加到了暫存區(qū)
時,想丟棄修改,分兩步,第一步用命令git reset HEAD "this file"
,就回到了場景1,然后第二步按場景1操作。場景3:已經(jīng)提交了不合適的修改到
版本庫
時,想要撤銷本次提交,使用版本回退命令:git reset --hard HEAD^ --向前一個版本 /區(qū)分于使用版本號回退版本
> 4.4 版本回退
使用
git reflog--簡便歷史記錄
命令查看commit歷史,以便確定回退到哪一個版本。 當然還有另一個查看commit提交歷史命令:git log--詳細commit歷史記錄
(如果嫌輸出信息太多,可以加上--pretty=oneline
參數(shù)后綴可以 即git log --pretty=oneline/git log --online
)現(xiàn)在可以通過
git log
可以看到commit_id(版本號)
。git必須知道當前版本是哪個版本,在Git中,用HEAD
表示當前版本,上一個版本就是:HEAD^
,上上一個版本就是:HEAD^^
,當然往上100個版本寫100個^比較容易數(shù)不過來,所以寫成:HEAD~100
。現(xiàn)在就是要把當前版本回退到
commit_id
的某一個版本去,就可以使用命令:git reset --hard HEAD^^(一個^代表向前一個版本)
,這時就已經(jīng)回退到之前修改的那個版本了。還有一個命令:git reset HEAD^
這個與版本回退不同這是重置,這是的操作是重置版本庫工作區(qū)不變。不過這時
git log
可以發(fā)現(xiàn)回退到當前版本的所有之前的提交歷史已經(jīng)消失了,如果回退操作出錯了可以在未關閉的當前終端窗口找到之前的版本的commit_id(版本號)
,然后使用命令 git reset --hard xxx(xxx版本號的前幾位左右作為區(qū)分,git會自動尋找)。Git的版本回退速度非常快,因為Git在內(nèi)部有個指向當前版本的 HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從新指向。如果見過git效果圖這種操作理解和效果就比較深刻了。在
4
中如果需要回到未來的某個版本就需要之前的版本號如果已經(jīng)關閉當前終端窗口了,就看不到未來的版本號了,但是可以使用命令git reflog
用于記錄每一次命令就可以在一次回到未來的某個版本。
總結:HEAD
指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令: git reset --hard commit_id
穿梭前,用 git reflog / git log
可以查看提交歷史,以便確定要回退到本地倉庫的哪個版本,通過版本號 commit_id
確定。
要重返未來,用 git reflog
查看commit操作命令歷史,以便確定要回到未來的哪個版本。
> 4.5 刪除文件
你通常直接在文件管理器中把沒用的文件刪了,或者用rm命令刪了
現(xiàn)在你有兩個選擇:
- 一是確實要從版本庫中刪除該文件,那就用命令git rm刪掉,并且git commit;
- 另一種情況是刪錯了,因為版本庫里還有呢,所以可以很輕松地把誤刪的文件恢復到最新版本:
git checkout -- test.txt
,git checkout
其實是用版本庫里的版本替換工作區(qū)的版本,無論工作區(qū)是修改還是刪除,都可以實現(xiàn)“一鍵還原”。
總結:命令 git rm
用于刪除一個文件。如果一個文件已經(jīng)被提交到版本庫,那么你永遠不用擔心誤刪,但是要小心,你只能恢復文件到最新版本,你會丟失最近一次提交后你修改的內(nèi)容。
> 4.6 分支的使用
創(chuàng)建了一個屬于你自己的分支,別人看不到,還繼續(xù)在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發(fā)完畢后,再一次性合并到原來的分支上,這樣,既安全,又不影響別人工作。
其他版本控制系統(tǒng)如SVN等都有分支管理,但是用過之后你會發(fā)現(xiàn),這些版本控制系統(tǒng)創(chuàng)建和切換分支比蝸牛還慢,簡直讓人無法忍受,結果分支功能成了擺設,大家都不去用。但git的分支是與眾不同的,無論創(chuàng)建、切換和刪除分支,git可以在很短的時間內(nèi)就能完成!無論你的版本庫是1個文件還是1萬個文件。
在git的版本回退里,每次提交,git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在git里,這個分支叫主分支,即 master分支
。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支
????? 一開始的時候,master分支是一條線,git 用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點:
HEAD
↘
master
↘
OO→ OO→ OO
????? 每次提交,master分支都會向前移動一步,這樣,隨著你不斷提交,master分支的線也越來越長
HEAD
↘
master
↘
OO→ OO→ OO→ OO
????? 當我們創(chuàng)建新的分支,例如 dev 時,git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上;git創(chuàng)建一個分支很快,因為除了增加一個dev指針,改變 HEAD 的指向,工作區(qū)的文件都沒有任何變化!
master
↘
OO→ OO→ OO
↑
dev
↖
HEAD
????? 不過,從現(xiàn)在開始,對工作區(qū)的修改和提交就是針對dev分支了,比如新提交一次后,dev指針往前移動一步,而master指針不變:
master
↘
OO→ OO→ OO→ OO
↑
dev
↖
HEAD
假如我們在dev上的工作完成了,就可以把dev合并到master上。git怎么合并呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合并.所以git合并分支會很快!就改改指針,工作區(qū)內(nèi)容也不變!
master
↘
OO→ OO→ OO→ OO
↑
dev
↖
HEAD
合并完分支后,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉后,我們就剩下了一條master分支:
HEAD
↘
master
↘
OO→ OO→ OO→ OO
>> 分支的實際運用:
????? a. 我們創(chuàng)建dev分支并同步切換到dev分支(二者同步執(zhí)行)
$ git checkout -b dev
Switched to a new branch 'dev'
/*
* git checkout命令加上-b參數(shù)表示創(chuàng)建并切換,相當于以下兩條命令:
* $ git branch dev
* $ git checkout dev
* Switched to branch 'dev'
*/
????? b. 然后,用 git branch
命令查看當前分支,git branch命令會列出所有分支,當前分支前面會標一個 *號
。
$ git branch
* dev
master
????? c. 然后,我們就可以在 dev分支
上正常提交,比如對xxx.txt
做個修改.
$ git add xxx.txt
$ git commit -m "branch test"
????? d. 現(xiàn)在,dev分支的工作完成,我們就可以切換回master分支,在主分支上以便后面的合并。注: 若dev當前分支有未提交內(nèi)容則切換會失敗提示先commit。
$ git checkout master
Switched to branch 'master'
????? e. 切換回 master分支
后,再查看一個 xxx.txt
文件,剛才添加的內(nèi)容不見了!因為那個提交是在dev分支上,而master分支此刻的提交點并沒有變;現(xiàn)在,我們把dev分支的工作成果合并到master分支上;當git無法自動合并分支時,就必須首先解決沖突。解決沖突后,再提交,合并完成。也可以用 git log --graph
命令可以看到分支合并圖
$ git merge dev //git merge命令用于合并指定分支到當前分支。合并后,再master分支查看xxx.txt的內(nèi)容,就可以看到,和dev分支的最新提交是完全一樣的。
????? f. 合并完成后,就可以放心地刪除dev分支了(在沒有把某個分支的內(nèi)容合并之前,若執(zhí)行刪除某個分支,會進行提示,讓你進行合并)
$ git branch -d dev
Deleted branch dev (was fec145a).
//刪除后,查看branch,就只剩下master分支了:
//$ git branch
// * master
????? //g. 如果合并分支時,沒有使用“Fast forward模式”,而禁用Fast forward,加上了"--no--ff"參數(shù)合并,則可以在最后查看分支歷史
$ git merge --no--ff -m "merge with no--ff" dev
$ git log --graph --pretty=oneline --abbrev-commit
> 4.7 可以創(chuàng)建Bug分支修復Bug或增加feature分支來增加新的功能。
> 4.8 忽略特殊文件
有些時候,你必須把某些文件放到git工作目錄中,但又不能提交它們,比如保存了數(shù)據(jù)庫密碼的配置文件等等,每次git status都會顯示Untracked files ...解決方法:在git工作區(qū)的根目錄下創(chuàng)建一個特殊的 .gitignore文件
,然后把要忽略的文件名填進去,git就會自動忽略這些文件。不需要從頭寫 .gitignore
文件,在使用GitHub中已經(jīng)為我們準備了各種配置文件,只需要組合一下就可以使用了
忽略文件的原則是:
*忽略操作系統(tǒng)自動生成的文件,比如縮略圖等;
*忽略編譯生成的中間文件、可執(zhí)行文件等,也就是如果一個文件是通過另一個文件自動生成的,那自動生成的文件就沒必要放進版本庫,比如Java編譯產(chǎn)生的.class文件;
*忽略你自己的帶有敏感信息的配置文件,比如存放口令的配置文件
最后一步就是把 .gitignore
也提交到git,就完成了!當然檢驗.gitignore的標準是git status
命令是不是說working directory clean;你想添加一個文件到git,但發(fā)現(xiàn)添加不了,原因是這個文件被.gitignore忽略了;同樣也可以強制添加到git。
//忽略編譯產(chǎn)生的等文件或目錄
# Windows: //#表示注釋
Thumbs.db
ehthumbs.db
Desktop.ini
# My configurations: //這是自己定義的文件的配置
db.ini
deploy_key_rsa
//如果需要所有其它文件或版本庫,使用.gitignore,則需使用 git config 命令配置git
$ git config -global ...
//文件被.gitignore忽略了,如果確實想添加該文件,可以用-f強制添加到Git
$ git add -f App.class
//或者你發(fā)現(xiàn),可能是.gitignore寫得有問題,需要找出來到底哪個規(guī)則寫錯了,可以用git check-ignore命令檢查
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
5. 將git的本地倉庫提交到github遠程倉庫(遠程操作.也可以搭建一個git服務器)
github網(wǎng)站
就是提供 git倉庫 托管服務的,所以,只要注冊一個GitHub賬號,就可以免費獲得Git遠程倉庫。
github網(wǎng)站在2018年被微軟收購后,后又推出最多三人的免費git私人倉庫(以前不付錢是沒有私人倉庫全部都是public )
由于git的本地倉庫和GitHub之間的倉庫是通過SSH加密的,所以還需要進行一些操作:
>> 5.1 創(chuàng)建SSH Key
在用戶主目錄下,看看有沒有.ssh
目錄,如果有,再看看這個目錄下有沒有 id-rsa
和 id-rsa.pub
這兩個文件,如果已經(jīng)有了,可直接跳到下一步;如果沒有,打開Shell(Windows下打開git Bash),即iMac終端。同樣也可以在終端中輸入:ssh,來查看是否有 SSH Key
。
>> 創(chuàng)建 SSH Key
步驟:
*1.終端輸入:ssh-keygen -t rsa -C xxxxx@xxxxx.com//注冊GitHub時的郵箱就可以了。
//Generating public/private rsa key pair生成了公共/私有密鑰對。(在終端輸入“whereis ssh”可查看ssh位置)
2.要查看 “ssh”,需要在終端輸入允許查看隱藏的文件(defaults write com.apple.finder AppleShowAllFiles -bool true)->/users.../.ssh
3.查看我的 public key:$cat ~/.ssh/id_rsa.pub
4.登陸GitHub,打開“Settings”,然后,點“SSH and GPG Keys”,點“New SSH Key”;填上任意Title,在Key文本框里粘貼id_rsa.pub文件的內(nèi)容。點“Add Key”,你就應該看到已經(jīng)添加的Key。其中可能還需要輸入GitHub的密碼;
5. 為了驗證是否成功:$ ssh -T git@github.com.如果第一次進行連接就會提示“Are you sure you want to continue connecting(yes/no)”,輸入yes看到提示,可能會需要輸入ssh設置的密碼,然后就表示成功連接上GitHub了
--回到github,刷新網(wǎng)頁就可以看到鑰匙旁的灰色小圓點變綠
>> 5.2 在GitHub上創(chuàng)建倉庫
登陸GitHub,然后,在右上角找到“New repository”按鈕,創(chuàng)建一個新的倉庫。
在Repository name填入你需要保存的倉庫名字,其他保持默認設置,點擊“Create repository”按鈕,就成功地創(chuàng)建了一個新的Git倉庫。
>> 5.3 在本地的倉庫下(cd+拖入倉庫文件)運行命令,以便連接GitHub遠程倉庫:
$ git remote add origin git@github.com:xxxxxx/xxxxxx.git
//origin是默認的遠程主機名;git@github.com:ghn/repository.git,ghn是我的GitHub的名稱,repository是要上傳的GitHub的倉庫名稱。通過ssh連接,不要使用https,點擊:Clone or download即可以出現(xiàn)地址。
可能出現(xiàn)的錯誤:在執(zhí)行上面的命令時,錯誤提示:fatal:remote origin already exists
解決辦法: $ git remote rm origin
然后在執(zhí)行:$ git remote add origin git@github.com:xxxx/xxxx.git
????? 使用下面的命令推送本地倉庫至遠程倉庫/從遠程倉庫pull,獲取遠程倉庫的文件到本地倉庫:
(最后實在不行,不管什么問題可以執(zhí)行強制推送:git push -u origin +mastr)
$ git push -u origin master/$ git pull origin master //這里的-u參數(shù)作為第一次提交使用,作用是把本地master分支和遠程master分支關聯(lián)起來,以后就可以直接使用:git push origin master命令即可直接push
而且一般會先pull在push,為了防止往GitHub上提交東西的時候,會因為遠程上有東西更新了但是本地倉庫沒有更新而造成提交失敗。
可能出現(xiàn)的錯誤:
1.error:failed to push some refs to.......
解決辦法:$ git pull origin master // 先把遠程服務器github上面的文件拉下來,再push 上去。 2.fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.
解決辦法:出現(xiàn)這個問題是因為,沒有在github賬號添加SSH key
3.如果pull報錯fatal: refusing to merge unrelated histories;
解決辦法:則可以命令:git pull origin master ----allow-unrelated-histories
6.GitHub使用:從GitHub上Clone、更新和多人進行協(xié)作開發(fā)
6.1 克隆遠程倉庫
如果本地沒有遠程倉庫的項目,想從遠程倉庫克隆一個倉庫到本地應該怎么做呢?
- 只需要用
cd+ ... 命令
切換到想要存放項目的路徑,然后直接執(zhí)行git clone +#遠程版本庫地址#
命令就行了,注意命令后面跟的是項目的URL地址。項目在GitHub上的SSH和HTTPS地址均測試成功。
git clone
和 git pull
的區(qū)別 (后面的介紹git pull和git fetch的區(qū)別)
-
git clone
:從遠程服務器克隆一個一模一樣的版本庫到本地,復制的是整個版本庫,叫做clone.(clone是將一個庫復制到你的本地某個目錄中,是一個本地從無到有的過程)
命令: git clone +#遠程版本庫地址# +#本地目錄名#
(需要制定不同的目錄名,可以將目錄名作為git clone 命令的第二個參數(shù),這樣就可以實現(xiàn)clone到本地的遠程版本庫的目錄名可以自己改名,可與遠程版本庫不同)
-
git pull
:從遠程服務器獲取到一個branch分支
或者是master默認主分支
的更新到本地,并更新本地庫,叫做pull.(pull是指同步一個在你本地有版本的庫內(nèi)容時更新的部分或者是分支內(nèi)容到你的本地庫)
命令: git pull +#遠程版本庫地址(origin)# +#遠程分支(next)#:#本地分支(master)#
如果遠程分支是與當前分支合并,則冒號后面的部分可以省略 git pull origin 遠程分支(next或者默認分支master)
相當于: git fetch origin+fit merge origin/next
.
如果 pull 報錯 fatal : refusing to merge unrelated histories;則可以命令:git pull origin master ----allow-unrelated-histories
關于git的本地與遠程之間的分支之間建立追蹤關系:其中有一點,git會自動在本地分支和遠程分支之間,建立一種追蹤關系。如在git clone的時候,所有本地分支默認與遠程的同名分支建立了一種追蹤關系即本地的master分支自動追蹤"origin/master"分支。同樣git可以手動建立追蹤git branch --set-upstream master origin/next --->指定master分之追蹤到origin/next。
6.2 同步遠程服務器更新即分支更新(pull VS fetch)
即本地倉庫同步遠程倉庫,但獲取遠程服務器更新的方式有兩種,分別是 fetch
和 pull
,二者有差別。但是獲取的遠程倉庫只是一個分支或者是默認分支(master).
fetch
:僅僅只是從遠處服務器獲取到最新版本到本地,假如你不去合并(merge)的話,本地工作空間是不會發(fā)生變化的!
pull
:是一步到位的,或者說:pull = fetch + merge
在實際使用中fetch更加安全,在merge(合并)之前可以查看更新情況,git status
查看,在決定是否進行合并。
6.3 在Github上進行多人協(xié)作開發(fā)(兩種方式)
在GitHub進行多人協(xié)作開發(fā)時,有兩種方式,
一種是幾個開發(fā)者使用幾個Github賬號,一個是管理者,其它開發(fā)者進行"fork"的自己github賬號,然后各個開發(fā)者push代碼到自己的github賬戶中,然后pull request 管理者;
第二種是:全部開發(fā)者使用一個github賬號,把每個開發(fā)者的電腦的ssh密鑰加入到github賬號中通過驗證,每個開發(fā)者都是管理者。
a. 現(xiàn)在,模擬一個你的小伙伴,可以在另一臺電腦(注意要把SSH Key添加到同一個GitHub賬號中)
$ git clone git@github.com:GDaYao/Project-iOS.git
b. 現(xiàn)在,你的小伙伴要在dev分支上開發(fā),就必須創(chuàng)建遠程 origin的dev分支
到本地,于是他用這個命令創(chuàng)建本地dev分支
$ git checkout -b dev origin/dev
現(xiàn)在,他就可以在dev上繼續(xù)修改,然后,時不時地把dev分支push到遠程
$ git commit -m "add /usr/bin/env"
$ git push origin dev
//向origin/dev分支推送了他的提交
總結:
1. 首先,可以試圖用git push origin branch-name推送自己的修改;
2. 如果推送失敗,則因為遠程分支比你的本地更新,需要先用git pull試圖合并;//如果git pull提示“no tracking information”,則說明本地分支和遠程分支的鏈接關系沒有創(chuàng)建,用命令git branch --set-upstream branch-name origin/branch-name
3. 如果合并有沖突,則解決沖突,并在本地提交;
4. 沒有沖突或者解決掉沖突后,再用git push origin branch-name推送就能成功
6.4 標簽管理
發(fā)布一個版本時,我們通常先在版本庫中打一個標簽(tag),這樣,就唯一確定了打標簽時刻的版本。將來無論什么時候,取某個標簽的版本,就是把那個打標簽的時刻的歷史版本取出來。所以,標簽也是版本庫的一個快照
。tag就是一個讓人容易記住的有意義的名字,它跟某個 commit_id
綁在一起。所以在不僅僅可以使用 commit_id
進行版本回退,標簽管理更加方便。
標簽使用:
*命令git tag <name>用于新建一個標簽,默認為HEAD,也可以指定一個commit_id;
*git tag -a <tagname> -m "blablabla..."可以指定標簽信息;
*git tag -s <tagname> -m "blablabla..."可以用PGP簽名標簽;
*命令git tag可以查看所有標簽。
首先,切換到需要打標簽的分支上
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
然后,敲命令 git tag <name>
就可以打一個新標簽
$ git tag v1.0
//可以用命令git tag查看所有標簽
$ git tag
v1.0
要對 add merge
這次提交打標簽,它對應的 commit_id是6224937
,敲入命令
$ git tag v0.9 6224937
再用命令git tag查看標簽
標簽不是按時間順序列出,而是按字母排序的。可以用 git show <tagname>
查看標簽信息,包括所有這個版本的很多內(nèi)容。
$ git show v0.9
還可以創(chuàng)建帶有說明的標簽,用 -a指定標簽名,-m指定說明文字
$ git tag -a v0.1 -m "version 0.1 released" 3628164
還可以通過 -s用私鑰簽名一個標簽
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a
當然還可以使用標簽進行版本回退,比每次操作 commit_id
更加方便(同版本回退的方法):
$ git reset --hard v0.1(即某個版本)實現(xiàn)回到之前的版本/未來版本。
操作標簽
$ git push origin <tagname>可以推送一個本地標簽;
$ git push origin --tags可以推送全部未推送過的本地標簽;
$ git tag -d <tagname>可以刪除一個本地標簽;
$ git push origin :refs/tags/<tagname>可以刪除一個遠程標簽
7. 常用 git
命令清單:-- 可查看使用
幾個專用名詞譯名:
Workspace:工作區(qū)
Index / Stage:暫存區(qū)
Repository:倉庫區(qū)(或本地倉庫)
Remote:遠程倉庫
1,新建代碼庫
# 在當前目錄新建一個Git代碼庫
$ git init
# 新建一個目錄,將其初始化為Git代碼庫
$ git init [project-name]
# 下載一個項目和它的整個代碼歷史
$ git clone [url]
2,配置
Git的設置文件為.gitconfig,它可以在用戶主目錄下(全局配置),也可以在項目目錄下(項目配置)
# 顯示當前的Git配置
$ git config --list
# 編輯Git配置文件
$ git config -e [--global]
# 設置提交代碼時的用戶信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
3.增加/刪除文件
# 添加指定文件到暫存區(qū)
$ git add [file1] [file2] ...
# 添加指定目錄到暫存區(qū),包括子目錄
$ git add [dir]
# 添加當前目錄的所有文件到暫存區(qū)
$ git add .
# 添加每個變化前,都會要求確認
# 對于同一個文件的多處變化,可以實現(xiàn)分次提交
$ git add -p
# 刪除工作區(qū)文件,并且將這次刪除放入暫存區(qū)
$ git rm [file1] [file2] ...
# 停止追蹤指定文件,但該文件會保留在工作區(qū)
$ git rm --cached [file]
# 改名文件,并且將這個改名放入暫存區(qū)
$ git mv [file-original] [file-renamed]
4.?代碼提交
# 提交暫存區(qū)到倉庫區(qū)
$ git commit -m [message]
# 提交暫存區(qū)的指定文件到倉庫區(qū)
$ git commit [file1] [file2] ... -m [message]
# 提交工作區(qū)自上次commit之后的變化,直接到倉庫區(qū)
$ git commit -a
# 提交時顯示所有diff信息
$ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代碼沒有任何新變化,則用來改寫上一次commit的提交信息
$ git commit --amend -m [message]
# 重做上一次commit,并包括指定文件的新變化
$ git commit --amend [file1] [file2] ...
5. 分支的使用(Git鼓勵大量使用分支)
查看分支:git branch
創(chuàng)建分支:git branch <name>
切換分支:git checkout <name>
創(chuàng)建+切換分支:git checkout -b <name>
合并某分支到當前分支:git merge <name> //這一步操作之前要進行分支切換以便確定合并到某分支
通常,合并分支時,如果可能,Git會用Fast forward模式即“快進模式”,也就是直接把master指向某分支的當前提交,所以合并速度非常快。但這種模式下,刪除分支后,會丟掉分支信息。
合并分支時,加上--no-ff參數(shù)就可以用普通模式合并,合并后的歷史有分支,能看出來曾經(jīng)做過合并,而fast forward合并就看不出來曾經(jīng)做過合并。
git merge --no-ff -m "merge with no-ff" dev
git log --graph --pretty=oneline --abbrev//查看分支歷史
刪除分支:git branch -d <name>
推送分支至遠程倉庫(這里master是git默認的主分支)
git push origin master
推送其他分支到遠程倉庫(dev是本地的其它分支)
git push origin dev
git branch --set-upstream dev origin/dev //指定本地dev分支與遠程origin/dev分支的鏈接
6.標簽
# 列出所有tag
$ git tag
# 新建一個tag在當前commit
$ git tag [tag]
# 新建一個tag在指定commit
$ git tag [tag] [commit]
# 刪除本地tag
$ git tag -d [tag]
# 刪除遠程tag
$ git push origin :refs/tags/[tagName]
# 查看tag信息
$ git show [tag]
# 提交指定tag
$ git push [remote] [tag]
# 提交所有tag
$ git push [remote] --tags
# 新建一個分支,指向某個tag
$ git checkout -b [branch] [tag]
7. 查看信息
# 顯示有變更的文件
$ git status
# 顯示當前分支的版本歷史
$ git log
# 顯示commit歷史,以及每次commit發(fā)生變更的文件
$ git log --stat
# 搜索提交歷史,根據(jù)關鍵詞
$ git log -S [keyword]
# 顯示某個commit之后的所有變動,每個commit占據(jù)一行
$ git log [tag] HEAD --pretty=format:%s
# 顯示某個commit之后的所有變動,其"提交說明"必須符合搜索條件
$ git log [tag] HEAD --grep feature
# 顯示某個文件的版本歷史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]
# 顯示指定文件相關的每一次diff
$ git log -p [file]
# 顯示過去5次提交
$ git log -5 --pretty --oneline
# 顯示所有提交過的用戶,按提交次數(shù)排序
$ git shortlog -sn
# 顯示指定文件是什么人在什么時間修改過
$ git blame [file]
# 顯示暫存區(qū)和工作區(qū)的差異
$ git diff
# 顯示暫存區(qū)和上一個commit的差異
$ git diff --cached [file]
# 顯示工作區(qū)與當前分支最新commit之間的差異
$ git diff HEAD
# 顯示兩次提交之間的差異
$ git diff [first-branch]...[second-branch]
# 顯示今天你寫了多少行代碼
$ git diff --shortstat "@{0 day ago}"
# 顯示某次提交的元數(shù)據(jù)和內(nèi)容變化
$ git show [commit]
# 顯示某次提交發(fā)生變化的文件
$ git show --name-only [commit]
# 顯示某次提交時,某個文件的內(nèi)容
$ git show [commit]:[filename]
# 顯示當前分支的最近幾次提交
$ git reflog
8. 遠程同步
# 下載遠程倉庫的所有變動
$ git fetch [remote]
# 顯示所有遠程倉庫
$ git remote -v
# 顯示某個遠程倉庫的信息
$ git remote show [remote]
# 增加一個新的遠程倉庫,并命名
$ git remote add [shortname] [url]
# 取回遠程倉庫的變化,并與本地分支合并
$ git pull [remote] [branch]
# 上傳本地指定分支到遠程倉庫
$ git push [remote] [branch]
# 強行推送當前分支到遠程倉庫,即使有沖突
$ git push [remote] --force
# 推送所有分支到遠程倉庫
$ git push [remote] --all
9. 撤銷
# 恢復暫存區(qū)的指定文件到工作區(qū)
$ git checkout [file]
# 恢復某個commit的指定文件到暫存區(qū)和工作區(qū)
$ git checkout [commit] [file]
# 恢復暫存區(qū)的所有文件到工作區(qū)
$ git checkout .
# 重置暫存區(qū)的指定文件,與上一次commit保持一致,但工作區(qū)不變
$ git reset [file]
# 重置暫存區(qū)與工作區(qū),與上一次commit保持一致
$ git reset --hard
# 重置當前分支的指針為指定commit,同時重置暫存區(qū),但工作區(qū)不變
$ git reset [commit]
# 重置當前分支的HEAD為指定commit,同時重置暫存區(qū)和工作區(qū),與指定commit一致
$ git reset --hard [commit]
# 重置當前HEAD為指定commit,但保持暫存區(qū)和工作區(qū)不變
$ git reset --keep [commit]
# 新建一個commit,用來撤銷指定commit
# 后者的所有變化都將被前者抵消,并且應用到當前分支
$ git revert [commit]
# 暫時將未提交的變化移除,稍后再移入
$ git stash
$ git stash pop
10. 其它
# 生成一個可供發(fā)布的壓縮包
$ git archive
在終端中的輸入git命令:
git //確定電腦安裝了git
git status //查看暫緩區(qū)的狀態(tài)
git log/git log --pretty=oneline//可以查看提交歷史,以便確定要回退到哪個版本。
git reflog //查看命令歷史,以便確定要回到未來的哪個版本。
git reset --hard (版本號) //HEAD指向的版本就是當前版本,因此Git允許我們在版本的歷史之間穿梭,使用此命令
git diff HEAD --...//工作區(qū)與版本庫中最新版本的差別
git checkout -- file //放棄對工作區(qū)當前文件的修改,讓這個文件回到最近一次git commit或git add時的狀態(tài)
git reset hard file//可以把暫存區(qū)的修改撤銷掉(unstage),重新放回工作區(qū)
git remote //查看遠程庫的信息
git remote -v //顯示更詳細的信息,顯示了可以抓取和推送的origin的地址。如果沒有推送權限,就看不到push的地址
8.git和GitHub的其它使用
8.1 如何為開源項目貢獻代碼
在GitHub上可以Clone別人的開源項目,在看別人代碼的時候,你覺得作者有某些地方寫得不好,寫錯,或者你有更好的想法,你在本地修改后,想把修改push推送到開源項目上,但是你不是項目的擁有著和參與者,是無法推送更改的!!
第一種方法:是讓作者把你加為寫作者,添加協(xié)作者流程:點擊倉庫的Settings-->Collaborators然后輸入想添加的人的用戶名或者郵箱,點擊添加即可。
第二種方法:1).點擊Fork按鈕,把這個項目fork到自己的賬號下,然后Clone到本地,然后做你想做的修改,commit提交.2).然后push到自己賬號里的GitHub倉庫,然后打開那個別人的開源項目,點擊 Pull requests ,然后新建一個pull request,接著設置自己的倉庫為源倉庫,設置源分支,目標倉庫與目標分支,然后還有pull request的標題和描述信息,填寫完畢后,確定。3).這個時候開源項目的作者就會收到一個pull request的請求,由他來進行審核,作者審查完代碼覺得沒問題的話,他可以點擊一下merge按鈕即可將這個pull request合并到自己的項目中,假如作者發(fā)現(xiàn)了你代碼中還有些bug,他可以通過Pull Request跟你說明,要修復了xxBUG才允許合并,那么你再修改下BUG,提交,更改后的提交會進入Pull Request,然后作者再審核這樣!
8.2 在 Xcode
中使用 git
以及遠程提交
在使用Xcode創(chuàng)建每個工程時,就已經(jīng)顯示了是否使用 git 來創(chuàng)建一個倉庫,并且已經(jīng)是初始化這個倉庫了。Create Git Repository On Mac
就已經(jīng)提示是否初始化創(chuàng)建為git倉庫。如果勾選了就可以像使用普通git倉庫一樣,使用add,commit,push,pull而且可以直接在Xcode中操作。
9. gitLab更改ssh 可以加入和創(chuàng)建
git使用還可參考: Git的教程可以參考“廖雪峰的Git教程”</font>
9.git便捷使用
常用:
git ps (上傳)
git ss (查看狀態(tài))
git aa (提交)
git ci -m“ ” (進一步提交)
git co -b dev (創(chuàng)建dev分支)
git ps origin dev
git br -a (列出分支)
//
Git便捷實用:
co = checkout
**ss = status -s
**ps = push
ci = commit -a
br = branch
st = status
**pl = pull
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
ft = fetch
di = diff
last = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -1
unstage = reset HEAD
mg = merge --no-ff
dt = difftool
aa = add .
theirs = checkout --theirs .
their = checkout --theirs --
ours = checkout --ours .
our = checkout --ours --
git 項目配置
注意: 所有的配置如果需要生效只有在配置更改信息后的下次變更時才會生效。
下面是git config相關的各個操作命令:
查看全局的 git配置,git cofnig 命令(在~/.gitconfig目錄文件中存儲的git global信息)
$ git config --global --edit (直接修改文件即可修改git全局配置的相關信息)
若需要直接從終端查看 user.name/user.email
$ git config --global user.name // 查看global user name
$ git config --global user.email // 查看global user eamil
查看或配置當前項目git 的相關信息(包括user.name+user.email+Author)
$ git show //查看當前項目的相關信息
$ git config user.name //查看當前項目的user name
$ git config user.email //查看當前項目的user email
$ git config user.name "GDayao" // 更改當前項目的 user name
$ git config user.email "xxxx@xx.com" // 更改當前項目的 user email ==> 注意這里的郵箱若和github/gitlab的注冊郵箱相同則在提交歷史中會顯示頭像否則為github默認頭像
當前項目的config配置Author信息可以和全局配的config信息不相同。所以在全局的config沒有配置的情況下,也可以配置當前項目的某些信息內(nèi)容。
git 子模塊
子模塊的初步使用
對于子模塊的理解使用,為什么使用子模塊?什么時候使用子模塊?最簡單的理解,如果有多人合作或者直接使用了另一個項目/庫,但是這個項目又需要調(diào)用主模塊的某些內(nèi)容,即使用 子模塊
。(使用靜態(tài)庫或者動態(tài)庫不能產(chǎn)生此種功能的情況下)
使用遠程地址 添加子模塊:
git submodule add <git://github.com/xxx.git>/本地git倉庫路徑也可
添加 submodule 成功后,會在主目錄中生成一個 `.gitmodules`文件,里面存儲了子模塊的信息。
當然一個主工程中可以生成和添加多個子模塊使用
在子模塊添加完成后,可通過終端 cd
再次進入子模塊內(nèi)容,其他操作等同于一個git倉庫,只不過這個 主工程不同的是項目工程中有兩個git倉庫需要維護和更新 add
/commit
帶有子模塊的項目拉取
克隆拉取帶有子模塊的項目
git clone git://github.com/xxx.git
而后 cd
進入主工程項目進行相關操作
git submodule init // 初始化你的本地配置文件
git submodule update // 從子工程中拉取項目更新添加數(shù)據(jù)
再次注意所有的子模塊操作 => cd進入子模塊進行等同git倉庫操作
刪除子模塊
使用如下步驟命令操作:
$ git submodule deinit <xxx> // clear directory xxx,
$ git rm <xxx> // 直接刪除這個子模塊的所有文件,包括子模塊的配置文件