版本库是集中存放在中央服务器的,只有一个中央控制,全部的开发人员都必须依赖于这个代码仓库。每次版本控制的操做也必须连接到服务器才能完成。(必须联网 上传效率 安全问题)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 至于别人可否接受你的修改 那就不知道了