git的基本使用

1 git是什么

官方说法:Git是一个开源的分布式版本控制系统。用于敏捷高效地处理任何或小或大的项目。

说白了,git就是帮助我们管理项目的一个工具。他的核心作用只有两点:

版本控制:当我们每向git提交一版代码,git会为我们自动保存这一版代码,当我们开发的时候写崩了某个部分而找不到解决办法时,就可以回滚到上一个版本。

多人协作:当有两个人开发同一个项目时,我今天写了一点,他也写了一点,那第二天我们两的代码不一致了,怎么办。git会告诉我们,当我们每天完成开发之后,将本地的代码上传到git服务器上面,第二天每个人只需要重新拉取一下远程代码,它不仅会将目前git服务器上最新的代码同步到本地,还不会覆盖本地已经修改的部分。

现在已经明白了git是什么,以及他最大的用处。我们还需要了解几个关键定义:

工作区(workspace):通俗来讲,就是本地一个项目的那个文件夹,就是工作区;

暂存区(staging area):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。版本库中最重要的就是暂存区,我们可以把修改之后的代码存在暂存区。

本地仓库(local repository):本地仓库就是一个本地的代码仓库,它的功能与远程仓库没有区别,是在本地存储代码的一个仓库。那么暂存区和本地仓库都是储存代码的,有什么区别呢。

首先,暂存区只是储存了修改过的代码,本地仓库存储了每一个版本的全部代码。你可以理解为需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改;

其次,本地仓库有所有的分支信息,也就是说在本地仓库整个项目的结构,以及仓库的开发结构是完整的,而暂存区只是将修改之后的文件散列的放在了一个地方。

远程仓库(remote repository):远程仓库就是我们一般所指的仓库,我们在开发中的代码基本上都要推送到远程仓库中,以防丢失。

2 git多人开发指南

2.1 创建git仓库

由项目管理员新建一个git远程仓库,此仓库是储存在远程服务器的,我们使用它的地址就可以进行访问。

git init

2.2 从远程仓库克隆到本地

在git远程仓库我们一般是不做开发的,而是先把此项目克隆到本地。

git clone <url>

当克隆到本地之后,我们就可以在本地此文件中进行开发了。

2.3 推送最新代码到服务器

当我们在本地完成开发之后,我们需要把代码推送到远程仓库中,让此项目别的开发者能够直接看到和使用你的代码。

git status //用于查看在你上次提交之后是否有对文件进行再次修改。

git add [file]  //此命令用于添加一个修改之后的文件到暂存区

git commit [file] -m [comment] //此命令用于将暂存区的文件提交本地的仓库中,可以使用-m后面做一些修改的备注

git push   //用于从将本地的分支版本上传到远程并合并

我们可以使用以上代码将本地修改之后的文件传入远程服务器。

2.4 拉取远程最新代码到本地

现在,程序员小赵已经将自己开发的最新代码放到了远程服务器上面,程序员小民也在同一个仓库进行开发,如果小民一直不从仓库拉去新代码,而一直在本地开发,时间长了之后再将代码上传到仓库中,会出现很多问题,比如命名冲突等,所以我们在开发过程中需要经常拉取最新的代码到本地,保持在最新代码的基础上进行开发。

git remote -v  //此命令用于查看远程仓库主机地址及其名称

git pull <远程主机名> <远程分支名>:<本地分支名>  //此命令用于将远程分支的最新代码拉取并合并到本地分支,分支后文解释

我们可以使用上面的代码将远程仓库最新的代码同步到本地,并在最新代码的基础上进行开发。

2.5 重置撤销

现在,你学会了提交代码。但是,git作为一个版本控制工具,当然还能支持我们撤销之前的提交。撤销可分为以下几个种类:

撤销工作区更改的文件:我们当然可以使用Command+Z一直撤销到上一次提交的位置,但是如果修改的太多,甚至超出了电脑本身的缓存步数,那么Command+Z显然是不太好用。但如果我们采用直接拉上一个版本的代码覆盖本地代码,会导致修改的其他文件都被覆盖。所以,git为我们提供的专门的命令来完成对工作区文件的修改撤销。

