1.Git 基础 - 获取 Git 仓库
你应该能够配置并初始化一个仓库(repository)、开始或停止跟踪(track)文件、暂存(stage)或提交(commit)更改。 本章也将向你演示如何配置 Git 来忽略指定的文件和文件模式、如何迅速而简单地撤销错误操作、如何浏览你的项目的历史版本以及不同提交(commits)间的差异、如何向你的远程仓库推送(push)以及如何从你的远程仓库拉取(pull)文件。1.
如果你打算使用 Git 来对现有的项目进行管理,你只需要进入该项目目录并输入:
$ git init
git添加跟踪(track)
$ git add *.c
git克隆仓库到本地
$ git clone https://github.com/404hasFound/myown.git (rename)
2.
初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。
git生命周期
查看哪些文件处于什么状态,可以用 git status
$ git status
要暂存这次更新,需要运行
git add
命令。 这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,
还能用于合并时把有冲突的文件标记为已解决状态等
。 将这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。
状态简览
git status
命令的输出十分详细,但其用语有些繁琐。 如果你使用 git status -s
命令或 git status --short
命令,你将得到一种更为紧凑的格式输出。 运行 git status -s
,状态报告输出如下:
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
新添加的未跟踪文件前面有 ??
标记,新添加到暂存区中的文件前面有 A
标记,修改过的文件前面有 M
标记。 你可能注意到了 M
有两个可以出现的位置,出现在右边的 M
表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M
表示该文件被修改了并放入了暂存区。
忽略文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore
的文件,列出要忽略的文件模式。 来看一个实际的例子:
$ cat .gitignore
*.[oa]
*~
详细对比当前目录和暂存区
$ git diff (name)
此命令比较的是工作目录中当前文件和暂存区域快照之间的差异, 也就是修改之后还没有暂存起来的变化内容。
提交更新
$ git commit
也就是提交暂存到本地仓库
跳过使用暂存区域
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit
加上 -a
选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add
步骤
2.3 Git 基础 - 查看提交历史
$ git log (-p详细信息) (--stat简单信息) (--pretty 使用不同方式展示信息
)
2.4 Git 基础 - 撤消操作
如果提交了,发现还有些没有提交完,如果再次提交也是可以的,只不过可能会有两次提交记录,看起来不是那么友好。那么就可以用这个命令,将会将上次提交和本次提交合并成一次提交,并可以重新编辑提交说明
$ git commit --amend
撤销操作到pull时的状态,就像svn的还原一样
注意:如果想返回到某次提交怎么办,首先reset到原先版本,然后checkout还原文件
或者 resert后面加上 --hard 工作空间全部还原
git checkout -- name.property
2.5 Git 基础 - 远程仓库的使用
查看远程仓库的地址或者名字
$ git remote [-v(更详细)]
添加远程仓库
运行 git remote add <shortname> <url>
从远程仓库中抓取与拉取
就如刚才所见,从远程仓库中获得数据,可以执行:
$ git fetch [remote-name]
clone
命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。
推送到远程仓库
当你想分享你的项目时,必须将其推送到上游。 这个命令很简单:git push [remote-name] [branch-name]
远程仓库重命名
$ git remote rename pb paul
3.1 Git 分支 - 分支简介
Git 保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照。
在进行提交操作时,Git 会保存一个提交对象(commit object)。知道了 Git 保存数据的方式,我们可以很自然的想到——该提交对象会包含一个指向暂存内容快照的指针。 但不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象,而由多个分支合并产生的提交对象有多个父对象
当使用 git commit
进行提交操作时Git 仓库中有五个对象:三个 blob 对象(保存着文件快照)、一个树对象(记录着目录结构和 blob 对象索引)以及一个提交对象(包含着指向前述树对象的指针和所有提交信息)。
分支创建
Git 是怎么创建新分支的呢? 很简单,它只是为你创建了一个可以移动的新的指针。 比如,创建一个 testing 分支, 你需要使用 git branch
命令:
$ git branch testing
两个指向相同提交历史的分支
那么,Git 又是怎么知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD
的特殊指针。 请注意它和许多其它版本控制系统(如 Subversion 或 CVS)里的 HEAD
概念完全不同。 在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD
想象为当前分支的别名)。 在本例中,你仍然在 master
分支上。 因为 git branch
命令仅仅 创建 一个新分支,并不会自动切换到新分支中去。
![HEAD 指向当前所在的分支。](https://i-blog.csdnimg.cn/blog_migrate/f4748c86909e97ca4c1be40f394eedfd.png)
分支切换
要切换到一个已存在的分支,你需要使用 git checkout
命令。 我们现在切换到新创建的 testing
分支去:
$ git checkout testing
分支合并
使用 git merge
命令来达到上述目的:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
在合并的时候,你应该注意到了"快进(fast-forward)"这个词。 由于当前 master
分支所指向的提交是你当前提交(有关 hotfix 的提交)的直接上游,所以 Git 只是简单的将指针向前移动。 换句话说,当你试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。
删除分支
branch
命令来删除分支:
$ git branch -d hotfix
可视化冲突解决
如果你想使用图形化工具来解决冲突,你可以运行 git mergetool
3.3 Git 分支 - 分支管理
查看已合并或者未合并的分支,以便删除
--merged
与 --no-merged
这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支。 如果要查看哪些分支已经合并到当前分支,可以运行 git branch --merged
:
如果搞不懂分支,看这节文章:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E8%BF%9C%E7%A8%8B%E5%88%86%E6%94%AF
跟踪分支(说白了就是拉取远程分支到本地)
从一个远程跟踪分支检出一个本地分支会自动创建一个叫做 “跟踪分支”(有时候也叫做 “上游分支”)。 跟踪分支是与远程分支有直接关系的本地分支。 如果在一个跟踪分支上输入 git pull
,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。
当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master
的 master
分支。 然而,如果你愿意的话可以设置其他的跟踪分支 - 其他远程仓库上的跟踪分支,或者不跟踪 master
分支。 最简单的就是之前看到的例子,运行 git checkout -b [branch] [remotename]/[branch]
。 这是一个十分常用的操作所以 Git 提供了 --track
快捷方式:
$ git checkout --track origin/serverfix
3.6 Git 分支 - 变基
和merge差不多,只不过Log看起来比较好看,pull request时作者也比较容易分辨。
详情:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA
其他
HEAD指向最后一次的快照,也就是最后一次commit
HEAD在git init时指向master 但是master指向空,在add后并且commit第一次HEAD就指向现在这次提交
如果直接clone那么git自己初始化HEAD指向master,并且所有add,也就是指向不为空
![reset ex3](https://i-blog.csdnimg.cn/blog_migrate/b098a8bb10518c88c1b0197b64ba46a4.png)
此时如果我们运行 git status
,会发现没有任何改动,因为现在三棵树完全相同。
git reset eb43bf file.txt