资讯专栏INFORMATION COLUMN

Git 基本命令,你都学废了吗

Tecode / 2147人阅读

摘要:掌握了命令行,使用图形化工具如探囊取物。管理的文件状态已修改已暂存已提交。由于我们使用了命令,但并未创建新的分支,所以创建了一个匿名分支。省略远程分支名表示将本地分支推送到与之存在追踪关系的远程分支通常同名。

概述

此篇博文意在让新手快速上手 Git,满足工作中的基本需求,而非梳理细节。后续会再开一个系列,来探讨 Git 细节问题。

一、Git 的安装
这部分网站上资料非常多,根据自己的系统版本查找资料并下载安装包安装即可。
二、初次使用 Git 之前的配置

  1. 配置用户名和邮箱 

git config --global user.name "user_name" git config --global user.email "email_address"
复制代码

  1. 查看配置 

git config --list
复制代码
三、理论基础

  1. 为什么要掌握 Git 命令

可能有很多小伙伴习惯了 Windows 的操作模式,对命令行相对抵触。而且市面上确实有诸如 TortoiseGit、SourceTree 等 Git 图形化工 具,使用体验也还尚可。但正所谓“Git 的设计让使用者觉得自己比想象中的笨”,Git 拥有太多强大的功能,而图形化工具中只封 装了其中的一部分,还是命令行的功能全面。其次,很多老鸟回望来路,都认为 Git 的学习确实需要自底向上的过程。掌握了命令 行,使用图形化工具如探囊取物。反之则不知其所以然,倘若后面遇到问题,就要抓瞎咯。

  1. 这么多差异版本,是如何保存的

SVN 记录原理

SVN 记录的是每一次版本变动的内容。换句话说,SVN 只保存差异。

Git 记录原理

Git 记录的则是将每个版本独立保存。譬如说 File1 有 5 个版本,那就有 5 个对应的拷贝。这种方式看似更浪费空间,但在分支管理上带来了很多便利。

  1. 工作区、暂存区和 Git 仓库

工作区:就是我们存放代码的地方,看得见摸得着。
暂存区:实际上是一个文件,其中保存我们的改动。
Git仓库:最终存放我们所有版本数据的位置。HEAD 指针指向的就是我们最新提交的版本。

  1. Git 的工作流程

在工作目录中增删、修改文件;

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

将暂存区的文件提交到 Git 仓库。

  1. Git 管理的文件状态

已修改(modified);

已暂存(staged);

已提交(committed)。

四、建仓、拉代码、添加到暂存区、提交

  1. 建仓

建立全新项目(空白目录)

在新建的空目录中执行以下命令,即可建仓:
git init
复制代码
建仓之后,可以看到在空白目录中新增了一个 .git 目录。这个目录就是用来跟踪版本迭代的。

已有项目代码建仓

进入项目代码根目录后,执行 git init 即可。

  1. 服务器拉代码

默认方式
git clone 仓库地址
复制代码

拉取指定分支
git clone -b branch_name 仓库地址
复制代码

我们可以通过增加 -b branch_name 选项来指定 clone 的分支

拉取所有分支

  1. 将文件添加到暂存区

新建一个 Readme.txt,内含部分描述信息(这是在工作区发生的)。然后将其添加到暂存区:
git add Readme.txt
复制代码

如果我们修改了很多文件,逐一 add 过于繁琐。此时可以通过如下命令,把工作区的修改一并加入暂存区:
git add -u
复制代码

  1. 将暂存区中的修改提交到 Git 仓库

输入以下命令,将修改提交到 Git 仓库:
git commit -m "log"
复制代码

我们还可以将略过添加暂存区的步骤,直接将文件提交到 Git 仓库:
git commit -am "log"
复制代码

五、查看工作状态和历史提交

  1. 查看状态

我们可以使用以下命令来查看当前的状态:
git status
复制代码

  1. 更新暂存区状态

某个文件已经加入暂存区,但我们又在工作区对其进行了修改,此时可以再次执行 git add,更新暂存区中的状态。

  1. 还原工作区修改

如果我们在工作区修改了某个文件,但这些修改不想要了,那么可以执行以下命令,来还原工作区中的文件:
git checkout -- file_name
复制代码
这里要注意,如果暂存区中有此文件,则会用暂存区的版本来覆盖工作区。如果暂存区中没有此文件,则会以 Git 仓库中的版本来覆盖工作区中的版本。如果想还原成 Git 仓库的版本,则可以先用 :
git reset HEAD file_name
复制代码
 将其从暂存区中移出,然后再使用 :
git checkout -- file_name
复制代码
从而使工作区中的文件还原为 Git 仓库中的状态。

  1. 查看历史提交

我们可以使用 git log 来查看历史提交。commit ID 是根据 sha1 算出来的。为什么不像 SVN 那样,从 1 开始排序?因为 Git 是分布式的,这样会引发冲突。

  1. git log 的常用选项

 --decorate:显示每个commit的引用(如:分支、tag等);

 --oneline:单行显示(简化版 log)

 --graph:以图形化方式查看 commit

 --all:查看所有分支的 commit

