Git学习笔记
1. 基础操作
1. Git命令整理
- git init
创建一个空的版本库。 - git add <filename>
将当前工作区中的文件的改动添加到暂存区。 - git commit -m "description"
将暂存区的改动提交到版本库中,-m参数后面跟着是本次改动的描述,为了可读性最好认真写。 - git status
查看当前工作区的状态 - git diff [(HEAD)或{commit id}][-- <filename> ]
查看工作区的修改内容
默认与HEAD指针指向的版本进行全部文件的比较。同时也可以通过指定参数来与相应的版本、相应的文件进行比较 - git reset (--mixed)或--soft 或--hard <version> -- <file>
用来重置版本库(暂存区、工作区)的状态。
重置的概念应该是恢复到某次提交的的时候。
--mixed:默认参数,重置暂存区和版本库,工作区修改不变。
--hard:重置工作区、暂存区和版本库。
--soft:只重置版本库,暂存区和工作区的修改不变。
此外,只有mixed即默认参数才能加<file>选项。 - git checkout -- <file>
还原工作区里的修改。这里分为两种情况:
- 在修改后提交到暂存区后又进行了一次修改,此时会将暂存区里的第一次修改的内容用来还原工作区的修改,即将工作区恢复到第一次修改的情况。
- 在修改后并未提交到暂存区,此时会将上一次版本库里的内容用来还原工作区的修改。
git checkout [-b] <branch>
切换到某个分支,当加上-b参数时则表示新建分支并切换到新分支。
- git rm
将文件删除并将文件的修改提交到暂存区。 - git branch <branch>
当不加<branch>时,git branch表示查看当前所有分支,加上参数后,表示创建一个名字即为参数的分支。
加上-d选项时,表示删除后面指定的分支。 - git remote
查看远程仓库信息,加入-v选项可以查看详细信息。 - git push [-u] origin master
将本地库选定分支的内容推送到远程仓库,-u选项可以将本地的分支与远程库绑定,以后可以直接通过git push推送到远程仓库。 - git tag <tagname> <commit id>
当命令仅为git tag时,可以查看全部的tag
加上<tagname>参数时,可以给最新的commit打上tag
加上-a选项,可以指定标签名
加上-m选项,可以指定描述
加上-d选项,可以删除指定标签 - git push origin <tagname>
可以将标签推送到远程库
git push origin --tags
一次性推送所有未推送的标签
git push origin :refs/tags/<tagname>
删除在远程库的标签
2. 名词概念
- 版本库(repository):
可以理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。 - 工作区:
在电脑上能看到的目录。 - 版本库:
即隐藏目录".git",其中最重要的是暂存区(stage),分支,以及HEAD指针。 - 暂存区:
文件修改暂时保存的地方,在执行提交命令之后,会把暂存区里所有的文件提交到版本库。
3. 创建版本库
- 可以通过git init命令在本地将当前目录变为由git管理的版本库。
.git文件夹保存了当前版本库的信息
4. 提交改动到版本库
git的提交操作分为两步:
- 使用git add将改动的文件提交到暂存区
- 使用git commit -m "xxx"将暂存区里的修改提交到版本库
5. 查看工作区状态
- 使用git status能查看当前工作区是否存在着文件修改。
- 当确定工作区存在文件修改时,可以通过git diff命令来查看修改的内容。
6. 版本回退
- 通过git log可以查看提交的历史
- 通过git reset --hard {HEAD指针}或{commit id}会回退到某个版本。
- 通过git reflog可以查看命令的历史
7. 撤销修改
想要撤销文件修改,可以根据文件修改的提交进度分为以下几种:
- 在工作区修改了,但未提交到暂存区和版本库。
- 通过git checkout -- <file>可以从暂存区或者版本库还原工作区。
- 通过git reset --hard {HEAD指针}或{commit id}来还原工作区、暂存区和版本库。不设置版本则还原到上一个版本。
- 在工作区修改了,并且提交到了暂存区,但是并未提交到版本库。
- 通过git reset [{HEAD指针}or{commit id}][file]来还原版本库和暂存区,默认是--mixed参数,因此并不会还原工作区的修改。这一操作的表现看起来就像是:“将暂存区的文件退回到工作区”,其实不然。此时可以按照需求选择是否丢弃工作区里的修改。
- 如果想一开始就不打算保存工作区里的所有修改,也可以通过git reset --hard来重置工作区、暂存区和版本库的所有修改。
- 在工作区修改了,而且不仅提交到了暂存区,还提交到了版本库。
- 通过git reset --hard <version> 来回退到上一个版本。
8. 删除文件
- 在工作区通过rm命令删除文件后,可以通过git add将删除文件的修改提交到暂存区,最后提交到版本库。
- 使用git rm可以直接将工作区的文件删除同时将这个修改提交到暂存区。
个人理解成git rm = rm + git add - 当误删时可以通过git reset 命令或者git checkout -- <file>来还原。
2. 远程仓库
1. 创建SSH key
ssh-keygen -t rsa -C "youremail@example.com"
输入命令后,会在家目录下生成.ssh文件夹,里面有id_rsa和id_rsa.pub两个密钥,其中id_rsa是私钥,id_rsa.pub是公钥。
将公钥绑定到github账号上,便有权限在当前设备推送代码到git。
2. 绑定远程库
git remote add origin git@github.com:username/repositoryname.git
这段命令表示将对应用户名、仓库名的远程仓库与本地库进行绑定,并且命名为origin。
3. 推送到远程仓库
git push -u origin master
git push是将本地库推送到远程仓库的命令,-u参数能把本地和远程仓库关联起来,以后使用git push 可以不带参数。
4. 从远程仓库克隆
git clone git@github.com:username/repositoryname.git
通过这条命令可以将远程仓库的内容克隆到本地,与git remote add的区别是:
git remote add是在本地库存在的情况下与远程库绑定的,而git clone则是在本地库不存在时,从远程仓库克隆并在本地创建本地库,因此创建本地库的命令除了git init还有git clone。
3. 分支管理
1. 创建分支
通过git branch <branchname>命令可以创建出一个新的分支,然后用git checkout <branchname>切换到新分支,也可以用git checkout -b <branchname>直接创建并切换到新分支。
2. 合并分支
可以使用git merge <branchname>来实现分支的合并
合并分支可以分为以下几种:
-
只有一个分支修改了内容,假如只有dev分支修改了文件,在提交完成后查看dev分支的提交历史。
dev提交历史
可以看到,修改后的dev比master提前了一个版本,但是dev和master本身还是处于同一条时间线的,这里如果直接在master分支使用git merge dev,但是想到之前版本回退和追溯的内容,我觉得这里应该是可以直接修改master指针位置使它指向最新的提交版本。
执行git reset --hard {commit id},在这里commit id是94cc,结果如下:
master提交历史
果不其然,结果和用合并分支的命令一样,从这里可以推测Fast-forward合并方式的本质就是修改落后分支的指针位置。 -
当两个分支都对内容进行修改时,只要两个分支都对库中的内容进行了修改,那么时间线就会这个点进行分离
master分支删除了masterfile后的提交历史
两个分支都无法看到对方的位置了,可见时间线已经进行了分叉,但因为并没有修改同一个文件,所以在使用合并命令的时候非常顺利。
这时git将合并生成的新的结点加到了当前分支的后面,并将指针指向了这个结点,而dev则没有改动,依然指向合并前的版本。
-
两个分支都对内容进行修改,并且修改了同一文件。
master分支
dev分支
首先还是相同的,两个分支的时间线分开了,然后执行合并语句。
合并失败
合并的时候发生了冲突,还提示了冲突的文件,修改完成后,手动提交,剩下的情况就和第二种情形相同。
因此我对第二种和第三种的理解是:
- 第二种是第三种的特殊情形,也就是虽然多个分支都修改了内容,但是却没有修改同一个文件,也就是没有发生冲突,所以合并过程非常顺利,这时git还顺手帮我们提交了一次。
- 而第三种情形出现了冲突,git在合并完其他的以后,将剩下的冲突的部分留给我们手动解决,解决以后我们需要手动提交一次。
此外,由于fast-forward模式在删除分支后会丢失分支信息,所以可以使用--no-ff选项来禁用fast-forward模式。
3. 多人协作。
- 使用git clone克隆远程仓库到本地时,只会克隆master分支,如果要创建其他分支可以用以下命令:
git checkout -b dev origin/dev - 如果git push的时候因为远程库的版本比本地库的版本要新时,这时候要先使用git pull从远程仓库拉取代码,解决冲突后再push到远程库。
如果显示没有指定本地dev与远程仓库origin/dev没有创建链接而无法push,可以用以下命令:
git branch --set-upstream-to=origin/dev dev
4. 标签
1. 创建标签
可以用git tag tagname创建一个标签