管理Git的分支

目录

一、本地分支(local branches)管理

1.1  查看和建立分支( git branch)

1.2  分支中提交的浏览与比较(git log)

1.3 切换当前分支(git switch)与合并分支(git merge)

1.4 签出分支(git checkout)

二、远程分支及其管理

2.1 远程仓库与远程分支

2.2远程仓库的复刻(fork)与克隆(clone)

复刻远程仓库

克隆远程仓库

2.3把本地分支推送到远程(git push)

2.4把远程仓库的更新提取到本地(git fetch)

注记2 


一、本地分支(local branches)管理

关于Git本地仓库分支的管理,按功能大致可分四组。

查看和建立分支等:包括查看、建立、删除分支,分支重命名等;

2 切换、浏览和比较分支:包括切换、浏览提交日志等;

3 分支比较及分支合并;

4  签出分支:把分支或提交或文件签出到当前分支的工作目录(working tree)中,以便进行查阅和修改。

尽管Git命令有许多是“一专多能”(带不同的参数即执行不同功能)的,但恐并不利于初学者理解。所以这一节对常用的十几个基本命令及其用法作一简介,希望利于初学者掌握。

1.1  查看和建立分支等( git branch

命令1.1  查看仓库里有哪些分支:

$ git branch

这是最常用的命令之一,Git输出本地仓库的所有分支名称。例如:

 图1  输出的结果说明仓库01有两个分支:maintest,而且主分支main是当前分支

1的输出说明:仓库01中只有两个分支,maintest。而且分支名main前标注的星号说明它是“当前分支”,即仓库的HEAD指针定位是main

我们也可以通过查看仓库01.git子目录里文件HEAD的内容得到谁是当前分支,因为其内容正是当前HEAD指针所指的分支路径,如下图所示:

   图2 01/.git里的文件HEAD的内容看到,当前分支是main

      那么从01/.git中怎样看出当前仓库有两个分支呢?查看一下文件夹01/.git/refs/heads即知其中恰有两个文件,名为 main test ,如下图:

   图3 01/.git/refs/heads里的文件看出仓库有几个分支 

 这里我们不妨猜一猜这两个文件的内容。需要注意的是,.git是隐藏的文件夹。

注:在命令$ git branch后加上参数 -avGit就会输出所有分支的信息,包括远程分支(见2.1节),而不只是本地分支。

命令1.2 创建一个名为Y的分支:

$ git branch Y

注意,这个命令会在当前分支的最新提交处(即分支指针所指的提交处)创建一个新分支Y。例如,设最新提交IDf30ab,则新分支Y以提交f30ab为分叉点。其实,命令$ git branch Y 也可以看成是命令“ git branch Y f30ab” 的省略形式,后者见命令1.3

如果现在查看图3中的文件夹,会发现多了一个名为Y的文件。而且这个文件的内容,是最新提交的ID号(40位哈希值)。

命令1.3 在指定的提交C处创建一个名为Y的分支:

$ git branch Y C

例如:在当前分支的一个提交4288处创建一个名为newone的分支

 命令1.4 删除一个名为Y的分支:

$ git branch -d Y

因为Git 分支就是指向某个提交(对象)的可移动的指针(参见《什么是Git的分支》),所以删除一个分支,只是去除一个指针及工作目录中相关的文件,并不会删除Git储存库里的那个提交。我们仍然可以通过提交ID访问那个提交。当然,Git也会自动地处理长期不用的提交。

命令1.5 当前分支名X改为 新的分支名Y:

$ git branch –m(或 -M) X Y

使用参数-m可以避免误删除同名分支Y:即在仓库中已经存在同名分支Y的时候Git提示报错     ;使用参数-M:在把X改为Y时,遇到仓库中存在同名分支Y时,就先把与Y同名的那个分支删除掉,然后再把当前分支名称改为Y,此时要慎重

因为创建、合并和删除分支的速度都非常快,所以Git鼓励使用分支。在新建分支中对追踪文档进行版本改进,虽然这与直接在主分支中工作的效果没有什么差别,但是这个过程的安全性和方便程度却大不相同了。

1.2  分支中提交的浏览与比较(git log

命令1.6  浏览分支X的提交日志清单

$ git log  X

例如,命令$ git log  main –oneline  可以列出主分支main中包含的所有提交。如下图:

    图4  列出主分支中包含的所有提交

一个提交的log信息,默认约占五行左右。为了提高浏览效率,Git用参数—oneline来缩减篇幅,使得一个提交一般只占一行。但是,就算使用了参数--oneline,还是可能需要回车很多次才能看完全部清单。看到清单末尾时,会出现一个醒目的结束提示 ”END”,如下图:

 图5 浏览到清单末尾时,要按字母Q退出浏览状态

注意,此时按字母Q退出浏览状态,回到命令行状态。

此外,清单的顺序是按时间由后向前排列的,即列出的第一个提交就是主分支的最新提交(见图4,其ID69ae5 ……)。

命令1.6中如果省略分支名称X,则默认是指当前分支。如果不用参数--oneline,那么列出的清单会比较长,参见图6

 图6   列出当前分支的提交清单

我们还可以用分支浏览命令来比较两个分支中提交的不同。

命令1.7  对于两个不同的分支X和Y,命令

$ git log Y ^X  列出那些在Y中而不在X中的所有提交;

$ git log X ^Y  列出那些在中而不在Y中的所有提交。

例如,在图7中,仓库01有两个分支:main 与test。图7中第二行命令没有任何输出,

 图7 比较分支main 与test的提交

说明主分支main中的所有提交都在分支test中;而图7中的第三行命令说明,分支test比主分支main多一个提交,提交号为fb9bf,而且该提交包括两个文件。

一个自然的问题是:与主分支main相比,test中的那两个文件是谁,内容如何?从下面的图8中可以看到,很容易查到两个新文件。其中:标注1的命令行列出了主分支工作目录的8个文件名;标注2的命令行把当前分支切换到test;标注3的命令则列出了test分支的工作目录中10个文件名。红色框中的两个文件就是test分支中的两个新文件。

图8 查看main 与test的文件名

这两个文件的内容见图9,第一个文件的内容只有1行,第二个文件的内容有14行(包含空行)

 图9查看两个文件的内容

其实,比较不同分支文件内容的差异不用这么麻烦,Git提供了可以直接比较文件差异的命令。

命令1.8  对于当前仓库的两个分支X和Y,命令

$ git diff X Y   列出所有不同文件的差异;

$ git diff X Y 文件名(带路径) 显示指定文件在两个分支中的不同;

$ git diff  X Y --stat   列出所有有差异的文件清单

例如: 我们执行命令$ git diff main test后,就可以看到Git输出的文件名和内容,见下面的图10。其中:红色框中是文件名test1.txt及其内容,文件内容为绿色(除标识行外)只有一行,而行首符号“+、-” 分别表示多(新增)、少(删除);黄色框中是文件名yc-test01.txt及其内容(绿色,只有14行,包括空行)。

图10比较两个分支中文件的差异(1)

注:文件模式100644表明是它一个普通文件(normal file);100755表示是一个可执行文件(executable file);120000表示为一个符号链接(symlink),等等。

如果上述命令带上参数--stat  ,Git就只列出两分支中有差异的文件的清单,见图11:

图11 比较两个分支中文件的差异(2)

思考:观察git log 带参数“--graph“的作用:

  图12 观察git log 的参数“--graph“的作用

1.3 切换当前分支(git switch)与合并分支(git merge)

命令1.9  当前分支切换到分支X:

$ git switch X

例如,如果当前分支是main,执行命令$ git switch test,就会把HEAD指针指向分支test。此时在01/.git/ 文件夹中可以查看到图6的内容变成了图4的情形:

   图13 01/.git里的文件HEAD的内容看出当前分支是test

该命令有一个偷懒的小技巧,即用“-“代替之前的分支名。例如把当前分支从main切换到test后,那么命令 $ git switch – 又会把HEAD切换回main

命令1.10 把分支X合并到当前分支:

$ git merge   --no-ff  X

例如,命令$ git merge --no-ff test把分支test 合并到当前分支。此处参数“--no-ff”形如“no fast”,含义是:不使用Git默认的快进式合并,同时启动系统的编辑器,以创建一个合并记录文本,可记载分支合并的目的和有关事项(注意,写完后按ESC+Shift+z+z 退出编辑器)。合并成功后会自动完成提交。

注意:使用合并命令之前,应保证当前分支是“干净”的,即工作目录中没有未提交或保存的新修改(可先用命令$ git status 查看一下)。

合并完成后,可以用命令2.6浏览一下提交记录,如下图。注意,Git把刚才的合并也算作是一个提交,从下图中可见,它的提交ID为f4b9d90。

图14  把分支合并到主分支后,Git在主分支中记录了一个新提交

1.4 签出分支(git checkout

Git签出分支(checkout)功能十分重要,它使得的我们可以在一个工作目录中处理任意多个分支的提交。

容易理解,已经提交到Git存储库的文件是不能被直接修改的,就像已进入了档案室的文件一样。确实需要更新内容怎么办?可先办一个手续复制一份出来进行修改。Git的签出有点类似这样的手续。

在签出一个分支时,Git会把该分支(中那个最新版本)复制到当前工作区 (working tree),所以此时在工作目录中就复现了该分支提交时的状态。这样就可以在此状态的基础上进行修改或更新。当这次修改完成后,再通过一个新的提交保存到Git存储库。

由此可见,签出分支的基本用途是:以某个分支(的已有版本)为基础或起点,对版本内容进行升级或改变,而不影响原来的提交。

下面的简单例子可以看出签出分支时工作区的变化。回顾查看仓库分支的命令1.1如果添加一个参数 -v ,则Git输出分支名称的同时会输出各分支最新提交的相关信息。如图15,仓库01的两个分支中,main的最新提交是f4b9d90,而test的最新提交是fb9bffc

 图15   用命令$git branch -v输出各分支最新提交的相关信息

Git签出一个分支就相当于切换到该分支刚完成最新提交时的状态。注意Git提交会生成三类对象,即提交对象、目录树对象和blob对象(参见《什么是Git的分支》), 所以回到上次提交时的状态是指Git把当时的三类对象都复原到了当前。

下图中的命令提示符带有(main),说明当前活动分支是main。用dir可看到当前工作目录中有10个文件:

这也很容易从windows 资源管理器中观察到:如果在Git的命令窗口中当前活动分支为main,那么可以看到仓库文件夹01中恰恰是上图中列出的10个文件:

 命令1.11 签出分支Y:

$ git checkout Y

下面我们签出分支test,此前我们已知test中只有8个文件。在命令窗口中执行: $git chechout test

然后dir,于是看到现在的工作目录中只有8个文件。

 此时也可以回到windows 资源管理器中再次观察:

图16  当前活动分支是test,仓库文件夹01中只有8个文件 

总之,Git的签出分支命令会引发下列操作:

  1. 将活动分支切换成被签出的分支;
  2. 把被签出分支所指向的提交内容覆盖到工作目录中。

要注意的是:执行签出命令之前要先(通过提交或储藏)处理好当前目录中还需要保存的新内容,以免出现无意中被删除(覆盖)、或者被Git拒签等情况。(当然,也可以用强制参数 -f 来废除工作目录中那些未提交的更改,强行签出)。

有时,我们也可能需要签出一个“非分支提交”,也就是说,签出某分支中的一个“老提交”而不是其最新的提交。比方说,如果我们正在01仓库的test分支中进行开发时,突然发现之前某次提交的版本可能导致项目出现了问题,所以想要从那个提交开始,重新进行设计提交。这就需要签出那个提交。

命令1.12 签出当前分支中提交号为N的非分支提交:

$ git checkout N

例子:图17中,仓库Image-Denoising的主分支main包含6个提交,其中的第4行提交(提交号为1eb7d6d删除了一个文件,但是现在发现这个文件不能删除。为了找到这个文件,我们签出第5行提交(提交号fb5ad91),命令为:$ git checkout fb5a,见图18。

图17  Image-Denoising的主分支main中,第4行提交1eb7d6d删除了文件“2016论文…”

图18 签出第5行提交fb5ad91,命令为 $ git checkout fb5a

Git对这个命令返回的消息比较多,其中的主要内容包括:

  1. 仓库的HEAD指针 现在指向了提交 fb5a (见返回信息中的第一行和倒数第一行)
  2. HEAD指针本应指向当前分支的最新提交(Git登记的提交),但现在它离开了最新提交
  3. 可以用命令 ”$git switch – “ 撤消这个操作;也可以在此提交处新建一个分支,从而保存在这里所做的修改或提交。

从下图中可以看到主分支 main  现在的最新提交是50a50f9(同图17中所见):

图19  从图中可以看到主分支的最新提交是50a50f9

但是下图说明,执行签出命令1.12后,文件HEAD的值已经改变:

图20 执行签出命令后,文件HEAD的值已经改变

回到当前工作目录,我们用dir查看一下文件夹:

图21  原来删除的那个文件(2016-论文….pdf)已经“回来”了  

发现原来删除的那个文件(2016-论文….pdf)已经“回来”了。上面已说到,要保存在这里所做的提交和修改,应该以此提交为分叉点新建一个分支(分支名为 paper):

 现在我们在上图中最下面一行提示符中看到了当前分支是paper。把它合并到主分支后,文件(2016-论文….pdf)就回到主分支了。

注:上图中的两行命令也可以用一行命令 “$git switch -c paper“代替,熟练后可偷懒。

Git也可以签出一个单独的文件,也就是说,只是签出某分支中的某提交里所包含的某个文件。

命令1.13 签出一个提交过的文件:

1)单独签出当前分支中(最新提交过的)文件file:git checkout file ;

2)单独签出提交N中的文件file:git checkout N file (N为提交号)

注意:单独签出一个文件不会影响当前分支,只会在工作目录中得到指定文件的另一个版本。但是,它会覆盖工作目录中的同名文件(如果有的话)。

下面是一个简单但也许常见的应用:怎样恢复一个已经提交修改了的文件?

例子:图22中,仓库Image-Denoising的当前分支DLmethods中,包含6个历史提交。

图22  在仓库Image-Denoising的分支DLmethods中,包含6个历史提交

从下图看到,当前工作目录中有5个文件,其中的第二个为 li.txt。

查看第二个文件 li.txt的内容,只有两行,见下图:

我们突然想增加一行:one two three four five。于是修改后进行提交,提交过程参见下面第二个图中的命令(其中提交说明为:增加一行)。修改后的内容见下图:

 问题:如果提交后发现这个修改是错误的,需要取消,怎么办?下面通过签出单独的文件来解决。

查看当前分支的提交记录发现,刚才的提交(“增加一行”)的ID为83be8ab。我们从其父提交50a50 签出文件li.txt,就轻松地取消了刚才的修改 。

二、远程分支及其管理

2.1 远程仓库与远程分支

一、理解远程

1、“远程”的含义

只要说到远程,也就说到了URL。一个远程网址URL可能(在多数情况下)对应着一个自己在GitHub上建立的Git仓库。不过,它也可以是指我们通过复刻(fork)别人在GitHub上的公开仓库而得的GitHub上的一个Git仓库,或者也可以是在不同服务器上的某个Git仓库。不管是哪种情况,这样产生的仓库都称为远程仓库,其分支称为远程分支

远程仓库也被称为远程服务器(remote server)或远程主机,甚至简称为远程

2、“远程代号”

很多工作在本地仓库中进行更为合适,因此常常要在本地引用远程仓库。所以为远程仓库设置一个代号(例如Git默认的代号origin),显然是明智而实用的(避免输入冗长的URL)。我们称这样的代号为远程代号。通过Git的remote命令,在本地可以灵活地管理这些代号,一个远程代号也称是一个远程引用(remote reference),但后者包括更多内容,例如标签等。

命令2.1 远程代号管理命令

 格式: $git remote <命令动词> ……

用法举例:

远程代号更名:git remote rename  <旧远程代号>  <新远程代号>

删除远程代号:git remote remove  <远程代号>

创建远程代号:git remote add  <远程代号>  <远程网址>。

3、Git分支的三种类型

现在我们可以来看看Git分支的三种类型。在建立了本地仓库与远程仓库的关联之后,Git仓库就会有三种类型的分支

第一种类型本地分支,是可在本地仓库中建立的分支(branches)。例如本地仓库初始化后所生成的主分支main,存放在本地仓库,而且可以直接在其中提交更新或进行推送(到远程)等操作;

第二种类型远程分支(remote branches),是存放在远程仓库中的分支,可以直接在Github远程仓库中建立,也可以通过用户本从地仓库的推送进行创建和更新;

第三种类型远程追踪分支(remote tracking branches)或称追踪分支,这是一类特殊的分支,是存放在本地仓库中的“哑(dumb)” 分支,用来追踪远程分支的状态,表示成<远程代号> / <远程分支>。例如,假定远程代号为origin,那么用来追踪远程主分支main的远程追踪分支,就表示成origin/main。

使用远程追踪分支,可以使得本地与远程交互变得简化和快速。Git只在必要的时候才会激活本地与远程的连接(临时连接),并且在连接结束的同时顺便给远程“拍一个照”,用来记录远程的当前状态,然后存放在远程追踪分支中。这样做的好处,是可以随时在本地查看远程的相关信息而不必连接远程(注意:看到的是上一次激活连接时的内容)。

值得注意的是,在用克隆(clone)的方法把远程仓库复制到本地的时候, Git不但会将所有远程分支都复制到本地,而且会自动为这些分支建立其远程追踪分支。此外,当本地操作需要连接远程时,便在Git命令中使用<远程代号> / <远程分支>来表示远程分支,即Git通过远程追踪分支把本地分支与远程分支连接。

最后,一个本地分支所对应的远程分支被称为该分支的上游分支(the upstream branch),而有时为了简便我们也把远程仓库或远程分支就简称为“远程”。

二、建立远程仓库和远程分支

命令2.2 创建SSH 密钥命令

$ ssh-keygen -t rsa -C "箱地址"

网站GitHub(一个面向开源及私有软件项目的托管平台,得名于其仅支持git的版本库格式)为Git仓库提供远程托管服务,它使得我们可把本地的Git仓库推送到“云中”,成为远程仓库。

本地仓库与Git远程仓库的通信需要使用网络安全协议。一个常用的加密协议是SSH(Secure Shell Protocol),该协议通过网络提供安全通道。为了简单起见下面只考虑采用此协议的情形。为了在GitHub中建立自己的Git仓库,需要先完成三个任务:

任务1:在GitHub主页https://github.com上注册一个用户账号,需要提供自己的邮箱地址。注册成功后可以通过网址https://github.com/你的用户名/ 访问自己的GitHub主页。(参见本节末的注)。

任务2:创建SSH Key(SSH 密钥)。在Windows开始菜单中打开Git Bash输入下列命令然后按括号中提示操作:

$ ssh-keygen -t rsa -C "你的邮箱地址"

------------------------------------------------------

Generating public/private rsa key pair.

Enter file in which to save the key (/c/Users/Administrator/.ssh/id_rsa): (按回车

Created directory '/c/Users/Administrator/.ssh'.

Enter passphrase (empty for no passphrase):(输入一个远程密码

Enter same passphrase again:(确认该远程密码

记住下面的两个文件名及路径

Your identification has been saved in /c/Users/Administrator/.ssh/id_rsa

Your public key has been saved in /c/Users/Administrator/.ssh/id_rsa.pub

The key fingerprint is:

SHA256:cQ5yPicAD9m4gtsQPEPSlEZTKp1d+pODg9XtT3GM0ew libcsgg@gmail.com

The key's randomart image is:

+---[RSA 3072]----+

…………

|o..o.o B = oE    |

| +..o = S +      |

|. .  . o *       |

......

--------------------------------------------------------------------

看到这样的图就说明创建SSH Key成功。从Windows用户主目录中找到子文件夹.ssh(按上面提示,其路径为“c/Users/Administrator/.ssh”),文件夹中应该有id_rsa和id_rsa.pub两个文件,它们是SSH的秘钥对。前者是私钥而后者是公钥。注意保存好远程密码并复制文件id_rsa.pub的内容(不是复制文件)。

任务3:登陆GitHub,打开“Account settings”找到“SSH Keys”页面,然后点击“Add SSH Key”,填上一个Title(为本地的远程连接取一个代号),再把id_rsa.pub的内容粘贴在Key文本框里,最后点“Add Key”,就可以看到新添加的Key了。

完成了上面三个任务就可以方便地在自己的Github账户中建立一些远程仓库和远程分支了。

下面是建立一个新仓库的过程简介:首先登录自己的Github主页,点击主页中第一行按钮中的Repositories(仓库),就进入了仓库编辑页面,如下图。然后点击该页面左边那个醒目的绿色按钮‘New’,并在下一个页面填入一个仓库名(Repository name),注意要符合命名规则。最后再点击页面最下面绿色的创建仓库按钮,就建立了这个新的远程仓库。

这个新的远程仓库有一个自动生成的主分支main,是仓库的当前分支。也就是说,仓库的HEAD指针现在指向它。

如果现在我们要建立分支,操作也很简单。在仓库主页点击进入Code页面, 按钮“Code”下方就出现橙色横线,见下图。再点击”branch”按钮,下图中红色箭头所指,就进入了分支主页。接下来就可以

在仓库主页中创建新分支了(在下图中点击最右边绿色的“New branch”按钮)。 

注记1  其实在注册Github账号时平台就会提示你先建一个特殊的公开仓库,并让你在其主分支main中撰写一个文件README.md 。可以在该文件中介绍你的情况,如兴趣,成就等,也可以在其中编辑你的Github主页的样式。这个README.md文件会在配置文件profile中出现,以后也可以随时修改它。

2.2远程仓库的复刻(fork)与克隆(clone)

复刻(fork)别人的某个公开仓库是最容易获得远程仓库的办法,而把远程仓库克隆(clone)到本地,则是用本地分支对远程分支进行维护的高效而方便的方案。

复刻远程仓库

复刻有许多应用。通过复刻所得的远程仓库只是原仓库(也称之为“上游仓库”)的一个副本,对它的任何更改都不影响其上游仓库。怎样进行复刻呢?下面通过一个例子说明。

例:把JulieS的主页(https://github.com/Juliecodestack)下的仓库Juliecodestack.github.io复刻到自己的Github账户下。

1)在JulieS的主页中点击Repositories(仓库)选项(见下图红色箭头所指),可进入到仓库列表页面。

2) 在仓库列表页面中一共列出了8个仓库,每个仓库下方和右边都有关于该仓库的一些基本信息。我们要复刻其中第二个,名为Juliecodestack.github.io。点击此仓库名,进入这个仓库的主页,见下图。

3) 在页面的右上方,排列着3个按钮,其中第二个就是Fork(红色箭头所指),旁边的数字说明此仓库被复刻了2次。点击红色箭头所指的小三角,然后选择菜单“Create a new fork”,然后查看下图中有红色标记的4处地方:

其中第一个是自己的Github账户名,第二个是给复刻仓库起的名,系统填了默认值(可以另起一个名)。第三个标记处输入关于复刻这个仓库的说明(也可忽略)。第四个标记处可以选择是否打勾,假如只要复刻上游仓库的一个主分支而不是全部分支,选择打钩。

完成以上步骤后,点击下方的绿色按钮,就完成了仓库的复刻。此时页面会跳转到自己Github网站中的这个复刻仓库的页面。

最后,可以点击复刻仓库的页面右下角的绿色按钮为这个(复制来的)新仓库撰写README文件(也可先忽略)。至此就完成了复刻仓库Juliecodestack.github.io的全部过程。

克隆远程仓库

下面再通过一个例子来说明怎样把自己远程仓库通过克隆(Clone)到本地的一个磁盘。注意,与前面的操作不同,这里的操作都是在Git Bash命令窗口中进行的。

命令2.3克隆远程仓库命令

 $ git clone  <远程地址>  <本地路径>

该命令把位于<远程地址>的远程仓库完整地复制到本地指定的路径。如果省略本地路径,则复制到当前文件夹。

  把远程仓库libcs-gg/01克隆到本地电脑的U盘F:/GitHub。为叙述简便,以下把文件夹“F:/GitHub”简记为A。

克隆过程如下:在A中打开Git Bash,输入命令:$git clone git@github.com: libcs-gg/01.git

注意:一般来说远程仓库“用户名/仓库名”的SSH地址为:git@github.com:用户名/仓库名.git。在目标仓库的页面中,点击“Code”就可以查到并进行复制(参见下图)

 此外,克隆时系统会要求输入“远程密码”,见2.1节中建立远程仓库和远程分支

上述过程正常完成后远程仓库就下载到了A 中。可以从命令窗口用dir命令可以看到A中出现了一个子目录01,还可以查看到01的文件和隐藏属性的子文件夹.git(当然,也可以直接在Windows的资源管理器中查看)。

2.3把本地分支推送到远程(git push

分享一个分支时,需要把它推送到一个具有写入权限的远程分支。从下面的例子中可以理解推送的基本过程。如果已有。

例1  本地分支 serverfix 要通过远程仓库(代号是origin)分享,可使用下列命令推送:

$ git push origin serverfix

这里省略了一个“尾巴”,Git 将上面的命令理解成 “git push origin serverfix:serverfix”。命令意味着把本地分支 serverfix推送到远程origin的 serverfix 分支(其中冒号前的serverfix表示本地分支,后面的则表示远程分支。此外,如果远程的同名分支不存在,则Git新建一个)。当然,冒号后的远程分支名称也可以是另外起的名。

例2  在下面实例中,我们要把本地名为test的新分支推送到远程。为此,先查看全部分支情况,并查看test分支的状态。如下图,test分支最新提交为fb9bffc,而且远程没有test分支。

下面在Git Bash中执行命令:

$ git push origin test

则Git返回了下图中的信息:

如果再执行一次$git branch -va,就可见远程出现了test分支,且其最新提交与本地test一致。命令git push的完整格式如下。

命令2.4 推送本地分支到远程仓库的命令

$ git push <远程代号> <本地分支>:<远程分支>

Git允许省略 “:<远程分支>”这个尾巴,前提是远程分支名称与本地相同。此外,如果<本地分支>与<远程分支>已经建立了关联(后者是前者的上游)那么命令可以简化成:

$ git push origin

如果远程仓库origin也是默认的,那么命令可以更简化:

$git push

2.4把远程仓库的更新提取到本地(git fetch

用git push命令推送本地分支时常可能遇到问题。因为Git要求本地仓库要在先提取(fetch)远程分支的更新(并完成合并)后,才能进行推送。所以 git fetch 命令是不可或缺的。

git fetch 用来从一个或多个其他存储库中提取“refs”(分支和/或标签),是提取上游更新的基本工具。提取更新的过程可分为“提取”和”合并”两步。

命令2.5 提取远程分支更新命令组

$git fetch  <远程代号>  <远程分支>

$git merge  <远程代号>/<远程分支>

其中第一部分$git fetch  <远程代号>  <远程分支>负责查找指定的远程分支中的新内容信息,并提取到本地的远程追踪分支中(必要时创建该本地分支);第二部分$git merge  <远程代号>/<远程分支> 负责把更新了的远程追踪分支合并到当前分支。

例1   如果远程(origin)主分支main接收了别人推送的更新,而本地分支没有改变,就会导致二者的分离(diverged),即本地分支的指针落后于远程分支的指针,此时不能从本地推送到远程。为了解决这个问题,执行命令:

$git fetch origin main

把远程的更新提取到本地的上游追踪分支origin/main中。再执行命令:

$git merge origin/main

当合并完成后,就完成了提取远程更新的全部过程。

注记2 

1、关于Git的远程提取命令 fetch,还有一点值得注意。如果提取远程分支serverfix时生成了一个本地的远程追踪分支origin/serverfix,那么Git不会自动生成其可编辑的本地副本。也就是说,这个分支并不会出现在Git工作区,也不能对它进行修改。所以,如果要拥有自己在本地的serverfix分支(作为远程serverfix的追踪分支),还要把刚才的远程跟踪分支签出到本地,其命令为:

$ git checkout -b serverfix origin/serverfix

2、默认情况下,任何指向被提取的历史的标签也会被获取,包括那些指向你提取分支的标签(这个默认行为可以通过使用 --tags 或 --no-tags 选项来改变)。

3、当没有指定远程时,默认情况下Git会使用 origin 远程,除非当前分支已经配置了上游分支。

4、Git还有一个命令可以用来提取上游的更新,它就是拉取命令

命令2.6拉取远程仓库更新命令

$git pull  <远程代号>  <远程分支>

拉取命令调用git fetch与git merge(或git rebase)一起执行,有点像个批处理。由于执行git pull时,Git会直接进行合并,就有可能无法知道造成了哪些冲突,所以它也并不一定会比前面的两个命令省事。

此外,使用命令git fetch 同时从多个远程中提取所有更新恐非明智之举,可能出现长时间的等待。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值