学习圣思园张龙老师的Git课程。html
使用Mac编程的好处,不是由于Mac长得好看git
若是你尚未用Git,就不要写代码了。程序员
GitHub仓库的使用。github
新员工入职的时候,会让他先用一周的时间去学习Git。web
Mac(优雅的开发环境,Terminal)正则表达式
不要使用GUI入门Git。要使用命令行。shell
安装Git编程
bashcentos
每个Linux和Mac自带的解释器。(可是功能不是很强大)
强大的叫:zsh.
增强版本: oh my zsh (自行安装)缓存
清屏命令:clear
or ctrl+L
建立命令:touch xxx.txt :=增删改等。
查看命令:man cp
vi的基本使用。
必需要掌握的:Terminal操做
做为一个JAVA程序员,应该大部分都是在Windows使用JAVA开发,可是但愿不要仅仅局限于JAVA。否则对成长很不友好。
学习方法:知道一,更知道二,更知道三。
开发Git来管理Git
不会Git,就别开发代码了。
Git文件:已经被版本库管理的文件
已修改:在工做目录修改Git文件
已暂存:(indea-staged)对已经修改的文件执行Git暂存操做,将文件存入暂存区
已提交:将已经暂存的文件执行Git提交操做将文件存放版本库
pic1
Git的文件状态以下
Pic2
pic3
Linux
Mac
Windows
须要自行了解 SSH
GUI:source tree & GitHub Desktop
ssh-keygen -t rsa ## 三次回车,跳过密码
得到版本库
git init git clone
查看信息
git help git log git diff
版本管理
git add git commit git rm
远程协做
git pull git push
其余经常使用指令
git status ##查看状态 git log ##查看commit记录 git checked -- xxx.txt ##丢弃已经修改的 git reset HEAD xxx.txt ##回到修改前的状态 git commit -m 'commit message' ##简要信息显示并commit echo 'welcome' > xxx.txt ##重定向welcome 到这个文件的输出 git add . ##当前目录全部文件都add git log -3 ## 最近三条的log git help config ## 获取配置 git config --help ## 帮助文档 man git-confgi ##帮助文档
配置username && email**
/etc/gitconfig (几乎不会使用,针对于整个操做系统的)
git config --system
~/.gitconfig (很经常使用,针对于当前用户的全部配置)
git config --global
.git/config (针对于特性项目)
git config --local
Git的提交ID(commit id)是一个摘要值,这个摘要值其实是个sha1计算出来的
删除(两种方式)
git rm 和 rm的区别 git rm : 1.删除文件 2.而且将删除的文件归入到暂存区当中(stage,index) 若想恢复删除的文件须要执行两个动做 1. git reset HEAD test2.txt ,将待删除的文件从暂存区恢复到工做区 2. git checkout -- test2.txt ,将工做区中的修改丢弃掉 rm: 将文件删除文件,这时候被删除的文件没有归入暂存区当中 注意: 这时候若是直接commit,是提示没有修改记录的。 想要归入暂存区的话,须要使用 git add xxx.txt 把这个文件的删除再加入暂存区。
重命名文件(两种方式)
git mv name1.txt name2.txt (归入暂存区的修更名字操做) 回退: git reset HEAD name1.txt git checked -- name1.txt 也可使用操做系统的mv指令,关系和删除是相同的
日志修改
git commit --amend -m 'new message' ##把上次保存的commit消息替换掉
熟练使用命令行,是提高开发效率的第一步。
操做的时候自动过滤制定的文件。放置在项目的根目录下
支持全文件名/正则表达式/后缀名/通配符
setting.properties ##删除指定文件 *.b ##后缀名 !a.b ## !除了什么 /TODO ##仅仅忽略项目根目录下的TODO文件, stu/TODO 这种是不忽略的 /*/TODO ##仅仅删除二级目录下的TODO文件 /**/TODO ##删除全部目录下的TODO文件 doc/*.txt ##忽略doc目录下的.txt文件,可是 doc/a/a.txt 是不会被忽略的 doc/**/*.txt ##忽略doc目录下的全部*.txt build/ ## 忽略build目录下的全部文件 #xxxx ## 表明注释
查看分支
git branch ## 查看分支
建立分支
git branch new_branch ##建立分支
切换分支
git checkout new_branch ##切换分支
删除分支
git branch -d new_branch ## 删除分支, ## 可是不能删除当前所处的分支。 ## 删除 未被合并的 - 使用大写的 D ## 删除 已经被合并的 - 使用小写的 d ## 是为了保护你的误操做。
建立分支的同时,切换到新分支
git checkout -b new_branch
合并分支(先修改,再合并)
git merge new_branch ##合并指定分支合并到当前分支
显示分支的操做
git branch -v ##显示当前分支最后一次提交的信息(commitId 和 message) git log git log -3
分支:一个commit对象链:一条工做记路线。
每个分支,会记录上一次的commitID。(工做记路线,时间线)。
HEAD指向的是当前分支
HEAD信息存放在:.git
目录下的HEAD
文件中
git reset HEAD filename ##以前使用过的恢复指令
master指向提交
Fast-Forward 快进 (没有冲突文件的合并)
若是可能,合并分支时Git会使用fast-forward模式
在这种模式下,删除分支时会丢掉分支信息
合并时加上 --no-ff
参数会禁用fast-forward,这样会多出来一个commit id
git merge --no-ff dev
查看日志
git log - -graph
出现冲突:conflict. 两个分支修改同一个文件的同一行
git add file
. 告诉git,你已经解决冲突git commit
再次保存. (master上面会出现一个merge的commit记录)建立分支,无非是建立了一个指针。
问题:为何修改文件以后须要add
一下,而后才能commit。(已明白,添加修改到暂存区。)
git commit -am 'commit message' ##添加全部修改文件到暂存区。而后commit。 合二为一
git reset --hard HEAD^ ##返回到上次提交 git reset --hard HEAD^^ ##返回到上两次提交 git reset --hard HEAD~1 ##回到第一个提交 git reset --hard HEAD~n ##回到第第n个提交 git reset --hard commitID ##回退到指定commit git reflg ##查看操做日志
git checkout -- <file> ## 丢弃指定文件在该空间下的改变 ## 丢弃的是未被放在缓存区的改变 ## 修改的是工做区,修改的是最后一次的修改 git reset HEAD <file> ## 将以前添加到暂存区(stage、index)的内容,从暂存区移除到工做区
git checkout 最多见的是用在分支的切换上
git checkout -b test ## 建立并切换到新分支 git checkout master ## 切换到master分支 git checkout commitid ## 检出到指定commitID
分支的更名
git branch -m master master2 ##修改分支master为master2
问题:有修改完的代码:如何切换分支。
如何完成临时保存?
##保存现场 git stash ## 保存当前工做区的全部修改。 git stash save 'message' ##保存到临时保存去。而且加注释 git stash list ## 查看保存区的临时修改 ##恢复现场 git stash pop ##将上次的临时保存的工做区取出来,而且将临时保存的分支给删除掉 git stash apply ##将临时工做区的内容取出来,可是不删除临时保存的分支 git stash drop stash@{0} ## 删除指定的保存区的存储内容
标签不依赖于分支
轻量级标签
git tag v1.0.1 ## 建立轻量级标签
建立一个带有标注性的标签
git tag -a v1.0.2 -m 'desc message' ##建立带有注释的标签
查看版本库中的全部标签
git tag git tag -l 'v1,0' git tag -l '*2' git tag -1 'v*'
删除标签
git tag -d v1.0.1
git blame 标签的使用
显示上一次对文件修改的做者信息和时间等
git blame <file>
diff标签的使用 (差别性查询)
1.先介绍 Mac自带的diff 比对命令
diff ## 系统自带的命令 diff a b ## 比较文件a 和 b的区别 diff -u a b ## 详细的介绍a和b的区别
diff 属性介绍
--- 原始文件 +++ 目标文件 @@-1,3 +1,3 @@ ` ` Hello world ## 没有符号表示两个文件都有的 `-` 表示第一个文件须要删除这一行 就能够生成a `+`表示第一个文件须要添加的这一行 就能够生成b 因此:- 表明第一行,+ 表明第二行
git diff 命令详解
git diff ## 默认比较:暂存区和工做区的差异 git diff commit_id ## 工做区和特定的commit_id的差异 git diff HEAD ## 工做区与当前分支的最新提交的代码的比较 git diff --cached ## 暂存区和版本库中的比较 git diff --cached commit_id ## 暂存区和版本库中指定版本的比较
也许你如今用以为学这些没有用,可是是否是了解了这些多的东西,是否是更能扩大你的思惟呢?
你以为没用,多是由于你没有见过实际的服务器环境
push 推送
pull 拉取,同时会执行合并merge
远程版本库:GitHub
内网远程版本库:GitLab
介绍:开源的社交平台。免费免费使用,代码须要开源。
推荐:学习好使用GitHub以后,就会发现新的世界
git remote add origin ip.... ## 添加远程地址 git push -u orgin master ## 将本地的master提到远端, 而且 -u 是master与仓库里的关联
远程分支:origin
git branch -a ## 查看分支(包括远端分支) git branch -av ## 查看分支并显示最后一次commitID
分支,指针,指向commit地址
git status 能够查看当前分支和远端分支的版本对比
本地不能直接对远端分支进行操做,若是切换到远端分支,就是对远端分支所指向的commit点来显示给你。
拉取远程仓库地址:
git clone ...地址 git clone ...地址 新项目名
fast forward : 快进
快进是没有冲突的时候的一种状态
git add的三个功能:
冲突解决步骤:
dd ## 删除一行 :2,4d ## 删除2-4行 vi操做 1.跳到文本的最后一行:按“G”,即“shift+g” 2.跳到最后一行的最后一个字符 : 先重复1的操做即按“G”,以后按“$”键,即“shift+4”。 3.跳到第一行的第一个字符:先按两次“g”, 4.跳转到当前行的第一个字符:在当前行按“0”。
GUI(在熟悉Git命令和参数以前,尽可能不要使用GUI)
GUI(图形工具)
Gitk(图形工具)
GItHub Desktop (图形工具)
Git合并原则:Git遵循着一个三方合并的原则
CommitID的生成策略是:SHA1
本质:字符串的替代
git config --global alias.br branch ## 使用br代替 branch 存在 ~/.gitconfig 文件里面 经常使用的: git config --global alias.st status git config --global alias.co checkout git config --global alias.unstage 'reset HEAD' git config --global alias.ui '!gitk' ## 调用外部命令
refspec 本质:本地的分支和远程分支上的对应关系
建立远端分支 新版本 git push --set-upstream origin develop ## 将本地的分支推送到远程,而且创建对应关系 旧版本: git push -u origin test ## 将本地的推送到远程,而且创建对应关系 建立本地分支和远端分支名字不一样的分支 git push --set-upstream origin develop:develop2 ## 源分支:远端分支 上述分支创完远端分支以后,本地分支不能直接push到远端分支那个上面 (建议同名)。 git push origin HEAD:develop2
关联远端分支 新版本 git checkout -b develop origin/develop ## 建立一个develop分支追踪远端的develop分支 旧版本: git checkout --track origin/develop ## 建立一个develop分支追踪远端的develop分支
删除远端分支 旧版本: git push origin :develop ## 推送一个空的分支到远端分支。 新版本: git push origin --delete develop ## 删除远端分支
几个重要的点:
git push 的完整写法:git push origin srcBranch:destBranch
pull 操做的完整命令:git pull origin srcBranch:destBranch
HEAD标记:HEAD文件是一个指向你当前所在分支的引用标识符,该文件内部并不包含SHA1值,而是一个指向另一个引用的指针
当执行git commit 命令时,Git会建立一个commit对象,而且将这个commit对象的parent指针设置为HEAD所指向的引用的SHA-1值
咱们对于HEAD修改的任何操做,都会被reflog给记录下来
查看远程HEAD
vi .git/ORIG_HEAD ##查看远程HEAD vi .git/FETCH_HEAD ##查看拉取的HEAD
远端分支重命名:只能先删除远端分支,而后从新推送远端分支
本地分支:本地远程分支:远程仓库的分支
Git的高级命令(咱们经常使用的全部命令都是高级命令)和底层命令(Git的基础)
底层命令
git symbolic-ref HEAD ## 读取文件的底层命令 git symbolic-ref HEAD refs/heads/develop ##
在远端仓库中: released就是表明的标签
git tag ## 查看全部的标签 git tag v1.0 ##建立轻量级标签 git tag -a v2.0 -m 'v2.0 released' ## 建立嗲注释的标签 git show v1.0 ##查看指定标签的信息 git tag -l '?2*' ##模糊查询标签
将标签推到远程仓库
git push ## 默认不会推送标签,只会推送分支 git push origin v1.0 ##推送指定标签到远程 git push origin v1.0 v2.0 v3.0 ##批量推送指定标签 git push origin --tags ## 一次性推送全部的标签 推送标签的完整语法 git push origin refs/tags/v7.0:refs/tags/v7.0
获取远程标签
git pull ##拉取的时候会获取全部的标签 拉取指定标签 git fetch origin tag v7.0 ## 拉取指定的标签
删除远端标签
1. 在远端仓库直接点击删除按钮。 2. 推送一个空的源标签推送到远程,就删除了。(方法和分支相似) git push origin :refs/tags/v6.0 ##经过本地命令删除远端标签 git push origin --delete tag v5.0 ## 方法2:经过本地命令删除远端标签 git tag -d v5.0 ##删除本地tag标签
在缺省状况下,refspec会被git remote add 命令所自动生成。Git会获取远端上refs/heads下的全部引用,而且将他们写到本地的refs/remotes/origin目录下,因此若是远端上有一个master分支。能够经过如下方式去查询远端分支的历史记录。
- git log - git log origin/master - git log remotes/origin/master - git log refs/remotes/origin/master (最全面的写法)
.config文件里面的信息
git fetch = +refs/ ## 这个加号,若是加上是 就算不能快进也能够拉取代码
refs文件 (refspec的缩写),存放的是全部远端分支
关于已经被删除的分支
A 在本地删除远端分支,B 在本地的远端分支还在
B这个时候拉取是不行的,会提示 没法拉取原单分支。
git remote prune ## (裁剪:删除本地多余的 远端分支)
git gc
会用的不多,大部分会在底层自动执行
做用:打包,压缩 ,对对象进行压缩
手动执行以后的效果:目录下的refs文件就会都不见了(被压缩到 packed refs文件里面了)
Objects/ 目录:就是每次压缩的时候所存放的目录
关于Git的全部操做和文件,都存放在.git的目录里面
使用 git rm
删除文件,包括本地和Git跟踪
使用git rm --cached
删除缓存区的文件,不删除本地文件
删除远端仓库
git remote rm origin ## git remote show origin ##展现远端仓库信息
关于重命名文件
使用 git mv hello.txt hello2.txt
至关于:
1. mv hello.txt hello.txt 2. git rm hello.txt 3. git add hello2.txt
关于重命名远程仓库
git remote rename origin origin2
Git 裸库: 没有工做区的仓库(通常在服务器端使用Git裸库)
建立裸库:git init --bare
出现的原因:开发项目的时候,这个项目依赖于其余项目。须要把子项目的源码也依赖到当前开发的项目当中
添加子模块
git submodule add 子模块的地址 mymodule ## 拉取子模块的代码到 mymodule文件中
添加完以后会自动生成两个文件: .gitmodules 和 mymodule文件夹
此时两个文件就已经相互包含了。在GitHub仓库里面也可以识别。
父项目获取子模块的最新代码
git pull
git submodule foreach git pull
子模块修改以后,须要在父模块进行提交子模块的修改
其余人如何克隆
方法一:
git clone
直接克隆父模块的时候,子模块是空的git submodule init
进行初始化git submodule update --recursive
方法二:
使用 git clone 仓库地址 存放地址 --recursive
一步完成
删除子模块
git rm --cached mymodule
rm -rf mymodule
.gitmodule 文件
(步骤同上)使用git subtree
查询subtree的使用帮助文档
功能和以前介绍的git submodule
同样,可是submodule存在着很致命的弊端。在主工程中修改子工程的代码。可能会形成不少不少的问题。submodule也没有提供删除操做。因此在后续版本中添加了git subtree
git subtree
的使用也比较简单,也很容易的实现父模块和子模块的双向修改。官方推荐使用subtree替换submodule.
如何使用
准备两个仓库,父模块和子模块
添加一个新的远程库。(subtree-origin)
添加子模块到父模块:
git subtree add --prefix=subtree subtree-origin master --squash #功能描述:添加远端仓库`subtree-origin` 的`master分支`到本项目的 `subtree`目录下 #PS:`--squash `合并压缩以前的全部commit为一个。
subtree和submodule的区别
submodule是使用指针指向子模块的目录
subtree是将代码真真正正的放在父模块中
修改子模块以后如何更新
git subtree pull --prefix=subtree subtree-origin master --squash
在父模块修改完子模块以后,如何同时提交两个仓库
git push
默认只是推送父模块一个项目git subtree psh --prefix=subtree subtree-origin master
推送子模块遇到问题:最好深刻底层的去了解为何会发生这样的问题,而后解决。
备注:git push --set-upstream origin master
推送当前分支到远端分支
或者:git push -u origin master
推送当前分支到远端分支
vi操做 1.跳到文本的最后一行:按“G”,即“shift+g” 2.跳到最后一行的最后一个字符 : 先重复1的操做即按“G”,以后按“$”键,即“shift+4”。 3.跳到第一行的第一个字符:先按两次“g”, 4.跳转到当前行的第一个字符:在当前行按“0”。
添加subtree
git subtree add -P subtree subtree-origin master --squash git subtree add --prefix subtree subtree-origin master --squash git subttee add --prefix=subtree subtree-origin master --squash #上述三种方式等价 使用 git subtree查看帮助可以看的到
在子模块修改subtree以后,在父模块获取
(注意:squash 要使用的全局都使用)
git subtree pull -P subtree subtree-origin master --squash
在父模块修改subtree以后,在父模块提交substree
git subtree push -P subtree subtree-origin master
直接push全部的内容到父模块
git push
父模块提交过以后,在子模块修改,再在父模块拉取代码,就会出现冲突
从理解上,应该不会冲突。可是产生冲突了
使用 git status
查看冲突位置
解决冲突,上传。可是会提示什么都没有修改
这时候再去修改subtree项目的文件,push
而后再去父模块拉取代码,此次就会成功了。
问题:为何有时候会出现冲突?有时候不会出现冲突?
根本缘由还在:squash这个参数。
由于使用了squash,致使三方合并的commit记录寻找不到。因此就会出现冲突
可是:squash 不论用不用,在子模块修改完第二次以后,在父模块修改的第一pull就会出现问题。
因此:要么全程都使用squash,要么全程都不使用squash
**substree spilt **
拆分子模块 git substree spilt
以前里面携带的commit记录,也会携带出来
用的很少,也有不少不方便的地方。好比:同时修改了子模块和父模块,是没办法区分子模块的
--squash
合并压缩以前的全部commit为一个。
合并压缩以前的全部commit为一个提交。(以前的每一个commit记录都会消失)
主仓库中是看不到squash
以前的commit的,因此容易致使出现修改子模块的时候出现问题。
做用:防止subtree的commit记录污染了父模块的记录
引发的问题: 合并commit记录以后,致使三方合并不可以正常进行
为何使用和不用squash均可能会冲突?(使用图形化界面能够合理的看出来缘由)
找到冲突的根本缘由(合并的时候没有共同的祖先)
三方合并的时候,虽然A B 有一个共同祖先,可是A的上面还有一个祖先。
往上追溯的时候,会发现他们的根本根源是没有交集的。因此在合并的时候不知足三方合并,因此就可能出现冲突。
总结:若是一开始就是用了squash
的话,请一直使用,若是不使用的话,就都不要使用。
学习重要且常见的命令和参数
对于技术的理解越深刻,你对其余技术的了解学习的也就越快
张龙老师应该是全网目前将的最系统,最深刻,最完整的课程
Git会伴随你的开发生涯。
功能描述:将这个分支上的commit记录,应用到另一个分支上。很简单可是颇有用。
如:develop改了c1,c2, 可是c1 c2 应该上master的。最笨的办法就是手动拷贝出来,而后删除本地的提交,提交在其余地方。
cherry-pick
就是为了解决这种问题而存在的。
主要应用在本地分支上。
语法:
git cherry-pick commitid ## 将指定的commitID的记录,放入到当前分支上。
若是有两个commitid,是否可以直接只截取最后一条,而不是按照以前commit的顺序去提交?
能够,可是会冲突。正常解决冲突就行了。
若是按照顺序,就不会用冲突。
在源分支上的 commit,仍是存在的。 使用 checkout去恢复。
充分利用Git提供的解决方案去解决咱们的问题
rebase:变基 (衍合):改变分支的根基
要完成的功能相似于merge的功能,从某种程度上结果相同,可是执行原理彻底不一样。
在A分支上,执行git rebase B
效果图如上
注意:
git add
添加,而后执行 git rebase --continue
git rebase -- abort
命令终止rebase,分支会恢复到rebase到开始前的状态rebase的最佳实践
不要对master分支执行rebase,不然会引发不少问题
通常来讲,执行rebase的分支都是本身的本地分支,没有推送到远程版本库
由于若是你已经上传,绝对不要使用git rebase,别人可能已经拉取了你的分支。历史应该是快照,不该该被修改。
rebase是会修改历史记录的。
若是已经合并到远程,请老老实实的使用git merge合并就行。
rebase是先将要变基的内容,以补丁的形式打包。而后添加到指定基础的分支的后面。
在执行git gc的时候,会清理掉补丁。 补丁存放在rebase-apply 目录下
在出现冲突的时候
Git merge:历史发生,就不能修改
Git rebase:历史能够被修改,只显示最好的
因此:视状况而定,因人而异
基于groove的脚本语言来编写和配置的
优点:兼容Maven
1.下载 2.配置
文档:很好,涉及了方方面面 点击跳转
DSL:领域特定语言。须要对groove语言有所了解
应用:
不要将本身的目光放在你当前的项目组,放眼去望。不要闭门造车
.gitignore
ESC(弹性计算服务)
github 服务器在国外,相对慢
gitlab 安装在Linux上面。 阿里云ECS(弹性计算服务)云服务
不少不少的创业型公司,都在使用云服务器,都不会去购买本身的服务器。由于便宜。
官网:www.aliyun.com
购买云服务器
SSH - 链接购买的 Linux系统,(centOS 7 )
Linux服务器的使用
命令操做
Linux学,不要怕,去积累,慢慢学。没别的办法。
国内大部分公司都在使用GitLab来托管代码
GitLabCE 社区版 (大部分使用这个)
GitLabEE 企业版
安装和配置必要的依赖
开启防火墙 HTTP/SSH (在ESC上可能会出现防火墙的问题)
执行脚本的时候,下载GitLab源的时候就会出问题。(须要手动下载rpm文件-对应centos7)
而后经过 scp 的方式,将本地下载的GItLab包上传到阿里云的ECS上
由于中国GMW禁用。
GitLab是Ruby语言写的
访问IP登陆。 设置登陆限制,是否容许注册等等。
通常内网是不容许本身注册的。
GitLab的功能是很是很是强大的。(项目,用户,组的管理)
30多讲和周边内容的介绍和学习,成为了一个能使用Git进行平常开发和托管-合格的使用人员
本地操做 - 命令行
add mv rm 基本操做
.gitignore 忽略文件
git branch :检出,合并,切换,推拉
git stash:暂存
git remote操做
github
远程协做模型、分支最佳实践
别名,alias设定
GUI工具,git gui, gitk
git refspec : push pull 分支映射的一些操做
.git目录下的文件和做用
git gc
git裸库,submodule ,subtree
git cherry-pick
git rebase
idea
greadle/getty
git/idea/gradle
ECS
gitlab
markdown
gitbook.com (电子书出版领域的标准) Word是最low的方式
记录本身可以用到的功能的命令
git init ## 初始化仓库 git remote add origin address ##建立远端地址 git remote remove name ## 删除远端地址 git commit -m 'message' ## 提交一次commit git rm test.txt #删除一个已经存到缓存区的文件 git add . ## 提交一次修改 git reset HEAD test.txt ## 将已经保存到暂存区的内容撤回到工做空间 git branch develop ##建立分支 git checkout develop ##切换分支 git checkout -b new_dev ##建立并切换到Dev git checkout - ##切换到上一次所在的分支 git config alias.co 'checkout' ## 定义别名 git merge branchname ## 合并指定分支到当前分支 git stash ##将暂时修改未提交的内容,暂存到一个分支 git stash pop ##返回上次暂存的一些内容 git checkout -- test.txt ##将指定文件返回到最初始未修改的状态 git tag ##查看标签 git tag v1.0 ##建立标签 git tag -d v1.0 ##删除指定标签 git checkout v1.0 ##切换到指定标签 git blame <file> ##查看指定文件的修改人员信息详情
.gitignore 文件的配置规则
gitbook的使用