【Git】---工作区、暂存区、版本库、远程仓库

工作区、暂存区、版本库、远程仓库

 

一、概念

   1、四个工作区域

Git本地有四个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)、git仓库(Remote Directory)。文件在这四个区域之间的转换关系如下:

    Workspace: 工作区,就是你平时存放项目代码的地方

Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息

    Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本

        Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换

   2、工作流程

git的工作流程一般是这样的:

1、在工作目录中添加、修改文件;

2、将需要进行版本管理的文件放入暂存区域;

3、将暂存区域的文件提交到git仓库。

因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)

   3、文件的四种状态

版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。

GIT不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用

SHA-1算法计算文件的校验和。

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

 下面的图很好的解释了这四种状态的转变:

新建文件--->Untracked

使用add命令将新建的文件加入到暂存区--->Staged

使用commit命令将暂存区的文件提交到本地仓库--->Unmodified

如果对Unmodified状态的文件进行修改---> modified

如果对Unmodified状态的文件进行remove操作--->Untracked

 

二、四个区域常用命令

   1、新建代码库

# 在当前目录新建一个Git代码库
 git init
# 新建一个目录,将其初始化为Git代码库
git init [project-name]
# 下载一个项目和它的整个代码历史
git clone [url]

   2、查看文件状态

#查看指定文件状态
git status [filename]
#查看所有文件状态
git status

    3、工作区<-->暂存区

复制代码
# 添加指定文件到暂存区
git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
git add [dir]
# 添加当前目录的所有文件到暂存区
git add .
#当我们需要删除暂存区或分支上的文件, 同时工作区也不需要这个文件了, 可以使用(⚠️)
git rm file_path
#当我们需要删除暂存区或分支上的文件, 但本地又需要使用, 这个时候直接push那边这个文件就没有,如果push之前重新add那么还是会有。
git rm --cached file_path
#直接加文件名   从暂存区将文件恢复到工作区,如果工作区已经有该文件,则会选择覆盖
#加了【分支名】 +文件名  则表示从分支名为所写的分支名中拉取文件 并覆盖工作区里的文件
git checkout
复制代码

    4、工作区<-->资源库(版本库)

复制代码
#将暂存区-->资源库(版本库)
git commit -m '该次提交说明'
#如果出现:将不必要的文件commit 或者 上次提交觉得是错的  或者 不想改变暂存区内容,只是想调整提交的信息
#移除不必要的添加到暂存区的文件
git reset HEAD 文件名
#去掉上一次的提交(会直接变成add之前状态)   
git reset HEAD^ 
#去掉上一次的提交(变成add之后,commit之前状态) 
git reset --soft  HEAD^ 
复制代码

    5、远程操作

# 取回远程仓库的变化,并与本地分支合并
git pull
# 上传本地指定分支到远程仓库
git push

   6、其它常用命令

  

# 显示当前的Git配置
git config --list
# 编辑Git配置文件
git config -e [--global]
#初次commit之前,需要配置用户邮箱及用户名,使用以下命令:
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
#调出Git的帮助文档
git --help
#查看某个具体命令的帮助文档
git +命令 --help
#查看git的版本
git --version
 

【Git】(2)---checkout、branch、log、diff、.gitignore

常用命令

 

一、命令

     1、checkout 切换分支

复制代码
git checkout 分支名 #切换分支
#如果在当前分支上对文件进行修改之后,没有commit就切换到另外一个分支b,
这个时候会报错,因为没有commit的文件在切换分支之后会不覆盖。所以Git 报错提示。
git checkout -f 分支名 #强制切换到分支
#如果在当前分支上对文件进行修改之后强制切换另一个分支,那么当前分支修改东西直接丢弃,所以-f 参数一定一定要非常非常小心使用,一般情况下不建议使用,除非真的要强制去执行

git checkout - # 切换到上一个分支
git checkout . # 撤销工作区中当前目录中的所有更改
复制代码

   2、branch 查看新建分支

复制代码
 git branch     # 列出所有本地分支
 git branch -r  # 列出所有远程分支
 # 新建一个分支,但依然停留在当前分支 这个时候本地已经有新分支了,但远程还没有,只有切换到新分支push后,远程就有了
 git branch [branch-name]
 git checkout -b [branch]     # 新建一个分支,并切换到该分支 
 git branch -d [branch-name]  #删除分支 已合并的分支 *不能删除当前所在的分支
 git branch -D dev            #强行删除分支  分支未合并
 git push origin --delete [branch-name] # 删除远程分支