六、回到过去

  1. reset 命令——用 Git 仓库中的版本覆盖暂存区

用 Git 仓库中 HEAD 所指版本覆盖暂存区(指定文件)
git reset HEAD file_name
复制代码

用 Git 仓库中 HEAD 所指版本覆盖暂存区(所有文件)
git reset HEAD
复制代码

如何使用 Git 仓库中的其他版本覆盖暂存区
首先,假设我们在工作区的所有修改都 add 并且 commit 了,可以用下图来表示当前状态:

接下来,使用 reset 命令来回滚快照:
git reset HEAD~
复制代码
 ~ 表示HEAD所指版本的前一个版本,~~ 等以此类推。如果 ~ 太多不便表示,可以在 ~ 后加数字来指定
回滚之后的状态如下:

注意,reset 命令实际包含了两个动作:

移动 HEAD 的指向,可以将其指向之前的快照(HEAD 指针的位置发生了改变,所以看 log 时,看不到最后一次提交的信息。要用 git reflog 才能看到所有 log)。
用 HEAD 移动后指向的快照覆盖暂存区。

  1. reset 命令的选项

 --mixed
git reset --mixed HEAD~
复制代码

--mixed 是默认选项,不写也会自动加上
移动 HEAD 的指向,可以将其指向之前的快照。并用 HEAD 移动后指向的快照覆盖暂存区。

 --soft
git reset --soft HEAD~
复制代码

使用 --soft 选项,只移动 HEAD 的指向,使其指向之前的快照,但并不覆盖暂存区中的内容。
这种用法通常用于撤销错误的 commit。

--hard
git reset --hard HEAD~6
复制代码

移动 HEAD 的指向,使其指向之前的快照。并用 HEAD 移动后指向的快照来覆盖暂存区中的内容。此外,还会将暂存区中的文件还原到工作区(也是 HEAD 所指的 Git 仓库版本的状态)。

  1. 使用commit ID 来执行 reset

git reset commit_ID
复制代码
数 HEAD 毕竟麻烦,我们也可以使用commit ID 来指定 reset 到哪个版本(不用全部 ID,足够识别就行了)。

  1. 回滚个别文件

git reset commit_ID file_name
复制代码
回滚个别文件时,HEAD 指针就不移动了。

  1. reset 还可以往前滚

git reset commit_ID
复制代码
 视情况使用 --hard
七、版本对比

  1. 比较工作区和暂存区的差异

git diff
复制代码

  1. 比较两个历史commit

git diff commit_ID1 commit_ID2
复制代码

  1. 比较工作区和 Git 仓库中的commit

git diff commit_ID
复制代码
 commit ID 用 HEAD 这种方式也可以

  1. 比较暂存区和 Git 仓库快照

git diff --cached/--staged [commit ID]
复制代码
 #如果不指定快照ID,则默认和仓库中最新commit比较

  1. diff 功能概览图

八、常用的小技巧

  1. 修改最后一次提交

情景一:代码已经 commit 到仓库,突然想起还有两个文件没有 add。

情景二:代码已经 commit 到仓库,突然想起 log 写得不全面。

执行带 --amend 选项的 commit 命令,Git 就会“更正”最近的一次提交。
git commit --amend   在接下来的界面中可修改 log
git commit --amend -m "new log"    直接提交新 log

  1. 删除文件

git rm file_name
复制代码
此命令删除的只是工作区和暂存区的文件,也就是取消跟踪,下次提交时,不纳入版本控制。已经提交到 Git 仓库的文件是不会删除的,需要移动 HEAD 指针来切掉。
如果误删除,可以使用以下命令来恢复:
git checkout -- file_name
复制代码

工作区和暂存区有差异

如果某个文件在工作区和暂存区的内容不一致,git rm 执行时会报错。我们可以用:
git rm -f file_name
复制代码
这会同时把工作区和暂存区的文件删除。
如果需要只删除暂存区的文件,保存工作区的文件,则可以执行 :
git rm --cached file_name
复制代码

  1. 重命名文件

git mv old_name new_name
复制代码
九、分支与分支管

  1. 什么是分支?为什么要有分支?
  2. 创建分支

git branch branch_name
复制代码
创建 branch_name 分支
git checkout -b branch_name
复制代码
 创建 branch_name 分支,并切换到此分支

  1. 切换分支

git checkout branch_name
复制代码

  1. 查看分支

查看本地分支
git branch -v
复制代码

查看远程分支
git branch -r
复制代码

查看本地分支和远程分支
git branch -a
复制代码

  1. 合并分支

git merge branch_name
复制代码
将 branch_name 分支合并到当前分支。
如果 merge 时提示 conflict,则需要手动解决冲突。Git 会在冲突的文件中加入一些提示。

  1. 删除分支

git branch -d branch_name
复制代码
删除分支后再查看 log,会发现虽然这些分支没有了,但在这些分支上提交的Commit ID依然存在。

  1. 匿名分支

