《安装后的配置》
改用第三方Beyond Compare作为对比工具
个人觉得小乌龟自带的对比工具显示效果太渣,个人强烈推荐改用beyond compare工具来对比
配置git账户密码—http方式
如果没有记住密码,默认第一次拉取代码时会提示输入git的账户和密码;
记住密码
如果第一次都输入正确完后,下次操作时还提示需要输入密码,请确保git的全局配置中是否包含了以下值,如没有请复制:
[credential]
helper = wincred
右键——TortoiseGit——Settings
扩展:
helper = store
这种方式个人不推荐使用,原因有二:
- 此种方式会将账户密码明文保存到“C:\Users\Administrator.git-credentials”中,不安全;
- 密码删除时,还需多一个先手动将“C:\Users\Administrator.git-credentials”文件删掉的步骤;
删除/修改密码
修改密码即为删除密码后重输: 控制面板
——>凭据管理器
配置git账户密码—ssh方式
SSH方式的特点:
1.没有直接传账户密码,安全性相对高
2.以后如果git的账户密码改了,使用ssh方式的也不并需要改密;
3.缺点是,需要在git网页上配置公钥
公钥是配置在git网页上的,私钥是放在自己电脑上的
,私钥需妥善保存好;
下面演示中给私钥顺带也加了个密,作用是如果其他人拿了我的私钥,在它的电脑上也会因没有密码而加载不上私钥
A.clone时使用ssh方式
小乌龟里的“puttygen.exe
”是用来生成公钥私钥的
B.中途由http改为ssh方式
配置commit时:提交人+邮箱
《基本操作》
ignore 添加到忽略文件
选中要忽略的文件/(空)目录——TortoiseGit——Add to ignore list
非空目录添加参考下面的手动加就好
.gitignore内容
# 01.【“/”开头的区别】
# “/”开头表示,仅忽略项目下那一个位置下的a.txt
# 不带“/”开头表示,忽略项目所有位置的a.txt
a.txt
/lib/a.txt
# 目录
lib/WEB
/lib/WEB
# 02.【通配符*】
# 星号代表0~n个任意字符,可出现在任意位置
/li*b/*a*.tx*t
lib/WEB*
# 右边的都符合下面这个:“/tmp1/1.txt”、“/a/tmp2/2.txt”、“/a/tmp3.txt”
*tmp*
idea中 已配好的.ignore文件
clone 克隆代码
方式一
远端git上创建好一个项目(注意网页创建新仓库时不要勾选“初始化仓库”),
然后点击clone即可
方式二
本地创建好一个空仓库,再配置好远端git,然后commit和push
pull 拉取代码
pull =
fetch + merge
注:有时候pull后本地remote库中的其他分支仍不是最新,此时建议fetch下
步骤:假设当前分支名为A:
- 先拉取远程git上所有分支内容到本地的remote库;
- 再将本地remote库中A分支合并到本地head库的A分支中
- 如果没有冲突,将自动提交;如果有冲突,需手动解决冲突后,再一并提交
fetch 获取代码
小乌龟中的fetch,会使
本地的remote库(所有分支)的代码更新到最新内容
唯一特例:远程git上删了某分支,fetch后本地remote库中并不会自动删除
add 新增文件交给git管理(可选项)
作用:将某个新增文件交给git管理
好处:被git管理的文件提交/贮藏时不容易遗漏、版本比对能够看到、reset hard回滚时刻意被还原等,总之,新增文件后续如果是要提交的,建议add
>>> idea一般都勾选了自动add
取消add:选择文件—右键—TortoiseGit—Revert
commit 提交代码
- 在空白处提交时,只会提交
当前目录及其子目录下的文件
;- 选中某些文件提交时,只会提交
选中的文件
+所有add状态的新增文件- 要提交未被git管理的新增文件时,请勾选show Unversioned Files 按钮
【重新修改上次commit记录】
仅建议在上次的commit记录还未push前进行
- 没有新改动,可直接重新修改上次的提交日志
- 有新改动,可以将本次新改动和上次已提交的合并成1分提交记录
push 推送代码
branch 分支操作
创建分支(创建后不切换)
右键TortoiseGit——create Branch
创建/切换分支(创建后会切换到该分支)
右键TortoiseGit——swith/checkout
删除分支
分支如果创建失败,可能是本地heads库中已存在了该分支,此时可考虑从heads库删除后,再创建该分支
【本地remotes库】的分支如需删除请慎重!!!
tag 标签操作
A.创建、删除(本地)、推送、拉取标签
拉取标签:仅需pull/fetch页面时勾上“tag”单选框即可
B.推送所有标签
会推送你本地所有标签,并不限于当前分支
C.删除远程标签
很遗憾,小乌龟无法删除远程标签!
- 要么去远程git网页中删除;
- 要么通过git命令删除,命令如下
git push --delete origin 标签名
clean up 删除新增文件
右键——TortoiseGit——Clean up
注1:只会对当前目录及其子目录范围有效
注2:.gitignore
文件本身如果没有被git管理,也将一并被删除哦
diff with 对比版本差异
sha-1值说明:
HEAD :表示(本地heads库)当前目录下的最新commit记录
HEAD~1 :最新commit记录的前一条记录,以此类推
0000..000 :当前工作空间
sha-1值 :可以去log历史中复制,下面动态图有演示
范围:未被git管理的新增文件不在比较范围,可以不同分支间比较
注:和commit、log类似,在空白处点和选中文件后点都是有不同的
show log 查看历史记录——提交点
和commit类似,空白处显示当前目录及其子目录的历史记录;
选中单个文件仅显示那一个文件的记录;
show log 查看历史记录——单个文件
选中单个文件后,用show log查看;
如果单个文件需要恢复到某一版本,找到某条记录下的该文件,右键revert即可还原这1个文件
blame 查看每行记录——单个文件
说明:
1.可以查看每一行代码是由谁提交的;2.也可方便的将文件恢复到某一版本
blame针对是每一行数据,并不能代表文件的所有历史记录(因为未包含合并记录)
stash 临时保存当前工作空间(贮藏)
stash:将你本地还未commit的代码提交到某个临时空间(记录的是文件变化量),提交后本地代码与head版本一致;
(后续恢复这些内容时,文件的状态也会一并恢复)场景模拟:
我本地改了一段代码,还没到能提交的时候。这时候突然因为一些原因,我需要切换、拉取分支去排查其他问题,但执行这些步骤的前提是需要将本地代码库和head库一致。为了不丢失我之前的工作记录,于是可以将当前工作空间先临时保存起来,后面等问题处理完后再恢复回来
- stash changes 进行贮藏,即将还未提交的内容保存到临时空间
- stash list 所有贮藏的清单
- stash pop 加载最近的一条贮藏,加载后会自动从list中删除
- stash apply 加载指定的贮藏,加载后不会自动删除
- 查看已贮藏的代码:见演示(未被git管理的新增文件和已忽略文件看不到)
《中级操作》
1.force push 强推
强行用本地分支覆盖掉git上的分支,请慎重使用!
否则可能把别人辛辛苦苦写的代码盖没了
使用场景:
- 使用reset向后回退时,如需回退远端git上内容,须搭配强推使用;
- push前你新提交的内容没有包含git上的最新内容,即git认定你新提交的内容是落后于最新代码的,此时不允许正常push,如确有需求要盖掉git上的,则可强推;
强推的优缺点:
- 优:“
向后回退+强推
”回退彻底,记录干净 - 缺1★:
需确保自己代码已是最新的
,不然容易盖掉其他人的文件; - 缺2★:需确保自己强推前
其他人没拉取过
你要回退的内容,不然下次别人push时还是带上来了,等于是做无用功
缺2的解决:
假设小明在你强推前已拉取了你要回滚的代码:
- 将小明电脑上本地git中的那次pull记录向后回退掉
- 或者让小明重新下载clone一套新代码,之前那套别用了
- 不用强推了,改用向前回退方式吧~
推荐场景:
你本地已拉取了git上最新内容,后不小心错误的提交推送了一段代码;且在你pull后这段时间没有其他人再拉取过代码,此时可考虑本地回退后强推上去
2.merge+conflict 合并+解决冲突 ★★
由于小乌龟自带的比较工具不好用(解决冲突时有坑),故我这里已改用第三方的beyond compare作为解决冲突的工具,具体配置请去目录找
- 当合并没有冲突时,无需commit,会自动提交;
- 当合并有冲突时,需手动解决冲突,然后在commit进行提交
(注:提交内容=你要提交的内容
+从远端分支拉下来的内容
)
冲突详解
假设是将 用户2(远端分支)—>合并进—>用户1(当前分支)
0.也可以直接完全以某一边的代码为准进行覆盖
1.文件删除时
2.文件修改时
3.文件新增时,一定不会冲突
取消合并
3.本地简单回退
01.向后回退——reset(3种)
| 回退方式| 本地实际代码 | 本地head版本库 | 已add/commit的新增文件 | 是否推荐 |
|–|–|–|–|–|–|
| hard 硬还原| 已回退 | 已回退| 已回退,即删除 |是 |
| mixed 混合还原 |无变化 | 已回退 |都在,且丢失add状态 | 否 |
|soft 软还原 |无变化 |已回退 | 都在,且处于add状态 | 是|
【特例】:有两种文件全程不会受到回退的影响,回退前后都不会有变化
- 新增的文件,且并未add过的;
- 在.gitignore忽略文件名单内的文件。已忽略的文件不会被提交、回退;
回退操作:进入log历史——>选中某条记录右键——>选择reset回退
补充说明:
如果要回退远端git上的代码,当采用向后回退方式时只能使用强推,请特别关注强推的两个注意点!
02.向前回退(2种)
本质:向前回退,其本质不是回退,而是继续提交一段新代码,只是提交后的代码内容刚好和要回退成的内容保持一致而已,使得版本是继续往前走的;
特点:
- 回退后是不用强推的;
- 且如需回退历史记录【中间】的某段提交内容,则只能用向前回退方式;
- 已回退的内容如果不是基于git上最新内容基础上重新修改的,即使再次合并时也不会生效(感觉没合并一样)
- 向前回退会产生新的提交记录,并不会删除之前的提交记录
方式一:revert
revert是按某次提交点中的变化量去回退的
reset是按某个提交点时文件的最终状态回退的
方式二:reset hard + reset soft
先用reset hard,使本地代码回退成想要的内容,然后在最新提交点上执行reset soft,此时本地代码并不会改变,但本地heads库已是最新的,等同于基于最新提交点将代码改回城要回退的内容
《高级操作》
版本回退—演示 ★★
直到
假设现在需要在小明分支上回退某些节点内容,且回退前已做好备份
回退最近的几次提交
回退:1节点
>《向后回退方式》
>>在2中reset hard,然后再强推即可
>《向前回退方式》
>>方案一:在1中revert,然后提交推送
>>方案二:先在2中reset hard,再在1中reset soft,最后提交推送
回退:1、5节点
>《向后回退方式》
>>在6中reset hard,再以3节点创建临时分支(临时标签也行),将该分支合并进来后,再提交强推
>《向前回退方式》
>>依次在1、5中revert(可能需解决冲突),最后提交推送
回退:1、5、6节点
>《向后回退方式》
>>在3中reset hard,再强推
>《向前回退方式》
>>方案一:在3中reset hard,再在1中reset soft,最后提交推送
>>方案二:依次在1、5、6中revert(可能冲突),再提交推送(不推荐)
回退中间的某段提交
【只回滚中间某段记录时,不适合使用向后回退方式】
回退:5节点
>《向前回退方式》
>>方案一:在5中revert(可能冲突),然后提交推送
>>方案二:以5创建临时分支tmp,tmp上在5中revert,然后tmp中提交,再将tmp分支合并进来(可能冲突),最后再提交推送
回退:5、6节点
>《向前回退方式》
>>方案一:依次在5、6中revert(可能冲突),然后提交推送
>>方案二:以5创建临时分支tmp,tmp上先在7中reset hard再在5中reset soft,然后tmp中提交,再将tmp分支合并进来(可能冲突),最后再提交推送
回退:3节点(4节点类同)
>>方案一:在3中revert,然后提交推送
>>方案二:以3创建临时分支tmp,tmp上先在4中reset hard再在3中reset soft,然后tmp中提交,再将tmp分支合并进来(可能冲突),最后再提交推送
回退某合并点的提交
假设小明pull时冲突了,且解决提交错误,需要回退2节点的那次合并
场景一:假设1节点内容可以不要了,此时合并点2即为git上最靠前节点
>《向后回退方式》
>>在5中reset hard,以3创建临时分支tmp,将tmp分支重新合并进来,合并解决冲突后,正确提交并强推;
场景二:假设1节点仍要,此时合并点2为git上的中间节点
【重点】2节点的合并既然是错误的,假设模拟产生了正确的合并节点"2new",则只需知道从2节点——>2new节点的文件变化,将这段变化合并进来不就是最终正确的效果了么
>>01.以5创建临时分支tmp5,以3创建临时分支tmp3,将tmp3正确合并进tmp5中[需开发确认冲突选择],然后提交,此时在tmp5中产生一个新的合并点(即为"2new")
>>02.复制2节点的sha-1值
>>03.在tmp5的任选一个节点使用reset soft,并且这次是根据sha值去回滚,即在reset界面的"commit"框处填写之前复制的sha-1值,soft回滚后提交,则此时提交点记录的是为从2节点——>2new节点的所有文件变化;
>>04.最后小明分支将tmp5分支合并进来(可能有冲突),提交推送即可
《其他情形》
要修改刚已提交的内容,但不想产生两次commit记录
见:基本操作——commit
解决仓库太大,clone不下来
项目根目录下的隐藏文件夹“
.git
”只会越来越大,因为你每一次提交记录和文件都完整的保存在.git中,这也是git可以任意还原的根本原因
方式一:clone时只勾选最近1条记录【虽切不了分支,但速度真的快】
方式二:有些网络环境下尝试使用ssh密钥方式可以clone下来
如果想从源头解决仓库过大问题:只能舍弃所有的历史记录
比如建一个新的仓库,并把旧仓库上的代码复制过去
(不要用下面的仓库间的推送方式),所有人全部改用新仓库去开发
将一个仓库的代码push到另一个仓库中
创建git新仓库时,可以将一个旧仓库某分支的代码,推送到新仓库的指定分支中(注:要推送的分支必须有完整的历史记录);
《天王盖
地虎,宝塔镇河妖》
★.我已回退的代码过段时间又回来了
可能原因:使用强推时机不对,没有和其他人做好沟通
使用强推方式回滚了远端git上的代码,过一段时间突然发现远端git上已经回退的代码又出现了,且提交记录还是自己。
大概率是在你强推前,其他人已经拉取了你的这段代码到他本地代码库,故他的本地库仍然保留了要回退的内容,等他下次对方再push时,要回退的内容又回来了~
解决办法:再次拉取最新代码后向前回退
★.我提交的代码不见了,且远端git上连我提交的历史记录也消失了
小明使用强推把你的代码覆盖了,如果你本地仍保存这段要提交的内容(或者小张有在小明强推前拉取过git上你提交的内容),重新推上去即可。如果没有,那恭喜你种大奖了~
★.我提交的代码不见了,且远端git上有我提交的历史记录,但我即使重新push,代码依然不生效
可能原因:错误使用正向回滚
小明在16点push了一段错误代码,你在17点push了你的代码,
18点时小明发现自己的错误,于是使用向前回滚的方式对代码进行“回滚”,使git上的代码彻底和16点前的完全一致。
由于18点的代码已经和16点前完全一致了,故小明必定是将17、16这两个时间的提交的所有内容都改回去了,“回滚”多了(查看小明最后一次提交的内容可知);
git认定最新截点应该就是该回去的效果,故你将之前提交的代码(落后截点)再次push上去,git上仍然不会变化(取最新截点)~
解决办法:可以考虑本地先拉取最新代码后,再用向前回滚方式(或者备份后重新提交)把你要提交的代码再改回去
★.我提交的代码不见了,远端git上有我提交的历史记录(gitlab查询单个文件的历史记录可能显示是旧的提交记录
),但我即使重新push,代码依然不生效
可能原因:开发人员pull后出现冲突后,错误提交文件导致
A同学的代码是基于04-01的基础开发的,后面就一直在写代码没有再pull或提交推送操作;B同学在04-10已提交push了一段代码。假设当前git上最新代码已迭代到04-15了,此时A同学准备要提交代码了,因为可能提交的某个文件在04-01后其他人也改到了,此时A拉取最新代码时发生了冲突。此时A同学解决冲突后进行commit时,只勾选自己要提交的代码(想的挺好的)后再push,此时远端B同学的代码内容就丢失了!
- 当pull没冲突时,本质是将git上的最新代码自动合并到你的分支中,并且自动做了commit操作,这样才保证你的本地heads版本库上包含了最新内容;
- 而当pull有冲突时,自动commit操作不会进行,而是需等开发人员解决冲突后再一起commit时,此时要提交的正确内容应该是“
你要提交的内容+其他人已提交的最新内容
”,如果此时只勾选自己要提交的代码而取消勾选这些看似和自己无关的代码(小乌龟commit时默认已勾选了这些“无关”代码),则被git认定为最新提交点中是特意要舍弃这些“无关”代码,导致其他人的一堆代码不见了~
解决办法:将A那次解决冲突后错误commit的那一条记录回滚掉(可能也有冲突),优先保证远端git上代码先恢复。恢复后让A同学基于最新代码的基础在重新提交自己的内容;