乐趣区

关于git:工作中的-git-详解

概述

始终想写一下 git 的笔记, 只是都没有工夫去做, 只能闲暇的时候缓缓的补齐了;

毫无疑问, git 是目前最优良的分布式版本控制工具, 没有之一; 作为一个码农, git 曾经是一项必备的技能了, 许多优良的社区都是基于 git 去做的版本控制; 比方寰球最大的程序猿同性交友网站 github ;

git 有很多种应用形式, 咱们能够应用 git bash 这种命令行模式, 也能够应用 TortoiseGit 或者是 SourceTree 这样的 GUI 工具, 这些 GUI 工具也能提供多种性能; 而集体还是比拟偏向于命令行的形式, 第一个是逼格比拟高, 第二个是大多数的 GUI 软件都只实现了 git 所有性能的一个子集以升高操作难度; 命令行的模式下能力执行所有的 git 命令, 尽管大多数是开发中用不到的;

装置和配置

git 的装置也是比较简单的, git 下载官网 找到和操作系统绝对应的版本, 一路 next 就能够了;

装置完之后, 快捷菜单外面会呈现 Git GUI HereGit Bash Here; 咱们能够关上 Git Bash, 在命令行界面外面输出:

$ git --version

  git version 2.18.0.windows.1

能呈现 git 的版本号, 就示意咱们的 git 曾经装置胜利; 咱们前面所有的操作都是基于 Git Bash 来进行的;

装置实现之后, 咱们能够应用 git 来获取 git 的降级:

$ git clone git://git.kernel.org/pub/scm/git/git.git

初始化配置

git 自带一个 git config 的工具来帮忙设置 git 的外观和行为的配置变量;
当装置完 git 之后, 应做的第一件事就是设置用户名和邮件地址;

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

因为 git 是分布式管理系统, git的每一次提交都会记录上用户名和邮箱, 并且不可批改; 须要留神的是 --global 选项只有运行一次, 之后无论在改零碎上做任何事件, 都会应用 global 的配置; 当然也能够对某个仓库指定不同的用户名和 Email 地址.

文本编辑器

git会应用操作系统默认的编辑器, 通常是 vim, 如果想应用其余的编辑器, 能够这样设置:

$ git config --global core.editor emacs

查看配置项

如果想要查看配置项, 能够应用 git config --list 命令来列出所有 git 能找到的配置;

$ git config --list

  core.symlinks=false
  core.autocrlf=true
  core.fscache=true
  color.diff=auto
  color.status=auto
  ...

也能够应用 git config <key> 来查看某一项的配置:

$ git config user.name

Git 版本库

版本库又名仓库, 英文名 repository, 能够了解为版本库就是一个目录, 这个目录外面的所有文件都能被 git 治理, 每一个文件的增, 删, 改都会被 git 跟踪, 以便任何时候都能够找到文件记录;

创立版本库有两种办法, 第一种是通过 git init 把以后文件夹变成一个 git 能够治理的仓库; 第二个是间接 clone 一个已有的仓库;

创立版本库

进入到一个空的目录下, 通过鼠标右键的菜单关上 bash 并输出:

$ git init

执行完 init 之后, 文件夹外面会多一个 .git 的暗藏文件夹, 如果没看到这个文件夹, 能够设置文件夹属性; 这个目录是 git 用来记录文件版本用的, 个别都不会去批改;

这个时候, 咱们只是做了一个初始化的动作, 目录外面的文件还没有被追踪, 能够应用 git add <file> 命令来实现对文件的追踪, 而后执行 commit 提交;

$ git add reademe.txt 
$ git commit -m "首次提交的内容"      

git add 命令就是将文件增加到仓库, 能够一次增加多个文件只须要在参数前面增加文件名而后按 tab键; 也能够一次增加全副文件, 应用 git add * 或者是 git add --all命令;

克隆仓库

如果想要取得已存在的 git 仓库的拷贝, 为某个开源我的项目奉献本人的一份力量, 这个时候就要用到 git clone <url> 命令:

$ git clone https://gitlab.com/Scorpio-nan/myproject

这将把近程的仓库克隆到本地, 并创立一个 myproject 的 git 仓库;

git 反对多种数据传输协定, 下面的例子就是用的 https:// 协定, 不过也能够应用 git:// 协定或者是 SSH 传输协定;

查看文件状态

git 目录上面的文件都只有两种状态: 已跟踪或者未跟踪. 已跟踪的文件都是指那些曾经被纳入版本控制的文件, 在日志中都有它们的记录, 在工作一段时间后, 它们的状态可能处于未修改, 已批改或已放入暂存区.

要查看哪些文件处于什么状态, 能够用 git status 命令; 当初, 咱们在目录上面新建一个 README.txt文件, 如果之前并不存在这个文件, 应用 git status就会看到一个未追踪的文件;

$ git status

  On branch master
  No commits yet
  Untracked files:
    (use "git add <file>..." to include in what will be committed)
          README.txt
  nothing added to commit but untracked files present (use "git add" to track)

在下面的文件状态中, 咱们能够看到新建的 README文件呈现在 Untracked files 上面; 示意该文件还没有被纳入 git 的版本控制;

增加文件

应用 git add <key> 命令开始追踪一个文件;

$ git add README.txt

当初, 咱们再一次查看文件状态, 能够看到文件 README.txt 曾经被追踪, 并处于暂存状态;

$ git status

  On branch master
  No commits yet
  Changes to be committed:
    (use "git rm --cached <file>..." to unstage)
          new file:   README.txt

只有在 Changes to be committed 这行上面的, 就阐明是已暂存状态.

暂存批改文件

当初, 咱们来批改一个曾经被追踪的文件; 在 README.txt 外面增加一些内容, 并查看文件状态;

$ git status

  On branch master
  No commits yet
  Changes to be committed:
    (use "git rm --cached <file>..." to unstage)
          new file:   README.txt
  Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)
          modified:   README.txt

Changes not staged for commit 阐明文件内容曾经产生了变动, 然而还没有增加到暂存区, 要更新到暂存区, 须要再一次执行 git add 命令;

git status命令的输入非常具体, 然而详细信息有些繁琐, 咱们还能够应用 git status -s 或者是 git status --short命令来查看状态;

$ git stauts -s

  AM README.txt
  • ?? 示意新增加, 还没追踪的文件;
  • A 示意新增加到暂存区中的文件;
  • M 示意批改过的文件;
    M 有两个能够呈现的地位, 右边示意文件被批改了并放入了暂存区; 左边示意文件被批改了, 然而还没增加到暂存区;

疏忽文件

有些时候, 咱们必须把文件放到 git 的目录中, 但又不能提交它们; 在这种状况下, 咱们能够创立一个 .gitignore 的文件, 列出须要疏忽的文件列表, 每次操作的时候 git 就会疏忽这些文件;

残缺的 .gitignore 配置详见 gitignore;

咱们在开发 vue 我的项目的时候, 如果是用的 git 来治理版本, 咱们能够在 .gitignore 外面增加如下内容;

dist
node_modules

当咱们每次执行增加和提交操作的时候, git 就会主动疏忽我的项目的开发依赖;

查看批改

git status 命令能够查看文件状态, 然而不能残缺的查看文件批改了哪些内容, 这个时候, 咱们就能够应用 git diff 命令来查看文件具体产生了哪些扭转;

$ git diff

  diff --git a/README.txt b/README.txt
  index 4632e06..5737925 100644
  --- a/README.txt
  +++ b/README.txt
  @@ -1 +1 @@
  -123456
  \ No newline at end of file
  + 轻易写点什么;
  \ No newline at end of file

此命令比拟的是工作目录中以后文件和暂存区域快照之间的差别, 也就是批改之后还没有暂存起来的变动内容

提交更新