git checkout commit_ID
复制代码
此时是分离头指针状态。由于我们使用了 checkout 命令,但并未创建新的分支,所以 Git 创建了一个匿名分支。既然是匿名分支,如果我们切换到其他分支,匿名分支中的所有操作都会被丢弃。所以我们可以用匿名分支来做些实验,反正没有什么影响。如果想保留匿名分支的操作,可以根据 Git 提示来操作,为其新建一个正式的分支。
8.本地分支与远程分支关联
git branch --set-upstream-to=origin/ local_branch
复制代码
使用git在本地新建一个分支后,需要做远程分支关联。如果没有关联,git会在下面的操作中提示你显示的添加关联。
关联目的是在执行git pull git push操作时就不需要指定对应的远程分支,你只要没有显示指定,git pull的时候,就会提示你。
十、将本地修改推到服务器
前面说过,Git 是分布式的 VCS 工具。我们本地有自己的仓库,服务器端有服务器端的仓库。为了确保其他人 clone 的代码中能包含我们的修改,就要把我们本地的修改推到服务器端。
我们通过 git push 命令,将本地修改推送到服务器端:
git push <远程主机名> <本地分支名>:<远程分支名>
复制代码
通常用 origin 来表示远程主机名。

  1. 省略远程分支名

表示将本地分支推送到与之存在追踪关系的远程分支(通常同名)。如果该远程分支不存在,则会新建。

origin: 远程主机名

master: 本地分支名
git push origin master
复制代码

  1. 省略本地分支名

表示删除远程分支。这一操作等同于推送一个空的本地分支到远程分支。

 origin : 远程主机名

 refs/for/master: 远程分支名
git push origin :dev
复制代码

  1. 同时省略本地分支名和远程分支名

如果当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略,将当前分支推送到origin主机的对应分支。
git push origin
复制代码

  1. 同时省略远程主机名、本地分支名和远程分支名

如果当前分支只有一个远程分支,那么主机名都可以省略:
git push
复制代码

  1. push提示reject的处理方式

如果我们本地的代码不是服务器上最新版本,push 代码时会被拒绝。此时我们要先更新本地代码,再push到服务器
git reset --hard
复制代码
将本地代码恢复到最新commit状态
git pull --rebase
复制代码
 将服务器更新合并到本地
十一、更新本地代码

前文说到,Git 是分布式的 VCS,很多人都会向服务器端 push 修改。接下来看看,我们如何将服务器上的更新同步到本地。

  1. 本地只有 master 分支,且未做修改

此时的本地代码处于 clean 状态,所以可以直接使用 git pull 来更新。

  1. 本地只有 master 分支,且有修改

修改需要保留

此时要先将修改 push 到服务器端,然后再使用 git pull 来更新。

修改无需保留

由于修改无需保留,我们可以使用 git reset --hard 将代码恢复到 clean 状态,然后再使用
 git pull 来更新。

  1. 本地在自有分支上修改

由于我们在自己的分支(假定分支名为 mybranch)上修改,master 处于 clean 状态。此时要分四步处理:

切换到 master 分支:
git checkout master
复制代码

 更新 master 分支:
git pull
复制代码

 切换到 mybranch 分支:
git checkout mybranch
复制代码

 把 master 分支合并到 mybranch 分支:
git merge master

链接:https://juejin.cn/post/6920555318141255688

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/126147.html

相关文章

  • STM32学习——半天学完正点原子入门篇例程,STM32:学会了吗?我:废了

    本文代码均来正点原子标准例程 声明:本文不是教学文章,可能也不适合初学者阅读 不知为什么,最近总蹦出有很多想法(可能是工作太闲了)一会想学这,一会想学那,这不,突然想复习一下STM32了。 我好久以前就学过正点原子的课程,还买过一些开发板,但现在手上只有一个核心板了,就暂且凑合着用吧。 我是个喜欢制定计划的人,既然有了想法,那就得制定一个学习计划,估摸了一下,明天要上班,现在已经中午了,所以我只...

    MingjunYang 评论0 收藏0
  • canvas菜鸟基于小程序实现图案在线定制功能

    摘要:多个页签的显示,其实不难,有现成的组件,于是老夫写代码就是一把梭,撸起袖子就是干,噼里啪啦一顿写,写完一测,没有任何问题,实在是不要太简单,丢给产品预览复制浏览器地址到别的地方粘贴,不能正确回显内需要实现跳转,而且要能返回。 前言 最近收到一个这样的需求,要求做一个基于 vue 和 element-ui 的通用后台框架页,具体要求如下: 要求通用性高,需要在后期四十多个子项目中使用,...

    darkerXi 评论0 收藏0
  • 记一次基于vue的spa多页签实践经验

    摘要:然后类似一样我的命名是可以在页面的任何地方使用,如果你对具体的实现方法有兴趣,欢迎点击本文结尾的链接,去我的仓库上查看。 前言 最近收到一个这样的需求,要求做一个基于 vue 和 element-ui 的通用后台框架页,具体要求如下: 要求通用性高,需要在后期四十多个子项目中使用,所以大部分地方都做成可配置的. 要求做成脚手架的形式.可以 npm 安装 要求实现多页签,并且可以通过浏...

    ispring 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<