git checkout -- <filepath>  //此命令用于撤销工作区某个文件的修改

撤销上传到暂存区:前面我们已经讲过,可以通过git add命令将工作区的文件添加到暂存区,git也为我们提供了把暂存区的某个文件重置为修改未暂存状态的命令:

git reset HEAD <file>  //此命令用于撤销暂存区文件

撤销commit:加入我们已经将暂存区的文件commit到了本地仓库,现在我们想撤销这次操作,那么我们可以使用以下的命令:

git reset --soft HEAD^  //此命令用于撤销某次commit

撤销push:前面我们已经讲过,远程仓库和本地仓库没有实质的区别,只是一个是远程仓库,一个是本地仓库,所以当我们push到了某个版本的代码到远程仓库想要撤销时,也是使用git reset命令。

现在我们已经明白了好几个撤销操作,但是我们发现,大多数的撤销操作都是用git reset命令来实现的,这么神奇的命令当然要解析一波。

在我们理解git reset之前,我们首先要弄清楚,git管理项目的方法。git作为管理工具,实际上它是管理了三颗文件树:

一颗是HEAD,它是当前分支引用的指针,它的作用为上一次提交的快照,下一次提交的父结点;

一棵是Index,它用于预期的下一次提交的快照,也就是我们前面提到暂存区;

一颗是Working Directory,它是本地工作区的文件树,称为沙盒。

经典的 Git 工作流程是通过操纵这三个区域来以更加连续的状态记录项目快照的。

现在,让我们来撸一遍提交的整个流程:

**初始化仓库:**假设我们进入到一个新目录,其中有一个文件file.txt。我们称其为该文件的 v1 版本,将它标记为蓝色。现在运行 git init,这会创建一个Git仓库,其中的HEAD引用指向未创建的master分支。那么此时,只有我们暂存区有此文件,而此时git仓库的状态为,没有任何文件。此时我们运行git status命令,显示有Untracked files,提示使用git add命令提交到暂存区。

现在我们运行git add file.txt命令之后,我们把此文件加入了暂存区,此时三棵树和git仓库的状态如下,Index所指的树已经和沙盒同步,使用git status查看此时的状态,提示我们有一个文件改动需要被提交。

现在我们执行git commit命令,提交到仓库之中,此时三棵树和git仓库的状态如下,三棵树的文件都已经同步,而且仓库中已经存储了这次改动,并且生成了一个哈希值eb43df8作为这次改动的唯一ID。此时运行git status命令,显示已经没有修改未上传的文件了。

通过这个过程我们可以看到,我们修改一次文件到将她推到仓库中,实际上是三棵树在同步的过程。现在我们想要对文件进行修改然后提交它。我们将会经历同样的过程;首先在工作目录中修改文件。我们称其为该文件的 v2 版本,并将它标记为红色。此时三棵树和仓库中的状态如下左图。当我们完整的走完一遍上述流程之后,三棵树和仓库的状态如下右图,仓库中已经存储了这次改动,并且生成了一个哈希值9e5e6a4作为这次改动的唯一ID。注意,此时虽然三棵树的状态已经完全同步了,但是在仓库中,其实还是保存了v1版本的file信息,而修改之后的文件commit上去之后,git仓库又为他创建了一个快照并且将HEAD指向了新的快照。