每次提交更新之前, 最好都先应用一下 git status 查看一下文件状态, 肯定要确认还有什么批改的或新建的文件没有 git add 过, 否则提交的时候不会记录这些文件的变动;

$ git commit -m "首次提交 2019 年 9 月 6 日 11:25:11"

  [master (root-commit) 424efbe] 首次提交 2019 年 9 月 6 日 11:25:11
   2 files changed, 4 insertions(+)
   create mode 100644 .gitignore
   create mode 100644 README.txt

git commit 命令, -m 前面的输出是本次提交的日志, 相似于 svn 提交信息, 能够输出任何内容, 但最好是有意义的, 这样咱们就能从历史记录外面不便的查找到批改的记录;

删除文件

要从 git 中移除某个文件, 就必须要从暂存区移除, 而后提交; 能够应用 git rm <file> [param] 命令实现操作;

如果只是简略的从目录外面手动删除文件, 运行 git status 时就会在 Changes not staged for commit 看到:

$ git status

  On branch master
  Changes not staged for commit:
    (use "git add/rm <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)
          deleted:    test.txt
  no changes added to commit (use "git add" and/or "git commit -a")

而后运行 git rm 记录此次移除的操作

$ git rm test.txt

  rm 'test.txt'

$ git status
  On branch master
  Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
          deleted:    test.txt

下次提交的时候就不会纳入版本治理了;

rm 前面的参数能够是单个的文件, 也可是整个文件夹, 然而要留神的是如果是删除文件夹, 就须要在前面增加 -r 参数:

$ git rm dir -r

查看历史记录

在提交了屡次更新后, 咱们能够通过 git log <key> 命令来查看以后我的项目的提交日志;

$ git log
  commit d9fcc0f21f254c59f13d302f77f608d573c51e09 (HEAD -> master)
  Author: Hope <2639319517@qq.com>
  Date:   Fri Sep 6 13:38:53 2019 +0800
      45546

  commit 379abcbace5c87823c3ab51ff54efcd20deaa487
  Author: Hope <2639319517@qq.com>
  Date:   Fri Sep 6 11:30:30 2019 +0800
      增加批改后的文件 2019 年 9 月 6 日 11:30:29

  commit 424efbec89f2ebc759866b03053bcf074b33b453
  Author: Hope <2639319517@qq.com>
  Date:   Fri Sep 6 11:25:12 2019 +0800
      首次提交 2019 年 9 月 6 日 11:25:11

默认不必任何参数的话, git log 会按提交工夫列出所有的更新, 最近的更新排在最下面;

git log 有许多选项能够抉择, 这里列举一些罕用的选项;

  • git log -p -2 -p 用来显示每次提交内容的差别; 也能够加上 -2 来仅显示最近两次提交;
  • git log --pretty=oneline --pretty 能够指定应用不同于默认格局的形式展现提交历史; oneline将每个提交放在一行显示; 另外还有 short, fullfuller 能够用;
  • git log --stat --stat 查看每次提交的简略的统计信息;
  • git log --shortstat --shortstat 只显示 –stat 中最初的行数批改增加移除统计
  • git log --name-only --name-only 仅在提交信息后显示已批改的文件清单
  • git log --name-status --name-status 显示新增、批改、删除的文件清单
  • git log --graph --graph 显示 ASCII 图形示意的分支合并历史

撤销操作

在任何阶段, 咱们可能都须要撤销某些操作; 当初, 咱们在 README.txt 外面批改一些内容, 并用 git status 命令查看一下:

$ git status
  On branch master
  Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)
          modified:   README.txt
  no changes added to commit (use "git add" and/or "git commit -a")

git 会通知咱们文件曾经被批改, 本次批改还未增加到暂存区; 并且提醒能够应用 git add <file>...更新操作 和 git checkout -- <file>...抛弃本次批改;

接下来, 对该文件应用撤销操作后, 再一次查看文件状态(也能够手动关上 README.txt 文件, 查看文件内容):

$ git checkout README.txt
$ git status

  On branch master
  nothing to commit, working tree clean

