Git官网链接: https://git-scm.com/
首先我们把Git官网首页上的两句话翻译成中文感受一下。
Git 是一个免费的、开源的分布式版本控制系统
,可以快速高效地处理从小型到大型的各种项目。
Git 易于学习,占地面积小,性能极快。 它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于 Subversion、CVS、Perforce 和 ClearCase 等版本控制工具。
当从个人开发最终过渡到团队合作的时候,就需要经常使用Git。
把工作区的代码添加到暂存区
进行临时存储;提交到本地库
的代码就会生成历史版本;注意工作区和暂存区写过的代码,如果感觉不合适都是可以删除掉的,并不涉及历史版本记录问题。
但暂存区中的代码一旦提交到本地库
,就会生成历史版本,代码就无法删除了。
举一个生活中的例子理解以上三个分区:
小蜗是某公司程序员,某天喝多了,在自己的程序里悄悄写进了一些吐槽老板的代码。
在工作区写完此代码老板肯定看不到,但小蜗为了追求刺激,把代码添加到了暂存区
;这种情况酒醒之后代码也可以进行删除,老板也看不到,因此还可以补救。
但如果一时冲动,把添加到暂存区的代码 提交到了本地库
,那么就会生成一个历史版本。这个时候,骂老板的代码就无法删除了,小蜗酒醒之后,只能修改自己提交的版本进行补救,但老板仍然可以通过git查看之前的版本,依然会存在被发现的风险。
代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库
。
我们知道,提交到本地库的代码可以形成历史版本。这时我们还可以通过push
命令把代码从本地库推送到远程库
。
签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。
Git 首次安装必须设置一下用户签名,否则无法提交代码。
※注意:这里设置用户签名和将来登录 GitHub(或其他代码托管中心)的账号没有任何关系。
验证是否操作成功:
找到C盘的用户目录进入当前用户目录,可以找到一个.gitconfig文件打开可以看到我们设置过的用户签名信息,即成功设置了用户签名。
需要使用Git管理这个目录的时候,就首先需要先进行初始化
来使Git获取此目录的管理权
。如下图我们在e盘的GitSpace/git-demo目录下进行初始化,然后在此目录下(右击空白处选择Git bash here,就进入了此目录)。
git-init命令
初始化成功之后就会生成一个.git目录,图形化界面如图展示。
其中ll命令是查看目录
,但由于.git文件是隐藏的,因此无法显示。可以通过ll-a命令显示全部文件
。
git status:查看本地库状态
首次查看本地库状态(工作区没有任何文件时),会输出这样三行日志信息。
①On branch master:提示当前本地库在master分支(默认分支名字,表示当前分支)里面;
②No commits yet:表示目前还没有提交过任何东西,目前是一个空的git库;
③nothing to commit (create/copy files and use “git add” to track):目前没有什么东西需要提交。
新增文件后再次查看本地库状态
vim.hello.txt可以创建并进入hello.txt。
此处常用的部分vim命令:
③查看尾部内容
tail -n 2 hello.txt:查看尾部第二行(回顾Linux命令)
此时再次查看本地库状态:
Untracked files: --------未被追踪的文件。说明此时hello.txt虽然有了,但只存在于工作区。
nothing added to commit but untracked files present (use “git add” to track)-----表示现在没有提交过任何东西,但有一个未被追踪的文件了,要使用git add进行追踪(添加暂存区)。
git add加文件名:添加暂存区
日志信息:warning: in the working copy of ‘hello.txt’, LF will be replaced by CRLF the next time Git touches it。—Git默认转换了行末换行符。
(警告不用管,问题不大)
Windows系统里的换行符是CRLF;Linux系统里面换行符是LF。
提交到暂存区之后继续查看本地库状态。
hello.txt由红色变为绿色,说明当前的Git已经追踪到了这个文件。(文件存到了暂存区),此时依然可以删除暂存区文件:使用git rm --cached 加文件名。
删除操作如下图,删除成功后查看本地库状态,发现hello.txt又变为红色:
注意:删除暂存区中的文件,工作区中的文件依然存在。
对添加到暂存区的文件提交至本地库。形成自己的历史版本。
git commit -m “设置提交信息” 文件名:提交本地库
日志信息:[master (root-commit) f785f7a] first-commit
1 file changed, 17 insertions(+)
create mode 100644 hello.txt
master(主干分支):第一次提交版本,一个文件被改变。第17行内容被插入;
f785f7a即为版本号。
然后再次查看本地库状态:
On branch master:表示当前是master分支
nothing to commit, working tree clean:表示已经提交过了,并且提交后文件没有新增也没有修改,工作树很干净。不需要再次提交。
git reflog:查看引用日志信息(精简信息)。
完整的版本号为:f785f7a29ddd59c5a9c5b5babbab3592dc37b554
使用reflog查看到的版本号为前七位精简版的版本号f785f7a
②进入编辑状态,修改文件,比如第一行后增加空格和7个3,如下图:
③查看本地库状态,如下图:
这时我们发现modified: hello.txt
-红色信息说明文件被修改了,并且还没有被添加到暂存区。(即Git还没有追踪到本次修改)。
所以我们对修改后的文件,使用git add添加到暂存区。如下图:
添加完成后,再次查看本地库状态。,如下图:
这时我们发现出现绿色提示信息。说明文件已经被添加到暂存区了。
接下来提交到本地库
注意日志信息最后一行提示: 1 file changed, 1 insertion(+), 1 deletion(-)
表示:一个文件被修改;其中一行新增,一行删除。
为什么我们对文件一行进行的是修改操作,会提示一行新增,一行删除?
因为Git中是通过行来维护文件,“修改了一行” 只能通过 “一行新增,一行删除” 来表达。
此时查看版本日志信息,就会发现有两个版本:first-commit和second commit。
而且当前的指针指向的是第二个版本:
( (HEAD -> master) HEAD@{0}: commit: second commit)。
此时查看文件信息,即为第二个提交版本的信息,如下图。
同理,如果再次对文件进行修改,如在第二行加上一个hhh。然后进行一系列操作:添加暂存区、提交本地库。
注意:尽管此时已经有了三个版本,但Git的工作区依然只有一个文件,如下图。因为Git控制版本是通过指针而非副本。
初到公司,如果需要查看当前项目经历了几个版本的迭代。可以使用git reflog命令(查看精简版日志)或者git log命令(查看详细版日志),如下图:
①版本穿梭
如果有一天老板感觉最新版本的代码还不如之前版本合适,就要求员工穿梭回原来的版本。
比如们想从第三版穿越回第一版,就可以先查看版本信息,复制第一版的版本号 f785f7a ,如下图:
然后通过命令 git reset --hard 后面加上版本号,如git reset --hard f785f7a
穿梭之后我们查看文件信息,cat hello.txt。发现文件内容已经穿梭到了第一次提交的版本,如下图。
版本穿梭,底层使用head指针。
在版本控制过程中,同时推进多个任务,为每个
任务,我们就可以创建每个任务的单独分支。
使用分支意味着程序员可以把自己的工作从开发主线上分离开来, 开发自己分支的时候,不会影响主线分支的运行。 对于初学者而言,分支可以简单理解为副本,一个分支可以理解为一个单独的副本。(分支底层实际上是指针的引用)
① 查看分支:git branch -v
上述信息显示:当前的demo只有一个master分支,并且有三个历史版本。
② 创建分支: git branch 分支名
比如,程序出现问题了,
我们通过git branch hot-fix创建一个紧急修复(hot-fix)分支,
然后通过git branch -v查看分支。创建成功,如下图:
③ 修改分支
接下来操作实现从master分支切换到hot-fix分支上,去修改hello.txt
vim hello.txt 编辑 hello.txt 删除第二行的hhh。如下图:
删除之后,查看本地地库状态。如下图:
红字表示有修改的文件,接下来依次对其进行添加暂存区、提交本地库操作。
然后查看hello.txt,发现成功修改。如下图:(注意此处修改的是hot-fix分支下的hello.txt)
同时磁盘里的文件内容也被修改,如下图:
注意:
此处修改的是hot-fix分支内容,master分支内容依旧不变
。
④合并分支
我们对代码进行修改之后,需要把hot-fix分支合并到master分支上,如何操作?
肯定先要切换到master分支,执行合并命令。
⑤冲突合并问题
冲突产生的原因:
合并分支时, 两个分支在同一个文件的同一个位置有两套完全不同的修改。
Git 无法替我们决定使用哪一个。必须人为决定新代码内容。
比如,我们先在master分支下,通过vim hello.txt。修改文件(倒数第二行增加一些内容)。如下图:
然后老套路:添加暂存区、提交本地库。
接在切换到hot-fix分支,----- git checkout hot-fix修改文件(倒数第一行增加一些内容),如下图:
切换到master分支,分支合并----- git merge hot-fix
此时日志提示在hello.txt里产生了冲突,自动合并存在问题。
此时再通过git status查看本地库状态。如下图
日志提示两个分支都对此文件进行了修改,此时Git无法判断保存哪一个。因此产生冲突。
因此为了解决冲突需要我们手动合并代码。
先vim hello.txt打开文件,发现文件中已经标出了哪一块发生了冲突。如下图。
以上两块代码都做了修改,合并冲突,需要手动去掉不需要的内容。
保留添加的内容,保存退出即可。如下图:
此时冲突已经解决,但不要忘记:添加暂存区、提交本地库。
但要特别注意的是,此时提交本地库的时候不可以加文件名,否则会报错。因为两个分支都修改了hello.txt,并且处于合并状态没有终止。如果带文件名就会报错。如下图:
此时再查看 cat hello.txt,发现成功解决合并冲突,达到了想要的合并效果。
注意:合并只会修改master分支的内容,hot-fix分支的内容不会被修改。
举例分析团队内协作:
作为华山派掌门人,岳不群在他的本地库里开发了一套《华山剑法》,开发完成之后岳不群总感觉此剑法差点火候,所以想让自己的大弟子—令狐冲帮忙完善一下剑法中的中的细枝末节。
于是岳不群使用push命令把自己的《华山剑法》推送到代码托管中心(如github、gitee),于是代码托管中心多了一个远程库,接到师傅命令后,大弟子令狐冲立刻把远程库clone克隆(完整复制)到自己的本地库中去。
经过多天苦苦完善后,令狐冲把自己完善后的版本push到了远程库里,岳不群就可以使用pull命令拉取远程库里的代码,更新自己的本地库。
最终得到终极版的华山剑法!!!
当然,他们需要是同一个团队才可以向此远程库push代码.
举例分析跨团队协作:
作为华山派掌门人,岳不群在他的本地库里开发了一套《华山剑法》,开发完成之后岳不群总感觉此剑法差点火候,所以想让自己的大弟子—令狐冲帮忙完善一下剑法中的中的细枝末节。
令狐冲一看,感觉十分头大。这么高深的剑法只有东方不败大佬才能进行优化。但东方不败不是我们团队里的,而且作为堂堂日月神教教主,东方不败肯定不愿意来我们华山派这个小团队。于是和东方不败进行了跨团队协作。
于是,东方不败就开始工作。他先在代码托管中心里把岳不群的远程库fork(叉过去)到自己的远程库里边,接着东方不败把自己的远程库内容clone到本地库,开始修改华山剑法,经过多天努力,在本地库里共提交了三个版本,最终选择v3版本,于是将其push到东方不败自己的远程库里。
接下来的工作就是,把远程库的内容发送给岳不群。东方不败需要先发送一个pull request请求给岳不群,告诉岳不群:修改好了,已经可以拉取了。
岳不群心想:不急,我要先看看你的代码,如果真比我的原版好。我岳不群直接拉取,无话可说。这时岳不群就先对修改内容进行审核,审核完成之后惊叹道:不愧是东方不败大佬,修改完的版本也太强了吧!于是把东方不败修改的代码和自己的代码进行merge合并。之后岳不群就可以把远程库里的内容通过pull拉取到本地库。
这时岳不群就可以修炼已经修改好的《华山剑法》,和岳不群同处一个团队的令狐冲也可以修炼此剑法。
GitHub官网:链接: https://github.com/
接下来使用如下三个账号进行演示。
用户 | 账号 |
---|---|
岳不群 | yuebuqunyyy |
令狐冲 | linghuchonghhh |
东方不败 | dongfangbubaizzz |
①进入github官网,登陆后点击右上角加号,选择new repository。
②设置如下信息,点击下方create repository
创建远程库别名:git remote add 别名 远程地址 。
查看当前所有远程地址别名:git remote-v
①复制HTTPS形式的地址:
②创建别名(别名最好跟库名一致)
③查看别名
显示两条记录,此别名既可以用于推送,也可以用于拉取。
至此,我们创建了远程库,起了别名。但远程库中还没有代码。
接下来我们把本地库中的代码推送到远程库:git push 别名 分支
执行成功后弹出如下图所示登录对话框。(运行不成功多试几次)
两个选项,选择第一个Sign in with your browser.表示选择浏览器账号登录。
进入远程库查看,可以看到本地库中的文件已经推送成功,如下图:
比如:岳不群出差了,但代码出现了问题,于是岳不群在github上进行修改,然后提交改变。如下图:
岳不群出差回来之后,发现本地库和远程库已经不同步了,因此需要使用拉取命令把远程库的代码拉取到本地,如下图:
使用git-status查看,发现无需手动提交,拉取之后会自动提交本地库。
在令狐冲电脑的硬盘目录下创建一个Git-LHC的文件夹,表示令狐冲需要克隆师傅岳不群的代码到此处。
②在Git-LHC文件夹下右键空白处选择git bash here,如下图:
令狐冲成功克隆git-demo到文件夹Git-LHC,如下图:
注意:岳不群创建了一个公共库,克隆不需要登陆账号授权。
接着我们进入git-demo目录下,通过git remote -v查看别名,这时我们会发现克隆后已经起好了默认别名origin,如下图:
克隆做了三件事:
经过一番克隆后,在令狐冲本地库中进行如下操作。
①使用vim编辑器,对文件进行编辑加入令狐冲的修改内容。
②添加暂存区,提交本地库。-------老套路
③把代码推送到远程库(否则岳不群看不到)
这里暂时不使用别名,直接复制远程库中https形式的链接。如下图:
接着令狐冲在自己电脑上进行登录授权。
git push https://github.com/yuebuqunyyy/git-demo.git master
但是无法授权成功,报错如下。
原因:众所周知,令狐冲是岳不群的弟子,但Git不知道。需要岳不群在GitHub上把令狐冲拉进自己的团队,Git才可以承认令狐冲是岳不群的弟子。
所以:需要进行邀请令狐冲加入此团队操作
岳不群登录自己的GitHub,然后点击settings
岳不群把邀请函通过其他方式给令狐冲,令狐冲收到地址之后登录自己的github,并把岳不群发来的邀请函在自己的GitHub的地址栏里粘贴进去,然后接受邀请,即可加入团队。
这样,Git才承认令狐冲进入了岳不群的团队。
然后,令狐冲才可以把自己的代码推送到远程库。
在自己的本地库中进行如下操作,授权登录,成功推送远程库:
这样一来岳不群就可以在远程库中看到令狐冲新加入的代码。
④岳不群在自己电脑上的工作区GitSpace的git-demo下把新的代码拉取到本地库,如下图:
⑤查看岳不群的本地库看是否拉取成功,如下图:
以上即为团队内协作过程。
岳不群和令狐冲的华山派小团队邀请日月神教团队的东方不败大佬,帮忙修改此项目代码。此为跨团队协作。
①首先岳不群复制自己远程库中HTTPS形式的链接,如下图。然后把此链接通过其他形式发送给东方不败。如下图:
②东方不败登录自己的GitHub账号,地址栏粘贴岳不群发来的链接,把岳不群创建的远程库叉(fork命令)过来。如下图:
create fork之后,东方不败的账号下就有了一个git-demo远程库。如下图:
③东方不败可以在自己的GitHub上直接修该代码,也可以clone到本地库在本地库修改,如下图:
④修改之后,在东方不败账号下的git-demo已经修改成功。但此时岳不群还看不到修改。此时需要先发送一个pull request请求给岳不群,如下图:
⑤岳不群登陆自己的GitHub账号,就可以看到拉取请求,如下图:
⑥岳不群审核修改的代码之后,发现修改后的比原来版本更好就可以合并代码,如下图:
⑦合并好之后,岳不群远程库的git-demo下就可以看到东方不败修改后的代码。如下图:
岳不群想利用远程库进行开发,但不想登陆自己的GitHub账号。就可以使用GitHub的ssh免密登录功能。
①首先,在岳不群想要使用免密登录功能的电脑上的:
C/用户/当前用户目录下删除 .ssh目录(如果有的话);
然后右键git bash here。
执行以下命令重新生成.ssh密钥目录:
ssh-keygen -t rsa -C 免密登录用户的邮箱,如下图:
然后发现.ssh密钥目录添加成功。其中一个公钥一个私钥,如下图:
②复制公钥添加至GitHub
此时注意,东方不败修改的代码,岳不群还没有拉取到本地库。因此在岳不群本地库中查看不到东方不败修改的代码。
⑤退出登录,进行测试,拉取远程库代码更新本地库,如下图:
命令:git pull +ssh形式的链接 + 分支名
此时查看本地库中代码,发现已经更新。如下图:
这时,岳不群在自己的工作区,更改代码,然后添加暂存区、提交本地库、推送远程库,如下图:
至此,免密登录操作成功!!!
项目中有很多文件与项目的实际功能无关,不参与服务器上部署运行,如下图中文件。因此把它们忽略掉能够屏蔽 IDE 工具之间的差异。
那么忽略文件如何进行配置?
首先需要回顾一下“.gitconfig”文件是什么?
忽略文件配置过程如下:
①文件格式:创建后缀为“.ignore”的忽略规则文件(eg:git.ignore)
②文件位置:为方便“.gitconfig”文件引用此忽略文件,建议把此文件放在用户家目录下。
③配置xxx.ignore忽略文件的文件类型内容:模板如下
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see
http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.classpath
.project
.settings
target
.idea
*.iml
配置好Git忽略文件之后,如果想要在IDEA中使用Git工具,还需要配置定位Git程序,如下图。
此时,就可以在IDEA中使用Git了。
接下来去项目的根目录下查看,发现多出一个“.git” 的目录,说明Git已经接管了此目录。
初始化本地库后可以观察到
如果点击Add,执行之后pom.xml会变绿,绿色表示已经添加到了暂存区,但还没有提交到本地库。
如果此时main目录下创建包com.atguigu.git,创建类GitTest。如下图:
创建好之后,会出现以下提示,询问新建的文件是否需要被Git追踪,追踪到之后也变为绿色。如下图:
提交之后代码文件颜色变为黑色,表示代码就不需要再被提交了。
注意:代码什么颜色并不影响程序的运行。
代码文件变为蓝色代表,代码被Git追踪后,又被修改了。
被修改的文件提交本地库后又恢复为黑色,此时本地库中就有了两个版本的代码。
再次修改代码,添加暂存区,提交本地库,增加一个版本三。
此时有三个版本,通过左下角Git按钮可以查看到版本信息。 如下图:
执行完成后发现,头指针(黄色的指针)指向第二个版本,代码也变为第二个版本的代码。如下图所示:
以上代码,在当前处于mster分支的第三个版本情况下。
方法二:IDEA右下角的master(表示当前分支默认处于master分支)按钮,如下图:
创建成功之后右下角按钮由master变为hot-fix。如下图:
右下角显示的按钮即为当前分支的名字
①在hot-fix分支下新增一行内容,如下图:
②修改之后GitTest文件就变为蓝色,需要添加暂存区,提交本地库,如下图。
③在hot-fix分支下增加了一行代码变为四行,master下的代码依然还是原来的三行。考虑把hot-fix分支合并到master分支。如下图:
在当前master分支下,点击左下角分支按钮,找到要合并的分支,选择合并到当前分支操作,即可合并分支。
操作完成后GitTest中代码变为四行,说明hot-fix分支合并成功!
此为没有冲突,正常合并的情况。
接下来看一下开发中常见的代码冲突问题如何在IDEA中解决。
首先制造一个代码冲突的场景
使用浏览器登录github官网
点击头像,进入settings
找到左侧导航栏最下方的Develop Settings
选择左侧导航栏为Personal Access Tokens的选项
点击Generate new Token
接下来需要给口令起名字,比如"hhh"
复制Token进入IDEA即可进行登录操作
新版IDEA绑定Github账号后,导航栏VCS会变为Git,如图我们选择Share Project on GitHub。
这样就可以执行两个操作:
然后提交本地库,设置提交名字为PUSH commit。如下图:
此时远程库还没有显示本地库中新增的这样一行代码,需要push
这时默认别名已经起好了,但默认使用的是HTTPS形式的链接进行push,此形式push不成功的概率高,所以建议使用SSH形式的链接进行push,操作如下:
①进入远程库,复制SSH形式的链接
注意:SSH形式的链接处如果有黄色框提示信息,则无法使用SSH功能。
需要我们在本机上配置SSH相关功能(具体操作见7.8,GitHub_ssh免密登录)
②复制SSH形式链接后再次进入PUSH选项卡,单击默认别名,选择Define remote,输入复制的链接,之后选择自定义好的选项,点击push。如下图:
①远程库修改代码,如下图:
②此时需要拉取远程库代码更新本地库
注意:pull 是拉取远端仓库代码到本地,如果远程库代码和本地库代码不一致,会自动合并,如果自动合并失败,还会涉及到手动解决冲突的问题。
注意:本地库代码和远程库代码不一致的问题!!!
我们直到push是将本地库diamond推送到远程库,但如果本地库代码和远程库代码版本不一致,push操作是会被拒绝的!!!要想push成功,一定要保证本地库的代码版本要比远程库的代码版本高!(push之前pull一下,就一定不会报错)、
因此,一个成熟的程序猿在动手修改本地代码之前,一定会先检查一下远程库和本地库代码的区别!如果本地库的代码版本已经落后,切记要先pull拉取一下远程库的代码,将本地库更新之后,再进行修改、提交、推送!
当我们把代码托管到了GitHub,相当于在云端对代码做了备份。删除本地库项目代码,依然可以从GitHub上“找回”(clone)
本笔记根据尚硅谷Git视频教程整理。大家可以点击下方链接进行学习,笔记内容不当之处也欢迎大家批评指正。
链接:
https://www.bilibili.com/video/BV1vy4y1s7k6?p=20&vd_source=0a6f87040fc9bf2f899ff136b4df18bf