复制代码

   3、log 查看提交记录

git log -数字    #表示查看最近几次的提交
git log -p -2    #显示最近两次提交的不同点
git log --author #查看具体某个作者的提交
git log --online #输出简要的信息

   4、merge 合并分支

git merge [branch] #合并指定分支到当前分支

   5、diff 解决冲突 制作补丁

合并分支时,如果两个分支都对同一文件进行修改,那么合并的时候就会有冲突。

git diff HEAD  #比较当前工作区和上一次提交时文件的差异
git diff HEAD^ #比较上一次提交和上上次提交的文件差异
git diff 分支名 #查看当前分支跟指定的分支的差异
git diff 分支名1 分支名2  #查看两个指定分支(已提交的)的差异,分支2 跟分支1的差别
git diff --name-only --diff-filter=U #查看冲突文件 这个太有用啦

HEAD用法

   HEAD 最近一个提交

   HEAD^ 上一次提交

  HEAD^ ^ 上一次的 上一次的提交(倒数第三次)

  HEAD^^^ 倒数 第四次的 提交

   6、reset 版本回退

语法:git reset --hard 版本号 注意:回退只是在本地进行回退,远程仓库还是最新的,所以之后要先pull

git reset --hard HEAD^   #将 Git 回退到上一个版本 也就是上上次提交的时候,这样就可以撤销当次提交的信息
git reset --hard 4b2a0c8 #版本号(commit id)没必要写全,一般写前七位就够了,Git会自动去匹配。

 

二、.gitignore 文件

      大量与项目无关的文件全推到远程仓库上,同步的时候会非常慢,且跟编辑器相关的一些配置推上去之后,别人更新也会受其影响。所以,我们使用该文件,

对不必要的文件进行忽略,使其不被git追踪。

     一把情况下,.gitignore文件,在项目一开始创建的时候就创建,并推送到远程服务器上。这样大家初次同步项目的时候,就是用到该文件,避免以后,团队

成员把与项目无关的文件,传到远程服务器上。

复制代码
*.log           #表示忽略项目中所有以.log结尾的文件
123?.log        #表示忽略项目中所有以123加任意字符的文件
/error.log      #表示忽略项目中根目录中的error.log 这个文件
src/main/test/* #表示忽略/src/main/test/目录下的所有文件
**/java/        #匹配所有java目录下的所有文件
!/error.log     #表示在之前的匹配规则下,被命中的文件,可以使用!对前面的规则进行否定
复制代码

对于已经提交到远程或本地仓库的文件,.gitignore配置之后不会生效。我们必须先删除本地暂存区里的文件,之后在加上.gitignore 文件,最后再把变更提交到远程仓库上。

git rm --cached 文件名     #从暂存区删除某个文件
git rm -rf --cached 文件夹 #表示递归删除暂存区该文件夹的所有东西

 

三、案例

   1、commit后,需要回到上一个版本,这个版本数据全部不要

(1)为保险起见,我们可以先切一个分支出来,保存当前版本,必然以后🈶️需要这个版本,又要重新开发

   git checkout -b [branch]

(2)先本地代码回到上上次提交的版本

   git reset --hard head^

  (3) 提交本地代码到远程

如果你在直接add,commit后直接 git push。会报错

err: Updates were rejected because the tip of your current branch is behind

因为远程本地分支回滚后,版本将落后远程分支,所以你要先pull最新的,在push,这就很尴尬,因为最近一次提交的代码我都不想要了干嘛还要拉到本地

所以你只能强制提交 这是个非常危险的命令,因为它会把该版本之前commit的数据全部丢失

   git push -f

  2、你在master修改代码,却需要把修改后代码推送到dev远程分支上

(1)在master上

   git add .

   git commit -m "本次提交说明"

(2)切换到dev分支

   git checkout dev

(3)合并master

   git merge master

  (4) dev分支提交代码 需要重新 add 和 commit

   git push

 

Git五个常见问题及解决方法

一、删除远程仓库上被忽略的文件

由于种种原因,一些本应该被忽略的文件被我们误操作提交到了远程仓库了。那么我们该怎么删除这些文件呢?

以误提交了.idea目录为例,我们可以通过下面的步骤处理:

1)我们首先应该清除暂存区的.idea文件,执行命令

# -r代表删除的是文件或者文件夹   --cached 只清除暂存区不清除工作区的
git rm -r --cached .idea

2)在 .gitignore 文件,添加需要忽略的文件。

.idea

之后在提交,就会删除.idea相关文件

