Featured image of post Java工程师 深入学习掌握Git

Java工程师 深入学习掌握Git

🌏Java工程师 深入学习掌握Git🎯 这篇文章用于记录 深入学习掌握Git

🎄本地仓库入门

git init # 初始化git仓库
git add -A # 将所有新建的文件(夹)加入到暂存区
git commit -m "提交说明" # 提交到本地仓库 加上说明

初始化本地Git仓库git init

E:/G_git_test/工作区目录下创建一个文件readme.txt 输入以下内容:

git add -A # 将所有新建的文件(夹)加入到本地仓库 git commit -m "Submit remarks" # 提交到本地仓库

🎄Git版本控制入门

git log # 查看当前窗口的git日志
git log --pretty=oneline # 相对于 git log 输出的信息更简洁
git reflog # 查看当前git仓库的所有日志 reflog 指 "reference log"
git reset --hard COMMIT_ID # 恢复版本
git status # 查看git管理的仓库的状态 哪些文件未track 哪些文件可以commit等
git diff HEAD -- FILE_NAME # 查看工作区和版本库里面最新版本的文件的区别
git checkout -- FILE_NAME # 未add的情况下恢复工作区的文件
git reset HEAD FILE_NAME # 已经add的情况下撤销add操作

🍭入门实践版本控制

🎯先做一系列的变动

readme.txt文件中换行追加内容:APPEND_1_git

然后提交

readme.txt文件中修改和删除内容

再次提交

添加一个新的文件 bigbigmeng.txt

然后再修改readme.txt

第4次提交

🎯查看git日志 并恢复版本

使用git log --pretty=oneline输出的信息更简洁 只显示commitID和commit内容

🎯版本恢复

使用git reset --hard 提交ID来恢复到 提交ID 所对应的版本 例如 这里输入git reset --hard 5041就能使得E:/G_git_test/目录下所有的文件从本地仓库恢复到第一次提交的状态:

恢复后查看log

再查看图形界面的文件夹 这个时候只剩下第一次提交的文件夹了

那如何再回到第4次 也就是最后一次commit的版本呢?只需要键入命令git reset --hard 最后一次提交的版本ID即可:

所有内容都又恢复到最新版了:

🍭使用git reflog可以查看从始至终所有的版本变化 最前面的橘黄色字符串就是版本ID

🍭工作区 版本库 和 暂存区

工作区:电脑上的图形用户界面 E:/G_git_test/目录下就是工作区

版本库:工作区下的 .git 文件夹

暂存区:git add 就是把工作区的文件添加到暂存区stage git commit把暂存区的文件添加到本地仓库

🍭变更管理(添加 删除 修改)

🎯用git diff HEAD -- readme.txt命令可以查看工作区和版本库已经commit的版本)里面最新版本的区别:

在工作区的 readme.txt 添加内容后查看区别:

🎯使用git status查看本地仓库变化

会得到提示哪些文件被修改、哪些文件可以add、哪些文件可以commit

🎯commit之后的提示的含义

🍭如何撤销修改

1️⃣没有git add

git checkout -- file 恢复工作区的文件(也就是说 拿已经add的此文件的最新版本去替换工作区被修改的文件 以此来完成工作区的修改操作的撤销)

🌰例如我现在对bigbigmeng.txt做了如下的修改(这个时候没有add):

使用git checkout -- file 命令来恢复文件:

再次使用git diff HEAD -- bigbigmeng.txt 没有提示表明已经恢复到上一次的版本

2️⃣已经git add

用命令git reset HEAD FILE_NAME可以把add操作撤销掉(unstage)再执行1️⃣的命令就可以恢复

🌰例如我现在对bigbigmeng.txt做了如下的修改(这个时候已经add了):

用命令git reset HEAD bigbigmeng.txt把暂存区的bigbigmeng.txt的修改撤销掉(unstage)

这个时候查看文件 发现还是修改后的样子

接下来继续使用git checkout -- filebigbigmeng.txt恢复成上一次修改的样子:

再次查看文件 就恢复了:

3️⃣已经git commit

git reset --hard COMMIT_ID回退版本

4️⃣推送到远程库

❗无法恢复🙄

5️⃣关于撤销删除操作

如果在工作区删除了test.txt 可以从版本库恢复 git checkout -- test.txt 如果版本库没有此文件 则无法恢复

🎄远程仓库