现在我们已经明白了在每一次提交代码时git都发生了怎样的变化,那让我们把话题拉回到reset上面,当我们执行git reset时,git都做了哪些事呢。比如,现在我们要撤销v2版本的提交,那么我们使用git reset eb43bf8命令,git内部一共执行了以下几件事:

  1. **移动HEAD:**此步会将HEAD所在分支指向eb43bf8;当我们移动到上一次提交记录时,那么此时的HEAD树就已经变成了v1版本的代码,这部操作看起来就像是我们撤销了commit操作一样;当我们在使用命令git reset --soft eb43bf8,加入了–soft参数之后,git会执行到这步停下来,此时我们就可以使用git status命令再来查看暂存区和仓库的区别。

  2. **更新Index:**接下来,reset 会用 HEAD 指向的当前快照的内容来更新Index树。执行完这一步之后,Index树就已经回滚到了上一次提交的版本,这也是git reset命令的默认停止地点,也就是说,当git reset命令在没有添加版本作为参数时,例如git reset HEAD~,到这一步就停止了,当我们制定了明确的版本号git reset eb43bf8,那我们可以使用git reset --mixed eb43bf8让它停在这一步,此时我们可以使用git status命令来查看一下当前的状态。它依然会撤销一上次提交,但还会取消暂存所有的东西。于是,我们回滚到了所有git add和git commit的命令执行之前。

  3. **更新工作目录:**ok,打起注意,这个操作,相当危险。当我们使用了git reset --hard命令,那么reset命令会强制执行这一步,将本地的代码也会滚到上一个版本,而且是强制覆盖,不能恢复,慎!

上面的讲解可能让你有点费解,那么用一种更加通俗的语言来说,reset就像是go-to命令一样,我们使用reset就会将HEAD指向另外一个版本,除了在当前分支上操作,你还可以通过传入这些标记来修改你的缓存区或工作目录:

  • –soft – 缓存区和工作目录都不会被改变;

  • –mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响;

  • –hard – 缓存区和工作目录都同步到你指定的提交;

ok,我们现在知道了reset从仓库重置代码的操作,如果你还记得,前面我们讲过,从暂存区撤销到工作区,也是使用reset命令,没错,当我们使用git reset 命令时,也就是后面跟一个文件路径时,git会自动跳过第一步移动HEAD,这是与git add完全相反的操作。现在,让我们来聊聊reset的弊端。现其一,在我们的仓库里有两个版本的代码v1和v2,当我们使用reset命令之后,HEAD指向了v1版本,而这个时候我们提交代码到远程仓库时是提不上去的,因为远程仓库的HEAD还留在v2版本,那就只能采用强制提交git push -f。采用这种方式回退代码的弊端显而易见,那就是会使 HEAD 指针往回移动,从而会失去之后的提交信息,也就是说,v2版本永远没了,当我们以后发现v2里面还有很多非常好的东西时,为时已晚;其二:当我们的仓库拥有三个以上版本的代码时,例如现在有v1,v2,v3,但是想要撤销v2点更改,那么使用git reset会将v3版本同时重置,但是v3是一个正确的版本。所以,我们需要找到一个命令,既可以回退代码,又可以保存错误的提交。这时,git revert命令就派上用场了。

git revert的作用通过反做创建一个新的版本,这个版本的内容与我们要回退到的目标版本一样,但是HEAD指针是指向这个新生成的版本,而不是目标版本。例如,在上述只有v1和v2两个版本时,我们使用git revert HEAD,此命令会在现在的HEAD基础上,在提交一次更新,在创建一个版本v3,而v3的内容和v1是一样的,但是却保留了v2版本的代码在仓库中,而不至于丢失。从直观上看,revert操作实际上是拉取了一次之前版本的代码, 提交到了当前的仓库,从而创建了一个新的版本。好了,问题来了,如果现在有三个版本的代码v1,v2,v3,我要使用revert操作回退v2版本,那实际上是拉取了v1版本的代码,然后提交到了v3上面。那如果此时我的工作区有修改了但是还没有提交代码,直接revert一个版本,不就会覆盖了我现在未提交的代码,让我丢失工作进度,产生了冲突。这个时候我们需要先解决冲突再进行提交,解决冲突的办法见后文。

2.6 推送代码的要求