git commit -m '提交信息'
git push

git rm 与 git rm --cached 的区别

git rm : 同时从工作区暂存区删除文件。即本地的文件也被删除了。

git rm --cached : 从暂存区删除文件。但是本地文件还存在,只是不希望这个文件被版本控制。

上面的 .idea文件 显然我自己工作区是不能删除的,只能删除暂存区,所以需要加上 --cached

如图

 

二、代码开发一半,有新任务了

当你正在巴拉巴拉开发某个需求的时候,你只完成了一半。这时,你又接到了另外一个需求,急需进行开发,之前那个需求可以先放一放。你又不想把它 git commit提交到版本库,也就是说工作区或者暂存区中有一些你并不想提交到版本库的代码。

这个时候又该怎么办呢?

你就可以使用 git stash 命令来解决这个问题。

  1. 首先,将工作区暂存区中的修改,存储到堆栈
# -u 表示还要存储工作区中新增的文件,如果不加u只会存储工作区中已经存在的文件的修改
git stash save -u "需求 a 只完成了一半"

这样,工作区和暂存区就都干净了。

我们也可以查看堆栈中的 stash 列表。(由于我们只 git stash 存储了一次,故堆栈中只有一个 stash)

$ git stash list
stash@{0}: On main: 需求 a 只完成了一半

也可以查看,stash中存了哪些内容

git stash show

2) 然后,就可以在当前的 dev 分支中,优先完成需求 b

如果需求 b 已开发完成,就将其提交到版本库。

git add .
git commit -m "需求 b 已完成"
# 推送到远程的 dev 分支
git push origin dev

3) 最后,我们将堆栈中的 stash 弹出,应用到当前的工作区

git stash pop

继续完成需求 a 中未完成的工作。如果需求 a 也完成了,也将其提交到版本库。

git add .
git commit -m "需求 a 也完成"
# 推送到远程的 dev 分支
git push origin dev

这就大功告成。


三、git pull代码冲突

当你提交代码的时候,想先 pull一下代码时你发现

$ git pull
error: Your local changes to the following files would be overwritten by merge:
        src/main/java/com/open/demo/beans/AppReqParmVO.java
Please commit your changes or stash them before you merge.
Aborting

很明显你本地修改的代码与他人修改提交的有冲突了。文件都告诉你了 AppReqParmVO.java

如何解决?

1)先把本地代码存储起来

git stash

2)然后再去pull远程代码

$ git pull
Updating 5b82c67..3d844c3
Fast-forward
 src/main/java/com/open/demo/beans/AppReqParmVO.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

发现已经不报错了,能够正常 pull下来。

3)最后再把本地存储的代码释放出来

$ git stash pop
Auto-merging src/main/java/com/open/demo/beans/AppReqParmVO.java
CONFLICT (content): Merge conflict in src/main/java/com/open/demo/beans/AppReqParmVO.java

释放出来,这里也告诉你有冲突,然后手动解决下冲突,就可以正常提交了。


四、合并分支发生的冲突

上面的问题是同一分支,拉取代码引起的冲突,而这里是在两个分支进行合并的时候,出现了冲突。

比如现在有两个分支,你在dev修改了一个文件后提交成功,而master分支也改了同一个文件也提交成功了,这个时候当你将dev合并到master的时候,你发现合并不了,出现冲突了,这种问题实际开发中也挺常见的。

这里在dev合并到master发生冲突

1)、从dev切到master分支

git checkout master

2)、合并dev

git merge dev

如果有冲突那么就会告诉你哪些文件冲突

$ git merge dev
Auto-merging src/main/java/com/open/demo/beans/AppReqParmVO.java
CONFLICT (content): Merge conflict in src/main/java/com/open/demo/beans/AppReqParmVO.java
Automatic merge failed; fix conflicts and then commit the result.

那你只需找到当前冲突文件,解决冲突即可。

<<<<<<< HEAD
    private final   long serialVersionUID = -1206184202179044275L;
=======
    private  long serialVersionUID = -1206184202179044275L;
>>>>>>> dev

修改完重新提交就可以了。


五、master修改代码,推送到dev

你在master修改代码,却需要把修改后代码推送到dev远程分支上

1)、在master上

   git add .
   git commit -m "本次提交说明"

2)、切换到dev分支

git checkout dev

3)、合并master

git merge master

4)、推送到主仓库

git push

如果dev分支提交代码 需要重新 add 和 commit。

posted @ 2022-02-21 19:05  hanease  阅读(744)  评论(0编辑  收藏  举报