git remote add origin git@github.com:BigXMeng/G_git_test.git # 关联远程仓库
git push -u origin master # 将本地仓库push到远程仓库并建立分支关联 在之后的push操作中只需要执行 git push 就能自动把本地当前分支的master分支push到远程origin的master分支下
git push -f origin master # 强行覆盖远程仓库 个人进行版本控制的时候可以这么做
git pull origin master # 先运行`git fetch origin master`获取远程仓库的最新更改,然后再运行`git merge origin master`将远程分支合并到本地分支
git remote rm origin # 解除已经关联的远程仓库
git clone git@github.com:github用户名/此用户的仓库.git # 克隆远程仓库

🍭添加和解除远程仓库

假如我们已经在本地创建了一个Git仓库,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作

在GitHub新建一个名为G_git_test的仓库:

添加一个名为 “origin” 的远程仓库,并将其地址设置为 “git@github.com:BigXMeng/G_git_test.git” 通过这个命令 我们可以将本地仓库与远程仓库关联起来 以便进行代码的推送和拉取操作

git remote add origin git@github.com:BigXMeng/G_git_test.git

将本地的G_git_test仓库的内容push到远程仓库的main分支 执行git push -u origin main

重新执行git push -u origin master

🎯关于git push -u origin master命令:

该命令会将本地当前的master分支与远程的origin仓库的master分支进行关联并push 其中-u的作用就是关联 以便后面的push操作只需要git push便可以推送到远程master分支下

使用 -u 参数的好处是可以简化推送命令的书写。默认情况下,如果没有指定 -u 参数,则需要手动指定要推送的分支和远程仓库,例如 git push origin master。而通过使用 -u 参数,我们只需要在第一次推送的时候执行一次 git push -u origin master,之后就可以简化为 git push

如果需要修改关联并重新执行一次带有 -u 参数的 push 指令就可以了

使用git remote rm origin可以解除已经关联的远程仓库:

🍭克隆远程仓库

如果想直接用别人的项目 可以把别人的项目直接克隆到本地新建的仓库

git clone git@github.com:github用户名/此用户的仓库.git

🍭pull 和 push

🔮git pull origin master

git pull命令实际上包括了两个其他命令的组合,它们是:

  1. git fetch: 这个命令用于从远程仓库获取最新的提交历史和文件变化,但是它并不会自动合并这些更改到本地分支。
    • git fetch命令会检索远程仓库中的所有新的提交,包括分支、标签等,并存储在本地仓库中的FETCH_HEAD引用中。
    • git fetch命令不会对本地代码进行任何更改,仅仅是将远程仓库的更改拉取到本地。
  2. git merge: 当执行git pull时,如果执行git fetch后获取到更新,然后将远程分支自动合并(merge)到本地分支。
    • git merge命令将远程分支的更改与当前所在分支进行合并。
    • 如果有冲突产生,我们需要手动解决冲突,并进行提交。

git pull origin master命令实际上执行了两个步骤:先运行git fetch origin master获取远程仓库的最新更改,然后再运行git merge origin/master将远程分支合并到本地分支

🔮git push origin master

git push origin master命令是在团队开发中进行使用的 如果出现冲突 需要手动进行修改和确认 个人开发的时候 远程仓库可以强行覆盖执行这个命令: git push -f origin master 见下图的强行覆盖实例

🎄分支管理

git branch NEW_BRANCH_NAME # 创建新的分支
git switch NEW_BRANCH_NAME # 切换到新的分支
git merge BRANCH_NAME # 在当前分支下合并其他分支
git branch -d BRANCH_NAME # 删除分支
git branch # 查看当前分支状态
git log --graph # 查看分支合并图
git merge --no-ff BRANCH_NAME # 使用非Fast-forward的模式合并分支
git stash # 保存当前分支未add&commit的修改
git stash list  # 列出当前分支所有的stash
git stash apply STASH_ID # 恢复到当前分支某一个stash
git stash pop # 恢复到当前分支的最近的stash并将其删除

img

分支具有以下作用和意义 这些意义会在后面的演示当中体现

🎯并行开发:使用分支,团队成员可以在不干扰彼此工作的情况下,同时进行独立的开发工作。每个分支都有自己的代码状态,开发者可以在分支上添加、修改、删除代码,并随时切换到其他分支以查看和比较代码的不同版本 同时 开启一个新的分支进行开发 也可以看做是功能开发的实验 出现问题,可以很容易地放弃或切回到原来的分支状态

🎯问题修复和紧急修复:当出现线上bug或问题时,分支可以用于及时修复,而不会影响到正在进行的开发工作。开发者可以在主分支之外创建一个用于修复bug的分支,在该分支上进行修改,并在修复完成后合并回主分支

🎯版本管理:通过使用分支,可以轻松地在主分支和各个子分支之间进行版本管理。每一个分支都代表着一个独立的代码状态,包含着特定时间点上的版本信息,可随时切换到任意分支以查看和管理不同的代码版本