我们在上面3和4中讲了推送最新代码到远程仓库,拉取远程最新代码到本地。那么问题来了,程序员小赵推送了最新代码到本地,程序员小民没有先拉取最新代码直接提交自己的代码到远程仓库,完蛋了,覆盖了,小赵一天的工作都没了,删人代码如杀人父母。宝啊,这可不兴的干啊。为了防止这种事情的发生,git设置了一些措施,会阻止没有拉取最新代码的推送。所以我们在每次推送自己的代码前都需要先拉取一下最新代码。另外,虽然git有一些措施防止未pull先push,但是也有一些强制push的方法,千万不要瞎搞,覆盖了别人的代码别人是会找你拼命的。

所以,对很多开发人员而言,一打开电脑,马上先git pull,拉取最新的。然后进行常规开发,开发完毕之后,在git push之前,还需要使用git pull再拉取一遍。

3 git分支–git的看家本领

3.1 分支是什么以及存在的意义

现在,我们一个项目有多个开发者,所有人在开发完之后都把代码上传到远程仓库,下一次开发时又拉取最新的代码。程序员小赵今天开发了模块A,但是才写到一半,晚上他把代码上传到了仓库,第二天程序员小民拉取了一份最新的代码,完犊子了,运行不了,里面有不成熟的代码。那我要是没有成熟的代码先不推送到仓库,等到完全开发完成再推送,那我每天都面临着丢失进度的风险。

这个时候分支的作用就体现出来了,master分支是主分支,而我们需要开发一个全新的模块时可以在这个分支上面新建一个全新的分支,你可以在此分支上拉起最新的maser分支上的代码,而自己还没开发完成的代码只需要推送到当前分支即可,这样我们就实现了即能保存自己最新代码的功能,也实现了多人协同开发。

3.2 分支的主要操作

git branch <branchname>  //此命令用于新建一个分支,当没有branchname参数时,会列出当前所有的分支
  
git checkout <branchname>  //此命令用于切换开发分支
  
git branch -d <branchname>  //此命令用于删除一个已存在的分支

3.3 合并分支

现在,我们已经在新的分支develop上面完成了新模块的开发,但是master主分支上面却没有我们开发的这部分代码,那我们需要将这部分的代码想办法推送到master分支上面。此时我们就需要使用到分支合并。分支合并的操作主要为以下两步:

git checkout master  //切换到主分支master

git merge develop  //主分支合并develop分支

当然,执行了以上两步之后,我们也只是将代码合并到了本地的master分支,而我们还需要将此部分代码推送到远程master分支。诶,这里我们又提出了一个远程分支和本地分支的概念,以及,我们在上面创建的远程分支和本地分支有什么关联呢。接下来让我们来讲一下这两者。

3.4 本地分支和远程分支

其实就我们自身开发而言,本地建立一个git仓库就已经完全能够实现版本控制的功能,而远程仓库所起的作用就是协作开发。所以,其实我们在开发中是维护了两个仓库,一个本地一个远程,git pull操作和git push操作为我们本地仓库和远程仓库交付代码的指令,而其他操作如新建分支都是在本地仓库进行操作的。那么问题来了,我们本地的仓库是怎么和远程的仓库关联起来的呢。问题就在第一步的git clone,此操作会将本地的master分支与远程的master分支关联起来,我们把这种关联称为trace,在我们没有建立其他关track之前,本地master和远程master是本地仓库和远程仓库唯一的关联。所以,我们在本地某个分支上开发结束之后,需要先合并到本地的master主分支,再从master主分支才能推送到远程仓库,而没有关联到远程分支的本地分支是不能直接进行git pull和git push操作的,当然,我们可以使用git push origin branchname和git pull orgin branchname来指定远程分支名。看到这儿,很多同学要口吐芬芳了,整这么个玩意儿,只能本地用,太鸡肋了吧。诶,别急,既然能建立远程master和本地master的联系,那当然也能建立其他分支的联系。

git checkout --track origin/branch_name  //此命令用于新建本地分支,并将他关联到远程同名分支

git push --set-upstream origin branch_name  //此命令用于在远程新建与本地同名分支,并将两者关联

