介绍
Workspace:就是我们的项目目录
Index: 暂存区
Repository: 本地仓库
Remote: 远程仓库
本地
通过初始化或者克隆创建本地仓库
初始化
在项目所在根目录执行:
git init
在项目目录多出了一个.git目录,关于版本等的所有信息都在这个目录里面。
克隆
git clone <url/ssh>
这样也能够创建出一个本地仓库
Git 文件操作
文件的4种状态
版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态。
Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add状态变为Staged.
Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改 !
Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified。
#查看指定文件状态
git status [filename]
#查看所有文件状态
git status
#添加所有文件到暂存区
git add .
#提交暂存区中的内容到本地仓库
git commit -m "消息内容"
#撤销工作区的修改
git checkout – +文件名
//git checkout – 1.txt
#撤销暂存区修改
git restore --staged +文件名
//git restore --staged 1.txt
#回滚前一个提交
bashCopy code
git reset --hard HEAD^
#回滚前两个提交
bashCopy code
git reset --hard HEAD^^
--hard
标志表示要清除工作目录和暂存区的更改,确保它们与回滚后的提交匹配。
远程
将本地仓库与远程仓库进行关联
git remote add origin <远程仓库的URL>
//git remote add origin https://gitee.com/qfytao/fmwy.git
将本地分支与远程分支进行绑定
git branch --set-upstream-to=<远程仓库名>/<远程分支名> <本地分支名>
查看远程仓库状态
git remote -v
分支
查看本地分支
git branch
//此时所在的分支前会加*
创建本地分支
git checkout -b <本地分支名>
创建并绑定本地分支到远程分支
git checkout -b <本地分支名> <远程仓库名>/<远程分支名>
查看远程仓库分支
git remote -r
绑定现有的本地分支到远程分支
git branch --set-upstream-to=<远程仓库名>/<远程分支名> <本地分支名>
确认绑定状态
git status
原理
拉取产生冲突:
git会保留你最新一次拉取远程分支的代码快照。举个例子
远程仓库中的代码和工作区(本地仓库)中的代码都会和快照进行对比,如果,两边对同一行做了不同的修改,就会产生冲突。
git pull 是 git fetch origin(拉取远程分支) 和 git merge origin/feature(合并远程分支) 的简化。
git fetch 只是将远程仓库的最新代码拉取到本地仓库,但不会与本地工作区进行合并。
远程仓库的内容会被存储在本地仓库中的一个特殊区域(origin/main 或 origin/branch_name)中,供你查看和比较。
上图是本地仓库,本地代码存的是从工作区commit上来的代码。代码对比是在本地仓库进行的,如果没有冲突进行合并后,就会更新本地代码这块,同时更新工作区。
本地代码commit后会形成一个哈希值<commit-hash>,可以通过git log 查看,
如果存在冲突,解决冲突出了问题,导致自己的工作区的代码出现了问题,此时可以进行回退,使用git reset --hard <commit-hash>。使用这个会将所有未commit的更改舍弃掉。
经常commit代码是个非常好的习惯。多次commit的代码会依次提交给远程仓库。
使用 git revert <commit-hash> 可以撤销之前的commit,示例
假设你的提交历史是这样的:(提交就是commit)
- A: 提交1
- B: 提交2
- C: 提交3
- D: 提交4
执行git revert C 会将C提交带来的影响撤销掉,但是并不会影响提交历史,提交历史变成了
- A: 提交1
- B: 提交2
- C: 提交3
- D: 提交4
- E: 撤销提交C
比如说提交C修改了l.txt文件,则执行E后,则C对l.txt的更改会被撤销掉。
这个语句影响的是本地仓库,不会影响提交历史,但是git reset 会影响提交历史。
git reset
- git reset --soft <commit>:
- 将 HEAD 移动到指定的 <commit>,但保留暂存区和工作区的更改。
- 使用场景:如果你想将最近的提交变为未提交的更改,以便重新修改或合并多个提交。
- git reset --mixed <commit>(默认):
- 将 HEAD 移动到指定的 <commit>,保留工作区的更改,但清空暂存区。
- 使用场景:如果你想撤销某个提交,同时保留更改以供进一步修改。
- git reset --hard <commit>:
- 将 HEAD 移动到指定的 <commit>,并丢弃所有工作区和暂存区的更改。
- 使用场景:当你想完全回到某个提交的状态,丢弃之后的所有更改。
这个执行就是将代码的状态进行回退,如回退到C状态,则D提交的所有修改都会被丢弃,再次提交后,提交历史也变成了ABCE。
1. 执行 git init 后项目是否自动放入工作区?
当你在一个包含你项目的文件夹中执行 git init 时,这个文件夹(及其子文件夹和文件)会被 Git 视为工作区的一部分。但是,这并不意味着这些文件已经被 Git 跟踪或管理。它们只是存在于工作区中,而 Git 还没有对它们进行任何版本控制操作。
2. 在不执行 git add 的情况下直接连接远程仓库并拉取代码会发生什么?
如果你在没有将任何文件添加到暂存区(即没有执行 git add)的情况下尝试连接远程仓库并拉取代码(使用 git pull 或 git fetch 后 git merge),Git 会尝试将远程仓库的内容合并到你的当前分支(通常是 master 或 main,取决于你的 Git 配置和远程仓库的设置)。
但是,由于你的工作区中没有任何文件被 Git 跟踪(因为你没有执行 git add),Git 在合并时会认为你的工作区是“干净”的,即没有未提交的更改。因此,它基本上会将远程仓库的内容覆盖到你的工作区中,可能会导致以下情况:
- 如果远程仓库和本地项目没有重叠的文件:远程仓库的内容将被完整地拉取到你的工作区中,你的本地项目文件可能会被覆盖(取决于远程仓库的内容)。
- 如果远程仓库和本地项目有重叠的文件:Git 可能会尝试合并这些文件,但由于本地文件没有被跟踪,Git 可能会将这些文件视为冲突,或者简单地用远程仓库的版本替换本地文件。
3. 如何避免这种冲突?
为了避免这种情况,你可以采取以下步骤:
- 先添加和提交你的本地更改:如果你有任何重要的本地更改,请先将它们添加到暂存区(使用 git add),然后提交(使用 git commit)。
- 拉取远程代码:在提交你的本地更改后,你可以安全地拉取远程仓库的代码(使用 git pull)。Git 会尝试合并这些更改,并在必要时提示你解决冲突。
- 或者使用分支:创建一个新的分支来尝试拉取和合并远程仓库的代码,这样你就可以在不干扰你主分支的情况下进行实验和测试。