Git学习

1.Git简介

Git是目前世界上先进的分布式版本控制系统(没有之一)

1.1版本控制

1.手动版本控制

 如果你用Microsoft Word写论文,那你一定有这样的经历:想删除一个段落,又怕将来想恢复找不 回来怎么办?有办法,先把当前文件“另存为……”一个新的Word文件,再接着改,改到一定程度,再“另 存为……”一个新文件,这样一直改下去,后你的Word文档变成了这样:
在这里插入图片描述
 过了一周,你想找回被删除的文字,但是已经记不清删除前保存在哪个文件里了,只好一个一个文件去找,真麻烦。
 看着一堆乱七八糟的文件,想保留新的一个,然后把其他的删掉,又怕哪天会用上,还不敢删, 真郁闷。
 更要命的是,有些部分需要你的财务同事帮助填写,于是你把文件Copy到U盘里给她(也可能通过 Email发送一份给她),然后,你继续修改Word文件。一天后,同事再把Word文件传给你,此时,你 必须想想,发给她之后到你收到她的文件期间,你作了哪些改动,得把你的改动和她的部分合并,真困 难。
 于是你想,如果有一个软件,不但能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样 就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里瞄一眼就可以,岂不是很方便?

2. 自动版本控制

这个软件用起来就应该像这个样子,能记录每次文件的改动:
在这里插入图片描述
这样,你就结束了手动管理多个“版本”的史前时代,进入到版本控制的20世纪。

  • vss:微软
  • cvs:开源
  • svn:google
  • git:分布式版本控制工具(标准)

2.Git实战

2.1安装git

 最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑。不过,慢慢地有人把它移植到了Windows上。现在,Git可以在Linux、Unix、Mac和Windows这几大平台上正常运行了。
 在Windows上使用Git,可以从Git官网直接下载安装程序,(网速慢的同学请移步国内镜像),然后按默认选项安装即可。
 安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!
在这里插入图片描述
安装完成后,还需要最后一步设置,在命令行输入:

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

 因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
 注意 git config 命令的 --global 参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

$ git config --global --get user.name #得到user.name的值

在这里插入图片描述

$ git config --global -l #列表参数

在这里插入图片描述

2.2创建版本库

 什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

1. 创建版本库

cd /d/ #window的git bash中进入d盘
$ mkdir learngit
$ cd learngit
$ pwd
/Users/michael/learngit
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/

在这里插入图片描述
 如果你使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。通过 git init 命令把这个目录变成Git可以管理的仓库,瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个 .git 的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
 如果你没有看到 .git 目录,那是因为这个目录默认是隐藏的,用 ls -ah 命令就可以看见。
 首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
 不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。

2.添加文件到版本库

现在我们编写一个 readme.txt 文件,内容如下:

Git is a version control system.
Git is free software.

 一定要放到 learngit 目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件。
 和把大象放到冰箱需要3步相比,把一个文件放到Git仓库只需要两步。
(1)用命令git add告诉Git,把文件添加到仓库

$ git add readme.txt

在这里插入图片描述
执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。
(2)用命令git commit告诉Git,把文件提交到仓库

$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt

在这里插入图片描述
提交后可用git log命令查看提交

$ git log
commit 6e4de12122b22ee3145dfa87af974d284f832dd2 (HEAD -> master)
Author: lxsong <lxsong77@163.com>
Date: Tue Jul 11 09:57:08 2023 +0800
wrote a readme file

在这里插入图片描述
 简单解释一下 git commit 命令, -m 后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
 嫌麻烦不想输入 -m “xxx” 行不行?确实有办法可以这么干,但是强烈不建议你这么干,因为输入说明对自己对别人阅读都很重要。实在不想输入说明的童鞋请自行Google,我不告诉你这个参数。
 git commit 命令执行成功后会告诉你, 1 file changed :1个文件被改动(我们新添加的readme.txt文件); 2 insertions :插入了两行内容(readme.txt有两行内容)。
 为什么Git添加文件需要 add , commit 一共两步呢?因为 commit 可以一次提交很多文件,所以你可以多次 add 不同的文件,比如:
在这里插入图片描述
命令git add .表示添加工作区的所有文件
命令git status表示查看git状态
执行命令git add .之后,提交之前,如下图
在这里插入图片描述
执行命令git commit之后,如下图
在这里插入图片描述
HEAD表示指针,会指向最新提交

3.修改commit备注信息

如果git提交代码时commit注释写错了,只是想改一下注释,只需要使用git commit --amend命令,此时会进入默认vim编辑器,修改注释完毕后保存就好了
在这里插入图片描述

总结
git add:把工作区文件添加到暂存区
git commit -m “xxxx”:把暂存区(stage)文件提交到分支
git status:查看git版本库状态
git log:查看版本提交
git commit --amend:修改提交后的注释信息

2.3版本控制

1.修改readme.txt

修改readme.txt文件,改成如下内容

Git is a distributed version control system.
Git is free software.

运行 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 status命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们, readme.txt被修改过了,但还没有准备提交的修改。
 虽然Git告诉我们 readme.txt 被修改了,但如果能看看具体修改了什么内容,自然是很好的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的 readme.txt ,所以,需要用 git diff 这个命令看看

$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.

git diff顾名思义就是查看difference,显示的格式正是Unix通用的diff格式,可以从上面的命令输出看到,我们在第一行添加了一个 distributed 单词。
注: git diff 属于本地代码发生更新但尚未执行git add命令时的状态,working tree的状态也随之更新,如下图
在这里插入图片描述
在这里插入图片描述
知道了对 readme.txt 作了什么修改后,再把它提交到仓库就放心多了,提交修改和提交新文件是一样的两步,第一步是 git add

$ git add readme.txt

同样没有任何输出。在执行第二步 git commit 之前,我们再运行git status看看当前仓库的状态

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

git status告诉我们,将要被提交的修改包括 readme.txt ,下一步,就可以放心地提交了

$ git commit -m "add distributed"
[master e475afc] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)

提交后,我们再用 git status 命令看看仓库的当前状态

$ git status
On branch master
nothing to commit, working tree clean

Git告诉我们当前没有需要提交的修改,而且工作目录是干净(working tree clean)的

2.版本回退

(1)首先,准备3个版本
现在,你已经学会了修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改readme.txt文件如下

Git is a distributed version control system.
Git is free software distributed under the GPL.

然后尝试提交

$ git add readme.txt
$ git commit -m "append GPL"
[master 1094adb] append GPL
1 file changed, 1 insertion(+), 1 deletion(-)

现在,我们回顾一下 readme.txt 文件一共有几个版本被提交到Git仓库里了
版本1:wrote a readme file

Git is a version control system.
Git is free software.

版本2:add three file

a, b, c

版本3:add distributed

Git is a distributed version control system.
Git is free software.

版本4:append GPL

Git is a distributed version control system.
Git is free software distributed under the GPL.

当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录。 git log命令查看版本,它显示从最近到最远的提交日志

$ git log
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:06:15 2018 +0800
append GPL
commit e475afc93c209a690c39c13a46716e8fa000c366
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file

如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数

$ git log --pretty=oneline
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file

一大串类似 1094adb… 的是 commit id (版本号)
(2)版本回退
首先,Git必须知道当前版本是哪个版本,在Git中,用 HEAD 表示当前版本,也就是最新的提交
1094adb… (注意我的提交ID和你的肯定不一样),上一个版本就是 HEAD^ ,上上一个版本就是HEAD^^ ,当然往上100个版本写100个 ^ 比较容易数不过来,所以写成 HEAD~100

现在,我们要把当前版本 append GPL 回退到上一个版本 add distributed ,就可以使用git reset命令

$ git reset --hard HEAD^
HEAD is now at e475afc add distributed

指定回到未来的某个版本,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPL 的 commit id 是 1094adb… ,于是就可以指定回到未来的某个版本

$ git reset --hard 1094a
HEAD is now at 83b0afe append GPL

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

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

$ git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file

总结

  • soft :仅仅移动本地库 HEAD 指针,不删除工作空间改动代码,撤销commit,不撤销git add .
  • mixed: 移动本地库 HEAD 指针,重置暂存区,不删除工作空间改动代码,撤销commit,并且撤销git add . 操作,这个为默认参数,git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的
  • hard:移动HEAD指针,重置暂存区,工作区,省略git checkout - - file,删除工作空间改动代码,撤销commit,撤销git add . ,完成这个操作后,就恢复到了上一次的commit状态
    注: 重置暂存区就是取消“添加文件到暂存区”的这个动作,即取消暂存,添加后,git status查看文件是绿色;取消添加,git status查看文件是红色

2.4 工作区和暂存区

1.工作区(Working Directory)

就是你在电脑里能看到的目录,比如我的 learngit 文件夹就是一个工作区
在这里插入图片描述

2.版本库(Repository)

工作区有一个隐藏目录 .git ,这个不算工作区,而是Git的版本库
(1)版本库基本状态
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支 master ,以及指向 master 的一个指针叫 HEAD
在这里插入图片描述
 前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
 第一步是用 git add 把文件添加进去,实际上就是把文件修改添加到暂存区
 第二步是用 git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支
 因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在git commit 就是往master分支上提交更改
 你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改

先对 readme.txt 做个修改,比如加上一行内容

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.

然后,在工作区新增一个 LICENSE 文本文件(内容随便写),先用 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
Untracked files:
(use "git add <file>..." to include in what will be committed)
LICENSE
no changes added to commit (use "git add" and/or "git commit -a")

Git非常清楚地告诉我们, readme.txt 被修改了,而 LICENSE 还从来没有被添加过,所以它的状态是 Untracked

现在,使用两次命令 git add ,把 readme.txt 和 LICENSE 都添加后,用 git status 再查看一下

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: LICENSE
modified: readme.txt

(2)add两次后的版本库状态

git add .

执行后git版本库状态如下
在这里插入图片描述
所以, git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支

$ git commit -m "understand how stage works"
[master e43a48b] understand how stage works
2 files changed, 2 insertions(+)
create mode 100644 LICENSE

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

$ git status
On branch master
nothing to commit, working tree clean

(3)commit后的版本库状态
在这里插入图片描述

2.5 撤销修改

1.git checkout命令

(1)git checkout -- file可以丢弃工作区的修改,用于恢复工作目录中被修改的文件到最近一次add或commit的状态,它可以用于撤销对文件的修改,并将文件还原为最近一次提交的版本

 $ git checkout -- readme.txt

注:
1.命令 git checkout – readme.txt 意思就是,把 readme.txt 文件在工作区的修改全部撤销,这里有两种情况:
(1)一种是文件自从修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态
在这里插入图片描述

(2)一种是文件已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态
在这里插入图片描述
(2)git checkout - - file 命令中的 - - 很重要,没有 - - ,就变成了“切换到另一个分支”的命令
(3)如果你想撤销整个工作目录中所有文件的修改,可以使用git checkout -- . 命令,这将撤销对所有已修改的文件的编辑,并将它们还原到最近一次提交的版本

2.git reset命令

git reset 命令既可以回退版本,也可以把暂存区的修改回退到工作区(即把文件取消暂存)
(1)git reset HEAD <file>:可以把暂存区的修改撤销掉(unstage),重新放回工作区,取消对指定文件的暂存操作,这个命令将会将该文件的暂存改动撤销,使其回到工作目录中的状态,但不会丢失文件的实际改动。你可以使用此命令对已经暂存的文件进行修改或重新添加
在这里插入图片描述
(2)git reset HEAD . git reset HEAD --:取消所有文件的暂存操作。使用这个命令时,它将会将所有已经暂存的文件的改动撤销,使它们回到工作目录中,但不影响实际的文件改动

  • git reset HEAD .

在这里插入图片描述

  • git reset HEAD --

在这里插入图片描述
在这里插入图片描述

注:
1.

git reset --hard HEAD^
等价于
git reset --mixed HEAD^
git checkout -- a.txt(文件名)

2.git reset HEAD就是回退到当前版本,git reset HEAD^回退到上一版本
3.若已提交的文件想要修改,就回退版本
4.git reset HEAD 只影响暂存区的文件

2.6删除文件

1.添加一个test.txt文件并且提交

$ git add test.txt
$ git commit -m "add test.txt" 
[master b84166e] add test.txt 1 file changed, 1 insertion(+) create mode 100644 test.txt

在这里插入图片描述

2.rm删除test.txt文件

$ rm test.txt

Git知道删除了文件,因此,工作区和版本库就不一致了, git status 命令会立刻显示哪些文件被删除了
在这里插入图片描述
在这里插入图片描述

(1)彻底删除此文件

$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt" 
[master d46f35e] remove test.txt 1 file changed, 1 deletion(-) delete mode 100644 test.txt

在这里插入图片描述
注: 若文件已提交则git rm删除后需要commit;若文件没有提交则直接git rm删除即可

(2)误删之后恢复文件

$ git checkout -- test.txt

注:
1.从来没有被添加到版本库就被删除的文件,是无法恢复的
在这里插入图片描述
在这里插入图片描述

2.git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”,本地版本库一般包括工作目录、暂存区(也叫索引)和版本历史记录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.远程仓库

3.1使用远程库

可以自己搭建一台运行Git的服务器,不过也可以使用现有的Git远程库,应用比较广泛的如下

  • github
  • gitee

1.使用SSH协议克隆远程库

ssh基于非对称加密的免密登录原理
在这里插入图片描述
对称加密:密码本是一个

  • MD5

非对称加密,秘钥是一对(公钥/私钥)

  • rsa
    (1)创建SSH Key
    在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有 id_rsa 和 id_rsa.pub 这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell (Windows下打开Git Bash),创建SSH Key,需要把邮件地址换成自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码,如果一切顺利的话,可以在用户主目录里找到 .ssh 目录,里面有 id_rsa 和 id_rsa.pub 两个文件,这两个就是SSH Key的秘钥对, id_rsa 是私钥,不能泄露出去, id_rsa.pub 是公钥,可以放心地告诉任何人
$ ssh-keygen -t rsa -C "lxsong77@163.com"
#用户宿主目录下.ssh   c:\Users\Administrator\.ssh\

(2)添加公钥
登陆Gitee,在公钥文本框里粘贴 id_rsa.pub 文件的内容
在这里插入图片描述

在这里插入图片描述
(3)克隆

git clone git@gitee.com:halo-dev/halo.git

2.使用HTTPS协议克隆远程库

不配置公钥也可以使用HTTS协议,在使用HTTPS协议时输入用户名,密码

#第一次访问需要输入gitee的用户名密码
git clone https://gitee.com/halo-dev/halo.git

注: halo是一个开源博客系统,基于spring boot和vue

3.2添加远程库

1.新建仓库

登陆Gitee,然后,在右上角找到“新建仓库”按钮,创建一个新的仓库,在Repository name填入learngit ,其他保持默认设置,点击“创建仓库”按钮,就成功地创建了一个新的Git仓库,不要选择初始化仓库和模板,要创建一个空的仓库
在这里插入图片描述
创建成功之后,gitee会出现以下提示步骤

  • Git 全局设置
git config --global user.name "雪松"
git config --global user.email "lxsong77@163.com"
  • 创建 git 仓库
mkdir learngit
cd learngit
git init
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin git@gitee.com:lxsong77/learngit.git
git push -u origin "master"
  • 已有仓库
cd learngit
git remote add origin git@gitee.com:lxsong77/learngit.git
git push -u origin "master"

注:
git init命令用于初始化一个仓库,在 Git 中,"初始化仓库"指的是创建一个新的 Git 仓库,用于管理你的代码和版本控制

当你在一个目录中执行git init命令时,Git 会在该目录下创建一个特殊的 .git 子目录,这个目录包含了 Git 仓库的所有必要信息。这些信息包括版本历史、分支、标签和配置等

在执行git init命令后,当前目录下的文件和子目录都会被纳入 Git 仓库的管理范围,即开始被 Git 跟踪。Git 会将当前目录下的文件复制一份,并将其保存在 .git 目录中的各个对象和索引文件中。这样,之后对文件的更改和提交都可以被 Git 跟踪和管理

通过初始化一个仓库,你就可以使用 Git 的各种功能来管理你的代码,包括提交修改、查看历史记录、创建分支、合并代码等。你还可以将该仓库与其他远程 Git 仓库进行交互,进行推送和拉取操作,与团队成员进行协作开发

2.关联远程库

根据Gitee的提示,在本地的learngit仓库下运行命令,添加后,远程库的名字就是 origin ,这是Git默认的叫法,也可以改成别的,但是 origin 这个名字一看就知道是远程库

git remote add origin git@gitee.com:lxsong77/learngit.git

该命令是用于将本地Git仓库与远程仓库建立关联,解释如下:

  • git remote add origin:指定一个远程仓库的别名为"origin",可以根据自己的需要自定义
  • git@gitee.com:lxsong77/learngit.git:远程仓库的地址,这里是以Gitee为例
  • git@gitee.com是Gitee的Git协议URL,lxsong77/learngit.git则表示Gitee上的用户名为lxsong77,仓库名为learngit
  • 通过执行这个命令,本地Git仓库与远程仓库之间建立了联系,这样在后续操作中,可以使用origin这个别名代替远程仓库的地址,方便管理、同步代码。比如执行git push origin master将本地master分支的代码推送到远程仓库中

3.推送本地库内容到远程库

把本地库的内容推送到远程库,用 git push 命令,实际上是把当前分支 master 推送到远程库,由于远程库是空的,我们第一次推送 master 分支时,加上了 -u 参数,Git不但会把本地的 master分支内容推送到远程新的 master 分支,还会把本地的 master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令

$ git push -u origin master
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (20/20), 1.64 KiB | 560.00 KiB/s, done.
Total 20 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:michaelliao/learngit.git
 * [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

在这里插入图片描述
从现在起,只要本地作了提交,就可以通过以下命令把本地 master 分支的最新修改推送至GitHub

$ git push origin master

注:
1.

  • 推送代码:git push
  • 拉取代码:git pull

2.如果在本地已经将一个仓库链接到远程库,然后再次在新的目录中进行初始化一个新的仓库,那么在新的仓库中是不会自动连接到远程库的

每个 Git 仓库都有自己的独立配置,包括远程库的链接信息,当执行git init命令来初始化一个新的仓库时,它将创建一个新的 .git 文件夹用于存储该仓库的配置和历史记录,默认情况下,这个新的仓库是没有任何远程库链接的

如果在新的仓库中连接到之前已链接的远程库,需要手动将远程库添加为该仓库的一个远程地址。可以使用 git remote add 命令来完成这个操作,例如:

git remote add origin <远程仓库地址>

这样,就将一个名为 origin 的远程库链接成功添加到了新的仓库中,之后,就可以使用 git push 命令将本地提交推送到该远程库

需要注意的是,虽然可能已经在一个目录中将本地库链接到了远程库,但在新的目录中进行仓库初始化时,并不会自动继承之前的链接信息。需要手动重新添加远程库链接,并确保链接信息正确,才能正常进行远程仓库的推送和拉取等操作
3.假设远程库有dev分支,克隆的本地库只有master分支,这时想把远程库的dev分支拉取到本地克隆库,需要在本地克隆库新建一个dev分支用于接收

3.3从远程库克隆

打开另一个窗口模拟其他人下载远程库

cd f:\tmp
git clone git@gitee.com:lxsong77/learngit.git #克隆远程库到本地库
$ git log --pretty=oneline
64eb3d86d3b46095c006edd91dcf5f2f97ba4b7b (HEAD -> master, origin/master,
origin/HEAD) remove test.txt
18a4e330ee23f4df88e1cb2de7c3bf42fcd60d57 add test.txt
fc99176b6e2d3b2159b6503429611127b090ade0 understand how stage works
64800dbc350bdb87529df4a1efb5203028086926 append GPL
6793214fbc09a35878b9366a4bc3a62b4ab504dd add distributed
bd875ec1f86c22f203741414a238526bfca26279 add 3 files.
6e4de12122b22ee3145dfa87af974d284f832dd2 wrote a readme file

4.分支管理

 分支就是git世界的平行宇宙,分支在实际中有什么用呢?假设准备开发一个新功能,但是需要两周才能完成,第一周写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险,现在有了分支,就不用怕了,创建一个属于自己的分支,别人看不到,还继续在原来的分支上正常工作,而在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作
 git相对于其他版本控制工具,分支功能非常快

4.1创建与合并分支

 在版本回退里,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支
 截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即 master 分支, HEAD 严格来说不是指向提交,而是指向 master , master 才是指向提交的,所以, HEAD 指向的就是当前分支
 一开始的时候, master 分支是一条线,Git用 master 指向最新的提交,再用 HEAD 指向 master ,就能确定当前分支,以及当前分支的提交点
在这里插入图片描述
每次提交, master 分支都会向前移动一步,这样,随着不断提交, master 分支的线也越来越长

当我们创建新的分支,例如 dev 时,Git新建了一个指针叫 dev ,指向 master 相同的提交,再把HEAD 指向 dev ,就表示当前分支在 dev 上
在这里插入图片描述
Git创建一个分支很快,因为除了增加一个 dev 指针,改改 HEAD 的指向,工作区的文件都没有任何变化

不过,从现在开始,对工作区的修改和提交就是针对 dev 分支了,比如新提交一次后, dev 指针往前移动一步,而 master 指针不变
在这里插入图片描述

假如在 dev 上的工作完成了,就可以把 dev 合并到 master 上,最简单的方法,就是直接把 master 指向 dev 的当前提交,就完成了合并
在这里插入图片描述
Git合并分支也很快,就改改指针,工作区内容也不变

合并完分支后,甚至可以删除 dev 分支,删除 dev 分支就是把 dev 指针给删掉,删掉后,我们就剩下了一条 master 分支
在这里插入图片描述
注:
1.运行以下命令将本地分支与远程分支关联

git push -u origin <branch-name>

如果是第一次将该分支推送到远程仓库,可能需要提供远程仓库的访问权限(例如用户名和密码、SSH 密钥等)
2.在新目录中初始化git仓库之后,若是在master分支中没有提交任何文件,则创建并且换到一个dev分支后,再想切换回master分支会报错
3.在Git中,每个分支都有自己的版本控制历史和文件快照。当创建一个新的分支时,它会继承自基础分支(通常是主分支或其他已存在的分支)的所有文件和提交历史

因此,文件在不同的分支之间可以有不同的版本。在一个分支上进行更改并提交时,这些更改只会影响当前分支,而不会对其他分支产生影响。这意味着每个分支可以独立地进行开发,不会相互干扰

虽然每个分支都有自己的文件快照,但它们共享相同的源代码库(通常是远程仓库)。这意味着所有分支都可以在需要的时候访问同样的文件和资源。当切换到另一个分支时,Git会将工作目录中的文件更改为该分支下的版本,使可以在不同的分支之间切换和比较文件

需要注意的是,如果在一个分支上对文件进行修改并提交后,切换到另一个分支并对同一个文件进行修改,这些更改可能会导致冲突。 在合并分支或切换分支时,Git会自动检测并标识这些冲突,需要手动解决冲突。

总而言之,每个分支都有自己的版本控制历史和文件快照,不同分支之间的文件可以有不同的版本。但它们共享相同的源代码库,可以访问同样的文件和资源

1.实战案例

(1)创建并切换到dev分支

$ git checkout -b dev
Switched to a new branch 'dev'
#以下两条命令是等价的
git log --oneline
git log --pretty=oneline --abbrev-commit 
#--pretty=oneline:显示单行
#--abbrev-commit:缩写commit id

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

$ git branch dev
$ git checkout dev
Switched to branch 'dev'

(2)查看当前分支
git branch命令查看当前分支,git branch命令会列出所有分支,当前分支前面会标一个 * 号

$ git branch
* dev
master

(3)修改文件
对readme.txt做个修改,加上一行以下语句

Creating a new branch is quick.

(4)添加并提交文件

$ git add readme.txt
$ git commit -m "branch test"
[dev b17d20e] branch test
1 file changed, 1 insertion(+)

(5)切换分支
dev分支的工作完成,我们就可以切换回master分支

$ git checkout master
Switched to branch 'master'

(6)查看readme.txt文件
切换回 master 分支后,再查看一个 readme.txt 文件,发现刚才添加的内容不见了,因为那个提交是在 dev 分支上,而 master 分支此刻的提交点并没有变
在这里插入图片描述
(7)合并分支
把 dev 分支的工作成果合并到 master 分支上,git merge命令用于合并指定分支到当前分支,合并后,再查看 readme.txt 的内容,就可以看到,和 dev 分支的最新提交是完全一样的

$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)

(8)删除分支
合并完成后,就可以放心地删除 dev 分支了

$ git branch -d dev
Deleted branch dev (was b17d20e).

删除后,查看 branch ,就只剩下 master 分支了

$ git branch
 * master

总结

  • git checkout

    • git checkout – file:把版本库的文件重置到工作区(撤销工作区的修改)
    • git checkout master:切换到master分支
    • git checkout -b dev:创建dev分支,并且切换到dev分支
  • git branch

    • git branch:列表分支分支,有*表示当前的分支
    • git branch dev:创建dev分支,如果切换需要git checkout dev
    • git branch -d dev:删除分支
  • git merge:合并分支

#master合并dev分支
git checkout master
git merge dev #使master分支合并dev分支
  • 创建新分支后立即查看日志(git log)会发现新分支的日志和主干分支相同
  • 切换分支后文件会跟着分支改变,如master分支下有a.txt文件,dev分支下没有a.txt文件,此时若处于master分支,则显示有a.txt文件,切换到dev分支,则没有a.txt文件,除非合并dev分支到master分支,则dev分支会显示a.txt文件

4.3分支管理策略

 在实际开发中,我们应该按照几个基本原则进行分支管理:
 master 分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活,干活都在 dev 分支上,也就是说, dev 分支是不稳定的,到某个时候,比如1.0版本发布时,再把 dev 分支合并到 master 上,在 master 分支发布1.0版本
 你和你的小伙伴们每个人都在 dev 分支上干活,每个人都有自己的分支,时不时地往 dev 分支上合并就可以了
 所以,团队合作的分支看起来就像这样
在这里插入图片描述

1.多人协作

从远程仓库克隆时,实际上Git自动把本地的 master 分支和远程的 master 分支对应起来了,并且,远程仓库的默认名称是 origin ,要查看远程库的信息,用 git remote

$ git remote
origin

或者,用 git remote -v 显示更详细的信息

$ git remote -v
origin git@github.com:michaelliao/learngit.git (fetch)
origin git@github.com:michaelliao/learngit.git (push)

上面显示了可以抓取和推送的 origin 的地址。如果没有推送权限,就看不到push的地址
(1)推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库,推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上

$ git push origin master

如果要推送其他分支,比如 dev ,就改成

$ git push origin dev

总结
1.master 分支是主分支,因此要时刻与远程同步
2.dev 分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步
3.bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug
4.feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发

(2)抓取分支
多人协作时,大家都会往 master 和 dev 分支上推送各自的修改
现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆

$ git clone git@github.com:michaelliao/learngit.git
Cloning into 'learngit'...
remote: Counting objects: 40, done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 40 (delta 14), reused 40 (delta 14), pack-reused 0
Receiving objects: 100% (40/40), done.
Resolving deltas: 100% (14/14), done.

当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的 master 分支。不信可以用 git branch 命令看看

$ git branch
* master

现在,你的小伙伴要在 dev 分支上开发,就必须创建远程 origin 的 dev 分支到本地,于是他用这个命令创建本地 dev 分支

git checkout -b dev
git push origin dev
$ git checkout -b dev origin/dev #创建dev分支,同时连接远程的dev分支

现在,他就可以在 dev 上继续修改,然后,时不时地把 dev 分支 push 到远程

#创建一个本地的bob分支
git checkout -b bob
touch en.txt
$ git add env.txt
$ git commit -m "add env"
[dev 7a5e5dd] add env
1 file changed, 1 insertion(+)
create mode 100644 env.txt
#切换dev分支
git checkout dev
git merge bob
$ git push origin dev
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
f52c633..7a5e5dd dev -> dev

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

cd f:\mickey
git checkout -b dev origin/dev
#等价下面两个命令
git checkout -b dev
git branch --set-upstream-to=origin/dev dev
git checkout -b mickey
$ cat env.txt
env
$ git add env.txt
$ git commit -m "add new env"
[dev 7bd91f1] add new env
1 file changed, 1 insertion(+)
create mode 100644 env.txt
$ git push origin dev
To github.com:michaelliao/learngit.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@github.com:michaelliao/learngit.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: '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
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 也失败了,原因是没有指定本地 dev 分支与远程 origin/dev 分支的链接,根据提示,设置 dev 和 origin/dev 的链接

$ git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

再pull

$ git pull
Auto-merging env.txt
CONFLICT (add/add): Merge conflict in env.txt
Automatic merge failed; fix conflicts and then commit the result.

这回 git pull 成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样,解决后,提交,再push

$ git commit -m "fix env conflict"
[dev 57c53ab] fix env conflict
$ git push origin dev
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 621 bytes | 621.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
7a5e5dd..57c53ab dev -> dev

因此,多人协作的工作模式通常是这样:

  1. 首先,可以试图用 git push origin 推送自己的修改
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用 git pull 试图合并
  3. 如果合并有冲突,则解决冲突,并在本地提交
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功,如果 git pull 提示 no tracking information ,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>
    这就是多人协作的工作模式,一旦熟悉了,就非常简单

多人协作实战案例
(1)模拟一个bob开发人员
在这里插入图片描述

#创建本地dev分支
git checkout -b dev
#提交dev给服务器
git push origin dev
#创建bob的本地分支
git checkout -b bob
#在bob分支下创建env.txt
touch env.txt
#提交
git add .
git commit -m "add env bob"
#回到dev,合并bob分支
git checkout dev
git merge bob
#上传dev到远程
git push origin dev

(2)模拟一个mickey开发人员
在这里插入图片描述
在这里插入图片描述

cd f:\mickey
git clone git@gitee.com:lxsong77/learngit.git
#注意,克隆时只会克隆master分支,其他分支不会被克隆
git checkout -b dev
git branch --set-upstream-to=origin/dev dev
#创建dev分支,同时链接远程dev分支,链接之后就可以进行push、pull操作了,等价于下面一行命令
git checkout -b dev origin/dev
#拉取dev分支
git pull origin dev
#创建mickey分支
git checkout -b mickey
#修改env.txt增加内容"mickey env"
vim env.txt
#提交
git add .
git commit -m "update env by mickey"
#合并到dev
git checkout dev
git merge mickey
#上传
git push origin dev

(3)合并dev分支到master分支

#拉取最新代码,在哪个用户下(bob、mickey)都可以
git pull origin master
git pull origin dev
git checkout master
git merge dev
#上传
git push origin master

注: 若dev分支或其它分支已经是最新的,则用pull拉取分支时会显示"already up to date"

总结
1.查看远程库信息,使用 git remote -v
2.本地新建的分支如果不推送到远程,对其他人就是不可见的
3.从本地推送分支,使用 git push origin branch-name ,如果推送失败,先用 git pull 抓取远程的新提交
4.在本地创建和远程分支对应的分支,使用 git checkout -b branch-name origin/branch-name ,本地和远程分支的名称最好一致
5.建立本地分支和远程分支的关联,使用 git branch --set-upstream branch-name
origin/branch-name
6.从远程抓取分支,使用 git pull ,如果有冲突,要先处理冲突

2.fast forward模式

通常,合并分支时,如果可能,Git会用 Fast forward 模式,但这种模式下,删除分支后,会丢掉分支信息,如果要强制禁用 Fast forward 模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

实战案例
项目1使用fast forward模式脚本如下

git init
touch a.txt
git add .
git commit -m "add a.txt"
git checkout -b dev
echo "add dev centent" >> a.txt
cat a.txt
git add .
git commit -m "dev update 1"
git checkout master
git merge dev
echo "master update1" >> a.txt
cat a.txt
git add .
git commit -m "master update 2"
git log --oneline --graph
git branch -d dev
git log --oneline --graph

项目2使用–no–ff进行实现

git init
touch a.txt
git add .
git commit -m "add a.txt"
git checkout -b dev
echo "add dev centent" >> a.txt
cat a.txt
git add .
git commit -m "dev update 1"
git checkout master
git merge --no-ff dev
echo "master update1" >> a.txt
cat a.txt
git add .
git commit -m "master update 2"
git log --oneline --graph
git branch -d dev
git log --oneline --grap

3.Bug分支

在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除
(1)stash命令
当接到一个修复一个代号101的bug的任务时,很自然地,需要创建一个分支 issue-101 来修复它,但是,等等,当前正在 dev 上进行的工作还没有提交

$ git status
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
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

Git提供了一个 stash 功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作

$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge

注:
1.git stash list命令,查看储存列表
2.git stash pop命令,恢复隐藏的工作内容,恢复的同时把stash list中内容也删了
3.stash不会保留暂存区的文件
(2)实战案例

#dev分支工作
git checkout dev
echo 'working on stage..' >> readme.txt
git add .
echo 'working on work space' >> readme.txt
#以上是现有工作
#接到一个改正bug101的任务
#现有工作,存储起来
git stash
#列表stash
git stash list
#切换回到master分支修改bug101
git checkout master
#创建修改bug101的分支
git checkout -b issue-101
echo 'fixed issue-101 bug' >> readme.txt
git add .
git commit -m "fixed bug 101"
#合并101分支
git checkout master
git merge issue-101
#bug改完了,回来继续工作
git checkout dev
git stash pop #把之前存储的工作,弹出

(3)自我尝试
正在进行dev分支下的工作,还没提交,突然接到bug任务
在这里插入图片描述
储藏当前工作现场,储藏后ll看不见工作现场中的文件
在这里插入图片描述
并且用git status查看工作区也是干净的
在这里插入图片描述
在master分支上修复bug,就从master分支上创建临时分支,在临时分支中完成修复bug的工作
在这里插入图片描述
修改完bug并提交
在这里插入图片描述
切换回master分支合并issue-101分支,并删除issue-101分支
在这里插入图片描述
把刚才储存的工作现场弹出,用git stash pop弹出的同时会删除列表(即git stash list)中的储藏
在这里插入图片描述

4.Feature分支

软件开发中,总有无穷无尽的新的功能要不断添加进来
添加一个新功能时,肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支
现在,终于接到了一个新任务:开发代号为Vulcan的新功能,该功能计划用于下一代星际飞船
于是准备开发

$ git checkout -b feature-vulcan
Switched to a new branch 'feature-vulcan'

5分钟后,开发完毕

$ git add vulcan.py
$ git status
On branch feature-vulcan
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: vulcan.py
$ git commit -m "add feature vulcan"
[feature-vulcan 287773e] add feature vulcan
1 file changed, 2 insertions(+)
create mode 100644 vulcan.py

切回 dev ,准备合并

$ git checkout dev

一切顺利的话,feature分支和bug分支是类似的,合并,然后删除
就在此时,接到上级命令,因经费不足,新功能必须取消
虽然白干了,但是这个包含机密资料的分支还是必须就地销毁

$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.

销毁失败,Git友情提醒, feature-vulcan 分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用大写的 -D 参数
现在强行删除

$ git branch -D feature-vulcan
Deleted branch feature-vulcan (was 287773e).

总结
开发一个新feature,最好新建一个分支,如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除

5.版本冲突

5.1准备新分支feature1

$ git checkout -b feature1
Switched to a new branch 'feature1'
git branch feature1 #创建分支
git checkout feature1 #切换分支
git branch #查看分支

5.2修改readme.txt文件

修改 readme.txt 最后一行,改为:

Creating a new branch is quick AND simple.

5.3在新分支(feature1)上添加并提交

在 feature1 分支上提交

$ git add readme.txt
$ git commit -m "AND simple"
[feature1 14096d0] AND simple
1 file changed, 1 insertion(+), 1 deletion(-)

5.4切换分支

切换到 master 分支,Git还会自动提示我们当前 master 分支比远程的 master 分支要超前1个提交

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)

5.5在master分支上进行修改

在 master 分支上把 readme.txt 文件的最后一行改为

Creating a new branch is quick & simple.

5.6在master分支上进行提交

$ git add readme.txt
$ git commit -m "& simple"
[master 5dc6824] & simple
1 file changed, 1 insertion(+), 1 deletion(-)

5.7发生冲突

现在, master 分支和 feature1 分支各自都分别有新的提交,变成如下这样
在这里插入图片描述
这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突

$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

Git告诉我们, readme.txt 文件存在冲突,必须手动解决冲突后再提交, git
status 也可以告诉我们冲突的文件

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
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.txt
no changes added to commit (use "git add" and/or "git commit -a")

发生冲突的情况下,直接查看readme.txt的内容,Git用 <<<<<<< , ======= , >>>>>>> 标记出不同分支的内容,如下图

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1

5.8发生冲突后修改文件

修改文件如下后保存

Creating a new branch is quick and simple.

5.9修改后提交

$ git add readme.txt
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed

现在, master 分支和 feature1 分支变成了下图所示
在这里插入图片描述

5.10查看分支合并情况

- -graph参数表示以图形化的方式显现
$ git log --graph --pretty=oneline --abbrev-commit
* cf810e4 (HEAD -> master) conflict fixed
|\
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file

5.11删除feature分支

$ git branch -d feature1
Deleted branch feature1 (was 14096d0).

6.标签管理

6.1创建标签

1.默认标签

使用git tag <name>命令来创建一个新标签,默认标签是打在最新提交的commit上的

$ git tag v1.0

2.指定标签

为具体某一次提交打标签

$ git tag v0.9 f52c633
$ git tag
v0.9
v1.0

注:
1.标签不是按时间顺序列出,而是按字母排序的
2.标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。

6.2查看标签

可以用命令git tag查看所有标签

$ git tag
v1.0

总结
1.命令git tag <tagname>用于新建一个标签,默认为最新提交 ,也可以指定一个commit id
2.命令git tag -a <tagname> -m "blablabla..."

  • 参数-a:设置标签名称
  • 参数-m:指定标签信息

3.命令 git tag 可以查看所有标签

6.3操作标签

1.删除标签

如果标签打错了,也可以删除,因为创建的标签都只存储在本地,不会自动推送到远程,所以,打错的标签可以在本地安全删除,git tag -d <tagname>命令用于删除标签

$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)

2.推送标签到远程

(1)推送某一个标签
如果要推送某个标签到远程,使用命令git push origin <tagname>

$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0

(2)推送所有标签
一次性推送全部尚未推送到远程的本地标签,使用git push origin --tags命令

$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v0.9 -> v0.9

3.删除远程标签

如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除

$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)

然后,从远程删除,远程删除标签命令为git push origin :refs/tags/<tagname>,删除命令也是push,但是格式如下

$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
- [deleted] v0.9

总结
1.命令 git push origin 可以推送一个本地标签
2.命令 git push origin --tags 可以推送全部未推送过的本地标签
3.命令 git tag -d 可以删除一个本地标签
4.命令 git push origin :refs/tags/ 可以删除一个远程标签

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值