好了,通过以上两条命令,我们成功的将本地分支与远程分支关联起来了,现在我们提交和拉取代码都只需要简单的使用git push和git pul。那么问题又来了,我们上面讲到,在将本地非主分支合并到远程主分支的操作中,需要先讲本地的此分支与本地master分支合并,再将master分支的代码推上去。但是我们现在建立了两条本地与远程的关联,那我们就有另外一种方式来实现本地非主分支合并到远程主分支,先将本地此分支的代码推到远程同名分支的代码中,再从远程将分支合并。这两种方法,都是可行的,但是在日常开发中,我们一般使用的是后者,原因见下文本公司Code托管操作指南。

3.5 分支带来的问题

我们现在已经知道了分支的操作,也体会到了分支带来的好处。但是,分支的到来也会产生一些弊端。程序员小赵和程序员小民在自己的本地开发,他们都关联了同一个远程分支develop,现在,小赵先推上了自己的代码到develop,而小民没有先合并代码就直接推上了自己的代码,那这就有可能产生冲突,因为两次提交可能会修改同一份代码。而一旦发生这样的事情,git就会提示我们产生了冲突,现在我们就需要自己解决冲突。

3.5.1 冲突解决的步骤

问题描述:在提交pr时会出现冲突,原因是目标分支的代码别人已经更改过了,而你没有拉取最新的代码,会导致这两个文件冲突。

解决办法:

本地checkout检出并切换到A分支,pull拉取更新到最新代码

查看冲突的代码部分,其中:

>>>>>>HEAD
{
	你的代码
}
======
{
	别人修改的代码
}
>>>>>>03hdaiondahdnsad

手动删除其中部分代码以及>>>>>>HEAD、======、>>>>>>03hdaiondahdnsad

git add 冲突的文件,git commit重新提交

4 fork仓库

公司的要求是在开发中现将公用的代码仓库fork到自己的仓库下面,然后在自己的仓库下进行开发,开发完成之后再进行同步。这样的好处是,如果很多人都在公共代码库中进行开发,虽然由于分支的存在,我们可以保证master主分支的纯洁性,但是会在这个项目下面建立太多分支,切所有人都在同一个远程仓库进行开发不方便管理。我们所希望看到的是,再没有开发结束之前,开发的代码不会在公共仓库中让所有人都能看见,而一个功能开发结束之后可以很简单的完成对公共仓库的更新,而不需要在公共仓库建立太多不实用的分支,再者,没有一个管理者会让开发者直接在中心仓库里直接进行修改而没有限制。

4.1 fork仓库与源仓库的关系

fork,以github为例,我们在进入一个仓库之后,点击右上角的​fork按钮就可以将这个仓库复制到自己的远程仓库中,接下来你只需要使用前面提到的git clone方法将他克隆到本地,这个仓库与源仓库的代码是一样的,只不过这个仓库是属于你个人,你想在此仓库上做什么开发都可以。

我们已经知道了这两个仓库其实是完全独立的两个仓库,但是我既然是fork的别人的仓库,那么我当然希望我的仓库和原仓库的代码能够保持一致。这时候我们需要为本地仓库添加源仓库的地址为数据源,然后从此数据源拉取代码即可。

git remote -v  //此命令用于查看本地仓库的数据源,如果你没有添加任何别的仓库,之间简单的clone了自己的仓库,那这里面应该只有一个名为origin的源,地址为你自己的远程仓库地址

git remote add <name> <url>  //此命令用于为本地仓库添加一个地址为url名为name的远程仓库数据源
  
git remote rm <name>  //此命令用于删除本地仓库的一个数据源
  
git pull <远程主机名> <远程分支名>:<本地分支名>  //此命令用于将远程分支的最新代码拉取并合并到本地分支

通过上面几条命令,我们实现了本地仓库与远程源仓库的数据同步,当然,我们接下来就可以通过push操作,将本地的代码又推到自己的远程仓库中。

4.2 Pull Request

