linuxhtml
$ sudo yum install git
mac: http://git-scm.com/download/macjava
windows: http://git-scm.com/download/winjquery
git官方文檔: https://git-scm.com/book/zh/v2linux
Git安裝完以後,須要作最後一步配置,若是你沒有作這項配置,是沒有git公鑰和私鑰的,而上傳代碼到遠程倉庫的時候須要祕鑰進行驗證是否本人上傳的,想要建立可使用下面的方法:git
打開git bash,分別執行如下兩句命令 git config --global user.name 「用戶名」 git config --global user.email 「郵箱」
config 的三個做用域github
--local 只對某個倉庫有效 --global 對當前用戶全部倉庫有效 --system 對系統全部登陸的用戶有效 --list
cd ~/.ssh
能夠查看是否已配置SSH。ssh-keygen -t rsa
並按回車3下(爲何按三下,是由於有提示你是否須要設置密碼,若是設置了每次使用Git都會用到密碼,通常都是直接不寫爲空,直接回車就行了)。會在一個文件夾裏面生成一個私鑰 id_rsa和一個公鑰id_rsa.pub。(可執行start ~
命令,生成的公私鑰在 .ssh的文件夾裏面)。C:\Users\Administrator
目錄下。若是看不到.ssh文件,可使用ls -ah
指令查看隱藏文件夾便可,這是存放祕鑰的文件,打開這個文件會看到id_rsa和id_rsa.pub。id_rsa是私鑰文件,id_rsa.pub是公鑰文件。cat ~/.ssh/id_rsa.pub
。兩種場景:web
1.把已有的項目代碼歸入Git管理shell
cd 項目代碼所在的文件夾 git init
2.創建新的項目直接用Git管理segmentfault
cd 某個文件夾 git init your_project #會在當前路徑下建立和項目名相同的文件夾 cd your_project
mkdir 建立目錄 echo "" > 文件名 建立文件 clear 清屏
在倉庫中添加文件windows
1.將文件拷貝到工做目錄
cp ... .
2.測試文件符合要求後添加到暫存目錄
git add files git add -u 全部文件
3.查看文件是否被git管理
git status
4.提交暫存區的文件
git commit -m'更改理由' -am'..'從工做區直接提交
git add 更新將要提交的內容 git restore 放棄工做目錄中的更改 git rm 移除
Git和其餘版本控制系統如SVN的一個不一樣之處就是有暫存區的概念。
就是你在電腦裏能看到的目錄,好比個人learngit
文件夾就是一個工做區
工做區有一個隱藏目錄.git
,這個不算工做區,而是Git的版本庫。
Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲咱們自動建立的第一個分支master
,以及指向master
的一個指針叫HEAD
。
git add
把文件添加進去,實際上就是把文件修改添加到暫存區;
git commit
提交更改,實際上就是把暫存區的全部內容提交到當前分支。
給文件重名名
git mv old new 操做完後commit提交
查看版本歷史,提交日誌
git log -n5 --oneline 最近5條 簡明 git log --all --graph 全部分支 圖像化關係
版本歷史圖形化工具
gitk
查看分支 git branch -v 建立分支 git checkout -b 分支名 commitid 切換分支 git checkout 分支名
查看某個命令的幫助文檔
git help --web 命令 --web 在網頁
HEAD文件:指向瞭如今引用的分支
cat HEAD ref: refs/heads/master
config文件:記錄了用戶的信息
refs/:引用目錄,包含了heads和tags目錄
tags:標籤 里程碑,項目開發到必定程度,給commit打一個標籤如[v1.0]
標籤文件是tag類型 自己有一個40位的哈希值 ,內容包含了一個commit的類型的object
heads:分支,如先後端創建獨立的分支,互不影響,須要集成時可合併到一個公共的分支
查看文件對象類型
cat 分支文件 git cat-file -t 哈希值 -p 看內容 若是哈希值足以保證惟一性可使用短的一部分
master文件爲commit類型
git branch -av查看分支能夠看到master分支引用指針就是heads目錄中master文件的哈希值
objects/:全部文件對象
git在每次commit的時候都會生成一個tree對象、一個parent對象(若是不是第一次提交的話)、和一個commit對象,這個最頂層的tree就是對應整個工做目錄,tree下面還有blob、tree對象,都是一串hash值指向對應的內容,當某個文件發生變更的時候會從新保存一次快照(hash),若是文件沒有發生變更,保留的快照依然是上次的。
鬆散對象 (loose object) 會被打包到pack/目錄
查看文件對象類型 爲:tree
git cat-file -t 文件名+哈希值
查看內容 包含一個blob文件,就是提交的內容
git cat-file -p 文件名+哈希值
每一次提交都會建立一個commit對象,一個commit對象對應包含一個tree對象,tree表明了當前時間點倉庫目錄結構的快照,blob指具體的文件,在git中若是兩個文件內容相同就看做一個文件,不論文件名
若是不當心經過git checkout命令切換到某個commit中(即HEAD指向某個commit),git會提示咱們正處於分離頭指針的狀態下(工做在沒有分支的狀況下),若是咱們作了大量的修改,可是某天咱們忽然又切換到另外一個commit時,咱們的修改就有可能被git當作垃圾清除掉,所以這個動做十分危險。
分離頭指針的用處:進行嘗試性的變動時
試着修改某些文件時,若是以爲修改的效果不滿意,能夠直接切換到別的分支,丟棄當前修改
若是咱們切換出去時,以爲當前的修改十分重要,就按照git的提示建立一個新分支
若是某個變動(提交)是很是重要的,那麼必定要跟某個分支綁定在一塊兒
建立新分支: git checkout -b 新分支名稱 基於某個分支或者commit eg:git checkout -b newBranch master 比較某兩個commit的區別 git diff 第一個commit 第二個commit eg:git diff HEAD HEAD^1 (當前的HEAD指向的commit和他的父級進行比對) HEAD^ ==HEAD~ == HEAD^1 == HEAD~1 HEAD^^ == HEAD^1^1 == HEAD^2
git branch -D 分支名
對最近一次commit的message作變動
git commit --amend
更改以前的message
git rebase -i 需更改commit的父級id 執行後進入編輯,把須要修改的一次message前面的'pick'改成'r'或'reword',保存退出,會跳轉到修改message
git rebase -i 父級commitid 執行後進入編輯,僅保留要合併到的commit的'pick',把須要須要合併的幾個'pick'改成's'或'squash',退出保存,修改說明
首先git log --graph
查看commit歷史
變基git rebase -i 父commitid
進入vi
將父commitid拷貝進來並改變順序,放在要合併的commit上面
要合併的commit的'pick'改成's'
pick acf475ed #父commit s 7ac3c1cb8b92 #要合併的commit ...其餘
保存退出後報錯:interactive rebase in progress; onto 7ac3c1c
而後執行git rebase --continue
繼續變基,進入vi
怎加一個message,保存退出便可
其餘參考:https://segmentfault.com/a/11...
什麼是合併衝突
在 Git 中,「合併(merging)」 是在形式上整合別的分支到你當前的工做分支的操做。你須要獲得在另一個上下文背景下的改動(這就也就是咱們所提到過的,一個有效的分支應該是創建在一個上下文工做背景上的),而且合併它們到你的當前的工做文件中來。
做爲你的版本管理系統,Git 所帶來的最偉大的改善就是它讓合併操做變得很是輕鬆簡單。在大多數狀況下,Git 會本身弄清楚該如何整合這些新來的變化。
固然,也存在極少數的狀況,你必須本身手動地告訴 Git 該怎麼作。最爲常見的就是你們都改動了同一個文件。即使在這種狀況下,Git 仍是有可能自動地發現並解決掉這些衝突。可是,若是兩我的同時更改了同一個文件的同一行代碼,或者一我的改動了那些被另外一我的刪除了的代碼,Git 就不能簡單地肯定到底誰的改動纔是正確的。這時 Git 會把這些地方標記爲一個衝突,你必須首先解決掉這些衝突,而後再繼續你的工做。
如何解決合併衝突
當面對一個合併衝突時,咱們首先要搞明白髮生了什麼。例如是否是你和你的同事都同時編輯了同一個文件的同一行代碼呢?是否是他刪除了一個你正在編輯的文件呢?是否是大家同時添加了一個相同文件名的文件呢?
當你使用 「git status」 時, Git 會告訴你存在一個 「未合併的路徑(unmerged paths)」,這只是用另一個方式告訴你,存在一個或多個衝突:
$ git status # On branch contact-form # You have unmerged paths. # (fix conflicts and run "git commit") # # Unmerged paths: # (use "git add <file>..." to mark resolution) # # both modified: contact.html # no changes added to commit (use "git add" and/or "git commit -a")1234567891011
就讓咱們來深刻地探討一下,如何去解決這些最多見的衝突。
當兩個改動發生在同一個文件的同一些行上,咱們就要看看發生衝突的文件的內容了。Git 會很是友好地把文件中那些有問題的區域在 「<<<<<<< HEAD」 和 「>>>>>>> [other/branch/name]」 之間標記出來。
第一個標記後的內容源於當前分支。在尖括號以後,Git 會告訴咱們這些改動是從哪裏(哪一個分支)來的。而後有衝突的改動會被 「=======」 分割起來。
如今,當清理文件並獲得最終代碼後,全部剩下的工做就是將這個結果保存起來,而且立刻退出這個合併工具。這樣 Git 就會知道你已經完成了這個操做。Git 會在後臺對那個文件自動地執行 「git add」 命令。這也標誌着衝突已經解決了。若是你不使用合併工具,而是手動在文本編輯器中清理這些衝突,你必須手動地將文件標記爲已解決狀態(經過執行命令 「git add 」)。
最終,當全部的衝突被解決後,你必須經過一個正常的提交操做來完成這個清理合並衝突的工做。
你應該始終牢記,你能夠在任什麼時候間執行撤銷操做,並返回到你開始合併以前的狀態。要對本身有信心,你不會破壞項目中的任何東西。只要在命令行界面中鍵入 「git merge –abort」 命令,你的合併操做就會被安全的撤銷。
當你解決完衝突,而且在合併完成後發現一個錯誤,你仍然仍是有機會來簡單地撤銷它。你只需要鍵入 「git reset –hard 」 命令,系統就會回滾到那個合併開始前的狀態,而後從新開始吧!
git status會有rebase in progress; onto ……這種問題? 該怎麼解決?
是你以前或者剛剛用過 git rebase
,但上一次的進程尚未完成。
能夠直接 git rebase --abort
來取消目前的進程
git diff --cached
git diff git diff -- 可加具體文件名
git reset HEAD
git checkout -- 文件名
git reset HEAD -- 文件名
git reset --hard commitid(想回到的commit狀態)
git diff 分支名或commitid 分支名或commitid -- 指定文件
git rm 文件名
場景:開發中有一部分文件已經放到了暫存區,一部分還在工做區修改當中,可是測試發現對應的分支是有問題的,須要臨時修復bug
1.先把手頭的工做備份到其餘地方git stash
,能夠用git stash list
查看
2.修復完bug提交後再恢復繼續
git stash apply
stash列表中存放的文件仍會保留
git stash pop
stash列表中存放的文件會移除
gitHub新建倉庫時會讓你配置一個.gitignore
文件,針對不一樣的語言指定不被git管理的文件類型
只能夠命名爲.gitignore
如java
# Compiled class file *.class # Package Files # *.jar *.war *.tar.gz *.zip ...
經常使用的傳輸協議
啞協議與智能協議
直觀區別:啞協議傳輸進度不可見,智能協議可見
傳輸速度:智能協議比啞協議塊
推薦使用智能協議
備份特色:多點備份
若是要和遠端的倉庫進行關聯的話,須要remote
git remote -v 查看 git remote add 名字 地址 新建遠端倉庫
當本地倉庫有新的分支,而遠端並未添加進去時,直接push
git push 遠端倉庫
遠程操做的第一步,一般是從遠程主機克隆一個版本庫,這時就要用到git clone
命令。
$ git clone <版本庫的網址>
好比,克隆jQuery的版本庫。
$ git clone https://github.com/jquery/jquery.git
該命令會在本地主機生成一個目錄,與遠程主機的版本庫同名。若是要指定不一樣的目錄名,能夠將目錄名做爲git clone
命令的第二個參數。
$ git clone <版本庫的網址> <本地目錄名>
git clone
支持多種協議,除了HTTP(s)之外,還支持SSH、Git、本地文件協議等
爲了便於管理,Git要求每一個遠程主機都必須指定一個主機名。git remote
命令就用於管理主機名。
不帶選項的時候,git remote
命令列出全部遠程主機。
$ git remote origin
使用-v
選項,能夠參看遠程主機的網址。
$ git remote -v origin git@github.com:jquery/jquery.git (fetch) origin git@github.com:jquery/jquery.git (push)
上面命令表示,當前只有一臺遠程主機,叫作origin,以及它的網址。
克隆版本庫的時候,所使用的遠程主機自動被Git命名爲origin
。若是想用其餘的主機名,須要用git clone
命令的-o
選項指定。
$ git clone -o jQuery https://github.com/jquery/jquery.git $ git remote jQuery
上面命令表示,克隆的時候,指定遠程主機叫作jQuery。
git remote show
命令加上主機名,能夠查看該主機的詳細信息。
$ git remote show <主機名>
git remote add
命令用於添加遠程主機。
$ git remote add <主機名> <網址>
git remote rm
命令用於刪除遠程主機。
$ git remote rm <主機名>
git remote rename
命令用於遠程主機的更名。
$ git remote rename <原主機名> <新主機名>
一旦遠程主機的版本庫有了更新(Git術語叫作commit),須要將這些更新取回本地,這時就要用到git fetch
命令。
$ git fetch <遠程主機名>
上面命令將某個遠程主機的更新,所有取回本地。
git fetch
命令一般用來查看其餘人的進程,由於它取回的代碼對你本地的開發代碼沒有影響。
默認狀況下,git fetch
取回全部分支(branch)的更新。若是隻想取回特定分支的更新,能夠指定分支名。
$ git fetch <遠程主機名> <分支名>
好比,取回origin
主機的master
分支。
$ git fetch origin master
所取回的更新,在本地主機上要用"遠程主機名/分支名"的形式讀取。好比origin
主機的master
,就要用origin/master
讀取。
git branch
命令的-r
選項,能夠用來查看遠程分支,-a
選項查看全部分支。
$ git branch -r origin/master $ git branch -a * master remotes/origin/master
上面命令表示,本地主機的當前分支是master
,遠程分支是origin/master
。
取回遠程主機的更新之後,能夠在它的基礎上,使用git checkout
命令建立一個新的分支。
$ git checkout -b newBrach origin/master
上面命令表示,在origin/master
的基礎上,建立一個新分支。
此外,也可使用git merge
命令或者git rebase
命令,在本地分支上合併遠程分支。
$ git merge origin/master # 或者 $ git rebase origin/master
上面命令表示在當前分支上,合併origin/master
。
git pull
命令的做用是,取回遠程主機某個分支的更新,再與本地的指定分支合併。它的完整格式稍稍有點複雜。
$ git pull <遠程主機名> <遠程分支名>:<本地分支名>
好比,取回origin
主機的next
分支,與本地的master
分支合併,須要寫成下面這樣。
$ git pull origin next:master
若是遠程分支是與當前分支合併,則冒號後面的部分能夠省略。
$ git pull origin next
上面命令表示,取回origin/next
分支,再與當前分支合併。實質上,這等同於先作git fetch
,再作git merge
。
$ git fetch origin $ git merge origin/next
在某些場合,Git會自動在本地分支與遠程分支之間,創建一種追蹤關係(tracking)。好比,在git clone
的時候,全部本地分支默認與遠程主機的同名分支,創建追蹤關係,也就是說,本地的master
分支自動"追蹤"origin/master
分支。
Git也容許手動創建追蹤關係。
git branch --set-upstream master origin/next
上面命令指定master
分支追蹤origin/next
分支。
若是當前分支與遠程分支存在追蹤關係,git pull
就能夠省略遠程分支名。
$ git pull origin
上面命令表示,本地的當前分支自動與對應的origin
主機"追蹤分支"(remote-tracking branch)進行合併。
若是當前分支只有一個追蹤分支,連遠程主機名均可以省略。
$ git pull
上面命令表示,當前分支自動與惟一一個追蹤分支進行合併。
若是合併須要採用rebase模式,可使用--rebase
選項。
$ git pull --rebase <遠程主機名> <遠程分支名>:<本地分支名>
若是遠程主機刪除了某個分支,默認狀況下,git pull
不會在拉取遠程分支的時候,刪除對應的本地分支。這是爲了防止,因爲其餘人操做了遠程主機,致使git pull
不知不覺刪除了本地分支。
可是,你能夠改變這個行爲,加上參數 -p
就會在本地刪除遠程已經刪除的分支。
$ git pull -p # 等同於下面的命令 $ git fetch --prune origin $ git fetch -p
git push
命令用於將本地分支的更新,推送到遠程主機。它的格式與git pull
命令相仿。
$ git push <遠程主機名> <本地分支名>:<遠程分支名>
注意,分支推送順序的寫法是<來源地>:<目的地>,因此git pull
是<遠程分支>:<本地分支>,而git push
是<本地分支>:<遠程分支>。
若是省略遠程分支名,則表示將本地分支推送與之存在"追蹤關係"的遠程分支(一般二者同名),若是該遠程分支不存在,則會被新建。
$ git push origin master
上面命令表示,將本地的master
分支推送到origin
主機的master
分支。若是後者不存在,則會被新建。
若是省略本地分支名,則表示刪除指定的遠程分支,由於這等同於推送一個空的本地分支到遠程分支。
$ git push origin :master # 等同於 $ git push origin --delete master
上面命令表示刪除origin
主機的master
分支。
若是當前分支與遠程分支之間存在追蹤關係,則本地分支和遠程分支均可以省略。
$ git push origin
上面命令表示,將當前分支推送到origin
主機的對應分支。
若是當前分支只有一個追蹤分支,那麼主機名均可以省略。
$ git push
若是當前分支與多個主機存在追蹤關係,則可使用-u
選項指定一個默認主機,這樣後面就能夠不加任何參數使用git push
。
$ git push -u origin master
上面命令將本地的master
分支推送到origin
主機,同時指定origin
爲默認主機,後面就能夠不加任何參數使用git push
了。
不帶任何參數的git push
,默認只推送當前分支,這叫作simple方式。此外,還有一種matching方式,會推送全部有對應的遠程分支的本地分支。Git 2.0版本以前,默認採用matching方法,如今改成默認採用simple方式。若是要修改這個設置,能夠採用git config
命令。
$ git config --global push.default matching # 或者 $ git config --global push.default simple
還有一種狀況,就是無論是否存在對應的遠程分支,將本地的全部分支都推送到遠程主機,這時須要使用--all
選項。
$ git push --all origin
上面命令表示,將全部本地分支都推送到origin
主機。
若是遠程主機的版本比本地版本更新,推送時Git會報錯,要求先在本地作git pull
合併差別,而後再推送到遠程主機。這時,若是你必定要推送,可使用--force
選項。
$ git push --force origin
上面命令使用--force
選項,結果致使遠程主機上更新的版本被覆蓋。除非你很肯定要這樣作,不然應該儘可能避免使用--force
選項。
最後,git push
不會推送標籤(tag),除非使用--tags
選項。
$ git push origin --tags