Git 学习笔记

名词介绍

Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。

其实一台电脑上也是可以克隆多个版本库的,只要不在同一个目录下。不过,现实生活中是不会有人这么傻的在一台电脑上搞几个远程库玩,因为一台电脑上搞几个远程库完全没有意义,而且硬盘挂了会导致所有库都挂掉。

工作区
简言之就是工作的区域。 对于git而言,就是的本地工作目录。 工作区的内容会包含提交到暂存区和版本库 (当前提交点)的内容,同时也包含自己的修改内容。 

版本库
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库

暂存区
暂存区 (stage area, 又称为索引区index),是git中一个非常重要的概念。 是我们把修改提交版本库前的一个过渡阶段。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区。

还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

把文件往Git版本库里添加的时候,是分两步执行的:

  1. 第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
  2. 第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

与其他版本控制系统对比

  1. 和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示。
  2. Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。

Git 常用命令

假如我们想恢复一个已经提交的版本怎么办。

为了消除一个旧版本,我们必须撤销旧版本里的所有更改然后提交一个新版本。这种操作叫做 reverse merge。

git config // 指定用户名和email地址

git init // 初始化仓库,将当前目录变为git可管理的仓库

git clone // 克隆远程库到本地库
git fork // 克隆到github账号

git add // 将文件添加到仓库

git commit // 把文件提交到仓库

git push // 把本地库的所有内容推送到远程库上

git pull // 更新本地库

git status // 查看仓库当前状态

git diff // 查看具体修改了哪些内容

git log // 查看历史记录,显示从最近到最远的提交日志,如果嫌输出信息太多,可以试试加上--pretty=oneline参数

git reset // 回退版本,回退到上一个:git reset HEAD^(HEAD指向的版本就是当前版本),也可以指定对应版本号

git reflog // 记录每一次命令

git checkout -- file // 把文件在工作区的修改全部撤销

git reset HEAD <file> // 可以把暂存区的修改撤销掉(unstage),重新放回工作区,git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本

git rm // 删除文件

git remote -v // 查看远程库信息

git remote rm <name> // 删除远程库

分支管理

git checkout -b 表示创建并切换,相当于以下两条命令

git branch dev // 创建分支
git checkout dev // 切换分支

git branch 命令查看当前分支,在master分支执行 git merge devdev分支合并到master分支上。

合并完成后,可以删除dev分支: git branch -d dev

切换分支使用git checkout <branch>,而前面讲过的撤销修改则是git checkout -- <file>,同一个命令,有两种作用,确实有点令人迷惑。

实际上,切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的git switch命令来切换分支。

git switch -c dev // 创建并切换到新的dev分支
git switch master // 切换到已有的master分支

解决冲突

当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。

解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。

git status可以告诉我们冲突的文件,用git log --graph命令可以看到分支合并图。

分支管理策略

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。合并dev分支,请注意--no-ff参数,表示禁用Fast forward

Bug分支

当手头工作没有完成时,需要先修复某个bug,Git提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作,刚才的工作现场存到哪去了?用git stash list命令看看,恢复工作现场有两个办法:

git stash apply // 恢复后,stash内容并不删除,你需要用git stash drop来删除
git stash pop // 恢复的同时把stash内容也删了

master分支上修复了bug后,因为dev分支是早期从master分支分出来的,所以,这个bug其实在当前dev分支上也存在。那怎么在dev分支上修复同样的bug

同样的bug,要在dev上修复,我们只需要把特定提交所做的修改“复制”到dev分支。Git专门提供了一个cherry-pick命令,让我们能复制一个特定的提交到当前分支。用git cherry-pick,我们就不需要在dev分支上手动再把修bug的过程重复一遍。

Feature分支

开发一个新feature,最好新建一个分支;

如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。

多人协作

  • 查看远程库信息,使用git remote -v
  • 本地新建的分支如果不推送到远程,对其他人就是不可见的;
  • 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
  • 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
  • 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name
  • 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

Rebase(待完成)

标签管理

默认标签是打在最新提交的commit上的。 标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。

git tag <name>

也可以指定某次committag

git tag v0.1 f52c533 // (commit id)

可以使用git tag查看所有标签,标签不是按时间顺序列出,而是按字母排序的。可以用git show <tagname>查看标签信息。

可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

git tag -a v0.1 -m "version 0.1 released" 1094adb

删除标签:

git tag -d v0.1

因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。如果要推送某个标签到远程,使用命令git push origin <tagname>,或者,一次性推送全部尚未推送到远程的本地标签:

git push origin -tags

如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

git tag -d v0.9

然后,从远程删除。删除命令也是push,但是格式如下:

git push origin :refs/tags/v0.9

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注