git 版本控制系统
Git 简介
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目, C 语言编写的。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
安装 git
- OS : Centos7
yum install git
- Window 7
从Git官网直接下载安装程序
安装完成后,还需要最后一步设置,在命令行执行如下命令
git config
命令的--global
参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
git config --global user.name "Your Name" git config --global user.email "email@example.com"
创建版本库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,
以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
创建git 目录
mkdir wpic # 创建一个新目录 cd wpic # 进入新目录 # 通过git init命令把这个目录变成Git可以管理的仓库 root@AY1406111318160294c8Z:~/wpic# git init Initialized empty Git repository in /root/wpic/.git/
瞬间Git就把仓库建好了,当前目录下多了一个.git
的目录,这个目录是Git来跟踪管理版本库的。
也不一定必须在空目录下创建Git仓库,选择一个已经有东西的目录也是可以的
把文件添加到版本库
首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道
echo "This is a git text file" > readme.txt # 创建一个文件 git add readme.txt # 添加文件到暂存区 git commit -m "add readme.txt file" #把暂存区的所有内容提交到当前分支
git 常用操作命令
git status # 修改文件后查看状态
echo "This is a git text file" >> readme.txt root@AY1406111318160294c8Z:~/wpic# git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: readme.txt # no changes added to commit (use "git add" and/or "git commit -a")
git diff 文件名 # 比较文件,看看文件具体修改了什么内容。只有文件在暂存区之前的时候才可以查看
root@AY1406111318160294c8Z:~/wpic# git diff readme.txt diff --git a/readme.txt b/readme.txt index 0665208..6bc98ef 100644 --- a/readme.txt +++ b/readme.txt @@ -1 +1,3 @@ This is a git text file +This is a git text file +This is a git text file
git log
每当文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit
。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit
恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
git log
命令显示从最近到最远的提交日志
root@AY1406111318160294c8Z:~/wpic# git log commit 91bd73040b8f1ebcf5c4c7e02072352d43d491d0 Author: root <yohamed@wpic.co> Date: Thu May 10 13:29:57 2018 +0800 change file content commit ed3d20fe002800da265af2bb5a9f7ffdc1183f73 Author: root <yohamed@wpic.co> Date: Thu May 10 13:13:20 2018 +0800 add readme.txt file
如果嫌输出信息太多,看得眼花缭乱的,可以加上--pretty=oneline
参数
root@AY1406111318160294c8Z:~/wpic# git log --pretty=oneline 91bd73040b8f1ebcf5c4c7e02072352d43d491d0 change file content ed3d20fe002800da265af2bb5a9f7ffdc1183f73 add readme.txt file
回退到历史版本
Git必须知道当前版本是哪个版本,在Git中,用HEAD
表示当前版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
我们要把当前版本回退到上一个版本,使用 git reset 命令
root@AY1406111318160294c8Z:~/wpic# git reset --hard HEAD^ HEAD is now at ed3d20f add readme.txt file root@AY1406111318160294c8Z:~/wpic# git log commit ed3d20fe002800da265af2bb5a9f7ffdc1183f73 Author: root <yohamed@wpic.co> Date: Thu May 10 13:13:20 2018 +0800
回退到未来的版本,可以使用提交ID
root@AY1406111318160294c8Z:~/wpic# git reset --hard 91bd73040b8f1ebcf5c4c7e02072352d43d491d0 HEAD is now at 91bd730 change file content
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD
指针,当你回退版本的时候,仅仅是改变当前版本的指针,然后顺便把工作区的文件更新了.
Git提供了一个命令git reflog
用来记录你的每一次命令
root@AY1406111318160294c8Z:~/wpic# git reflog 91bd730 HEAD@{0}: reset: moving to 91bd73040b8f1ebcf5c4c7e02072352d43d491d0 ed3d20f HEAD@{1}: reset: moving to HEAD^ 91bd730 HEAD@{2}: commit: change file content ed3d20f HEAD@{3}: commit (initial): add readme.txt file
git checkout -- file #可以丢弃工作区的修改
git checkout -- readme.txt
命令git checkout -- readme.txt
意思就是,把readme.txt
文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt
自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt
已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
git reset HEAD file
命令git reset HEAD file
可以把暂存区的修改撤销掉(unstage),重新放回工作区
git reset
命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD
时,表示最新的版本。
git reset HEAD readme.txt
git rm
删除版本库文件
git rm readme.txt git commit -m "delete readme.txt"
远程仓库
Git是分布式版本控制系统,注册一个GitHub账号,就可以免费获得Git远程仓库。
由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的。所以需要设置SSH key 登录 gihub.
由于设置密钥登录比较简单,这里不做说明.
同步远程仓库
1. 在本地仓库下运行如下命令
添加后,远程库的名字就是origin
,这是Git默认的叫法,也可以改成别的,但是origin
这个名字一看就知道是远程库。
git remote add origin https://github.com/bushaoxun/test.git
2.把本地库的所有内容推送到远程库上
由于远程库是空的,我们第一次推送master
分支时,加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令。
git push -u origin master
从现在起,只要本地作了提交,就可以通过命令把本地master
分支的最新修改推送至GitHub 。
git push origin master
从远程仓库克隆
远程库已经准备好了,我们可以用命令git clone
克隆一个本地库:
git clone https://github.com/bushaoxun/test.git
git remote -v
查看远程仓库详细信息
root@AY1406111318160294c8Z:~/wpic# git remote -v origin https://github.com/bushaoxun/test.git (fetch) origin https://github.com/bushaoxun/test.git (push)
分支管理
创建了一个属于你自己的分支,别人看不到,在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上。
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master
分支。HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,所以,HEAD
指向的就是当前分支。
创建 dev 分支,然后切换到 dev 分支
git checkout -b dev
git checkout
命令加上-b
参数表示创建并切换,相当于以下两条命令:
git branch dev # 创建分支 git checkout dev # 切换到分支
git branch
命令查看当前分支:
root@AY1406111318160294c8Z:~/wpic# git branch * dev maste
dev
分支切换回master
分支
root@AY1406111318160294c8Z:~/wpic# git checkout master Switched to branch 'master' root@AY1406111318160294c8Z:~/wpic# git branch dev * master
dev
分支合并到master
分支上
如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>
强行删除。
git merge dev # 合并 dev 分支到 master 分支 git branch -d dev # 合并完成后删除分支
解决冲突(统一文件多分支改动)
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
用git log --graph
命令可以看到分支合并图。
分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
合并dev
分支,使用-no-ff
参数,表示禁用Fast forward
因为合并要创建一个新的commit,所以加上-m
参数,把commit描述写进去
git merge --no-ff -m "merge with no-ff" dev
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本;
你和你的小伙伴们每个人都在dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。
标签管理
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
创建标签
root@AY1406111318160294c8Z:~/wpic# git branch * master root@AY1406111318160294c8Z:~/wpic# git tag v1.0 # 打标签 root@AY1406111318160294c8Z:~/wpic# git tag # 查看标签 v1.0
标签不是按时间顺序列出,而是按字母排序的。可以用git show <tagname>
查看标签信息
-
命令
git tag <name>
用于新建一个标签,默认为HEAD
,也可以指定一个commit id; -
git tag -a <tagname> -m "blablabla..."
可以指定标签信息; -
git tag -s <tagname> -m "blablabla..."
可以用PGP签名标签; -
命令
git tag
可以查看所有标签。
操作标签
创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
删除标签
git tag -d v1.0
推送某个标签到远程
git push origin v1.0
-
命令
git push origin <tagname>
可以推送一个本地标签; -
命令
git push origin --tags
可以推送全部未推送过的本地标签; -
命令
git tag -d <tagname>
可以删除一个本地标签; -
命令
git push origin :refs/tags/<tagname>
可以删除一个远程标签。
自定义 git
- 让Git显示颜色,会让命令输出看起来更醒目:
git config --global color.ui true
- 忽略特殊文件
忽略某些文件时,需要编写.gitignore
;
.gitignore
文件本身要放到版本库里,并且可以对.gitignore
做版本管理!
- 配置别名
# 比如敲git st就表示git status git config --global alias.st status
配置文件
配置Git的时候,加上--global
是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用
每个仓库的Git配置文件都放在.git/config
文件中。可以通过修改此配置文件更改设置,如别名,email 等等.