Git理解与使用指南

huangchunxia 2020-05-31

基础

1. git

git是当前项目的快照,可以理解成把复制粘贴了项目的目录,当然比这个要简单多了

2. git commit

git commit是一种简单的记录项目修改的方式,它会比对这次和上次的变化,并把变化作为一个修改记录提交;注意到“上次”和“这次”是一种父子关系,或者说这次的每个修改都是在上次的基础上做的。

git commit 在当前分支上提交一个修改记录

git commit -m "你的评论" 带评论

3. git branch

分支只是简单地指向某个提交纪录 —— 一个指针;许多 Git 爱好者传颂:“早建分支!多用分支!"这是因为即使创建再多分的支也不会造成储存或内存上的开销,并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了。

记住使用分支其实就相当于在说:“我想基于这个提交以及它所有的父提交进行新的工作。”

git branch <branch-name>  创建名为branch-name的分支

 git branch -f <branch-name> someplace 把某branch强制移动到someplace,注意branch本身就是一个指针,这个命令在之后还会解释

 

3. git merge <branch-name>
git merge x y
把当前分支merge到branch-name上
git merge的场景是:新建一个分支,在其上开发某个新功能,开发完成后再合并回主线。使用git merge在 Git 中合并两个分支时会产生一个特殊的提交记录,它有两个父节点。翻译成自然语言相当于:“我要把这两个父节点本身及它们所有的祖先都包含进来。”
 
 4. git rebase <branch-name>

git rebase x y

把当前分支里的工作直接移到branch-name分支上。移动以后会使得两个分支的功能看起来像是按顺序开发,但实际上它们是并行开发的。

实际上就是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。
 
2. 在项目提交树上移动
HEAD就是一个随着commit记录不断在项目提交树上移动的东东;一般情况下指向当前分支的最新一次提交
1. git checkout <branch-name>
or git checkout <commitHash>
把HEAD切换到某个branch,或者某个提交记录(以Hash值记载,具体通过commit log查看)
其实两个区别不大,记得branch只是指向某次commit的指针,只不过是最新一次的commit
 因为commitHash往往不便于记忆,git支持采用相对引用的方式(其实就是相对位置)
 git checkout HEAD^ (去往HEAD的父提交)
 git checkout HEAD~4 ( 去往HEAD的前4次提交,把git checkout HEAD^执行4次)
 git branch -f <branch-name> HEAD^ (把某branch强制移动到某个位置,注意branch本身就是一个指针)
 
2. git reset someplace
* someplace 是上面checkout命令可以移动到的所有地方

git reset 把分支向上移动到某处,原来指向的提交记录就跟从来没有提交过一样。

git reset 通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。
在 Git 里撤销变更的方法很多。和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。

 (在reset后, C2 所做的变更还在,但是处于未加入暂存区状态。)

3. git revert somplace

虽然在你的本地分支中使用 git reset 很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的哦!

为了撤销更改并分享给别人,我们需要使用 git revert。来看演示:

 
3. 整理提交记录
 1. git cherry-pick <提交号>

本系列的第一个命令是 git cherry-pick, 命令形式为:

  • git cherry-pick <提交号>...

如果你想将一些提交复制到当前所在的位置(HEAD)下面的话

比merge或者rebase的区别:可以只取某个分支的一部分提交

 

4. 远程合作

1. git clone 

git clone会复制一个远程仓库,注意你复制下来的仓库中有个origin/master分支

你可能注意到的第一个事就是在我们的本地仓库多了一个名为 o/master 的分支, 这种类型的分支就叫远程分支。由于远程分支的特性导致其拥有一些特殊属性。

远程分支反映了远程仓库(在你上次和它通信时)的状态。这会有助于你理解本地的工作与公共工作的差别 —— 这是你与别人分享工作成果前至关重要的一步.

如果checkout到origin/master上并且commit会怎么样

正如你所见,Git 变成了分离 HEAD 状态,当添加新的提交时 o/master 也不会更新。这是因为 o/master 只有在远程仓库中相应的分支更新了以后才会更新。

 

Git 远程仓库相当的操作实际可以归纳为两点:向远程仓库传输数据以及从远程仓库获取数据。既然我们能与远程仓库同步,那么就可以分享任何能被 Git 管理的更新(因此可以分享代码、文件、想法、情书等等)。

2. git fetch

更新和远程的交互状态,也就是把远程的状况自动下载到本地,则origin/master自动更新

git fetch 完成了仅有的但是很重要的两步:

  • 从远程仓库下载本地仓库中缺失的提交记录
  • 更新远程分支指针(如 o/master)

git fetch 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态。

如果你还记得上一节课程中我们说过的,远程分支反映了远程仓库在你最后一次与它通信时的状态,git fetch 就是你与远程仓库通信的方式了!希望我说的够明白了,你已经了解 git fetch 与远程分支之间的关系了吧。

 

 

git fetch 不会做的事

git fetch 并不会改变你本地仓库的状态。它不会更新你的 master 分支,也不会修改你磁盘上的文件。

理解这一点很重要,因为许多开发人员误以为执行了 git fetch 以后,他们本地仓库就与远程仓库同步了。它可能已经将进行这一操作所需的所有数据都下载了下来,但是并没有修改你本地的文件。我们在后面的课程中将会讲解能完成该操作的命令 :D

所以, 你可以将 git fetch 的理解为单纯的下载操作。

 
3. git pull

其实有很多方法的 —— 当远程分支中有新的提交时,你可以像合并本地分支那样来合并远程分支。也就是说就是你可以执行以下命令:

  • git cherry-pick o/master
  • git rebase o/master
  • git merge o/master
  • 等等

实际上,由于先抓取更新再合并到本地分支这个流程很常用,因此 Git 提供了一个专门的命令来完成这两个操作。它就是我们要讲的 git pull

 
4. git push

git push 负责将你的变更上传到指定的远程仓库,并在远程仓库上合并你的新提交记录。一旦 git push 完成, 你的朋友们就可以从这个远程仓库下载你分享的成果了!

你可以将 git push 想象成发布你成果的命令。它有许多应用技巧,稍后我们会了解到,但是咱们还是先从基础的开始吧……

注意 —— git push 不带任何参数时的行为与 Git 的一个名为 push.default 的配置有关。它的默认值取决于你正使用的 Git 的版本,但是在教程中我们使用的是 upstream。 这没什么太大的影响,但是在你的项目中进行推送之前,最好检查一下这个配置。

 ( 还要注意origin/master可以随着push自己移动,因为当你push上去的时候,你就成了和远程仓库通信的最新了)
PS : 
cat .git/HEAD
git symbolic-ref HEAD
git log --oneline -5
 
参考:

相关推荐