Git

简介

​ Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目,不必服务器端软件支持。

区别

  • Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。
  • **Git 把内容按元数据方式存储,而 SVN 是按文件:**所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。
  • **Git 分支和 SVN 的分支不同:**分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
  • **Git 没有一个全局的版本号,而 SVN 有:**目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
  • **Git 的内容完整性要优于 SVN:**Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。

安装配置

Debian/Ubuntu

$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
	libz-dev libssl-dev

$ apt-get install git

$ git --version

Centos/RedHat

$ yum install curl-devel expat-devel gettext-devel \
  openssl-devel zlib-devel

$ yum -y install git-core

$ git --version

配置文件

​ Git 提供了一个叫做 git config 的工具,专门用来配置或读取相应的工作环境变量。这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:

  • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
  • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。
  • 当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。

工作流程

  • 克隆 Git 资源作为工作目录。
  • 在克隆的资源上添加或修改文件。
  • 如果其他人修改了,你可以更新资源。
  • 在提交前查看修改。
  • 提交修改。
  • 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。

工作区 暂存区 版本库

  • **工作区:**就是你在电脑里能看到的目录。
  • **暂存区:**英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • **版本库:**工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

img

操作

git init

初始化仓库 , 生成.git目录

#使用当前目录
git init

#使用指定目录
git init newrepo

添加文件

git add *.cpp
git add README.md
git commit -m "first version"

在 Linux 系统中,commit 信息使用单引号 ',Windows 系统,commit 信息使用双引号 "

git clone

从现有Git仓库拷贝项目

git clone <repo>

#克隆到指定目录
git clone <repo> <directory>

git clone https://github.com/li-ruida/test.git

#自定义克隆项目名称
git clone git://github.com/li-ruida/test.git mygrit
git clone git@github.com:li-ruida/test.git#SSH协议
git clone git://github.com/li-ruida/test.git#GIT协议
git clone https://github.com/li-ruida/test.git#HTTPS协议

git config

配置个人的用户名称和电子邮件地址

git config --global user.name "test"
git config --global user.email test@lrdhappy.com

​ 如果用了 –global 选项,那么更改的配置文件就是位于用户主目录下的那个,所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。

git config --list# 查看配置信息
vim ~/.gitconfig #linux修改配置
git config -e	#windows修改当前仓库配置
git config -e --global #针对windows上所有仓库

# 配置也可以在 ~/.gitconfig 或 /etc/gitconfig 看到
git config user.name
# 直接查看某个环境变量配置
#修改差异分析工具
git config --global merge.tool vimdiff
//查
git config --global --list
git config --global user.name
git config --global user.email

//增
git config  --global --add user.name xxx
git config  --global --add user.email xxx

//删
git config  --global --unset user.name xxx
git config  --global --unset user.email xxx

//改
git config --global user.name xxx
git config --global user.email xxx

git add

git add [file1] [file2] ... #添加文件到暂存区
git add README hello.cpp

git add [dir] #添加目录到暂存区,包含子目录

git add .	#添加当前目录所有文件到暂存区

git status

git status 命令用于查看在你上次提交之后是否有对文件进行再次修改

git status

使用 -s 参数来获得简短的输出结果 , 添加文件后执行 , 可以看到文件开头显示A已经添加到暂存区,如果显示**??**则没有添加到暂存区

git status -s

对文件修改后,文件开头显示AM表示添加到暂存区后又有改动

git diff

git diff 命令比较文件的不同,即比较文件在暂存区和工作区的差异。

  • 尚未缓存的改动:git diff
  • 查看已缓存的改动: git diff --cached
  • 查看已缓存的与未缓存的所有改动:git diff HEAD
  • 显示摘要而非整个 diff:git diff --stat
git diff [file] #显示暂存区和工作区的差异
git diff --cached [file] #显示暂存区和上一次提交(commit)的差异   
#或
git diff --staged [file]
#显示两次提交之间的差异
git diff [first-branch]...[second-branch]

git commit

将暂存区内容添加到本地仓库中

在 Linux 系统中,commit 信息使用单引号 ',Windows 系统,commit 信息使用双引号 "

git commit -m [message]#[message]为备注信息
git commit -a #不需要执行git add,直接提交

commit后执行status nothing to commit (working directory clean)

git reset

git reset 命令用于回退版本,可以指定退回某一次提交的版本

git reset [--soft | --mixed | --hard] [HEAD]

–mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变

git reset  [HEAD] 

git reset HEAD hello.cpp  #取消缓存
git reset HEAD^            # 回退所有内容到上一个版本  
git reset HEAD^ hello.cpp  # 回退 hello.php 文件的版本到上一个版本  
git  reset  052e           # 回退到指定版本

–soft 参数用于回退到某个版本

git reset --soft HEAD

git reset --soft HEAD~3   # 回退上上上一个版本 

–hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交

git reset --hard HEAD

git reset --hard HEAD~3  # 回退上上上一个版本  
git reset –hard bae128  # 回退到某个版本回退点之前的所有信息。 
git reset --hard origin/master    # 将本地的状态回退到和远程的一样 

