Git
一 使用Git对仓库(项目)进行管理
1 在工作目录中初始化新仓库
要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行:
1 | $ git init |
初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。
如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,然后提交:
1 | $ git add *.c |
稍后我们再逐一解释每条命令的意思。不过现在,你已经得到了一个实际维护着若干文件的 Git 仓库。
2 从现有仓库克隆
1 | $ git clone |
使用git clone命令来抓取模块A的代码仓库,但要同时抓取到子模块的仓库
$ git clone –recurse-submodules https://xxx/xxx
二 仓库基本管理
什么是仓库
在 Git 的概念中,仓库,就是你存在.git目录的那个文件夹内的所有文件,包括隐藏的文件,Git程序会再当前目录以及上级目录查找是否存在.git文件,如果存在,则会将.git目录存在的文件夹开始下的所有文件当成你需要管理的文件,所以,我们如果想将某个文件夹当做一个Git仓库,你可以在那个文件夹下通过终端(Window为Cmd或者PoewrShell或者Bash)来执行
1 | $ git init |
什么是版本
在Git中,计数基础是提交,即我们常说的Commit,我们每做一点更改便可以产生一次提交,当提交累计起来,可以作为产品定型时,就在当前的Commit上打上一个标记,将这个标记我们称之为版本多少多少. 在Git中,版本仅仅只是某一个提交的标签,并没有其他意义,Git本身也仅有打标签的功能,并没有版本功能,版本功能是根据Tag来扩展的,Git本身并没有.
什么是分支
这是Git中最重要的也是最常用的概念和功能之一,分支功能解决了正在开发的版本与上线版本稳定性冲突的问题在Git使用过程中.
1 主分支master
首先,代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布
2 开发分支Develop
那么当我们需要添加新功能或者做修改时,只需要新建一个分支,然后在该分支上开发,如果想正式对外发布,就在Master分支上,对Develop分支进行”合并”(merge)
#Git创建Develop分支的命令:
1 | git checkout -b develop master |
#将Develop分支发布到Master分支的命令:
#切换到Master分支
1 | git checkout master |
#对Develop分支进行合并
1 | git merge --no-ff develop |
什么是提交
Git对于版本的管理其实是对于提交的管理,在整个Git仓库中,代码存在的形式并不是一分一分的代码,而是一个一个的提交,Git使用四十个字节长度的16进制字符串来标识每一个提交,这基本保证了每一个提交的标识是唯一的,然后通过组织一个按照时间排序的提交列表,就组成了我们所说的分支,请注意,分支在本质上只是一个索引,所以,我们可以任意回退,修正,即使因为某些原因丢失了,也可以重建另外,关于Git的储存方式:Git是仅仅只储存有修改的部分,并不会储存整个文件,所以,请不要删除文件夹整个文件夹的内容,除非你确定你不再需要他,否则请勿删除.
什么是同步(拉取)
同步,也可以称之为拉取,在Git中是非常频繁的操作,和SVN不同,Git的所有仓库之间是平等的,所以,为了保证代码一致性,尽可能的在每次操作前进行一次同步操作,具体的为在工作目录下执行如下命令:
1 | git pull origin master或者branch |
其中origin代表的是你远程的仓库,可以通过命令 git remote -v 查看,master是分支名,如果你本地是其他分支,请换成其他分支的名字,如果远程仓库与你本地仓库存在冲突,需要处理冲突。
什么是推送
和拉取一样,也是一个非常频繁的操作,当你代码有更新时,你需要更新到远程仓库,这个动作被称之为推送,执行的命令与拉取一样,只是将其中的pull这个单词改成push,同样,如果远程仓库存在你本地仓库没有的更新,则在推送前你需要先进行一次同步,如果你确定你不需要远程的更新,则在推送时加上 -f 选项,则可以强制推送,注:在协同开发中,我并不建议这么做,因为这样很可能覆盖别人的代码
推送代码示例:
1 | git push origin master |
强制推送代码示例:
1 | git push origin master -f |
什么是冲突
在使用Git开发时,如果只是一个人使用,那么基本不会产生冲突,但是在多人合作开发的情况下,产生冲突是很正常的一件事情
什么是合并
合并这个命令通常情况下是用于两个分支的合并,一般用于本地分支,远程分支多用Pull命令,该命令的功能是将待合并分支与目标分支合并在一起,注意,这个命令只会合并当前版本之前的差异,两个分支的提交历史会根据提交时间重新组织索引,故只可能会产生一次冲突但是会生成一个提交,如果你不想生成这次提交,加上 --base参数即可
什么是暂存
这个既是一个概念也是一个命令,其含义就是字面上的,作用就是可以将你当前正在进行的工作暂时存起来,然后在此基础上干别的事情,等你别的事情干完后,再转回来继续,注意,暂存只是针对你最后一次改动而言,即针对当前所在的版本的所有改动都算具体执行命令为:
将当前改动暂存起来:
1 | git stash |
恢复最后一次暂存的改动
1 | git stash pop |
查看有多少暂存
1 | git stash list |
什么是撤销
撤销命令使用是非常频繁的,因为某些原因,我们不再需要我们的改动或者新的改动有点问题,我们需要回退到某个版本,这时就需要用到撤销命令,或者说这个应该翻译成重置更加恰当。具体命令如下:
撤销当前的修改:
1 | git reset --hard |
请注意:以上命令会完全重置你的修改,如果你想保留某些文件,请使用checkout +文件路径 命令来逐一撤销修改
如果你想重置到某一版本,可以将 --hard 改为具体的Commit的id如:
1 | git reset 1d7f5d89346 |
请注意,这时你的修改仍然存在,只是你的最近一次提交的版本号变成了你要重置的版本,如果说你想完全丢弃修改,只需要加上 –hard参数就可以
Git 有一个特殊指针HEAD, 总是指向当前分支的最近一次快照。
常用命令
1 从远程拉取全部分支
1 | git pull |
2 从远程拉取指定分支
1 | git pull origin branchname: branchname |
3 git branch命令可以列出本地的所有分支。
1 | $ git branch |
4 创建一个名为MyBranch的新分支,但是依然停留在当前分支。
1 | $ git branch MyBranch |
5 新建孤儿分支
项目进行中,需要创建一个空分支。在Git中创建分支,是必须有一个父节点的,也就是说必须在已有的分支上来创建新的分支,如果你的工程已经进行了一段时间,这个时候是无法创建空分支的。
该命令会生成一个新的分支,该分支会包含父分支的所有文件。但新的分支不会指向任何以前的提交,就是它没有历史,如果你提交当前内容,那么这次提交就是这个分支的首次提交。
1 | git checkout --orphan new-orphan-branch |
6 将某个远程主机的更新,全部取回本地。默认情况下,git fetch取回所有分支的更新。如果只想取回特定分支的更新,可以指定分支名
1 | git fetch |
1 | git fetch <远程主机名> <分支名> |
7 查看本地所有分支
1 | git branch |
8 删除本地分支
1 | git branch -d <branchname> |
常见问题
git fetch 和 git pull区别
git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。
而git pull 则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。
you need to resolve your current index first
合并冲突问题
建议使用git fetch代替git pull
fatal: The current branch ngk2-267 has no upstream branch.
To push the current branch and set the remote as upstream, use
1 | git push --set-upstream origin ngk2-267 |
建立本地分支和远程分支的联系
refusing to merge unrelated histories
我们在初见一个git仓库需要将之提交到远程仓库时,使用git pull origin master 命令操作时,会遇到这样的错误:fatal: refusing to merge unrelated histories
这是因为远程仓库已经存在代码记录了,并且那部分代码没有和本地仓库进行关联,我们可以使用如下操作允许pull未关联的远程仓库旧代码:
1 | git pull origin master --allow-unrelated-histories |
这样,就关联了远程仓库;
然后我们可以push代码了:
1 | git push origin master |