到这里,我们已经说完了从公共仓库fork一个自己的仓库,从自己的仓库clone到本地仓库,建立本地仓库与公共仓库的连接,同步公共仓库的代码到本地,同步本地的代码到自己的远程仓库。诶,是不是觉得差了点什么。没错,我们还没有把自己的开发数据同步到公共仓库。这就是我们这里要讲的,Pull Request,俗称PR。

Pull Request 是一种通知机制。你修改了他人的代码,将你的修改通知原来的作者,希望他合并你的修改,这就是 Pull Request。通俗来讲,现在我在本地完成了某个模块的开发,我现在需要把写好的代码上传到公共仓库,我就需要从自己的远程仓库发起一个到公共仓库的PR,公共仓库的管理员通过此次PR之后,那么你的代码就同步到了公共仓库。而一般,项目管理者是不会同意你直接将代码PR到master分支上面,需要保持master分支的纯洁性,所以我们在发起PR的时候,需要在公共仓库建立一个新的分支,将代码PR到这分支上。当然,在自己的仓库中,分支名可以自己任取,但是公共仓库的分支名需要遵循一定的规范,我们公司的命名规范详见https://km.sankuai.com/page/456502954。

5 标签

Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点即版本( v1.0 、 v2.0 等等)。

git tag   //此命令用于查看当前的标签

Git支持两种标签:轻量标签(lightweight)与附注标签(annotated)。轻量标签很像一个不会改变的分支——它只是某个特定提交的引用。而附注标签是存储在 Git 数据库中的一个完整对象, 它们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard (GPG)签名并验证。 通常会建议创建附注标签,这样你可以拥有以上所有信息。

git tag -a <tagname> -m "message"  //此命令用于创建一个附注标签,message为标签注解

git tag -a <tagname>  //当我们不使用-m添加注解时,Git会打开你的编辑器,让你写一句标签注解,就像你给提交写注解一样

git tag <tagname>   //此命令用于创建一个轻量标签

如果我们忘了给某个提交打标签,又将它发布了,我们可以给它追加标签,只需要在命令后面追加一个该次提交的校验和或者部分校验和。例如:

git tag -a v1.2 9fceb02

6 SSH和HTTPS

在clone仓库和push代码时,我们都有两种方式,一种是ssh,另一种为https,这两者的区别如下:

clone:使用ssh方式,首先你必须是该项目的管理者或拥有者,并且需要配置个人的ssh key。而https方式就没有这些要求。设置ssh key的方法这里不再详述,见https://km.sankuai.com/page/461077334

push:使用ssh方式,只要已经完成了配置,是不需要验证用户名和密码的,如果你在配置ssh key时设置了密码,则仅需要验证配对密码。而对于使用https方式来讲,每次push都需要验证用户名和密码。

7 Git工作流

Git工作流可以理解为团队成员遵守的一种代码管理方案,在Git中有以下几种常见工作流:

  • 集中式工作流

  • 功能开发工作流

  • Gitflow工作流

  • Forking工作流

7.1 集中式工作流

集中式工作流保留了在 SVN 下的工作风格,对于每一个 Repo,集中式工作流只使用 master 分支进行开发。整个项目只有一个仓库,并且只有一个master主分支,开发者会先把远程的仓库克隆到本地,之后的修改和提交都在本地操作,直到在某个合适的时间点将本地的代码合入到远程master。这种工作流适合小团队或者个人开发,因为不会有太多合作。在开发者提交自己的修改到master前,需要先fetch在master的新增提交,rebase自己的提交于master的最新版本。在手动解决冲突之后,上传代码到远程仓库。
在这里插入图片描述

7.2 功能开发工作流

这种工作流关注功能开发,不直接往master提交代码保证它是稳定并且干净的,而是从master拉取feature分支进行功能开发,团队成员根据分工拉取不同的功能分支来进行不同的功能开发,这样就可以完全隔离开每个人的工作。当功能开发完成后,会向master分支发起Pull Request,只有审核通过的代码才真正允许合入master,也就是我们常说的Code Review,这样就加强了团队成员之间的代码交流。

