Git 是如何工作的
本地建库
Git 是一个分布式版本控制系统,当你准备使用git 来管理文件的版本时,首先在你本地需要一个git 库用来存储git 的提交记录,这里有两种方式用来创建本地库
一、使用git init 在本地初始化一个git 库
初始化一个git 库
当执行完git init 命令后,git 将会在项目目录下建立一个隐藏目录 .git 。这个时候就说明本地的库已经创建成功,可以正常使用git 提供的各种命令去管理版本。
git 创建这个 .git 目录是用来做什么的呢?
.git 是 git 存储数据的目录,我们也可以通过直接拷贝.git目录的方式直接复制出一个git库。默认情况下 .git 包含了以下文件:
- HEAD 文件、(尚待创建的)index 文件,和 objects 目录、refs 目录。 这些条目是 Git 的核心组成部分。
- objects 目录存储所有数据内容;
- refs 目录存储指向数据(分支)的提交对象的指针;HEAD 文件指示目前被检出的分支;
- index 文件保存暂存区信息。
- description 文件仅供 GitWeb 程序使用,我们无需关心。
- config 文件包含项目特有的配置选项。
- info 目录包含一个全局性排除(global exclude)文件,用以放置那些不希望被记录在 .gitignore 文件中的忽略模式(ignored patterns)。
- hooks 目录包含客户端或服务端的钩子脚本(hook scripts)
在使用git init 命令成功创建本地库后可能需要关联到远程库
ssh 协议:
git remote add origin git@172.10.100.188:serio/gitdemo.git
http/https 协议:
git remote add origin http://172.10.100.188/serio/gitdemo.git
如不想每次push的时候都输入密码:
git config --global credential.helper store
二、使用git clone从远程库clone 一个到本地库
Clone 有两种方式一个是使用http/https 协议、还有一种就是ssh 协议
http/https协议:
ssh协议:
假如你没有将你的公钥配置到远程库所在的服务器上将会报以上这个错误。
那如何生成公私钥,如何配置呢?
Windows 上公私钥可以通过 msysgit 软件包的 ssh-keygen 生成,这里会提示公私钥存放目录和密码,截图中我都是默认目录和无密码设置
这里可以看到公私钥已经生成到 c/Users/苦参/.ssh 目录下
然后将 id_rsa.pub 文件中的内容全文拷贝到服务器上即可
Gitlab: http://172.10.100.188/profile/keys
Gihub:https://github.com/settings/keys
在你配置好公钥后就可以顺利的使用ssh协议去pulll 远程的代码
使用 git 管理版本
一、开始使用git 管理版本前
配置使用人名称、邮箱
git config --global user.name 名称
git config --global user.emal 邮箱
这个配置是用来记录提交人名称和邮箱,如果加了--blobal 将设置成全局配置,默认为local。除了使用命令行配置之外还可以直接修改配置文件进行配置。
全局配置文件位于用户目录下,比如我的就是C:Users苦参.gitconfig,本地配置文件位于项目.git/config
git config --global pull.rebase true
配置拉取远程分支代码时候将默认merge改为rebase
git config --global branch.autoSetupRebase always
配置所有分支拉取远程代码时候将默认merge改为rebase
为什么要将 pull 默认的merge 设置成rebase?
当我们在开发的时候在本地develop分支commit 了两次(C) 和 (D),而这个时候另外一个开发在他的develop分支提交了(E)、(F),同时他push到了远程的develop,这个时候我们正常情况下向远程push代码是不被git允许。我们需要通过pull命令从远程获取一次代码,默认pull 命令由两个命令组成 git fetch + merge FETCH_HEAD,当我们执行git pull 的时候将发生以下操作
pull 之前
origin/develop
|
+−−−− (E)−−−−(F)
/
(A) −− (B)−−−−−−− (C) −− (D)
|
Develop
默认pull 之后
origin/develop
|
+−−−− (E)−−−−(F)−−−−−−−−−−−−−−−−
/
(A) −− (B) −−−−−−−−(C) −− (D)−−−−(G − merge commit)
|
develop
如果是使用pull --rebase的之后
(A) −− (B)−−−−−−− (E) −− (F) −−−−−−− (C') −− (D')
| |
origin/develop develop
如果使用默认的 merge 去远程pull 代码,当远程分支和你本地分支都有在同一个commit后commit过的时候,系统将会自动将这两个commit 合并到一个变更记录里做提交操作
这将导致我们在后期 git log 的时候发现 会多出来一个commit ,同时 --graph 的时候会发现分支线出现多条影响提交日志的追踪。
二、常用命令和常见问题
git 命令有两种一个是高层命令、另外一个是底层命令,这里只要讲的是常用的高层命令,如果度底层命令感兴趣可以去阅读底层命令
查看当前状态
git status
忽略文件
在.gitignore 文件中添加需要忽略的文件即可
验证忽略格式
git check-ignore */target/*
创建分支
git checkout -b 分支名
git branch 分支名
git checkout -b develop origin/develop
删除分支
删除本地分支
git branch -d 分支名
删除远程分支
git push o rigin :分支名
合并分支
假如需要将develop分支合并到master分支上
先将HEAD切到master上
git checkout master
通过merge 命令将develop 合并过来
git merge develop
解决冲突
如何解决冲突
当一个文件在两个分支同时修改同一个地方时,merge 或者 rebase 将有将会有冲突产生,git 在 merge/rebase 过程中将通过
<<<<<<<=======>>>>>>> 这个三个符号标记出不同版本的修改记录,这个时候需要手动去解决冲突,删除不需要的版本留下需要的版本
Here are lines that are either unchanged from the common ancestor, or cleanly resolved because only one side changed. <<<<<<< yours:sample.txt Conflict resolution is hard; let's go shopping. ======= Git makes conflict resolution easy. >>>>>>> theirs:sample.txt And here is another line that is cleanly resolved or unmodified.
如果是merge的时候出现冲突
解决完冲突后
git add .
git merge --continue
如果是rebase的时候出现冲突
git add .
git rebase --continue
冲突的时候如何取消merge 或者 rebase
git merge --abort
git rebase --abort
查看修改记录
# 提交记录
git log
# 本地操作记录
git reflog
放弃修改
放弃存放到暂存区的修改
git reset HEAD 文件
放弃工作区的修改
git checkout HEAD 文件
将工作区修改存放到stash中
git stash
从stash 中取出修改
git stash apply stash@{0}
从stash中取出并删除stash
git stash pop stash@{1}
显示所有的stash
git stash list
回滚代码
回滚本地库代码
git reset 版本号 --hard
如果加上如果不加--hard git 将会把放弃的commit还原到工作区
临时将当前指针指向到指定版本号中
git checkout 版本号
回滚远程版本
当只有一个commit需要回滚的时候可以通过revert回滚,revert 命令将会提交一份删除了指定版本commit
比如这里需要回滚D的代码
(A) −− (B) −−−−−−−−(C) −− (D)
git revert D
(A) −− (B) −−−−−−−−(C) −− (D)−− (D')
这个将会有产生一个新的提交记录 D' ,而 D' 提交的将是删除 D的修改后的状态
git revert 版本号
git push
当需要回滚很多代码的时候
同过reset 将本地库回滚到指定版本
删除远程分支
git push :develop
推送本地分支到远程分支
git push origin develop
打标签
git tag -a标签名 -m “注释”
显示所有标签
git tag
删除标签
git tag -d 标签名
推送到远程
git push origin 标签名
删除远程标签
Git push origin :标签名
GIt 分支模型
关于分支模型可以去看我另外一篇文章
推荐阅读
教程:https://www.liaoxuefeng.com
推荐阅读:https://git-scm.com/book/zh/v2
git 命令手册: https://git-scm.com/docs