git版本控制、本地仓库、远程连接等操作分析

一、Git基本操作

1.1 配置

git是一个分布式版本控制系统,这意味着每个人的电脑上都是一个完整的版本库,我们不再需要将代码上传至”中央服务器上“,每个人电脑里都有完整的版本库,某一个人的电脑坏掉了问题不大,从其他人那里复制一个就可以了。

  1. 首先在官网上下载并安装,教程太多了。
  2. 在上传某个项目的代码时,需要在文件夹内配置个人信息,这里的用户名和密码表示的是你在github或是gitee上的账号信息。
//因为Git是分布式版本控制系统,所以每个机器都必须自报家门:你的名字和Email地址
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

​ 注意:git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

  1. 配置git环境变量,这个网上教程也太多了。

1.2 创建版本库

1.2.1 创建空文件夹

mkdir Ryuko_learn_git
cd Ryuko_learn_git

1.2.2 初始化仓库

# 初始化本地仓库
git init

此时文件夹内会创建一个空的仓库,并且目录下多了一个.git的隐藏目录,这个目录是Git来跟踪管理版本库的。

1.3 Git 常用操作

1.3.1 git status

git status命令可以让我们时刻掌握仓库当前的状态。

1.3.2 git add

git add <filename>可以把文件从工作区(编写代码的地方)添加到暂存区。

1.3.3 git commit