刚刚批改过的文件就还原到了批改之前的状态;

git checkout 命令还能够增加 -- 参数, 示意把 README.txt 文件在工作区的批改全副撤销, 这里分两种状况:

  • 一种是 README.txt 自批改后还没有被放到暂存区, 当初, 撤销批改就回到和版本库截然不同的状态;
  • 一种是 README.txt 经增加到暂存区后, 又作了批改, 当初, 撤销批改就回到增加到暂存区后的状态;

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

如果被批改的文件曾经执行了 git add 增加操作, 但还未 commit 咱们还能够应用 git reset HEAD <file> 把暂存区的文件批改撤销掉, 还原到工作区;

$ git reset HEAD README.txt

  Unstaged changes after reset:
  M       README.txt

git reset 命令既能够回退版本, 也能够把暂存区的批改回退到工作区. 当咱们用 HEAD 时, 示意最新的版本; 再用 git status 看一下, 就能够看到文件回到了 git add 之前的状态;

总结:
    1. 如果想要抛弃工作区的批改, 应用 git checkout -- file 命令;
    1. 批改的内容被增加到了缓存区, 想要抛弃批改, 须要先执行命令 git reset HEAD <file> , 就回到了 1. 的操作步骤, 而后再执行 git checkout -- file 命令;

版本回退

下面的查看历史的章节外面, 咱们能够看到, 执行git log 命令的时候, 日志的签名都会有一长串数字和字母组合的字符串, 相似这样的 f4c0417dd64876552e17ff63dcb76c2baa33feee;

SVN 不一样的是, SVN每次提交的日志 (也能够称之为版本号) 都是累加的, 而 gitSHA1 计算出来的一个十分大的数字, 用十六进制示意;

在日常工作中, 如果咱们不小心将批改谬误的文件提交到了近程仓库上, 咱们也能够借助 git 的版本回退命令将版本退回到之前的某一个版本;

首先, git 必须晓得以后版本是哪个版本, 在 git 中, 用 HEAD示意以后版本, 上一个版本就是 HEAD^, 上上一个版本就是 HEAD^^… 再往上 N 多个版本, 写 ^ 比拟容易数不过去, 能够间接用 HEAD~n 来代替, 这里的 n 指的是具体数值;

当初, 咱们要把以后版本退回到上一个版本就能够间接应用:

$ git reset --hard HEAD

 HEAD is now at b560ce1 批改.md 外面的文件内容

如果咱们的日志外面记录的版本十分的多, 而且, 上一次回退版本之前的新版本也找不到了, 这个时候如果 bash 还没有被敞开的话, 咱们还能侥幸的看到之前新版本的版本号; 咱们能够应用 reset 命令回退到之前的新版本;

$ git reset --hard f4c041

  HEAD is now at f4c0417 提交批改

--hard 前面接的是版本号, 不必写全, 只须要输出版本号的后面几位, git 就会主动去找到残缺的版本号;

然而, 下面的回退操作是在 bash 还没有被敞开的时候, 咱们还能通过操作记录查找到之前的操作, 然而, 当咱们应用 $ git reset --hard HEAD^ 回退版本的时候, 如果是敞开掉 bash 或者是敞开了电脑, 想要再复原到之前的版本, 就必须找到之前版本的版本号;

所幸, git 还为咱们提供了一个 git reflog 命令, 用来记录每一次的命令:

$ git reflog
  f4c0417 (HEAD -> master, origin/master) HEAD@{0}: reset: moving to f4c041
  f4c0417 (HEAD -> master, origin/master) HEAD@{1}: reset: moving to HEAD
  f4c0417 (HEAD -> master, origin/master) HEAD@{2}: commit: 提交批改
  b560ce1 HEAD@{3}: commit: 批改.md 外面的文件内容
  2872d97 HEAD@{4}: initial pull 

这个时候, 咱们又能够应用 reset 命令来指定回退到哪一个版本了;

近程仓库

