博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java Web开发入门 - 第5章 Git
阅读量:6110 次
发布时间:2019-06-21

本文共 14264 字,大约阅读时间需要 47 分钟。

  hot3.png

版本控制简介

大纲

  • 版本控制系统
  • 分支模型
  • Git
    • Git介绍
    • Git命令详情

版本控制系统

  • 版本控制系统即VCS(Version Control System)是一种记录若干文件的修订记录的系统,帮助我们查阅或回到某个历史版本
    • VCS 人肉式
    • LVCS本地式版本控制系统
    • CVCS集中式版本控制系统
    • DVCS分布式版本控制系统

人肉VCS

输入图片说明

问题

最大问题,污染了整个工作空间,没办法集中精力维护当前编辑的版本。

Local VCS - 本地式

  • 举例
    • RCS(Revision Control System)

输入图片说明

优缺点

优点:具备个人版本管理

缺点:多人协同开发无法开展

CVCS - 集中式

  • 举例
    • CVS(Concurrent Versions System)
    • SVN(Subversion)
    • Perforce

输入图片说明

优缺点

优点:中央版本管理,数据内容可控

缺点:每次操作经过中央库,单点故障

DVCS - 分布式

  • 举例
    • Git
    • Mercurial

输入图片说明

优缺点

优点:本地操作,查看历史版本,版本差异比较

分支模型

版本污染,开发提交被迫终止, 问题定位比较复杂: 输入图片说明

如果采用如下方式进行开发:
输入图片说明

分支和分支模型

  • 分支:
    从目标仓库获得一份项目拷贝,每条拷贝都有和原仓库功能一样的开发线
  • 分支模型(branching model)/工作流(workflow):
    一个围绕项目**[开发/部署/测试]**等工作流程的分支操作(创建、合并等)规范集合

产品级的分支模型

常驻分支

常驻分支一但被创建就不会进行更改

  • development分支
    • 必须从master分支创建,master就是产品分支,必须是可
  • production(master)
    • 默认分支

活动分支

活动分支,跟着产品发布进行动态创建,有时候也进行删除,留下对应的版本号

  • feature分支
    • 从development创建
  • hotfix分支
    • 如hotfix-36,是从master创建
  • release分支
    • 如release-110,从development分支创建

分支模型-特性开发

输入图片说明

分支模型-发布线

输入图片说明 注意代码修复分支也应当合并到development开发分支,这样代码修复的分支也可以被追溯

涉及到的环境

  • 开发环境
    测试/开发环境具有测试数据库,缓存、相应配置等。开发环境需要提交到下一个release的特性分支,在本地测试分支
  • 测试环境
    测试数据库环境与缓存。release/development分支
  • 预发布环境
    release分支代码
  • 生产环境 master分支代码

输入图片说明

Git简介

Git是什么

  • git是一个免费开源的分布式版本控制系统(DVCS)
  • git是一个基于内容寻址的存储系统

历史

  • git的出现离不开linux
    • 1991-2002:几乎无版本控制(patch包)
    • 2002-2005:BitKeeper
    • 2005-至今:git

优势

  • 速度快,不依赖网络,本地操作
  • 完全的分布式
  • 轻量级的分支操作
  • Git已经成为现实意义上的标准
  • 社区成熟活跃
    git离不开github

安装

  • Windows:msysgit (编者建议使用:)
  • Mac
brew install git
  • Ubuntu
apt-get install git

Git命令详解

Git常用命令

命令中输入git,可以看到git推荐的常用命令:

zhanpeng@GE70:~$ gitusage: git [--version] [--help] [-C 
] [-c name=value] [--exec-path[=
]] [--html-path] [--man-path] [--info-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=
] [--work-tree=
] [--namespace=
]
[
]The most commonly used git commands are: add Add file contents to the index bisect Find by binary search the change that introduced a bug branch List, create, or delete branches checkout Checkout a branch or paths to the working tree clone Clone a repository into a new directory commit Record changes to the repository diff Show changes between commits, commit and working tree, etc fetch Download objects and refs from another repository grep Print lines matching a pattern init Create an empty Git repository or reinitialize an existing one log Show commit logs merge Join two or more development histories together mv Move or rename a file, a directory, or a symlink pull Fetch from and integrate with another repository or a local branch push Update remote refs along with associated objects rebase Forward-port local commits to the updated upstream head reset Reset current HEAD to the specified state rm Remove files from the working tree and from the index show Show various types of objects status Show the working tree status tag Create, list, delete or verify a tag object signed with GPG'git help -a' and 'git help -g' lists available subcommands and someconcept guides. See 'git help
' or 'git help
'to read about a specific subcommand or concept.