`git commit -m 'message’可以把文件从暂存区提交到本地仓库。

-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

1.3.4 git remote add

git remote add origin https://github.com/..表示添加远端仓库到本地,这句话的意思是将后面的仓库地址保存到本地仓库,origin是给这个地址起的别名。

1.3.5 git push --set-upstream

git push --set-upstream origin master:master的意思是,push到名字为origin的远程仓库,这个名字指的是我们在1.3.4中为仓库起的别名。

master:master的意思是把本地仓库的master(左)分支推到远程仓库的master分支(右),因此如果是 git push --set-upstream origin a:b 意思是把本地的a分支推到远程的b分支;–set-upstream 可以记住本次推送,下次推送可以直接选择 git push。

本节开头的例子可以简写为:git push -u origin master

二、版本控制

2.1 状态跟踪

首先在github上面创建一个仓库,然后建立本地和远程仓库的连接。

我用的是以前的项目来举例,所以就不再介绍如何建立连接了。

下面进入正文。

我们在刚刚拿到团队仓库中的代码后进行编码操作,新建文件夹的时候会发现,这个文件的尾部会有一个绿色的U,将a.js的状态表示为U (untracked)表示当前文件还没有加入到版本库(版本库不会记录当前文件的提交和修改)

在这里插入图片描述

由于版本库不会记录提交和修改,所以我们在这个文件中无论如何输入代码,都不会改变它(untracked)的状态

在这里插入图片描述

此时当我们使用 git add a.js之后,a.js状态为A(added),表示当前文件加入到暂存区

当我们修改a.js之后,a.js状态为M (modified),表示当前文件被修改了

在这里插入图片描述

当文件修改之后,仍然需要调用git add命令将修改的东西提交到暂存区(此时文件状态变为A

我们可以使用git commit命令将暂存区的修改提交到分支

当出现冲突的时候,状态为c (conflict),此时我们要解决冲突,不过这两点我放在后面介绍。

2.2 查看历史版本

通过git log可以看到每一次commit提交后的版本信息

在这里插入图片描述

通过git log --pretty=oneline可以将上述信息压缩为一行展示:

在这里插入图片描述

2.3 版本回退

在上一节的图片中有这样一句话HEAD -> master,在git中通过git reset --hard [回退级数]进行版本回退

  • HEAD表示当前版本
  • HEAD^表示上一个版本
  • HEAD~100表示往上100个版本

​ 在这里通过git reset --hard HEAD~2回到两个版本以前,也就是删除文件 README.en.md这里:

在这里插入图片描述

由于当时我的项目中只有README文件,所以版本回退时,工作区的内容只显示当时存在的文件,其他的文件(后续提交中编写的文件)由于当时并不存在,所以并不显示出来:

在这里插入图片描述

git reset一共有三个参数:

  • git reset --hard HEAD^:将工作区、暂存区、本地仓库的改变全都丢失,即代码的修改内容丢失
  • git reset --soft HEAD^:回退到git commit之前,此时处在暂存区。(即执行git add 命令后)
  • git reset --mixed HEAD^(默认):就等于 git reset HEAD 回退到工作区,即git add 之前

2.4 版本还原

在我们回退到以前版本的时候,回退操作倒是成功实现了,可是git log打印提交信息的时候发现,后续的版本看不到了!(见2.3中图1),如果我们想要回到最新版本该怎么办呢?

git提供了一个命令git reflog用来记录你的每一次命令:

在这里插入图片描述

使用下面命令就可以指定回到未来的某个版本:

git reset --hard b56a
// 版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。

现在成功回到最新版本:

在这里插入图片描述

git的版本回退速度非常快,因为git在内部有个指向当前版本的 HEAD指针,当你回退版本的时候,git仅仅是把HEAD的指向改变了。现在回到工作区看看,最新的代码已经回来了!

在这里插入图片描述

三、工作区,本地仓库,暂存区

在前面的章节中,我用上了工作区版本库暂存区等概念,现在整体介绍一下。

3.1 工作区

指在电脑里能看到的目录,平时你通过vscode打开某个文件夹写代码,此时的代码就写在工作区中。

3.2 暂存区和本地仓库

工作区有一个隐藏目录 .git,这个不算工作区,而是Git的版本库。

git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

在这里插入图片描述

3.3 编码详解

3.3.1 本地提交

修改a.js,然后通过git status看一下状态:

在这里插入图片描述

使用git add .之后再看看状态:

在这里插入图片描述

现在a.js文件被添加到了缓存区(stage)中,之后通过git commit就可以一次性把暂存区的所有修改提交到分支。

一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

在这里插入图片描述

3.3.2 撤销工作区修改

继续修改a.js,当我们准备提交代码的时候,发现其中某行代码发生了错误,想要撤回到之前没有修改过的状态。

我们使用 git status命令查看一下:

在这里插入图片描述

你可以发现,git提供了一个指令:git restore <file>可以丢弃工作区的修改。(也可以使用git checkout -- file丢弃修改)

git checkout -- a.js意思就是,把a.js文件在工作区的修改全部撤销,这里有两种情况:

​ 一种是a.js自修改后还没有被放到暂存区,现在撤销修改就回到和版本库一模一样的状态;

​ 一种是a.js已经添加到暂存区后同时作了修改,现在撤销修改就回到添加到暂存区后的状态。

​ 总之,就是让这个文件回到最近一次 git commitgit add时的状态。

3.3.3 撤销暂存区修改

假如我们在a.js中做了修改,并且使用 git add到暂存区了,接下来我们使用 git status查看一下,修改添加到了暂存区,还没有commit。接下来Git告诉我们,用命令 git git restore --staged <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区。

在这里插入图片描述

3.3.4 删除本地仓库文件

要从版本库中删除该文件,那就用命令git rm删掉,并且git commit

git rm a.js
git commit -m "remove a.js"

现在,文件就从版本库中被删除了。

​ 另一种情况是删错了,没有commit,此时版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

git reset
git checkout -- a.js

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

四、远程分支管理

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

​ 现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样既安全,又不影响别人工作。

4.1 分支的创建和管理

​ 首先,我们创建dev分支,然后切换到dev分支:

// git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
// git branch dev
// git checkout dev
git checkout -b dev

然后,用 git branch命令查.看当前分支:

//  git branch命令会列出所有分支,当前分支前面会标一个*号
git branch

// 输出
* dev
  master

然后我们就可以在dev分支上正常提交,需要注意的是,此时如果切回到master分支:

git checkout master

切回到master分支后,会发现刚刚在dev分支修改的内容消失掉了,因为那个提交是在dev分支上,而master分支此刻的提交点并没有变。现在我们将dev分支上的内容合并到maste分支上:

git merge dev

此时在master分支中成功合并了dev分支中的修改内容。

4.2 解决分支合并冲突

产生冲突问题的根本原因在于多个人同时修改了同一个文件。

我们在使用版本控制工具管理源代码的时候,冲突问题不可避免。要解决冲突问题的最好方案就是多个人不要同时修改同一个文件(分工明确)。

<<<<<<< HEAD
console.log("hello world")
=======
console.log("Ryuko_黑猫几绛")
>>>>>>> 0755800755f210e82e4d3f364760a7fb6922846c

出现了冲突问题之后,我们只要把<<<<< ==== >>>>>删掉,保留正确代码,再add commit pull push就可以了

4.3 推送和抓取分支

git push origin dev2   //向服务器推送dev2分支
git checkout -b dev3 origin/dev2   //从服务器抓取dev2分支 放在本地dev3分支上

还有一种可能是分支推送冲突,比如:

你的小伙伴已经向 origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:

// 修改dev分支下的c.js
console.log("张三修改dev分支下的c.js")
// 向dev分支提交修改
git add a.js
git commit -m "张三修改dev分支下的c.js"
// 推送到远程仓库的dev分支
$ git push origin dev
// 推送报错
To github.com:mazg1987/learngit.git
 ! [rejected]        dev -> dev (fetch first)
error: failed to push some refs to 'git@github.com:mazg1987/learngit.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

​ 推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后在本地合并,解决冲突再推送:

git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:mazg1987/learngit
   5d981b2..5f6d427  dev        -> origin/dev
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> dev

// 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>

五、忽略配置文件

在项目目录下新建一个 .gitignore文件,在改文件中添加 不需要上传到服务器文件和文件夹,模板例如:

.DS_Store
node_modules/
dist/

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode

# local env files
.env.local
.env.*.local

猜你喜欢

转载自blog.csdn.net/flow_camphor/article/details/125751873
今日推荐