为了能在任意 Git 我的项目上合作, 咱们得须要晓得如何治理本人的近程仓库; Git 是分布式版本控制系统, 同一个 Git 仓库, 能够散布到不同的机器上; 前面咱们能够本人搭建一台运行 Git 的服务器;

不过现阶段, 为了学习应用 git, 咱们能够先应用 Github 收费的仓库托管服务来获取咱们的近程仓库, 这个章节也是 git 关联咱们的近程仓库的最佳实际;

Github 的应用也是比较简单, 咱们只须要在 Github 下面注册一个账号, 就能够收费应用了;

增加近程仓库

本章节是将后面根本的 git 的指令联合起来的实际章节; 咱们会从 0 开始创立一个近程仓库;

首先, 在咱们的磁盘上找到一个空的目录, 而后执行以下命令:

$ mkdir GithubTest
$ cd GithubTest/
$ git init

这个时候, 咱们就在本地曾经创立了一个 git仓库; 而后咱们关上 Github 并登入;

登入胜利之后, 能够看到右上角下面有一个 + 图标, 抉择 New repository, 会呈现上面的表单项:

[外链图片转存失败, 源站可能有防盗链机制, 倡议将图片保留下来间接上传(img-1ogCGLg9-1627108169032)(/img/createRepository.png)]

创立实现之后, 咱们能够看到一个空的仓库就创立好了, 并且还为咱们主动创立了 3 个文件, .gitignore , LICENSE , README.md;

如果不做任何操作的话, 这个仓库货默认将 README.md 文件作为主页; .md 文件是 markdown 的缩写;

(强烈推荐应用 marckdown 语法来写笔记或者是博客);

[外链图片转存失败, 源站可能有防盗链机制, 倡议将图片保留下来间接上传(img-E8xPCXBR-1627108169035)(/img/repository.png)]

做完以上操作之后, 咱们能够将生成的 git 地址复制进去, 并切换到咱们本地的 bash 命令行中来, 在命令行中输出一下命令:

$ git remote add origin https://github.com/Scorpio-nan/GithubTest.git

增加实现之后, 近程仓库的名称就是 origin , 这个是 git 的默认叫法, 也能够改成别的;

因为咱们在 Github 创立的仓库不是一个空的仓库, 咱们需先执行一下 git pull <name> [param] 命令, 将近程仓库的内容拉取到本地;

$ git pull origin master

  remote: Enumerating objects: 5, done.
  remote: Counting objects: 100% (5/5), done.
  remote: Compressing objects: 100% (4/4), done.
  remote: Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
  Unpacking objects: 100% (5/5), done.
  From https://github.com/Scorpio-nan/GithubTest
   * branch            master     -> FETCH_HEAD
   * [new branch]      master     -> origin/master

origin 是咱们的仓库名, master 代表的是主线(主分支); (前面 git 分支的章节会具体介绍)

执行实现之后, 咱们能够看到之前新建的空文件夹上面多了几个文件, 并且都有标记为追踪文件(windows 下面的 git 标记一版是一个绿色的 号图标);

当初, 咱们把 README.md 外面的文件内容做一些批改;
README.md

#### 应用办法
````bash
$ git clone https://github.com/marmelab/react-admin.git

$ cd react-admin
$ npm install
$ npm start
````

而后一次执行 git 的文件操作命令:

$ git status
  ...

$ git add README.md
$ git commit -m "批改.md 外面的文件内容"
  ...

$ git push origin master
  Enumerating objects: 5, done.
  Counting objects: 100% (5/5), done.
  Delta compression using up to 8 threads.
  Compressing objects: 100% (3/3), done.
  Writing objects: 100% (3/3), 439 bytes | 439.00 KiB/s, done.
  Total 3 (delta 1), reused 0 (delta 0)
  remote: Resolving deltas: 100% (1/1), completed with 1 local object.
  To https://github.com/Scorpio-nan/GithubTest.git
     2872d97..b560ce1  master -> master