7.3 Gitflow工作流

在这里插入图片描述

在此工作流中,master和develop始终并行进行。

  1. master分支是一个稳定的分支,不允许开发者直接往master分支push代码,只允许release分支和hotfix分支发起merge request进行合流。

  2. develop分支是相对稳定的分支,用于日常开发,包括代码优化、功能性开发等开发结束后将代码提交至release分支进行测试。

  3. feature分支是从develop分支拉取的开发分支,在进行开发时,会先从develop拉去一个新的分支进行开发,开发结束后merge到develop。

  4. release分支从develop分支拉取,用于回归测试,完成后打tag并合入master和develop。

  5. hotfix分支用于紧急修复上线版本的问题,修复后打tag并合入master和develop。

7.4 Forking工作流

Forking工作流常用于开源项目,这种工作流有一个公共的中心代码仓库,其他开发者可以通过fork这个仓库作为自己的私人仓库,在自己的私人仓库上进行开发,而中心仓库的代码只有项目的管理者才能进行操作,其余开发者在push自己代码到自己的私人仓库后,可以通过发起Pull Request将自己的代码合并到中心仓库。主要步骤如下:

RD fork 公共代码库;

RD克隆自己的代码库到本地;

建立RD自己的代码库到公共代码库的remote,以保持代码最新;

RD在其本地系统中创建一个新的功能分支,进行开发并提交。

从该分支创建一个pull request,提交到公共代码库。

公共代码库管理员检查查pull request中的修改并批准将这些修改合并到官方代码库中。

8 常用git命令

关于git常用命令的联系,可以去https://learngitbranching.js.org/?locale=zh_CN,这里面讲解比较详细全面

8.1 新建项目

git init  //用于在当前目录新建一个仓库

git init [project-name]  //新建一个project-name的文件夹,并初始化为一个git仓库

git clone [url]  //克隆一个远程git仓库的代码及所有历史记录到本地

9.2 git配置

git config -l  //查看git配置

git config --global user.name "[username]"  //设置提交代码的用户名

git config --global user.email "[useremail]"  //设置提交代码的用户邮箱

8.3 增加、删除文件

git add [file1][file2]...  //添加修改的文件进入暂存区,也可以使用目录名作为参数,添加整个目录进入暂存区

git add .  //添加当前目录的所有文件到暂存区

git rm [file]  //将文件从暂存区和工作区中删除

8.4 提交代码

git commit -m [message]  //提交暂存区到本地仓库中

git push <远程主机名> <本地分支名>:<远程分支名>  //本地仓库代码提交到远程仓库

8.5 分支操作

git branch  //查看本地分支

git branch [branchname]  //新建分支branchname

git branch -d [branchname]  //删除分支branchname

git branch -a  //查看所有本地分支和远程分支

git checkout [branchname]  //切换到已存在分支branchname

git checkout -b [branchname]  //新建并切换到分支branchname

git branch --set-upstream [branch] [remote-branch]  //建立本地分支与远程分支追踪关系

git merge [branchname]  //合并branchname分支到当前分支

git branch -dr [remote/branch]  //删除远程分支

8.6 查看信息

git status  //查看在你上次提交之后是否有对文件进行再次修改

git remote -v  //查看远程仓库源

git log  //查看当前分支的历史版本

git diff  //查看暂存区和工作区的差异

8.7 远程同步

git fetch [remote]  //下载远程仓库代码变动

git log -p FETCH_HEAD  //检查fetch下来的代码与本地代码的差异

git pull <远程主机名> <远程分支名>:<本地分支名>  //拉取远程分支最新代码与本地合并,相当于git fetch和git merge的组合使用

8.8 撤销

git checkout [file]  //恢复暂存区指定文件到工作区

git checkout .  //恢复暂存区所有文件到工作区

git reset --hard [commit-id]  //会滚到指定版本,commit-id是提交代码的标识,可以通过git log查看

git revert [commit-id]  //反做

注:部分图片来源:git-scm

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值