HEAD 说明:

  • HEAD 表示当前版本
  • HEAD^ 上一个版本
  • HEAD^^ 上上一个版本
  • HEAD^^^ 上上上一个版本
  • 以此类推…

也可以使用 ~数字表示

  • HEAD~0 表示当前版本
  • HEAD~1 上一个版本
  • HEAD^2 上上一个版本
  • HEAD^3 上上上一个版本
  • 以此类推…

git rm

git rm <file> #将文件从暂存区和工作区中删除

git rm test.cpp

如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

git rm -f test.cpp

如果想把文件从暂存区域移除,但仍然希望保留在当前工作目录中 , 使用 –cached 选项

git rm --cached <file>
git rm --cached test.cpp

递归删除

git rm –r * #删除整个目录的所有目录与文件

git mv

移动或重命名一个文件、目录或软连接

git mv [file] [newfile]

git add README 
git mv README  README.md

如果新文件名已经存在,但还是要重命名它,可以使用 -f 参数

git mv -f [file] [newfile]

git log

查看历史提交记录

  • --oneline 选项来查看历史记录的简洁的版本
  • --graph 选项,查看历史中什么时候出现了分支、合并。以下为相同的命令,开启了拓扑图选项
  • --reverse 参数来逆向显示所有日志
  • --author 查找指定用户的提交日志可以使用命令
  • 如指定日期,可以执行几个选项:–since 和 --before,也可以用 --until 和 --after。
  • –no-merges 选项以隐藏合并提交
git log

git log --oneline

git log --graph

git log --reverse

git log --author lrd
git log --author=lrd
git log --author=lrd --oneline -2 #显示lrd提交的两个

git log --oneline --before={3.weeks.ago} --after={2010-04-18}

git blame

查看指定文件的修改记录

git blame <file>

git remote

git remote -v #显示所有远程仓库

#先载入远程仓库,然后查看信息 origin 为远程地址的别名
git clone https://github.com/tianqixin/runoob-git-test
cd runoob-git-test
git remote -v

origin  https://github.com/tianqixin/runoob-git-test (fetch)
origin  https://github.com/tianqixin/runoob-git-test (push)
git remote show [remote] #显示某个远程仓库的信息

git remote show https://github.com/tianqixin/runoob-git-test
git remote add [shortname] [url] #添加远程版本库 shortname 为本地的版本库

# 提交到 Github
git remote add origin git@github.com:tianqixin/runoob-git-test.git
git push -u origin master
git remote rm name  # 删除远程仓库
git remote rename old_name new_name  # 修改仓库名

git fetch

从远程获取代码库 , 该命令执行完后需要执行 git merge 远程分支到你所在的分支

git merge #从远端仓库提取数据并尝试合并到当前分支
git fetch [alias] #提取更新的数据
git merge [alias]/[branch]  #以上命令将服务器上的任何更新 , 合并到你的当前分支
git fetch origin
git merge origin/master

git pull

从远程获取代码并合并本地的版本 , git pull 就是 git fetchgit merge FETCH_HEAD 的简写

git pull <远程主机名> <远程分支名>:<本地分支名>

git pull
git pull origin master #远程分支是与当前分支合并,则冒号后面的部分可以省略
git pull origin master:brantest # 将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并

git push

将本地的分支版本上传到远程并合并

git push <远程主机名> <本地分支名>:<远程分支名>
#如果本地分支名与远程分支名相同,则可以省略冒号:
git push <远程主机名> <本地分支名>
#将本地的master分支推送到origin主机的master分支
git push origin master
#相当于
git push origin master:master

#如果本地版本与远程版本有差异,但又要强制推送使用 --force 参数
git push --force origin master

#删除主机的分支可以使用 --delete 参数
git push origin --delete master

git branch

​ 一个分支代表一条独立的开发线 , Git 分支实际上是指向更改快照的指针 . 当切换分支的时候,Git 会用该分支的最后提交的快照替换工作目录的内容, 所以多个分支不需要多个目录

img

git branch #列出分支
git branch (branchname) #创建分支
git checkout (branchname)#切换分支
git merge #合并分支 git merge newtest
git checkout -b (branchname) #创建新分支并立即切换到该分支下
git branch -d (branchname) #删除分支

合并冲突

遇到冲突文件,手动修改后,对文件add commit

git tag

使用git tag对提交快照打标签 , -a 选项意为"创建一个带注解的标签 , 执行git log可以看到标签

git tag -a v1.0 #创建带注解的标签
git tag v1.0 #创建不带注解的标签
git tag #查看标签
git tag -d v1.0 #删除标签
git show v1.0 #查看该版本修改内容
git tag -a v0.9 85fc7e7#追加标签

git tag -a <tagname> -m "标签" #指定标签信息
git tag -s <tagname> -m "标签" #PGP签名标签

Github

img

ssh -T git@github.com #验证连接是否成功
echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:li-ruida/test.git
git push -u origin main