执行实现之后, 咱们就把本次对 README.md 作出的批改推送到了近程的 git 服务器上; 上面咱们切回到 Gitbub 页面验证一下咱们的提交是否胜利;

能够看到, github 下面的 GithubTest 这个仓库外面的内容曾经更新了;

从近程仓库克隆

克隆仓库的操作和创立的操作差不多, 不过, 不必在本地先创立好空的仓库, 只须要把 Github 下面创立好的仓库的地址复制下来, 而后在 bash 里输出命令 git clone 即可;

$ git clone https://github.com/Scorpio-nan/GithubTest.git
  
$ cd GithubTest
$ ls
  LICENSE  README.md

如果有多人帮助开发, 那么每个人各自从近程克隆一份就能够了;

查看近程仓库

如果想查看曾经配置的近程仓库服务器, 能够运行 git remote 命令;

$ git remote

  origin

origin 就是 git 给克隆仓库的默认名称;

当然, 也能够指定 -v 项, 会显示须要读写近程仓库的应用的 git 保留的简写和对应的 URL;

$ git remote -v

  origin  https://github.com/Scorpio-nan/GithubTest.git (fetch)
  origin  https://github.com/Scorpio-nan/GithubTest.git (push)

从近程仓库拉取

从近程仓库拉取数据, 能够执行 git fetch [remote-name]:

$ git fetch origin

fetch 命令会将数据拉取到本地的仓库, 但并不会主动合并或批改以后的工作; 这个时候咱们能够应用 git pull 命令来主动的抓取而后合并近程分支到以后分支;

$ git pull

通常, 在多人合作的我的项目中, 如果操作不当, 执行git pull 的过程中就会发生冲突; 并且, 命令行外面会提醒错误信息;

error: Your local changes to the following files would be overwritten by merge;

这表明, 本地的文件与近程仓库上的文件不统一, 本地的文件将会被服务器上的文件笼罩, 这个时候咱们能够有两个抉择:

1. 如果想保留方才本地批改的代码,并把 git 下面的代码 pull 到本地 (本地刚刚才批改的代码会被缓存起来)
$ git stash
$ git pull origin master
$ git stash pop

如此一来, 服务器上的代码更新到了本地, 而且本地刚批改的代码也没有被笼罩, 之后应用 add commit push 就能够更新本地代码到服务器了;

2. 如果想齐全笼罩本地代码,已服务器下面 pull 下来的代码为准,那咱们能够间接退回到上一个版本之后再 pull
$ git reset --hard
$ git pull origin master

Git 别名

Git 并不会在你输出局部命令时主动推断出你想要的命令. 如果不想每次都输出残缺的 Git 命令, 能够通过 git config 文件来轻松地为每一个命令设置一个别名;

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

这意味着, 当要输出 git commit 时, 只须要输出 git ci

Git 分支

git 分支是为了将批改记录的流程离开存储, 让离开的分支不受其余分支的影响, 所以在同一个仓库里能够同时进行多个不同版本的批改;

试想一下, 在工作中如果咱们有新的需要, 会间接在代码外面去增加需要的业务代码, 然而如果这个时候已上线的我的项目外面须要紧急上线一个小版本, 解决程序外面的 bug;

这个时候就坑爹了, 因为本地的代码外面曾经加上了将来新版本的需要, 有可能这个需要是须要同后盾 api 一起上线能力失常应用, 如果想要应用新需要之前的代码, 只能将版本回退到增加需要之前, 这也就意味着前面的工作都是无用功; 当然, 也能够把现有的代码备份起来, 等还原之后再同步过来, 不过这样效率会非常低, 而且比拟容易出错;

分支能够帮忙咱们更好的治理不同版本的代码;

创立与合并分支

git 在执行 git init 的时候, 其实就是相当于为咱们主动创立了一个 master 分支; 应用 git branch 能够看到咱们以后所在的分支; git branch 会为咱们列出所有的分支, 以后分支后面会显示 *

$ git branch
 
