Git & Github Tutorial
教程地址:Git & GitHub Tutorial | Visualized Git Course for Beginner & Professional Developers in 2024
git自动跟踪每个代码更改,允许多个人无缝处理同一个项目,让成员浏览项目历史记载
1.检查git版本
2.配置姓名和邮箱
为了跟踪谁对项目进行了更改,使用姓名和电子邮件配置git
- git config --global user.name 'yourname'
复制代码- git config --global user.email 'youremail'
复制代码
仓库(repo)是git跟踪项目中所有内容的地方,将仓库视为存储所有代码版本的文件夹
3.创建本地仓库 (git init
)
在终端创建一个本地仓库
.git文件夹中包含了提交历史(commit history)、分支情况(branches)、远程仓库(remote repo)情况等
分支默认名称为master,请用main、trunk、development等其他名称更换
4.修改初始化默认分支名称
修改使用git init
初始化时的分支名称
- git config --global init.defaultBranch main
复制代码 验证一下刚才的设置,当我重新创建一个新文件夹并初始化本地仓库时,看看默认分支名称是否为main
分支(branch)是你项目的并行版本
5.查看git状态(git status
)
现在我们来添加一些文件让git对其进行跟踪
我们看到刚刚创建的文件还没有被git跟踪
目前在主分支
尚无提交
有两个未跟踪的文件
6.将文件添加到暂存区(git add)
为了让git能够跟踪两个文件,后续对这两个文件的更改git会记载下来你的更改操纵,我们将文件添加到git暂存区(staging)
如果想要将所有修改过的文件都参加到git暂存区
这里的点(.)告诉git将所有创建、修改、删除的文件添加到git暂存区
7.提交文件(git commit)
提交(commit)我们将文件添加到git暂存区后必要提交它,提交就像是在某个时间点拍摄项目的快照,可以将其视为创建文件夹的全新副本,并告诉git记住你何时何地执行了此操纵。如果将来发生任何事情,你将使用你指定的提交名称退回到此文件夹以获取并查看此中的内容
定期提交更改可以资助你跟踪项目进度,并轻松恢复到以前的版本
接下来我们将hello.py文件参加git暂存区后提交
- git add hello.py
- git status
复制代码
- git commit -m 'add hello and readme'
复制代码 这里的m代表message消息,消息的尺度是“祈使语气‘(类似命令式的语气),这样别人在归并你的分支时就明白,如果将你的分支归并进来会发生什么情况
查看所有提交commit的历史记载
log中包含了提交的ID(hash值)、作者姓名、邮箱、提交时间、提交信息
提交hello文件后HEAD指针(指向分支的最新节点)由readme节点转移到了hello节点
8.切换分支
8.1.1 git checkout
当前版本的代码存在一些缺陷,想回到上一个版本重新修改代码,这时就必要切换分支
假设我要从当前节点切换到前一个节点
- git checkout 提交readme那个节点的哈希值
复制代码 留意单单checkout不会删除原来节点的内容
我们从hello文件那个节点切换到readme那个文件的节点
切换后发现之前节点的hello.py文件消失了(其实它还在并没有被删除),HEAD指针(本来就应该指向最新提交的节点) 指向了当前节点
切换后出现了警告“HEAD指针不再指向最新节点”
固然表面上切换之前的节点消失了,但其他它还存在,并没有被删除
从readme节点切换到了主分支main的最新节点
切换后我们发现“消失”的hello.py又出现了
8.1.2 git checkout -f
如果想要切换分支的同时放弃当前分支的新修改
我当前在“add hello.py”节点上,我对hello.py文件添加一行
当我使用checkout切换时,提示错误,我对该文件做出了修改,但没有提交,如果我不想要修改过的代码了,那么我强制进行切换,直接抛弃修改过的代码
- git checkout -f README节点的哈希值
复制代码
当前我们在readme这个节点,我们切换回hello那个节点,检查一下之前在hello.py添加的那行代码还在不在
原来在hello文件中修改的代码,确实在git checkout -f 时被抛弃了
9.git和github的区别
git是一个用来跟踪项目更改的工具
github是一个云平台吗,允许你存储你的git仓库,并与其他人协作将你本地仓库推送到github远端仓库
git init
是在初始化本地仓库,git push
是将本地仓库推送到github远端仓库
10.github上创建远端仓库
远程仓库名为origin(等价于远程仓库的URL)
11.更改主分支名称(git branch -M)
如果本地的主分支名称还没有更改为main,请使用
12.本地仓库链接到远端仓库(git remote add origin)
在本地终端运行
- git remote add origin 远程仓库URL
复制代码 13.本地仓库推送到远程仓库(git push
-u origin)
origin等价于远程仓库的URL,这里用origin直接取代
main是本地仓库主分支名称
14.分支(branch)
14.1 为什么必要分支?
git的分支允许你创建项目的不同版本,在特定时刻复制项目代码,在这个复制的版本上进行更改,这些更改不影响主分支的代码
可以将在其他分支中开辟的新功能归并(merge)到主分支
在主分支外使用单独分支的原因:
1.为项目实现不同功能
2.错误修复
各个分支的功能
master 分支
master 为主分支,也是用于摆设生产环境的分支,确保master分支稳固性
master 分支一样平常由develop以及hotfix分支归并,任何时间都不能直接修改代码
develop 分支
develop 为开辟分支,始终保持最新完成以及bug修复后的代码
一样平常开辟的新功能时,feature分支都是基于develop分支下创建的
feature 分支
开辟新功能时,以develop为基础创建feature分支
分支定名: feature/ 开头的为特性分支, 定名规则: feature/user_module、 feature/cart_module
release分支
release 为预上线分支,发布提测阶段,会release分支代码为基准提测
当有一组feature开辟完成,首先会归并到develop分支,进入提测时,会创建release分支。
如果测试过程中若存在bug必要修复,则直接由开辟者在release分支修复并提交。
当测试完成之后,归并release分支到master和develop分支,此时master为最新代码,用作上线。
hotfix 分支
分支定名: hotfix/ 开头的为修复分支,它的定名规则与 feature 分支类似
线上出现告急问题时,必要及时修复,以master分支为基线,创建hotfix分支,修复完成后,必要归并到master分支和develop分支
引用:您必须知道的 Git 分支开辟规范
14.2 创建分支(git branch)和切换分支(git checkout)
创建的同时切换分支
留意执行该命令时所处的分支,由于这个创建分支是在当前所处分支上进行的,所以创建分支前要检查当前所处分支
如果不想检查当前所处分支,而是就直接指定在某个分支上创建新分支
我当前在主分支上,但是我不想从主分支上建立新分支,我直接在指定分支new-branch上创建新分支feature-B
- git branch feature-B new-branch
复制代码
由于我们仅仅是对本地仓库进行更改,并没有同步到远端仓库,所以github中并没有发生变化
14.3 推送分支(git push
--set-upstream)
我们将新建分支推送到远端仓库
- git push
- --set-upstream feature-B
复制代码 git push
:将本地仓库的提交推送到远程仓库
–set-upstream(简写为 -u):建立本地分支与远程分支的跟踪关系
origin:远端仓库URL(默认名称,可自定义)
feature-B:本地分支名,同时也是目标远程分支名(若不存在则会创建)
我们看到目前远端仓库中有主分支main、和刚刚推送的分支feature-B,而分支new-branch并没有在远端
origin为远端仓库URL、main为本田主分支名称、feature-B为本地分支名称、new-branch为本地分支名称、HEAD头指针(黄色标签,指向当前分支)
我现在切换到未推送的new-branch分支
把未推送的new-branch分支也推送到远端仓库
- git push
- -u origin new-branch
复制代码
我们看到分支new-branch前面多了一个origin(远端仓库URL)
执行 git push
-u origin feature-B ,会直接推送本地 feature-B 分支到远程仓库 origin ,并建立好跟踪关系,后续在 feature-B 分支上可直接用 git push
和 git pull
操纵(同步了分支后,后续就可以直接在分支上git push
)
由于modify hello.py没有推送到远端,必要把主分支main再次推送到远端
15.将远端仓库同步更新到本地仓库(git pull
)
如果其他协作者将自己修改的代码上传到了远端仓库,自己必要在其基础上开辟,这时就必要将远端仓库的代码同步到自己的本地仓库
16.拉取请求(pull request)后归并(merge)
如果你在其他分支上完成了功能的开辟,你得把你的分支归并到主分支上,在归并前就必要拉取请求(pull request)让团队负责人进行审核和反馈,一旦请求获得批准,你的分支就能成为主分支的一部分
16.1 新建拉取请求
16.2 解决冲突
表现其他分支中详细的修改内容,如果其他分支相比主分支在类似文件中有改动,那么就必要解决冲突问题,比如主分支在第100行有代码,其他分支在100行是空行
16.3 拉取请求
若没有冲突或解决了冲突,那么就可以创建拉取请求(create pull request)
添加请求的title和description
拉取请求后提示该分支与主分支没有冲突
16.4 其他分支归并到主分支
没有冲突后,我们确认归并
固然也可以在本地终端执行,确认当前所处分支
归并后,我们发现主分支上出现了featureB分支的内容,代表归并成功
归并后查看一下项目分支信息
如果某分支的ahead值为0,表明该分支的所有提交都归并到了主分支,我们可以将该分支删除了,由于该分支的开辟功能都归并到了主分支,所以该分支的任务已经完成了,可以将其删除
16.5 分支的Ahead和Behind
了解一下Ahead和Behind
在多个分支并行开辟时,我们常常必要了解每个分支相对于主分支的提交差异。这就是git ahead/behind信息的作用。
git ahead表示分支比主分支多了多少个提交,而git behind表示分支比主分支少了多少个提交。通过了解这些信息,我们可以知道主分支和分支之间的提交差异,从而更好地管理和归并代码。
git ahead表示分支上相对于主分支多出来的提交数。如果分支有3个提交,而主分支只有2个提交,则分支比主分支多1个提交,即git ahead为1。
git behind表示分支上相对于主分支少了多少个提交。如果分支有2个提交,而主分支有3个提交,则分支比主分支少1个提交,即git behind为1
–引用:Git分支中主分支与分支之间的git ahead/behind信息
个人明白:如果这里某个分支ahead值大于0,代表分支的某些东西还没有归并到主分支上。如果这里某个分支behind值大于0,代表该分支的内容少于主分支必要pull更新该分支
核心概念:提交差异的本质
当我们说某个分支ahead N或behind M时,现实上是在比较两个分支的共同先人之后的提交差异:
- ahead N:分支 A 比主分支(如main)多了N 个未合并的提交。
- behind M:分支 A 比主分支少了M 个提交(即主分支有 M 个提交未同步到分支 A)
复制代码 ahead/behind 的现实含义
- ahead > 0分支有新提交未归并到主分支,通常意味着: 你在分支上开辟了新功能,必要通过git merge
- 或git rebase将变动同步到主分支。 若主分支是发布分支,这些变动尚未发布。behind > 0分支落后于主分支,可能必要更新以获取主分支的最新变动: 若要在分支上继续开辟,发起先git pull
- 主分支的更新,避免后续归并时冲突过大。 若准备将分支归并到主分支,发起先同步主分支的最新代码(git rebase main),保持提交历史整洁。
复制代码 如何处理 ahead/behind 状态
场景 1:分支 ahead N,必要同步到主分支
- git checkout main
- git merge
- feature # 将feature的变动归并到main
复制代码 场景 2:分支 behind M,必要更新
- git checkout feature
- git pull
- origin main # 合并主分支更新到当前分支
- # 或使用rebase保持线性提交历史
- git rebase main
复制代码 场景 3:同时 ahead N 且 behind M(常见于长期分支)
- # 1. 先同步主分支更新git checkout featuregit pull
- --rebase origin main# 2. 解决可能的冲突后,推送更新后的分支git push
- -f origin feature # 若使用rebase,可能必要强制推送# 3. 最后将分支归并到主分支git checkout main
- git merge
- feature
复制代码 16.6 将远端仓库的更改同步到本地仓库
以上归并操纵均发生在远端仓库,我们的本地仓库还没有发生变化,如下图
先切换到主分支
拉取远端仓库
大概不切换分支而是直接使用
我在远程仓库中将分支featureB归并到了主分支,随后删除了分支featureB,接着在本地git pull
同步更新,但我发现featureB仍存在
git pull
主要用于拉取远程分支的更新并归并到本地分支 ,它并不会自动删除本地已经不存在于远程的分支引用。在远程删除分支后,本地仍保留着该分支的相干信息,是本地的远程分支跟踪记载未被更新
-p 是 --prune 的缩写,该命令会从本地仓库中移除那些远程仓库已不存在的分支的跟踪信息
我们发现featureB前面的origin消失了
如果不仅远程分支被删除,你也想删除本地的 featureB 分支 ,在完成上述清理操纵后,先确保不在 featureB 分支上(可切换到其他分支,如 git checkout main
) ,然后使用以下命令删除本地分支:
我们刚刚从本地仓库中移除那些远程仓库已不存在的分支featureB的跟踪信息,但是本地分支中featureB仍存在
如果 featureB 分支的所有提交都已经归并到其他分支,此命令可安全删除分支
若 featureB 分支存在未归并的提交,使用 -D 强制删除,但会丢失未归并的提交内容,需谨慎操纵
17.解决归并冲突(Resolving Merge Conflicts)
17.1 什么是归并冲突?
当两个或多个开辟职员编辑类似的代码时,git会感到困惑,这被称为归并冲突
冲突后到底要选择保留哪些代码大概哪个开辟职员的更改?这就是在解决冲突
17.2 冲突的产生
案例:
在主分支上有一个README.md内容为一行笔墨:Hello Git!
我在主分支上创建两个分支featureA、featureB,从主分支切换到分支featureB
- git commit -m 'add README'
- git branch featureA
- git checkout -b featureB
复制代码 在featureB中我们更改一下README的内容,修改为:Welcome to Git! - This is coming from featureB
修改后我们将修改过的readme添加到git 暂存区
主分支的readme与featureB分支的readme内容是不一样的
比较两个文件,拉取请求,创建拉取请求
在featureB分支上,提交修改过的readme
- git commit -m 'Modify readme by changing the heading and adding a new line'
复制代码 将featureB分支同步到远端仓库
- git push
- -u origin featureB
复制代码
我们切换到featureA分支,对readme也进行修改
添加到暂存区,提交修改后的commit,将分支featureA同步到远端仓库
- git add .
- git commit -m 'add a few lines on readme'git push
- -u origin featureA
复制代码 我们在featureA上也拉取请求,目前两个分支各有一个拉取请求
现在我们将featureA中readme内容归并到主分支
归并后的主分支中readme内容为
现在我们把featureB中的内容归并到主分支发现了冲突,归并操纵被阻止了
点击解决冲突(Resolve conflicts)
冲突的来源是:featureA修改了readme文件且归并到了主分支,但是featureB也修改了readme文件中的同一行,所以在featureB提出归并请求时出现了冲突
git遇到冲突后希望你解决冲突,决定保留哪个版本的代码,然后手动更新代码
你和协作者在同一代码上工作时就会因对同一行代码进行修改而发生冲突,终极无法归并到主分支
17.3 解决冲突的尺度流程
先从featureA分支切换到主分支
从远端仓库拉取最新的更改
切换到featureB分支
HEAD头指针(黄色tag)已经移动到了featureB
正常流程是把我们的分支归并到主分支上去,为了淘汰团队负责人解决冲突的工作量,我们先把最新主分支拉到本地,把主分支归并到我们的分支后解决冲突内容,最后请求团队负责人将我们的分支归并到主分支
目前我们在featureB分支,我们将主分支归并到featureB分支
pycharm上方有个Git->Resolve Conflicts
点击merge,在这个对话框里解决冲突
比如我把featureB的归并到main
我们把必要的内容都归并到中间Results,之后点击右下角Apply
当前我们在featureB分支上,我们把这个归并结果添加到暂存区,后提交,push推到远端仓库
- git add .
- git commit -m 'resolve merge conflicts'git push
复制代码 我们看到featureB已经与main没有冲突了
我们解决冲突后给团队负责人一个comments,说明我们已经解决冲突请求归并到主分支
检查一下我们修改过的文件中的内容
如果另有问题可以写comment,点击上面红框中右上角的对话框,如果没有就可以让团队负责人归并我们的分支了
现在主分支的情况
我们看到我们刚刚的操纵,把最新主分支拉到featureB分支,修改冲突后,提取请求,归并到主分支
18.git使用的常见步骤
1.clone the repository
2.create a new branch from the main or another branch
3.make your changes
4.push the branch to the remote repo
5.open a pull request
6.merge the changes
7.pull the merged changes into your local main branch
8.repeat from step 2
19.重置历史提交记载(reset)
19.1 工作区和暂存区
工作区:你现实编辑文件的地方,是 “未完成” 的修改。
暂存区:用于准备提交的中间地区,是 “已完成且准备好提交” 的修改。
Git 的核心流程:工作区修改 → git add → 暂存区 → git commit → 本地仓库 → git push
→ 远程仓库
19.2 软重置(soft reset, git reset --soft)
作用:将 HEAD 移动到指定提交,不改变暂存区和工作区。
场景:撤销提交,但保留所有变动(相当于 “取消提交”,但变动仍在暂存区)。
- git reset --soft <commit-hash>
复制代码 回溯到历史记载3,但保留历史记载3之后的所有历史记载(这些提交commit记载在暂存区,没修改的和修改完没提交的在工作区)
也就是说已经被git跟踪的代码(暂存区)、以及没修改的和修改完代码没提交的均不会被删除
我们尝试一下软重置
- git reset --soft <reademe的hash>
复制代码 HEAD头指针回到了readme那边
其他提交记载均不表现在log中
我们回到原来的状态
- git reset --soft <最新的hash>
复制代码
HEAD头指针重回最新提交记载
19.3 硬重置(hard reset, git reset --hard)
回溯历史记载3,但删除历史记载3之后的所有历史记载(这些提交commit记载在暂存区,没修改的和修改完没提交的在工作区)
也就是说已经被git跟踪的代码(暂存区)、以及没修改的和修改完代码没提交的均会被删除
19.4 默认重置(mixed reset,git reset)
作用:将 HEAD 移动到指定提交,重置暂存区,但保留工作区的修改。
场景:取消暂存(unstage)文件,但保留工作区的修改
把已经被跟踪的代码移除暂存区,那些还没来改完的代码(没有给git跟踪的代码)保留下来
19.5 git reset、git reset --soft、git reset --hard区别
提交的commit记载在暂存区(被git跟踪的代码)
没修改的和修改完没提交的在工作区(还没有被git跟踪的代码)
20.撤销历史提交记载(git revert)
应用场景:我已经提交了commit信息,但是我想反悔,不想提交了这个信息,大概公共分支上我提交了commit信息,别人也提交了commit,但是我的commit的代码有些问题,想撤回来不提交。–引用:git 教程 --git revert 命令
git reset 是回滚到对应的commit-id,相当于是删除了commit-id以后的所有的提交,而且不会产生新的commit-id记载,如果要推送到远程服务器的话,必要强制推送-f
git revert 是反做撤销此中的commit-id,然后重新生成一个commit-id。自己不会对其他的提交commit-id产生影响,如果要推送到远程服务器的话,就是普通的操纵git push
就好了。–引用:git 教程 --git revert 命令
git revert命令:是用于“反做”某一个版本,以达到撤销该版本的修改的目的。–引用:Git的三种后悔药:amend、revert、reset
假设某个项目已经开辟了三个功能
进行了四次commit
可以用pycharm中集成的commit功能来提交,也可以终端输入命令
假设现在项目经理说:我们现在必要把功能二撤下来(对应second function),难道我们去手动取出功能二的所有代码(固然可能不止在一个文件中,可能包含在其他文件中的代码)?如果直接使用reset则会影响其他写的功能(third function),这时就使用git revert
在second function上右键后点击git revert
回退second function之前
回退second function之后
生成了新提交 revert “second function”
我们发现second function.py的文件消失了,但是third function和fourth function的文件还在,也就是说回退second function并没有影响到其他功能
我们将回退功能二之后的本地仓库更新到远端仓库
如果自己就在main分支,则命令简化为
也就是说如果你想将现在所处的分支推送到远端,就直接push,如果现在所处的分支不是你想要推送的,但又不想切换分支,那就用-u origin 你想推送的分支名称
21.暂存(git stash
)
git stash
是一个强大的工具,用于临时生存当前未提交的修改,让你可以在不提交的情况下切换分支或执行其他操纵
此时有一个告急bug必要处理,但是目前写了一些紧张的代码但还没有写完,我如果直接切换分支的话,我写的紧张代码就删除了,此时代码也不能commit由于还没写完,这时可以临时生存起来,等到修复完告急bug后再继续写
假设现在修复完了告急bug,现在想回去继续写紧张代码
查看临时存储列表里之前生存的临时代码
从存储列表中找到之前暂存的代码信息,恢复以前暂存的代码
- git stash
- apply stash@{0}
复制代码 恢复前
恢复后
22.Git GUI
其实在很多酿成开辟环境(IDE)中就有git的可视化操纵界面
例如:pycharm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |