0


管理Git的分支

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

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

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

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

3 分支比较及分支合并;

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

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

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

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

$** git branch **

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

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

图1的输出说明:仓库01中只有两个分支,main和test。而且分支名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后加上参数 -av,Git就会输出所有分支的信息,包括远程分支(见2.1节),而不只是本地分支。

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

$** git branch Y **

注意,这个命令会在当前分支的最新提交处(即分支指针所指的提交处)创建一个新分支Y。例如,设最新提交ID是f30ab,则新分支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,其ID是69ae5 ……)。

命令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。点击此仓库名,进入这个仓库的主页,见下图。

  1. 在页面的右上方,排列着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 同时从多个远程中提取所有更新恐非明智之举,可能出现长时间的等待。

标签: git github

本文转载自: https://blog.csdn.net/qq_53514756/article/details/130655451
版权归原作者 libcs 所有, 如有侵权,请联系我们删除。

“管理Git的分支”的评论:

还没有评论