写在前面
-
VCS中集中式与分布式的差别
集中式的服务器如果挂了,那么所有人都挂了,因为完整仓库只存在服务器上 ; 而分布式如果github|gitlab挂了 ,你还可以重新建一个服务器,你把任何一个人的仓库clone过去就OK,因为分布式版本控制的每个节点都是一个完整仓库
每个节点都是完整仓库 what mean ?
- 每个人(节点)都有自己的历史版本记录
- 虽然我们在使用git时也会定义一个用来交换修改的中央仓库,但其实我们在git中把它称为原始库(origin)
Quick Start
from gitlab quick start
- Git global setup
git config --global user.name "wesley"
git config --global user.email "wesley.wang@maixian.com"
- Git repository
2.1 Create a new repository
git clone http://wesley@10.1.0.200/wesley/mx-bss.git
cd mx-bss
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
2.2 Existing folder
cd existing_folder
git init
git remote add origin http://wesley@10.1.0.200/wesley/mx-bss.git
git add .
git commit -m "Initial commit"
git push -u origin master
2.3 Existing Git repository
cd existing_repo
git remote add origin http://wesley@10.1.0.200/wesley/mx-bss.git
git push -u origin --all
git push -u origin --tags
分支管理
- 创建分支
- 创建并切换分支。
$ git checkout -b test
- 开始一项功能的开发工作时,基于develop创建功能分支。
$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
- master 分支
Git初始化仓库时的默认分支,通常用来作为其它长期分支(develop)的主干。
在Git里,这个分支叫主分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
- 删除分支
- 已经合并的分支
$ git branch --merged
*master
temp
git branch -d branch-name
- 如果要丢弃一个没有合并的分支
$ git branch --no-merged
$ git branch -D branch-name。//-D可理解为强制
- 分支模型
git merge
- 合并策略 strategy
- default
- resolve
- recursive
合并一个分支时默认的合并策略。 - octopus
合并多个分支时默认的合并策略。 - ours
- subtree
- 常用命令和参数释义
把dev分支的工作成果快速合并到当前分支上:
$ git merge dev-
$ git merge –no-ff 可以保存你之前的分支历史。能够更好的查看 merge历史,以及branch 状态。
$ git merge 则不会显示 feature,只保留单条分支记录。
如图:来自于网络
解决冲突
当两个需要合并的两个分支上针对同一文件都有各自的修改时,就必须首先解决冲突,解决冲突后,再提交,合并完成 ! 用git log --graph命令可以看到分支合并图。
git diff
- 查看尚未暂存的文件差异更新
$ git diff
不加参数直接输入
此命令比较的是工作目录(Working tree)和暂存区域快照(index)之间的差异
也就是修改之后还没有暂存起来的变化内容。
- 查看已经暂存起来的文件(staged)和上次提交时的快照之间(HEAD)的差异
$ git diff --cached
$ git diff --staged
显示的是下一次commit时会提交到HEAD的内容(不带-a情况下)
- 提交后修订版本,工作区中所有修改的文件
eg. $ git diff [修订版本如:Head] [-- file]
可以查看工作区和版本库里面最新版本的区别:
$ git diff HEAD -- mx-bss/src/main/webapp/WEB-INF/jsp/platform/oms/order/OrderInfo.jsp
- 直接将两个分支上最新的提交做diff
$ git diff temp master 或 git diff temp..master
- 输出自topic和master分别开发以来,master分支上的changed。
$ git diff topic...master
Changes that occurred on the master branch since when the topic
branch was started off it
查看简单的diff结果,可以加上--stat参数
git diff --stat
查看当前目录和另外一个分支的差别
git diff test
显示当前目录下的lib目录和上次提交之间的差别(更准确的说是在当前分支下)
git diff HEAD -- ./lib
比较上次提交commit和上上次提交
git diff HEAD^ HEAD
比较两个历史版本之间的差异
git diff SHA1 SHA2
diff输出格式
版本管理系统git,使用的是合并格式diff的变体。
$ git diff
显示结果如下:
diff --git a/f1 b/f1
index 6f8a38c..449b072 100644
--- a/f1
+++ b/f1
@@ -1,7 +1,7 @@
a
a
a
-a
+b
a
a
a
第一行表示结果为git格式的diff。
diff --git a/f1 b/f1
进行比较的是,a版本的f1(即变动前)和b版本的f1(即变动后)。
第二行表示两个版本的git哈希值(index区域的6f8a38c对象,与工作目录区域的449b072对象进行比较),最后的六位数字是对象的模式(普通文件,644权限)。
index 6f8a38c..449b072 100644
第三行表示进行比较的两个文件。
--- a/f1
+++ b/f1
"---"表示变动前的版本,"+++"表示变动后的版本。
后面的行都与官方的合并格式diff相同。
@@ -1,7 +1,7 @@
a
a
a
-a
+b
a
a
a
版本回退 reset
常用命令
- 把暂存区的修改回退到工作区(unstage)
当我们使用git add file 把工作区文件添加到暂存区时 。 这时git就会告诉我们:
(use "git reset HEAD <file>..." to unstage) //可以把暂存区的文件拉回工作区
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
- git reset
git reset --hard HEAD^ (HEAD指向的版本就是当前版本,HEAD表示上一版本,HEAD^表示上上版本balabala)
- --hard表示强制回退
- git reflog用来记录你的每一次命令
因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
版本回退前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
使用场景
只是修改了工作区某个文件的内容:
想直接丢弃工作区的修改时,用命令git checkout -- file。当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
已经提交到版本库时:
想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
储存现场
相关命令
- 存储现场 git stash
git stash: 从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时将当前的工作区内容保存到Git栈中。
git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理。
git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
git stash clear: 清空Git栈。
- 查看工作现场 git stach list
我们进行存储工作现场后,发现工作的内容被git藏起来了,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:参考(3. 恢复现场)
- 恢复现场
恢复现场有两种方式:
1)使用git stash apply 来恢复,然后再使用git stash drop来删除stash的内容。如果要多次使用stash,恢复的时候先用git stash list查看,然后在指定你要恢复的内容:git stash apply stash@{0}。
2) 使用git stash pop,来恢复并删除stash内容。
咱们一般为了方便,就直接用git stash pop了
使用场景
<a>使用git的时候,我们往往使用branch解决任务切换问题:</a>
1) 一言不合(紧急任务或bug)就提交是不好的
例如,我们往往会建一个自己的分支去修改和调试代码, 如果别人或者自己发现原有的分支上有个不得不修改的bug,我们往往会把完成一半的代码 commit提交到本地仓库,然后切换分支去修改bug,改好之后再切换回来。这样的话往往log上会有大量不必要的记录。
其实如果我们不想提交完成一半或者不完善的代码,但是却不得不去修改一个紧急Bug,那么使用'git stash'就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区和上一次提交的内容是完全一样的,所以你可以放心的修 Bug,等到修完Bug,提交到服务器上后,再使用'git stash apply'将以前一半的工作应用回来。
2) 可以多次将未提交的代码压入到栈中
也许有的人会说,那我可不可以多次将未提交的代码压入到栈中?答案是可以的。当你多次使用'git stash'命令后,你的栈里将充满了未提交的代码,这时候你会对将哪个版本应用回来有些困惑,'git stash list'命令可以将当前的Git栈信息打印出来,你只需要将找到对应的版本号,例如使用'git stash apply stash@{1}'就可以将你指定版本号为stash@{1}的工作取出来,当你将所有的栈都应用回来的时候,可以使用'git stash clear'来将栈清空。
3) 以一言以蔽之
当前工作区内容已被修改,但是并未完成。这时Boss来了,说前面的分支上面有一个Bug,需要立即修复。可是我又能提交目前不完美的修改。但是,不提交的话,又没有办法checkout到前面的分支。此时用Git Stash就相当于备份工作区了。然后在Checkout过去修改,这样就能够达到保存当前工作区的同时又能及时恢复。
git 配置别名 alias
- 当然是和配置用户信息一样 用--global啦, --global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用
- 常用alias
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
// 命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。既然是一个unstage操作,就可以配置一个unstage别名
git config --global alias.unstage 'reset HEAD'
// 配置一个git last,让其显示最后一次提交信息
git config --global alias.last 'log -1'
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"
Window 下使用Git常见问题
1. warning: LF will be replaced by CRLF
原因分析:
CRLF -- Carriage-Return Line-Feed 回车换行
就是回车(CR, ASCII 13, \r) 换行(LF, ASCII 10, \n)。
这两个ACSII字符不会在屏幕有任何输出,但在Windows中广泛使用来标识一行的结束。而在Linux/UNIX系统中只有换行符。
也就是说在windows中的换行符为 CRLF, 而在linux下的换行符为:LF
使用git来生成一个工程后,文件中的换行符为LF, 当执行git add .时,系统提示:LF 将被转换成 CRLF
解决方法:
删除.git文件
$ rm -rf .git
$ git config --gobal core.autocrlf false
这样系统就不会去进行换行符的转换了