参考链接:https://git-scm.com/book/zh/v2
三种状态
Git 有三种状态,你的文件可能处于其中之一: 已提交(committed)、已修改(modified) 和 已暂存(staged):
- 已修改表示修改了文件,但还没保存到数据库中。
- 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交表示数据已经安全地保存在本地数据库中。
这会让我们的 Git 项目拥有三个阶段:工作区、暂存区以及 Git 目录:
- 工作区是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。(工作区就是当前目录)
- 暂存区是一个文件,保存了下次将要提交的文件列表信息。 按照 Git 的术语叫做“索引”,不过一般说法还是叫“暂存区”。
- Git仓库是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。(仓库又分为本地仓库和远程仓库)
为什么要有暂存区:Git中的暂存区是一个关键的缓冲区,它位于工作目录和版本库之间,允许用户更加灵活地控制文件的提交和管理代码的变动。
Git基础
1.获取 Git 仓库
有两种获取 Git 项目仓库的方式:git init和git clone
2.记录每次更新到仓库
工作目录下的每一个文件都不外乎这两种状态:已跟踪 或 未跟踪。已跟踪的文件是指那些被纳入了版本控制的文件。
使用 git status
命令可以查看文件状态,使用 git status -s
将得到更为紧凑的输出。
使用 git add
命令可以开始跟踪一个文件,该命令用于将工作区的文件变动添加到暂存区,准备下一次的提交。
使用 git rm
命令可以将文件从已跟踪文件清单中移除(确切地说,是从暂存区域移除),再次提交就能在仓库中删去这个文件。
暂存区准备就绪后,可以使用 git commit
命令提交了。添加 -m
选项,将提交信息与命令放在同一行;添加 -a
选项,相当于跳过 git add
步骤,把所有已经跟踪过的文件暂存起来一并提交。
3.查看提交历史
使用 git log
会按时间先后顺序列出所有的提交,最近的更新排在最上面。使用 -2
选项来只显示最近的两次提交。一个比较有用的选项是 -p
,显示每次提交所引入的差异补丁。
4.撤消操作
有时提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行 git commit --amend
命令来修正上次提交。
使用 git reset HEAD <file>…
来取消暂存文件,变回修改未暂存的状态,使之可以留到之后再提交。
如果不想保留对文件的修改,想将它还原成上次提交时的样子,使用 git checkout -- <file>...
可以撤消对文件的修改。(注意:此操作会丢弃所有本地修改,不可逆)
5.远程仓库的使用
远程仓库是指托管在因特网或其他网络中的你的项目的版本库。与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。远程仓库可以有好几个,这里我们只考虑一个,一般origin是远程仓库的默认名字。
使用 git remote show origin
命令,可以查看某个远程仓库的信息,这会列出远程仓库的 URL 与跟踪分支的信息。
使用 git fetch
命令,会访问远程仓库,从中拉取所有你还没有的数据。 但只会将数据下载到你的本地仓库,并不会自动合并或修改你当前的工作。
使用 git pull
命令,会抓取数据并自动尝试合并到当前所在的分支。简单理解就是pull = fetch +merge。
使用 git push
命令,可以推送到上游远程仓库。注意:只有当你有权限,并且之前没有人push过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先抓取他们的工作并将其合并进你的工作后才能推送。
Git 分支
1.分支相关操作
Git 的分支,其实本质上仅仅是指向提交对象(commit object)的可变指针。Git 的默认分支名字是 master
,跟其它分支完全没有区别。
使用 git branch
命令,可以创建分支,这会在当前所在的提交对象上创建一个指针。有一个名为 HEAD
的特殊指针,指向当前所在的本地分支。
使用 git checkout
命令,可以切换分支,这会改变 HEAD 指针。注意分支切换会改变你工作目录中的文件。
在不同的分支上修改并提交,项目的提交历史将产生分叉。你可以在不同分支间不断地来回切换和工作,并在时机成熟时将它们合并起来。
切换分支之前,要留意你的工作目录和暂存区里那些还没有被提交的修改, 它可能会和你即将检出的分支产生冲突从而阻止 Git 切换到该分支。 最好的方法是,在你切换分支之前,保持好一个干净的状态。例如commit一下或者amend commit一下,另外贮藏(stashing)也可以绕过这个问题。当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。
使用 git merge
命令,可以将目标分支合并到当前分支。合并可能会出现三种情况。情况一:当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。情况二:Git 会使用两个分支的末端所指的快照以及这两个分支的公共祖先,做一个简单的三方合并。Git 会将此次三方合并的结果做一个新的快照并且自动创建一个新的提交指向它。情况三:如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,在合并它们的时候就会产生合并冲突。为了解决冲突,你必须选择使用两部分中的一个,或者你也可以自行合并这些内容。 解决冲突后,可以再次提交来完成合并提交。
2.远程分支
远程跟踪分支是远程分支状态的引用,以 <remote>/<branch>
的形式命名。
使用 git push <remote> <branch>
命令,可以将分支推送到远程仓库。本地的分支并不会自动与远程仓库同步,你必须显式地推送想要分享的分支。
跟踪分支:从一个远程跟踪分支检出一个本地分支会自动创建所谓的“跟踪分支”(它跟踪的分支叫做“上游分支”)。 跟踪分支是与远程分支有直接关系的本地分支。
使用 git pull
命令,会查找当前分支所跟踪的服务器分支, 从服务器上抓取数据然后尝试合并入那个远程分支。
3.变基
整合来自不同分支的修改主要有两种方法:merge 以及 rebase。
使用 rebase
命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。
这两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。一个经过变基的分支的提交历史是一条直线没有分叉。
一般我们这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁——例如向某个其他人维护的项目贡献代码时。 在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。 这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。
merge和rebase的区别:变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。
什么情况下不要使用变基:如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
贡献与维护
学习完1-3章git基础,第4章可跳过,第5-6章可以阅读原文了解如何作为贡献者或维护者,在一个分布式协作的环境中使用 Git。
拉取请求(Pull Request,简称PR)是一种将一组更改从一个分支合并到另一个分支的提案。在拉取请求中,协作者可以在将更改集成到主要代码库之前审查和讨论所提议的一组更改。拉取请求通常用于共享存储库模型中的协作,例如GitHub上的开源项目。