查询命令帮助

输入图片说明

举例

git help clone

git config - 配置

命令行配置git

  • 用户配置
    • git config --global user.name "ZhanPeng"
    • git config --global user.email
  • 配置级别
    • --local 【默认、高优先级】:只影响本仓库 .git/config
    • --global 【中优先级】:影响到所有当前用户的git仓库~/.gitconfig
    • --system 【低优先级】:影响到全系统的git仓库/etc/gitconfig

config文件

zhanpeng@GE70:~/Workspace/git/git_test$ cat .git/config [core]	repositoryformatversion = 0	filemode = true	bare = false	logallrefupdates = true

git init - 初始化仓库

查看当前仓库的信息

git status

由于没有初始化仓库,则没有任何信息内容,提示我们不是git仓库

zhanpeng@GE70:~/Workspace/git$ git statusfatal: Not a git repository (or any of the parent directories): .git

初始化git仓库

之后我们使用git init对仓库进行初始化

git init

显示如下信息

zhanpeng@GE70:~/Workspace/git/git_test$ git initInitialized empty Git repository in /home/zhanpeng/Workspace/git/git_test/.git/

查看目录结构

zhanpeng@GE70:~/Workspace/git/git_test$ tree -a.└── .git    ├── branches    ├── config    ├── description    ├── HEAD    ├── hooks    │   ├── applypatch-msg.sample    │   ├── commit-msg.sample    │   ├── post-update.sample    │   ├── pre-applypatch.sample    │   ├── pre-commit.sample    │   ├── prepare-commit-msg.sample    │   ├── pre-push.sample    │   ├── pre-rebase.sample    │   └── update.sample    ├── info    │   └── exclude    ├── objects    │   ├── info    │   └── pack    └── refs        ├── heads        └── tags

再次查看信息

zhanpeng@GE70:~/Workspace/git/git_test$ git statusOn branch masterInitial commitnothing to commit (create/copy files and use "git add" to track)

git status - 三对关系的状态变化

三种状态变化

  • 未跟踪 <-> 跟踪
  • 工作目录 <-> 暂存区
  • 暂存区 <-> 最新提交

git-status:对状态的跟踪

  • 内容状态

    • 工作目录
    • 暂存区
    • 提交区
  • 文件状态

    • 未跟踪
    • 已跟踪

这些状态是可以相互进行转化的

输入图片说明
git status帮助我们了解这些状态

创建文件查看状态

git touch命令创建文件,但是有没有add文件

