版本庫是集中存放在中央服務器的,只有一箇中央控制,全部的開發人員都必須依賴於這個代碼倉庫。每次版本控制的操做也必須連接到服務器才能完成。(必須聯網 上傳效率 安全問題)html
簡單的說,分佈式版本控制系統根本沒有"中央服務器",分佈式的版本控制就是每一個人均可以建立一個獨立的代碼倉庫用於管理,各類版本控制的操做均可以在本地完成。每一個人修改的代碼均可以推送合併到另一個代碼倉庫中。(本地不依賴網 高效 安全)node
在官網下載安裝 一路next下來 git官網git
例如:個人git所在路徑是 D:\火狐下載\Git
那麼我須要把git下的bin目錄和cmd目錄添加進系統環境變量便可 D:\火狐下載\Git\bin
和 D:\火狐下載\Git\cmd
github
在命令行輸入 git --version
能夠查看git版本安全
git init
命令bash
示例(接下來的例子所有在gitdemo目錄下)服務器
$ git init
Initialized empty Git repository in C:/Users/lenovo/Desktop/gitdemo/.git/
複製代碼
這時在目錄下會出現一個.git隱藏目錄 這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄裏面的文件,否則改亂了,就把Git倉庫給破壞了。ssh
git status
命令分佈式
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
nothing added to commit but untracked files present (use "git add" to track)
複製代碼
第一次查看 顯示的是一組沒有被跟蹤的文件 好比個人目錄下的'index.html'svn
爲了個人源文件能被git管理 第一步就是須要添加到暫存區
git add
命令 這裏分爲兩種狀況: 1)首次添加跟蹤 2)修改代碼後添加
我如今要把'index.html'第一次提交到暫存區
使用$ git add index.html
此時讓咱們再來查看狀態
$ git status
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: index.html
複製代碼
顯示一個新文件已經被添加到暫存區被git跟蹤了
問題來了 項目下的文件不少 難道咱們須要一個個的手動把須要跟蹤的文件添加到暫存區嗎?
固然不是 咱們能夠用 git add .
命令 將目錄裏面的所有文件添加到暫存區
但是 有不少的文件咱們是不須要跟蹤的
例如:項目依賴包 node_module目錄
在項目目錄的根文件夾建立一個以'.gitignore'命名的文件 而後在裏面直接能夠寫忽略的文件夾 或者忽略的文件路徑
好比上面的index.html已經添加到暫存區 而後我如今改變了裏面的一處代碼 我該怎麼再次提交到暫存區呢?
仍然可使用 git add 'index.html'
或者將項目下全部的文件變更一次性提交 使用 git add --all
成功把文件添加到暫存區了 可是這並不表明你把文件添加到版本庫分支裏面了
還須要git commit
命令
$ git commit -m 'first updata'
[master (root-commit) a73f689] first updata
1 file changed, 10 insertions(+)
create mode 100644 index.html
複製代碼
簡單解釋一下git commit命令,-m後面輸入的是本次提交的說明,能夠輸入任意內容,固然最好是有意義的,這樣你就能從歷史記錄裏方便地找到改動記錄。
工做區:就是咱們的項目文件夾不包括.git隱藏文件夾的區域
暫存區:Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區。 還有Git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫HEAD。
git log
命令
$ git log
commit a73f6890fa66a68919b57707505b597c7cd8761b (HEAD -> master)
Author: 小旭 <908130255@qq.com>
Date: Tue Jun 6 15:09:10 2017 +0800
first updata
複製代碼
說明: commit a73f6890fa66a68919b57707505b597c7cd8761b
是commit id(版本號)
first updata
是咱們當時commit -m ''本身輸入的引號內的信息
假如我修改了不少次代碼 提交了不少的不一樣版本到個人本地版本庫分支master上 但是我發現最後一個有問題 我須要回到以前的版本怎麼辦?
這時候須要使用命令 git reset --hard 編號
(編號就是上節說的commit id(版本號) 不須要寫出完整的版本號 通常前8位以上就ok了)
$ git reset --hard a73f6890fa
HEAD is now at a73f689 first updata
複製代碼
此時版本已經回退到指定的版本號了 你能夠看看你工做區的文件 是否是回到了以前的修改(神奇!)
git diff
命令
每次工做區修改完成後可使用(對比本地文件一開始的樣子)
$ git diff
diff --git a/index.html b/index.html
index 50c3720..9052a59 100644
--- a/index.html
+++ b/index.html
@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
+ <h2>nihao</h2>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
複製代碼
分爲三種狀況
1)只在工做區修改了 沒提交到暫存區 $ git checkout -- index.html
撤銷工做區修改(其實 git checkout -- file 就是用暫存區的版原本代替工做區的版本)
2)修改提交到暫存區以後 又修改了
先使用$ git reset HEAD index.html
將暫存區的修改撤銷掉,從新放回工做區,而後重複1)中的命令
3)已經提交到本地的版本庫分支master上了(前提是沒推送到遠程版本庫)
使用版本回退
分爲兩種狀況:
1)誤刪
使用 $ git checkout -- index.html
2)確實要刪
使用 $ git rm index.html
$ git rm index.html
rm 'index.html'
複製代碼
而後 $ git commit -m 'delete index.html'
使本地版本庫的當前分支刪除文件
$ git commit -m 'delete index.html'
[master 4e36418] delete index.html
1 file changed, 11 deletions(-)
delete mode 100644 index.html
複製代碼
以前介紹的都是停留在本地倉庫 也就是說不須要聯網就能夠進行操做 接下來進行遠程倉庫學習
$ ls -al ~/.ssh
$ ls -al ~/.ssh
total 30
drwxr-xr-x 1 lenovo 197121 0 6月 2 10:40 ./
drwxr-xr-x 1 lenovo 197121 0 6月 6 10:50 ../
-rw-r--r-- 1 lenovo 197121 1675 5月 27 18:39 github_rsa
-rw-r--r-- 1 lenovo 197121 404 5月 27 18:39 github_rsa.pub
-rw-r--r-- 1 lenovo 197121 1675 6月 2 10:40 id_rsa
-rw-r--r-- 1 lenovo 197121 398 6月 2 10:40 id_rsa.pub
-rw-r--r-- 1 lenovo 197121 1187 6月 5 15:25 known_hosts
複製代碼
看看有沒有id_rsa和id_rsa.pub這兩個文件,若是已經有了,能夠直接將id_rsa.pub文件裏的內容複製一份到剪切板
$ ssh-keygen -t rsa -C "youremail@example.com"
你須要把郵件地址換成你本身的郵件地址,而後一路回車,使用默認值便可,因爲這個Key也不是用於軍事目的,因此也無需設置密碼。
接下來在用戶主目錄裏找到.ssh目錄,裏面有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的密鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,能夠放心地告訴任何人。
登陸GitHub,打開"Account settings","SSH Keys"頁面
點"Add SSH Key",填上任意Title,在Key文本框裏粘貼id_rsa.pub文件的內容,點"Add Key",你就應該能看到已經添加的Key。
此時咱們已經有一個本地版本庫了 可是咱們沒有與遠程庫創建聯繫 因此咱們的代碼只有本身一我的知道 不能分享與合做
我以前在github上面創建了一個git-demo的倉庫
使用$ git remote add origin 你的倉庫ssh地址
將遠程庫和本身的本地庫鏈接
$ git remote add origin git@github.com:BigSharkLx/git-demo.git
鏈接成功後查看遠程倉庫地址 git remote -v
$ git remote -v
origin git@github.com:BigSharkLx/git-demo.git (fetch)
origin git@github.com:BigSharkLx/git-demo.git (push)
複製代碼
第一次提交時使用 git push -u origin master
(-u是使用流形式 速度更快 提交到遠程庫主分支master上)
$ git push -u origin master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 449 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:BigSharkLx/git-demo.git
f665eb1..97f9675 master -> master
複製代碼
若是git遠程庫已經存在內容(不是空的),新關聯的本地庫第一次提交代碼是不被容許的 會報錯以下:
$ git push -u origin master
To github.com:BigSharkLx/git-demo.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'git@github.com:BigSharkLx/git-demo.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.
複製代碼
1) git push origin master -f
強推(利用覆蓋的方式用本地代碼替代git倉庫內容 簡單粗暴 後果自負)
2) 先將遠程庫的東西fetch到本地 而後再merge(效果等同於git pull)
別人寫好的代碼你能夠把他們克隆到本身的本地目錄 git clone 倉庫地址
$ git clone git@github.com:BigSharkLx/git-demo.git
Cloning into 'git-demo'...
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 5 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.
Resolving deltas: 100% (1/1), done.
複製代碼
通常狀況下你克隆的代碼是沒有權限push到別人的代碼庫的(由於別人的github帳號並無添加你電腦的公鑰)
分支就是指互不干擾的一條代碼時間軸
咱們有本地分支和遠程庫分支 怎麼查看分支呢
可使用 git branch
查看本地分支
$ git branch
* dev
master
複製代碼
(前面的*表明當前選定的分支)
也能夠查看全部分支(包括遠程庫的分支) git branch -a
$ git branch -a
* dev
master
remotes/origin/dev
remotes/origin/master
複製代碼
git branch 分支名
git checkout 分支名
git checkout -b 分支名
git merge 分支名
$ git merge dev
Already up-to-date.
複製代碼
刪除本地分支: git brand -d 分支名
$ git branch -d dev
Deleted branch dev (was 97f9675).
複製代碼
刪除遠程庫分支: git push origin --delete 分支名
$ git push origin --delete dev
To github.com:BigSharkLx/git-demo.git
- [deleted] dev
複製代碼
在實際開發中,咱們應該按照幾個基本原則進行分支管理:
首先,master分支應該是很是穩定的,也就是僅用來發布新版本,平時不能在上面幹活;
那在哪幹活呢?幹活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,好比1.0版本發佈時,再把dev分支合併到master上,在master分支發佈1.0版本;
你和你的小夥伴們每一個人都在dev分支上幹活,每一個人都有本身的分支,時不時地往dev分支上合併就能夠了
首先,在本地建立和遠程分支對應的分支,使用
git checkout -b 分支名 origin/分支名
,本地和遠程分支的名稱最好一致
而後,創建本地分支和遠程分支的關聯,使用
git branch --set-upstream 分支名 origin/分支名
如今,能夠試圖用
git push origin 分支名
推送本身的修改;
若是推送失敗,則由於遠程分支比你的本地更新,須要先用
git pull
試圖合併;
若是合併有衝突,則解決衝突,並在本地提交;沒有衝突或者解決掉衝突後,再用
git push origin 分支名
推送就能成功!
標籤說白了就是方便咱們記憶和管理的,由於你不可能去記住 你每次提交的commit id(版本號)因此你只須要打上一個標籤
$ git tag 標籤名
默認是爲咱們最後一次commit建立標籤
若是想爲每次commit建立標籤怎麼辦呢
很簡單 拿到commit id(版本號)就行
$ git tag 標籤名 版本號
git tag
查看全部存在的標籤
$ git tag
log
v0.9
v1.0
複製代碼
git show 標籤名
查看具體的某一個標籤
$ git show v2.0
tag v2.0
Tagger: 小旭 <908130255@qq.com>
Date: Wed Jun 7 11:05:25 2017 +0800
新升級了一些功能
commit 97f96751df5eafc7d53718802aa5e019ff789b26 (HEAD -> master, tag: v2.0, tag: v1.0, tag: log, origin/master)
Author: 小旭 <908130255@qq.com>
Date: Wed Jun 7 08:58:32 2017 +0800
new updata
複製代碼
$ git tag -a 標籤名 -m '描述信息'
1)刪除本地標籤
$ git tag -d 標籤名
2)刪除遠程庫標籤
git push origin :refs/tags/標籤名
$ git push origin :refs/tags/v0.9
To github.com:BigSharkLx/git-demo.git
- [deleted] v0.9
複製代碼
git push origin 標籤名
$ git push origin v2.0
Counting objects: 1, done.
Writing objects: 100% (1/1), 186 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To github.com:BigSharkLx/git-demo.git
* [new tag] v2.0 -> v2.0
複製代碼
或者一次性推送所有的標籤
$ git push origin --tags
$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:BigSharkLx/git-demo.git
* [new tag] v0.9 -> v0.9
* [new tag] v1.0 -> v1.0
複製代碼
解決方案一:把開發人員的電腦ssh公鑰添加到項目負責人的git服務器帳號上 這樣就有push權限
解決方案二:創建一個組織,分別賦予組織成員push權利
你須要先fork別人的項目到本身的遠程倉庫 以後在你的本地倉庫修改提交到遠程 最後在別人的項目地址pull request 至於別人可否接受你的修改 那就不知道了