🍭创建与合并分支

创建并切换分支

在新的分支下 创建一个新的文件 dev_20230915.txt

add & commit 该文件

这个commit我忘记加上 -m 备注 git会提示加上备注 加上后才会提交

切换回master分支并将development_20230915分支master分支合并

❓这里的Fast-forward是什么含义?

Fast-forward(快速向前)是指在合并分支时,分支的提交历史能够直接延伸到目标分支的末尾,即当前分支的HEAD直接指向了目标分支的最新提交。这种情况下,Git会直接将HEAD指针移动到目标分支上,并且不会创建新的合并提交。因为没有进行实际的合并操作,所以这个操作非常快速,称为Fast-forward合并

通常情况下合并分支 Git会用Fast forward模式 但这种模式下 删除分支后会丢掉分支信息 合并分支指定参数--no-ff可以强制禁用Fast forward模式 禁用后 Git就会在merge时生成一个新的commit 这样从分支历史上就可以看出分支信息 具体的演示可见后面这一节:【🍭使用非Fast forward模式合并分支】

HEAD指针是什么?

在Git中,HEAD是一个特殊的指针,它代表当前所在的分支或者提交。它通常指向当前分支的最新提交,或者直接指向某个具体的提交(如切换到特定的commit)

合并完成后,就可以放心地删除development_20230915分支分支了:

git branch查看当前分支状态:

🍭处理分支合并冲突

在master分支下创建 conflict.txt 并add&commit

切换到新的conflict分支下 创建conflict.txt文件 add&commit:

这个时候再切换到master分支进行合并(提示有冲突 合并失败):

查看此冲突文件 git提示出HEAD指针指向的当前的master分支的conflict.txt 和 conflict分支下的conflict.txt文件的不同(冲突的行)

⚡手动切换到两个分支下将conflict.txt文件的内容改为一致:

1️⃣先切换到master分支 修改并重新add&commit

2️⃣切换到conflict分支 修改并重新add&commit

❗❗注意 修改后要保证master分支和conflict分支下的conflict.txt文件完全相同 多一个换行都不可以!!会使得合并仍然不成功!!

3️⃣回到master分支重新合并conflict分支 这次合并成功~

🍭使用非Fast forward模式合并分支

在上一节合并分支的时候是使用默认的Fast forward模式 通常情况下合并分支 Git会用Fast forward模式 但这种模式下 删除分支后会丢掉分支信息 合并分支指定参数--no-ff可以强制禁用Fast forward模式 禁用后 Git就会在merge时生成一个新的commit 这样从分支历史上就可以看出分支信息

创建新的分支 dev_20230916

在分支 dev_20230916下创建新的文件 new.txt 并add&commit

回到master分支 在master分支下使用非Fast-forward的模式合并分支dev_20230916

git merge --no-ff dev_20230916

git log查看分支历史:git log --graph --pretty=oneline --abbrev-commit

相当于下图 非Fast-forward的模式合并分支的时候会新建一个commit 然后master指向它

🎄Bug分支

假如说 某程序员A正在dev分支上进行日常开发 还需要2天就能完成dev分支的开发的任务 这个时候接到上级指示 master分支中有一个bug需要紧急处理

程序员A先将自己的dev分支使用git stash命令保存

注意 使用 git stash 命令时 可以在任何分支上执行以下操作:保存当前工作目录的修改并清空工作目录,切换到另一个分支,完成在该分支上的任务,然后再回到原来的分支并通过 git stash apply 或者 git stash pop 命令恢复之前保存的修改

然后创建新的bug分支进行修改bug 修改后回到master分支进行合并

这个时候查看new.txt文件 是看不到stash之前的修改(dev正在developing…)的

bug修复后程序员A使用git stash pop再回到dev刚才的开发状态并查看new.txt文件(stash命令的工作表现可见下图):

注意 使用 git stash 命令时 可以在任何分支上执行以下操作:保存当前工作目录的修改并清空工作目录,切换到另一个分支,完成在该分支上的任务,然后再回到原来的分支并通过 git stash apply 或者 git stash pop 命令恢复之前保存的修改

🎄团队协作方法

团队协作的工作模式通常是这样:

  1. 首先,可以试图用git push origin <branch-name>推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并(git pull命令实际上包含了两个独立的操作,即git fetch和git merge 前者用于从远程仓库获取最新的提交信息,后者用于将这些提交合并到当前分支);
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!

如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name> ,另外有一个命令是 git push -u origin <branch-name> 这个命令建立关联并push,包含了前一个命令,前一个命令只建立关联

参考链接:https://www.liaoxuefeng.com/wiki/896043488029600