zhanpeng@GE70:~/Workspace/git/git_test$ touch README.mdzhanpeng@GE70:~/Workspace/git/git_test$ git statusOn branch masterInitial commitUntracked files:  (use "git add 
..." to include in what will be committed) README.mdnothing added to commit but untracked files present (use "git add" to track)

git add

添加单个文件

添加文件内容到缓存区(同时文件被追踪),如下举例添加文件

zhanpeng@GE70:~/Workspace/git/git_test$ git add README.md zhanpeng@GE70:~/Workspace/git/git_test$ git statusOn branch masterInitial commitChanges to be committed:  (use "git rm --cached 
..." to unstage) new file: README.md

添加文件,代表着内容状态:从工作目标转到了缓存区;文件状态:从未跟踪转到了已跟踪。 输入图片说明输入图片说明

批量添加

zhanpeng@GE70:~/Workspace/git/git_test$ touch package.jsonzhanpeng@GE70:~/Workspace/git/git_test$ git add .zhanpeng@GE70:~/Workspace/git/git_test$ git statusOn branch masterInitial commitChanges to be committed:  (use "git rm --cached 
..." to unstage) new file: README.md new file: package.json

批量添加会添加在不想要添加的内容

忽略文件

  • .gitignore
    • 在添加时忽略匹配的文件
    • 仅作用于未追踪的文件

常见gitignore

# Logslogs*. log# Runtime datapids*.pid*.seed# Directory for instrumented libs generated by jscoverage/JSCoverlib-cov# Editor config*.sublime-*# Compiled binary addons (http://nodejs.org/api/addons.html)build/Release# Dependency directorynode_modules

如果不知道如何书写gitignore,github上有官方仓库

只是帮助我们忽略文件,并不是删除

git rm - 删除

  • git rm --cached仅从暂存去删除
  • git rm从暂存区与工作目录删除
  • git rm $(git ls-files --deleted)删除所有被跟踪,但是在工作目录被删除的文件

工作目录与暂存区

工作目录与暂存区可以同时存在两个文件

zhanpeng@GE70:~/Workspace/git/git_test$ vim README.md zhanpeng@GE70:~/Workspace/git/git_test$ git statusOn branch masterInitial commitChanges to be committed:  (use "git rm --cached 
..." to unstage) new file: README.md new file: package.jsonChanges not staged for commit: (use "git add
..." to update what will be committed) (use "git checkout --
..." to discard changes in working directory) modified: README.md

暂存区

  • 每个文件只能放置一次工作目录
    • 工作目录和暂存区可以同时出现同一文件
    • 工作目录的文件可以替换掉暂存区的文件
    • 可以删除文件
    • 提交暂存区,生成提交内容记录

git commit -

根据暂存区内容创建提交记录

zhanpeng@GE70:~/Workspace/git/git_test$ git commit -m '第一次提交'[master (root-commit) dfebdc2] 第一次提交 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md create mode 100644 package.jsonzhanpeng@GE70:~/Workspace/git/git_test$ git statusOn branch masterChanges not staged for commit:  (use "git add 
..." to update what will be committed) (use "git checkout --
..." to discard changes in working directory) modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")

直接提交

git commit -a -m 'update message in here'

git log

  • commit 分割提交记录,SHA-1编码的HASH标识符
  • git-config 配置的提交者的信息
zhanpeng@GE70:~/Workspace/git/git_test$ git logcommit dfebdc23263e5500782b4d6126949eda5dd0e582Author: 抢小孩糖吃 
Date: Sat Aug 27 16:57:11 2016 +0800 第一次提交

可以通过参数让log更美观

zhanpeng@GE70:~/Workspace/git/git_test$ git log --onelinedfebdc2 第一次提交

更复杂的美观配置

git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

输出

zhanpeng@GE70:~/Workspace/git/git_test$ git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit* dfebdc2 - (HEAD, master) 第一次提交 (31 hours ago) 
<抢小孩糖吃>

git中alias命令

  • git config alias.shortname <fullcommand>
    超长命令修改成为别名
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

别名输出

zhanpeng@GE70:~/Workspace/git/git_test$ git lg* dfebdc2 - (HEAD, master) 第一次提交 (31 hours ago) 
<抢小孩糖吃>

别名会配置到config文件当中

zhanpeng@GE70:~$ cat ~/.gitconfig [username]	email = zhan.peng@aliyun.com	name = zhanpeng[user]	email = zhan.peng@aliyun.com	name = 抢小孩糖吃[core]	autocrlf = input[alias]	lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

git diff - 显示不同版本差异

  • git diff:
    • 工作目录与暂存区的差异
  • git diff -cached [<reference>]
    • 暂存区与某次提交差异,默认为HEAD
  • git diff <reference>
    • 工作目录与某次提交的差异

输入图片说明

撤销本地修改

git status提示了如何撤销

zhanpeng@GE70:~/Workspace/git/git_test$ git statusOn branch masterChanges not staged for commit:  (use "git add 
..." to update what will be committed) (use "git checkout --
..." to discard changes in working directory) modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")

git checkout -- <file>将文件内容从暂存区复制到工作目录

输入图片说明

##撤销暂存区内容 git reset HEAD <file>将文件内容从上次提交复制到暂存区

输入图片说明

撤销全部改动

git checkout HEAD -- <file>将内容从上次提交复制到工作目录

输入图片说明

课堂题目

输入图片说明

总结

输入图片说明

分支操作

git branch

  • git branch <branchName> 创建分支
  • git branch -d <branchName> 删除分支
  • git branch -v 显示所有分支信息

提交历史是不断向前的线,新提交会指向之前的分支,分支名称如master还有指针对象HEAD,在新提交时,都会指向新提交

输入图片说明

git branch创建分支

创建next分支,有别于master分支

git branch next

查看分支信息

$ git branch -v* master 2986d7d hello world  next   2986d7d hello world

输入图片说明

查看分支引用文件内容

yanfa@yanfa-PC MINGW32 /d/ZhanPeng/Workspace/git/git_test (master)$ cat .git/refs/heads/master2986d7d4706045d995943933f95389b8e51eedd0yanfa@yanfa-PC MINGW32 /d/ZhanPeng/Workspace/git/git_test (master)$ cat .git/refs/heads/next2986d7d4706045d995943933f95389b8e51eedd0

这时候我们git commit内容 输入图片说明

git checkout

通过移动HEAD检出版本,可以用于分支切换

  • git checkout <branchName>
  • 'git checkout -b <branchName>'
  • git checkout <reference>

切换分支

git checkout next

这里是列表文本 我们这里查看文件内容,确实被切换到了next分支,文件内容也跟随发生了变化

切换分支后提交

修改文件内容,使用git commit进行提交,通过branch -v查看

yanfa@yanfa-PC MINGW32 /d/ZhanPeng/Workspace/git/git_test (next)$ git branch -v  master 93d0158 master* next   cd72638 next branch

输入图片说明

恢复到上一个分支

git checkout -

输入图片说明

新建并切换到新分支

新建并切换到issue-26分支

git checkout -b issue-26

输入图片说明

查看分支

yanfa@yanfa-PC MINGW32 /d/ZhanPeng/Workspace/git/git_test (issue-26)$ git branch -v* issue-26 90e2ef3 issue 26  master   93d0158 master  next     cd72638 next branch

分离HEAD指针

通过git log查看所有提交的信息

yanfa@yanfa-PC MINGW32 /d/ZhanPeng/Workspace/git/git_test (issue-26)$ git logcommit 90e2ef3f203ed8b536bbf63af49bc4b56daa051aAuthor: zhanpeng 
Date: Mon Aug 29 14:48:36 2016 +0800 issue 26commit cd72638964210491b5a594134b3f92c3893555b8Author: zhanpeng
Date: Mon Aug 29 14:41:18 2016 +0800 next branchcommit 2986d7d4706045d995943933f95389b8e51eedd0Author: zhanpeng
Date: Mon Aug 29 14:23:26 2016 +0800 hello worldcommit 379674d9469e1dd3ef38643259bf4dd96f02981bAuthor: zhanpeng
Date: Mon Aug 29 14:22:02 2016 +0800 init and add readme:...skipping...commit 90e2ef3f203ed8b536bbf63af49bc4b56daa051aAuthor: zhanpeng
Date: Mon Aug 29 14:48:36 2016 +0800 issue 26commit cd72638964210491b5a594134b3f92c3893555b8Author: zhanpeng
Date: Mon Aug 29 14:41:18 2016 +0800 next branchcommit 2986d7d4706045d995943933f95389b8e51eedd0Author: zhanpeng
Date: Mon Aug 29 14:23:26 2016 +0800 hello worldcommit 379674d9469e1dd3ef38643259bf4dd96f02981bAuthor: zhanpeng
Date: Mon Aug 29 14:22:02 2016 +0800 init and add readme

HEAD跳转到固定提交点,输入值为提交点的前7位

git checkout 379674d

这时候HEAD和具体的分支进行了分离,这个状态我们称为detached head!

输入图片说明

如果在HEAD与分支节点分离时,尽量减少提交内容,没有引用指向这个提交记录,会被git垃圾回收。

输入图片说明

可以看到暂存区内工作文件内容发生变化,但实质的工作目录并没有变化。

git reset

将当前分支回退到历史某个版本

  • git reset --mixed <commit>(默认)
  • git reset --soft <commit>
  • git reset --hard <commit>

分支跳转到固定以前的版本

git reset --mixed 

除了切换master回到原来的某个commit,还会将当前的内容复制到暂存区 输入图片说明

当我们使用git reset --hard <commit>时,还会将内容复制到工作目录

当我们需要暂存区和工作目录都保持现在的状态,则需要使用git reset --soft <commit>命令
由于之前的提交没有指针指向,则变成了没有索引的提交,将有可能进行垃圾回收
###git reflog - 找回垃圾回收内容

yanfa@yanfa-PC MINGW32 /d/ZhanPeng/Workspace/git/git_test (master)$ git reflog93d0158 HEAD@{0}: checkout: moving from next to mastercd72638 HEAD@{1}: checkout: moving from master to next93d0158 HEAD@{2}: checkout: moving from 379674d9469e1dd3ef38643259bf4dd96f02981b to master379674d HEAD@{3}: checkout: moving from issue-26 to 379674d9469e1dd3ef38643259bf4dd96f02981b90e2ef3 HEAD@{4}: commit: issue 26cd72638 HEAD@{5}: checkout: moving from next to issue-26cd72638 HEAD@{6}: commit: next branch2986d7d HEAD@{7}: checkout: moving from master to next93d0158 HEAD@{8}: commit: master2986d7d HEAD@{9}: commit: hello world379674d HEAD@{10}: commit (initial): init and add readme

我们可以通过这个命令,找回commit。注意:这个reflog是不断向前的,也就是说有些信息会丢失。

如何避免hash值进行操作

使用便捷操作

  • A^:A上的父提交
  • A~n:在A之前的第n次提交

输入图片说明

##reset与checkout 输入图片说明

git stash

保存stash

保存目前的工作目录和暂存区状态,并返回到干净的工作空间

git stash save 'push to stash area'

输入图片说明

查看stash记录

git stash list

git stash apply

提取栈顶内容

git stash drop

丢弃栈顶内容 输入图片说明

stash pop = stash apply + stash drop

提取栈顶内容,并丢弃

git merge - 合并开发

合并分支

git merge next

输入图片说明

git cat-file -p HEAD

获取所有节点的父子关系

合并冲突

git merge next master

发生冲突,指两个分支都做了内容修改

merge fast-forward

不要使用fast forward方式合并出现新的commit

git merge next --no-ff

merge不足

人数增多,分支增多交叉非常多,使用命令帮助我们修剪分支

git rebase

修剪提交历史基线,俗称变基

git rebase master

重演复制过程

输入图片说明

git rebase --onto

挑选commit的提交对象会被重演

rebase与merger

输入图片说明 **注意:**不要在公有分支(master)使用rebase

git tag

对某个提交设置一个不变的别名

git tag v0.1 hash

远程操作

Git支持本地协议,所以我们可以初始化一个本地的远程服务器。

将当前仓库初始化为一个裸仓库

git init ~/git-server --bare

注意:裸仓库是没有工作目录的,如果有工作目录,并且进行了提交,反而对整个git系统发生错乱,中央服务器被动接受,防止多人提交造成冲突。

git push

git push ~/git-server master

输入图片说明

git remote

远程仓库相关配置操作

git remote add origin ~/git-servergit remote -v

我肯可以在.git/config文件中,查看到我们填写的远程仓库内容信息。

注意:默认的远程分支名称默认叫做origin

冲突解决

在git commit提交后,希望把编写的信息提交到git服务器上,则需要如下命令:

git push origin master

输入图片说明

我们可以看到上面的人提交的分支,顺利推送到了远程origin上,但是下面的人提交的分支无法同步到远程。这时候需要获取远程仓库的提交历史,并解决冲突。

git fetch

获取远程仓库的提交历史

git fetch origin master

git fetch + merge解决冲突

git merge origin/master

最终会完成一个新的提交

git push origin master

git pull

git pull = git fetch + git mergo

完整获取远程仓库

git clone = git init + git remote + git pull

克隆一个远程仓库作为本地仓库

其他参考资料

转载于:https://my.oschina.net/hava/blog/738755

你可能感兴趣的文章
Spring Data Redis 2 之消息订阅
查看>>
centos中如何查看tomcat的版本
查看>>
[XML/RSS] XML加ASP实现网页自动适应多国语言
查看>>
Android小笔记自定义控件
查看>>
学会思考
查看>>
docker 镜像仓库Harbor https访问
查看>>
dblink创建
查看>>
磁盘管理
查看>>
luov之SMTP报错详解
查看>>
软件概要设计做什么,怎么做
查看>>
dwr
查看>>
java的特殊符号
查看>>
word2010中去掉红色波浪线的方法
查看>>
fabric上下文管理器(context mangers)
查看>>
JQuery-EasyUI Datagrid数据行鼠标悬停/离开事件(onMouseOver/onMouseOut)
查看>>
并发和并行的区别
查看>>
Java增强的for循环和普通for循环对比
查看>>
颜色渐变的算法
查看>>
第四次作业
查看>>
getLocation需要在app.json中声明permission字段,解决办法
查看>>