* master

假如 master 外面存储的是咱们在线上曾经正式经营的产品的代码, 上面咱们会在 master 上面新建一个 dev 开发环境的代码;

$ git checkout -b dev

  Switched to a new branch 'dev'

下面的 git checkout -b 命令, 相当于以下两条命令:

$ git branch dev
$ git checkout dev

  Switched to branch 'dev'

咱们在 master 上面创立了一个 dev分支, 并且还主动为咱们切换到了 dev 分支上, 让咱们再一次 git branch 查看一下;

$ git branch

* dev
  master

而后, 咱们能够在 dev 分支上失常的提交, 比方在 README.md 文件外面增加一些内容, 而后提交;

$ git add *
$ git commit -m "这是咱们在 dev 分支上做出的批改;"

  [dev 4fee0ed] 这是咱们在 dev 分支上做出的批改;
   1 file changed, 19 insertions(+)

当初, 咱们在 dev 分支上的工作曾经做完了, 让咱们切换到 master 分支上;

$ git checkout master

  Switched to branch 'master'

$ git branch
  dev
* master

切换到 master 分支之后, 在查看一下 README.txt 文件, 发现咱们刚刚增加下来的内容不见了, 因为刚刚的批改是在 dev 分支上进行的, 而 master 分支此刻的状态并没有扭转;

这个也就是 git 分支的妙用, 对应到开发工作中就是 dev 是为咱们开发需要应用的, 而 master 是当火线上正在运行的版本;

当初, 咱们须要将 dev 分支下面做出的批改合并到 master 分支上; 咱们能够应用 git merge 命令:

$ git merge dev

  Updating f4c0417..4fee0ed
  Fast-forward
   README.md | 19 +++++++++++++++++++
   1 file changed, 19 insertions(+)

git merge <branch> 命令用于将指定分支合并到以后分支上; 合并之后咱们再查看一下 README.md 的内容, 就能够看到曾经和 dev 分支下面的内容是截然不同的了;

留神到下面的 Fast-forward 信息, Git 通知咱们, 这次合并是 快进模式, 也就是间接把 master 指向 dev 的以后提交, 所以合并速度十分快;

合并实现之后, 就能够删除 dev 分支了;

$ git branch -d dev

  Deleted branch dev (was 4fee0ed).

$ git branch
* master

合并抵触

合并分支, 往往不是像上述的疾速合并这么简略的; 例如: dev 分支上, 咱们对开发版本做了许多的批改; 然而这个时候 master 的版本外面也须要做一些批改; 当初 masterdev 分支上各自都有了新的提交;

这种状况下git 是无奈执行疾速合并的, 只能试图将各自批改的版本合并起来, 然而这种合并往往会有抵触;

$ git merge dev

  Auto-merging README.md
  CONFLICT (content): Merge conflict in README.md
  Automatic merge failed; fix conflicts and then commit the result.

git 通知咱们 README.md 文件存在抵触, 必须手动解决抵触之后再提交; 咱们能够在合并抵触后的任意时刻应用 git status 命令来查看那些因蕴含合并抵触而处于未合并 unmerged 状态的文件:

$ git status

  On branch master
  You have unmerged paths.
    (fix conflicts and run "git commit")
    (use "git merge --abort" to abort the merge)

  Unmerged paths:
    (use "git add <file>..." to mark resolution)
          both modified:   README.md
  no changes added to commit (use "git add" and/or "git commit -a")

任何有抵触而有待解决的文件, 都会以未合并状态标识进去, git 会在有抵触的文件中退出抵触标记, 呈现抵触的文件会蕴含一些非凡的区段:

<<<<<<< HEAD
轻易改一改货色
=======
这是在 dev 分支上做出的批改


>>>>>>> dev

HEAD 所批示的版本(也就是 master 分支所在的地位), 在这个区段的上半局部(======= 以上的局部) , 而 dev 分支所批示的版本是在 ======= 的下半局部. 为了解决抵触, 咱们必须抉择由 ======= 宰割的两个局部中的一个; 或者咱们能够自行合并这些抵触, 删除掉某半的内容;

