git概念理解和实操[总][践]

什么是版本控制系统(VCS)

版本控制系统(VCS)最基本的功能是版本控制。所谓版本控制,意思就是在文件的修改历程中保留修改历史,让你可以方便地撤销之前对文件的修改操作。
最初的版本控制系统,是中央式版本控制系统(Centralized VCS)。Git 是分布式的版本控制系统(Distributed VCS)。
分布式 VCS (Distributed VCS / DVCS)和中央式的区别在于,分布式 VCS 除了中央仓库之外,还有本地仓库:团队中每一个成员的机器上都有一份本地仓库,这个仓库里包含了所有的版本历史,或者换句话说,每个人在自己的机器上就可以提交代码、查看历史,而无需联网和中央仓库交互——当然,取而代之的,你需要和本地仓库交互。

描述了 Git 的最基本的工作模型:

  • 从 GitHub 把中央仓库 clone 到本地(使用命令: git clone)
  • 把写完的代码提交(先用 git add 文件名 把文件添加到暂存区,再用 git commit 提交)
  • 在这个过程中,可以使用 git status 来随时查看工作目录的状态
  • 每个文件有 “changed / unstaged”(已修改), “staged”(已修改并暂存), “commited”(已提交) 三种状态,以及一种特殊状态 “untracked”(未跟踪)
  • 提交一次或多次之后,把本地提交 push 到中央仓库(git push)

相关命令:
git clone 远端地址 //将中心仓库的代码克隆到本地
git log //查看操作日志
git status //查看文件状态
git add 文件名 //添加文件至版本库
git commit //将在版本控制下的文件提交至本地仓库
git push //将本地仓库的代码推送至中心仓库

把上面的那个「多人合作的基本工作模型」进行了改良:
写完所有的 commit 后,不用考虑中央仓库是否有新的提交,直接 push 就好
如果 push 失败,就用 pull 把本地仓库的提交和中央仓库的提交进行合并,然后再 push 一次
到此为止,这个工作模型已经是一个最简单的可用的工作模型了。

相关命令:
git pull 用于从另一个存储库或本地分支获取并集成(整合),作用是:取回远程主机某个分支的更新,再与本地的指定分支合并

HEAD、master 与 branch

HEAD 是指向当前 commit 的引用,它具有唯一性,每个仓库中只有一个 HEAD。在每次提交时它都会自动向前移动到最新的 commit 。
branch 是一类引用。HEAD 除了直接指向 commit,也可以通过指向某个 branch 来间接指向 commit。当 HEAD 指向一个 branch 时,commit 发生时,HEAD 会带着它所指向的 branch 一起移动。

master 是 Git 中的默认 branch,它和其它 branch 的区别在于:
新建的仓库中的第一个 commit 会被 master 自动指向;
在 git clone 时,会自动 checkout 出 master。

branch 的创建、切换和删除:
创建 branch 的方式是 git branch 名称 或 git checkout -b 名称(创建后自动切换);
切换的方式是 git checkout 名称;
删除的方式是 git branch -d 名称。

相关命令
git branch feature1 创建分支feature1
git checkout feature1 切换到你的新 branch 去
git checkout -b feature1 创建分支feature1,再直接切换过去
git checkout master 切换到master分支
git branch -d feature1 删除分支feature1 ,出于安全考虑,没有被合并到 master 过的 branch 在删除时会失败,可以把 -d 改成 -D 进行强制删除

push指令的本质

push 是把当前的分支上传到远程仓库,并把这个 branch 的路径上的所有 commits 也一并上传。
push 的时候,如果当前分支是一个本地创建的分支,需要指定远程仓库名和分支名,用 git push origin branch_name 的格式,而不能只用 git push;或者可以通过 git config 修改 push.default 来改变 push 时的行为逻辑。
push 的时候之后上传当前分支,并不会上传 HEAD;远程仓库的 HEAD 是永远指向默认分支(即 master)的。就是对于远程仓库而言,HEAD永远指向主分支,对于本地仓库而言,HEAD可以自由切换其他分支

merge相关

merge 的含义:从两个 commit「分叉」的位置起,把目标 commit 的内容应用到当前 commit(HEAD 所指向的 commit),并生成一个新的 commit;
merge 的适用场景:
单独开发的 branch 用完了以后,合并回原先的 branch;
git pull 的内部自动操作。

merge 的三种特殊情况:
冲突原因:当前分支和目标分支修改了同一部分内容,Git 无法确定应该怎样合并,应对方法:解决冲突后手动 commit;
HEAD 领先于目标 commit:Git 什么也不做,空操作;
HEAD 落后于目标 commit:fast-forward。

命令相关:
git merge branch1
编辑冲突,解决<<< === >>>
git add shopping\ list.txt # 嗯是的,这里 commit 前也需要先 add 一下
git commit
git merge –abort //由于现在 Git 仓库处于冲突待解决的中间状态,如果你最终决定放弃这次 merge

流行的git工作流

git checkout -b books
git push origin books
git pull
git chekcout books
git checkout master
git pull # merge 之前 pull 一下,让 master 更新到和远程仓库同步
git merge books
git push
git branch -d books
git push origin -d books # 用 -d 参数把远程仓库的 branch 也删了

看看我更改了啥

查看历史中的多个 commit:log
查看详细改动: git log -p
查看大致改动:git log –stat
查看具体某个 commit:show
要看最新 commit ,直接输入 git show ;要看指定 commit ,输入 git show commit的引用或SHA-1
如果还要指定文件,在 git show 的最后加上文件名
查看未提交的内容:diff
查看暂存区和上一条 commit 的区别:git diff –staged(或 –cached)
查看工作目录和暂存区的区别:git diff 不加选项参数
查看工作目录和上一条 commit 的区别:git diff HEAD

rebase

rebase 指令,它可以改变 commit 序列的基础点。它的使用方式很简单:

1
git rebase 目标基础点

需要说明的是,rebase 是站在需要被 rebase 的 commit 上进行操作,这点和 merge 是不同的。
相关命令:
git checkout branch1
git rebase master
git checkout master
git merge branch1

修正

刚提交了代码,发觉写错了怎么办?
优雅和简单的解决方法:commit -—amend
在提交时,如果加上 –amend 参数,Git 不会在当前 commit 上增加 commit,而是会把当前 commit 里的内容和暂存区(stageing area)里的内容合并起来后创建一个新的 commit,用这个新的 commit 把当前 commit 替换掉。