从零开始的git学习(所有命令后面-h有提示)
基本组成
1、本地仓库——工作区下的.git目录,存放了管理该工程的所有版本数据
2、工作区——日常写代码的区域,直接写代码的界面就是工作区
3、暂存区——.git/index文件夹中
文件状态
1、已经提交(committed)已经安全保存到本地仓库
2、已经修改(modified)没提交保存
3、已经暂时存放(staged)
基本概念:修改记录
有的时候也称为节点,每次commit操作有一个对应的hash值
1、每个修改记录都有对应的id
2、当发现修改有问题时,可以进行回滚操作。
3、回滚的本质是一次新的更新以复原修改。但是如果不是针对最新记录进行回滚,会出现冲突。
这里需要举例说明
基本概念:分支
1、分支是一个远程仓库中的多个独立副本,副本之间是互不影响的。他们的文件修改记录都是相互独立的。
2、一个远程仓库默认有一个主分支,默认情况下文件会被存储到主分支。
3、创建分支时,需要基于:某个修改记录某个分支或者某个tag
4、一个分支的所有修改可一次全部更新到别的分支,称为合并。合并实际上是对目标分支提交一次新修改。但是如果目标分支则修改过某个文件,则可能产生冲突。
基本概念:TAG
1、标记某个修改记录,用于归档对应的分支下截止到这次修改的文件。有点像是游戏中的存档点。
git 基本配置
git 有三种基本配置:
git config --local ///对当前仓库生效
git config --global ///对当前用户的所有仓库生效,会修改~/.gitconfig 或 C:Users你的用户名.gitconfig
git config --system ///对当前系统下所有用户生效
最常见的配置如下,只需要在第一次使用git的时候配置即可,以后上传代码都不需要再配置了!!!
git config --global user.name # 查看全局用户名
git config --global user.email # 查看全局邮箱
git——与服务器的认证配置
ssh-keygen -t rsa -C "your email"
直接按三次回车,可以看到公钥。
在代码管理平台的profile Settings中 找到SSH Keys, 添加SSH Keys,将公钥复制到Public Key即可
指令大全
1、将仓库克隆到本地 git clone
2、查看工作区修改的内容—— git diff
3、查看工作区文件的状态—— git status
1、将文件移动到暂存区 git add / rm / mv
2、将工作目录中的修改文件和暂存区都保留到临时的栈中 git stash
3、将临时栈中的文件和暂存区恢复 git stash pop
4、git pull 将工作区和本地仓库都更新为最新。
5、git commit 将修改的文件提交到本地仓库
6、git push 将修改推送到远程仓库
分支管理
1、git branch 列出所有本地分支
2、git branch/checkout -b //新建本地分支
3、git branch -d //删除本地分支
4、git checkout //切换本地分支
5、git merge //合并分支
6、git reset //强制回退到历史节点
基本命令1:git clone 将仓库克隆到本地。
//检查是否有工程权限
git clone xxx.git(URL) //生成name本地仓库
克隆的时候默认克隆的分支是主分支
基本命令2:在本地创建一个新的git 工程
git init name //生成name本地仓库
基本命令3:在本地创建一个新的git 工程
git init name //生成name本地仓库
基本命令4:对暂存区进行操作
git add xxx将某个文件 存入暂存区
git mv xxx 移动文件位置,或者重命名
基本命令5:比较差异
git diff --cached//比较当前暂存区中文件与上一次提交间的差异
git diff master ../当前工程路径 --name-status(只列出文件名)
//比较两个分支之间的差异
基本命令6:查看工作目录和暂存区的状态
git status //可以显示当前所在分支以及文件状态
(to be committed已经暂存尚未提交
not staged 还未暂存
untracked 未跟踪
)
基本命令7:将暂存区的文件提交到本地仓库
git commit filename -m "xxxxx"//提交指定的文件,如果不指定文件则是暂存区中所有文件。
git log 可以查看此次提交的Id和描述信息。
基本命令8:将本地的分支推送到远端
在提交到本地仓库后,可以推送到远端
git push origin(服务器名) branch_name(远端显示的分支名)
服务器名可以通过git remote来查看,一般都是origin.
基本命令9:查看分支
git branch 查看本地的所有分支
git branch -r 查看远端服务器上的所有分支
git branch -a 本地,远端所有分支
git branch xxx新建分支但是不会切换到新的分支
git checkout -b xxx 新建分支且切换到新的分支
git branch -D xxx 删除本地分支
git branch -D -r xxx 删除远端服务器的分支
git push origin branchname 远程删除需要推送远端
基本命令10:获取分支的更新
git diff remote_branch local_branch //可以先查看一下本地分支和远端分支是否一致,远端分支是否有更新。
git pull origin remote_branch:local_branch 将远程仓库 origin 的remote_branch分支 获取+合并到本地某分支上
大多时候,远端的分支和本地的分支是一样的,直接
git pull origin remote_branch 即可
为了给用户确认的余地,有fetch命令
git fetch origin remote_branch:local_branch 获取远端分支更新但是不合并
大多时候,远端的分支和本地的分支是一样的,直接
git fetch origin remote_branch 即可
基本命令11:分支的合并
我们先来介绍一下为什么需要有分支更新这个概念。
假如现在我们只有一个分支main ,那么大家都在这个分支上进行开发。这样显然是不合适的,因为我们需要保留稳定的版本。如果一直在main上开发,很难保证版本的稳定性。
那么假设我们现在默认main分支是稳定的版本。他的分支如下
main1.0->main1.2->main1.3(当前最新的稳定版本)
现在产品有3个功能模块需要开发,分别是支付模块,AI模块和客服模块。
一般开发组会这样:从main1.3分出三个分支P,A,C,分别在分支上开发这三个模块。等某个模块开发完毕,测试完毕后,再合并到main分支中。
合并这个工作由谁来进行呢?一般是版本的管理员。
假设现在管理员所在的分支是main1.3,我们需要将开发好的分支A合并到main1.3中。
git merge src dst //指定src分支合并到dst分支
//合并成功后,可将dst推送远端。git push origin dst
1、操作在本地进行。
没有发生冲突:更新的文件会被自动commit到本地仓库。工作区也更新。可以直接push到远程
发生冲突:冲突文件不被加入暂存区,非冲突文件加入暂存区。后续需要将冲突文件手动添加到暂存区,然后再commit才到本地仓库。
关于分支和merge操作,这两张图比较合适。在主干分支上,我们引出了一个分支来开发支付功能Feature,但是此时Master陆续有我们同事的工作在更新。一个节点就是一个commit。当我们开发完成时,master分支已经更新了两次。现在我们功能验证完毕,需进行分支合并。
这里我们以master合入Feature为例,结果如下。我们发现合入这个动作会让我们的分支多出一个节点,也就是多出一次commit记录。这次记录会同步这段时间内Master产生的更新。
基本命令12:如果当前进行了文件修改,但是没有add到暂存区,想要在工作区中进行回退
git status //可以看到哪些文件被修改但是没有add
git checkout .//回退所有modified状态的文件
git checkout -filename //仅回退一个文件
//再用status指令会发现该文件已经没有modified标识
git checkout commitid回退到某一个历史提交版本
基本命令13:本地修改提交到远程,对上一次提交进行amend
git status //可以看到哪些文件被修改但是没有track
git add. //所有未被track的文件添加到暂存区
git commit -am "add something"//提交到本地仓库
git commit --amend//可以在vim界面中修改上次提交的信息
//i :insert ///esc :wq(保存 退出)
git push origin master //推送到远端
基本命令14:下载仓库到本地后,开启新的分支进行开发
git checkout -b newbranch//开启新的分支并且切换到分支,会集成原有分支的所有的历史提交节点。
//进行开发,并且
基本命令15:跨分支的部分更新——cherry-pick
假如现在我们的main分支的更新如下
main1.0->main1.1->main1.2
有一个新开发的业务从main1.1引出了分支,有
main1.1->feature1.2->feature1.3---->feature1.19
但是我们现在main分支1.2紧急需要feature中的某个功能,该功能在feature1.3中有开发。但是有不想合入整个feature,因为有feature的部分功能尚未验证。此时我们只想让feature1.3中的修改引入main1.2。
git checkout main1.2
git cherry-pick harshid(feature1.3对应的commit_id)//内容会同步,但是会在当前分支下添加一个新的commit_id, 和 harshid不同
git push origin //直接推送即可
切换到 main 分支
git checkout main
应用 feature 分支的提交 C(假设提交哈希为 abc123)
git cherry-pick abc123
测试通过后推送到远程
git push origin main
常见操作:git branch/checkout 分支操作
我们clone下来的是一个仓库,仓库有不同的分支,我们可以进行分支的切换。
1、在本地副本下,采用git branch 指令查看仓库的所有分支
2、并且用git checkout xxx进行分支的切换。也就是说,我们可能下载下的是主分支,但是可以在本地直接利用这个命令进行分支切换,这样本地的分支就变成了分支xxx。
3、如果当前副本已经进行了修改,还未提交修改,则无法切换分支。
4、基于3,如果需要使用多个仓库分支代码,建议克隆多个仓库副本
5、如果下载本地副本以后,有别的用户更新了远程仓库,那么当前本地仓库和远程仓库是不一致的。如果此时提交修改,则可能发生冲突。
如果我们在本地副本修改了文件集合A,远程仓库的文件集合B发生了更新,而A和B有交集,也会出现更新冲突导致的更新失败。
问题:如何处理冲突呢?
git add . //修改后的文件A保留到暂存区
git commit -m xxx//文件A已经提交到本地仓库,此时暂存区为空
git push //发现冲突
//此时务必先执行git status确保没有未提交的修改!!!
git pull //更新工作区和本地仓库为最新版本,这里需要手动解决冲突
git add .//重新将A添加到暂存区
git commit --amend --no-edit xxx//合并两次提交,而不是创建新的提交
git push -f //强制推送
问题:如果当前本地我们所在的分支是A分支,而该仓库实际上有多个分支,那么git pull指令更新的是A分支,还是仓库的所有分支?
git pull命令只会更新当前所在的本地分支,而不会同时更新其他分支
git pull的本质是两个操作的组合:
1、git fetch:从远程仓库下载所有分支的最新提交记录(但不合并到本地)。
2、git merge:将当前分支对应的远程分支(如origin/main)合并到本地当前分支。