或者咱们能够应用 git merge --abort 来撤销本次合并; 在手动解决完这些抵触之后, 再对每个文件应用 git add命令来将其标记为抵触已解决;

强制 push 到近程

$ git push -u origin master -f

分支开发流程

在理论开发中, 咱们应该依照几个根本的准则进行分支的治理:

    1. 首先 master 分支是十分稳固的, 也就是仅用来公布版本, 不能在下面做开发;
    1. dev 分支是不稳固的, 用来做新版本的迭代, 开发实现之后再合并到 master 分支下来;
    1. 在多人合作的我的项目开发中, 每个人都在 dev 分支上开发, 每个人都有本人的分支, 常常往 master 分支上合并就行了;

近程分支

近程援用是对近程仓库的援用, 包含分支和标签等; 咱们能够通过 git ls-remote 来显示的查看近程援用的残缺列表; 或者是通过 git remote show 来取得近程分支的更多信息;

我司的自动化运维架构就是基于 git 分支去治理站点代码的; 合作流程大略为开发人员开发完新版本之后, 将不同的站点的业务代码提交到 git 绝对应的分支上, 而后服务端依据不同的站点标识去拉取分支上的代码, 并推送到服务器上;

Git 疾速克隆大我的项目

随着公司的业务线增多, 产品也越来越多, 单个的 git 仓库曾经满足不了业务需要, 咱们要应用多个仓库去治理我的项目; 并且, 多个我的项目不停迭代的同时, 咱们还须要应用多个分支去做版本控制;

而随着业务量的增多, 一些我的项目变的十分的宏大, 如果咱们只是想获取到我的项目的代码以及之后的更新, 咱们就不须要去关注我的项目的历史提交记录, 那么咱们就只用克隆某一个分支的最初一次提交;

  • 抉择克隆单个分支:git clone --branch <branch_name> <remote-address>
  • 只克隆最新的提交记录: git clone <remote-address> --depth 1
  • 组合: git clone --branch <branch_name> <remote-address> --depth 1

-- depth 代表克隆的深度, --depth 1代表只克隆最新一次提交记录以及这次提交之后的最新内容, 不克隆历史提交, 所造成的影响就是不能查看历史提交记录, 然而克隆速度大大晋升;

$ git clone --branch=dev http://git.nbet-group.com dev --depth=1

git clone 命令, url 前面如果增加名称的话, 那克隆下来的文件夹名称就是命令行增加的名称, 如果不加则以克隆下来的我的项目名命名文件夹;

Git 强制笼罩本地代码

Git 强制笼罩:

git fetch --all                     #  拉取所有更新,不同步
git reset --hard origin/master      #  本地代码同步线上最新版本(会笼罩本地所有与近程仓库上同名的文件)
git pull                            #  更新一次(其实也能够不必,第二步命令做过了其实)

git 强制笼罩本地命令(单条执行):

git fetch --all && git reset --hard origin/master && git pull
Git 勾销本地所有批改

本地批改了许多文件, 其中有些是新增的, 因为开发须要这些都不要了, 想要抛弃掉, 或者是因为实现某个性能, 然而没有胜利, 反而把代码搞得一团蹩脚, 这个时候咱们能够勾销本地所有的更改, 回复到更改之前的状态, 能够应用如下命令:

git checkout . #本地所有批改的。没有的提交的,都返回到原来的状态
git stash #把所有没有提交的批改暂存到 stash 外面。可用 git stash pop 回复。git reset --hard HASH #返回到某个节点,不保留批改。git reset --soft HASH #返回到某个节点。保留批改
 
git clean -df #返回到某个节点
git clean 参数
    # -n 显示 将要 删除的 文件 和  目录
    # -f 删除 文件
    # -df 删除 文件 和 目录

单条执行:

git checkout . && git clean -xdf
退出移动版